Commit ea10cfeb authored by Alan Cox's avatar Alan Cox Committed by Linus Torvalds

[PATCH] update the u14-34f driver to maintainer updates

(With bios changes merged)
parent 4476a8de
/*
* u14-34f.c - Low-level driver for UltraStor 14F/34F SCSI host adapters.
*
* 28 Oct 2002 Rev. 8.00 for linux 2.5.44-ac4
* + Use new tcq and adjust_queue_depth api.
* + New command line option (tm:[0-2]) to choose the type of tags:
* 0 -> disable tagging ; 1 -> simple tags ; 2 -> ordered tags.
* Default is tm:0 (tagged commands disabled).
* For compatibility the "tc:" option is an alias of the "tm:"
* option; tc:n is equivalent to tm:0 and tc:y is equivalent to
* tm:1.
*
* 10 Oct 2002 Rev. 7.70 for linux 2.5.42
* + Foreport from revision 6.70.
*
......@@ -304,19 +313,22 @@
* et:n use disk geometry jumpered on the board;
* lc:y enables linked commands;
* lc:n disables linked commands;
* tm:0 disables tagged commands (same as tc:n);
* tm:1 use simple queue tags (same as tc:y);
* tm:2 use ordered queue tags (same as tc:2);
* of:y enables old firmware support;
* of:n disables old firmware support;
* mq:xx set the max queue depth to the value xx (2 <= xx <= 8).
*
* The default value is: "u14-34f=lc:n,of:n,mq:8,et:n".
* The default value is: "u14-34f=lc:n,of:n,mq:8,tm:0,et:n".
* An example using the list of detection probes could be:
* "u14-34f=0x230,0x340,lc:y,of:n,mq:4,et:n".
* "u14-34f=0x230,0x340,lc:y,tm:2,of:n,mq:4,et:n".
*
* When loading as a module, parameters can be specified as well.
* The above example would be (use 1 in place of y and 0 in place of n):
*
* modprobe u14-34f io_port=0x230,0x340 linked_comm=1 have_old_firmware=0 \
* max_queue_depth=4 ext_tran=0
* max_queue_depth=4 ext_tran=0 tag_mode=2
*
* ----------------------------------------------------------------------------
* In this implementation, linked commands are designed to work with any DISK
......@@ -374,6 +386,7 @@ MODULE_PARM(linked_comm, "i");
MODULE_PARM(have_old_firmware, "i");
MODULE_PARM(link_statistics, "i");
MODULE_PARM(max_queue_depth, "i");
MODULE_PARM(tag_mode, "i");
MODULE_PARM(ext_tran, "i");
MODULE_AUTHOR("Dario Ballabio");
......@@ -400,6 +413,7 @@ MODULE_AUTHOR("Dario Ballabio");
#include <linux/init.h>
#include <linux/ctype.h>
#include <linux/spinlock.h>
#include <scsi/scsicam.h>
#if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD)
#error "Adjust your <asm/byteorder.h> defines"
......@@ -460,6 +474,9 @@ MODULE_AUTHOR("Dario Ballabio");
#define ABORTING 6
#define NO_DMA 0xff
#define MAXLOOP 10000
#define TAG_DISABLED 0
#define TAG_SIMPLE 1
#define TAG_ORDERED 2
#define REG_LCL_MASK 0
#define REG_LCL_INTR 1
......@@ -593,6 +610,12 @@ static int have_old_firmware = TRUE;
static int have_old_firmware = FALSE;
#endif
#if defined(CONFIG_SCSI_U14_34F_TAGGED_QUEUE)
static int tag_mode = TAG_SIMPLE;
#else
static int tag_mode = TAG_DISABLED;
#endif
#if defined(CONFIG_SCSI_U14_34F_LINKED_COMMANDS)
static int linked_comm = TRUE;
#else
......@@ -605,61 +628,56 @@ static int max_queue_depth = CONFIG_SCSI_U14_34F_MAX_TAGS;
static int max_queue_depth = MAX_CMD_PER_LUN;
#endif
static void select_queue_depths(struct Scsi_Host *host, Scsi_Device *devlist) {
Scsi_Device *dev;
int j, ntag = 0, nuntag = 0, tqd, utqd;
static int u14_34f_slave_attach(Scsi_Device *dev) {
int j, tqd, utqd;
char *tag_suffix, *link_suffix;
struct Scsi_Host *host = dev->host;
j = ((struct hostdata *) host->hostdata)->board_number;
for(dev = devlist; dev; dev = dev->next) {
if (dev->host != host) continue;
if (TLDEV(dev->type) && (dev->tagged_supported || linked_comm))
ntag++;
else
nuntag++;
}
utqd = MAX_CMD_PER_LUN;
tqd = max_queue_depth;
tqd = (host->can_queue - utqd * nuntag) / (ntag ? ntag : 1);
if (TLDEV(dev->type) && dev->tagged_supported)
if (tqd > max_queue_depth) tqd = max_queue_depth;
if (tqd < MAX_CMD_PER_LUN) tqd = MAX_CMD_PER_LUN;
for(dev = devlist; dev; dev = dev->next) {
char *tag_suffix = "", *link_suffix = "";
if (dev->host != host) continue;
if (TLDEV(dev->type) && (dev->tagged_supported || linked_comm))
dev->queue_depth = tqd;
else
dev->queue_depth = utqd;
if (TLDEV(dev->type)) {
if (linked_comm && dev->queue_depth > 2)
link_suffix = ", sorted";
else
link_suffix = ", unsorted";
if (tag_mode == TAG_SIMPLE) {
scsi_adjust_queue_depth(dev, MSG_SIMPLE_TAG, tqd);
tag_suffix = ", simple tags";
}
else if (tag_mode == TAG_ORDERED) {
scsi_adjust_queue_depth(dev, MSG_ORDERED_TAG, tqd);
tag_suffix = ", ordered tags";
}
else {
scsi_adjust_queue_depth(dev, 0, tqd);
tag_suffix = ", no tags";
}
if (dev->tagged_supported && TLDEV(dev->type) && dev->tagged_queue)
tag_suffix = ", soft-tagged";
else if (dev->tagged_supported && TLDEV(dev->type))
tag_suffix = ", tagged";
else if (TLDEV(dev->type) && linked_comm) {
scsi_adjust_queue_depth(dev, 0, tqd);
tag_suffix = ", untagged";
}
printk("%s: scsi%d, channel %d, id %d, lun %d, cmds/lun %d%s%s.\n",
BN(j), host->host_no, dev->channel, dev->id, dev->lun,
dev->queue_depth, link_suffix, tag_suffix);
else {
scsi_adjust_queue_depth(dev, 0, utqd);
tag_suffix = "";
}
return;
if (TLDEV(dev->type) && linked_comm && dev->new_queue_depth > 2)
link_suffix = ", sorted";
else if (TLDEV(dev->type))
link_suffix = ", unsorted";
else
link_suffix = "";
printk("%s: scsi%d, channel %d, id %d, lun %d, cmds/lun %d%s%s.\n",
BN(j), host->host_no, dev->channel, dev->id, dev->lun,
dev->new_queue_depth, link_suffix, tag_suffix);
return FALSE;
}
static inline int wait_on_busy(unsigned long iobase, unsigned int loop) {
static int wait_on_busy(unsigned long iobase, unsigned int loop) {
while (inb(iobase + REG_LCL_INTR) & BSY_ASSERTED) {
udelay(1L);
......@@ -721,7 +739,7 @@ static int board_inquiry(unsigned int j) {
return FALSE;
}
static inline int port_detect \
static int port_detect \
(unsigned long port_base, unsigned int j, Scsi_Host_Template *tpnt) {
unsigned char irq, dma_channel, subversion, i;
unsigned char in_byte;
......@@ -843,7 +861,6 @@ static inline int port_detect \
sh[j]->this_id = config_2.ha_scsi_id;
sh[j]->can_queue = MAX_MAILBOXES;
sh[j]->cmd_per_lun = MAX_CMD_PER_LUN;
sh[j]->select_queue_depths = select_queue_depths;
#if defined(DEBUG_DETECT)
{
......@@ -930,11 +947,14 @@ static inline int port_detect \
if (max_queue_depth < MAX_CMD_PER_LUN) max_queue_depth = MAX_CMD_PER_LUN;
if (tag_mode != TAG_DISABLED && tag_mode != TAG_SIMPLE)
tag_mode = TAG_ORDERED;
if (j == 0) {
printk("UltraStor 14F/34F: Copyright (C) 1994-2002 Dario Ballabio.\n");
printk("%s config options -> of:%c, lc:%c, mq:%d, et:%c.\n",
driver_name, YESNO(have_old_firmware), YESNO(linked_comm),
max_queue_depth, YESNO(ext_tran));
printk("%s config options -> of:%c, tm:%d, lc:%c, mq:%d, et:%c.\n",
driver_name, YESNO(have_old_firmware), tag_mode,
YESNO(linked_comm), max_queue_depth, YESNO(ext_tran));
}
printk("%s: %s 0x%03lx, BIOS 0x%05x, IRQ %u, %s, SG %d, MB %d.\n",
......@@ -975,6 +995,8 @@ static void internal_setup(char *str, int *ints) {
if (!strncmp(cur, "lc:", 3)) linked_comm = val;
else if (!strncmp(cur, "of:", 3)) have_old_firmware = val;
else if (!strncmp(cur, "tm:", 3)) tag_mode = val;
else if (!strncmp(cur, "tc:", 3)) tag_mode = val;
else if (!strncmp(cur, "mq:", 3)) max_queue_depth = val;
else if (!strncmp(cur, "ls:", 3)) link_statistics = val;
else if (!strncmp(cur, "et:", 3)) ext_tran = val;
......@@ -1001,7 +1023,7 @@ static int option_setup(char *str) {
return 1;
}
int u14_34f_detect(Scsi_Host_Template *tpnt) {
static int u14_34f_detect(Scsi_Host_Template *tpnt) {
unsigned int j = 0, k;
unsigned long spin_flags;
......@@ -1033,7 +1055,7 @@ int u14_34f_detect(Scsi_Host_Template *tpnt) {
return j;
}
static inline void map_dma(unsigned int i, unsigned int j) {
static void map_dma(unsigned int i, unsigned int j) {
unsigned int data_len = 0;
unsigned int k, count, pci_dir;
struct scatterlist *sgpnt;
......@@ -1123,7 +1145,7 @@ static void sync_dma(unsigned int i, unsigned int j) {
DEV2H(cpp->data_len), pci_dir);
}
static inline void scsi_to_dev_dir(unsigned int i, unsigned int j) {
static void scsi_to_dev_dir(unsigned int i, unsigned int j) {
unsigned int k;
static const unsigned char data_out_cmds[] = {
......@@ -1176,7 +1198,7 @@ static inline void scsi_to_dev_dir(unsigned int i, unsigned int j) {
}
static inline int do_qcomm(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
static int u14_34f_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
unsigned int i, j, k;
struct mscp *cpp;
......@@ -1232,7 +1254,7 @@ static inline int do_qcomm(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
/* Map DMA buffers and SG list */
map_dma(i, j);
if (linked_comm && SCpnt->device->queue_depth > 2
if (linked_comm && SCpnt->device->new_queue_depth > 2
&& TLDEV(SCpnt->device->type)) {
HD(j)->cp_stat[i] = READY;
flush_dev(SCpnt->device, SCpnt->request->sector, j, FALSE);
......@@ -1257,14 +1279,7 @@ static inline int do_qcomm(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
return 0;
}
int u14_34f_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {
int rtn;
rtn = do_qcomm(SCpnt, done);
return rtn;
}
static inline int do_abort(Scsi_Cmnd *SCarg) {
static int u14_34f_eh_abort(Scsi_Cmnd *SCarg) {
unsigned int i, j;
j = ((struct hostdata *) SCarg->host->hostdata)->board_number;
......@@ -1338,12 +1353,7 @@ static inline int do_abort(Scsi_Cmnd *SCarg) {
panic("%s: abort, mbox %d, invalid cp_stat.\n", BN(j), i);
}
int u14_34f_abort(Scsi_Cmnd *SCarg) {
return do_abort(SCarg);
}
static inline int do_reset(Scsi_Cmnd *SCarg) {
static int u14_34f_eh_host_reset(Scsi_Cmnd *SCarg) {
unsigned int i, j, time, k, c, limit = 0;
int arg_done = FALSE;
Scsi_Cmnd *SCpnt;
......@@ -1476,28 +1486,23 @@ static inline int do_reset(Scsi_Cmnd *SCarg) {
return SUCCESS;
}
int u14_34f_reset(Scsi_Cmnd *SCarg) {
return do_reset(SCarg);
}
int u14_34f_biosparam(struct scsi_device *sdev, struct block_device *bdev,
sector_t capacity, int *dkinfo) {
static int u14_34f_bios_param(Disk *disk, struct block_device *bdev,
int *dkinfo) {
unsigned int j = 0;
int size = capacity;
int size = disk->capacity;
dkinfo[0] = HD(j)->heads;
dkinfo[1] = HD(j)->sectors;
dkinfo[2] = size / (HD(j)->heads * HD(j)->sectors);
if (ext_tran && (scsicam_bios_param(bdev, capacity, dkinfo) < 0)) {
if (ext_tran && (scsicam_bios_param(disk, bdev, dkinfo) < 0)) {
dkinfo[0] = 255;
dkinfo[1] = 63;
dkinfo[2] = size / (dkinfo[0] * dkinfo[1]);
}
#if defined (DEBUG_GEOMETRY)
printk ("%s: biosparam, head=%d, sec=%d, cyl=%d.\n", driver_name,
printk ("%s: bios_param, head=%d, sec=%d, cyl=%d.\n", driver_name,
dkinfo[0], dkinfo[1], dkinfo[2]);
#endif
......@@ -1529,7 +1534,7 @@ static void sort(unsigned long sk[], unsigned int da[], unsigned int n,
return;
}
static inline int reorder(unsigned int j, unsigned long cursec,
static int reorder(unsigned int j, unsigned long cursec,
unsigned int ihdlr, unsigned int il[], unsigned int n_ready) {
Scsi_Cmnd *SCpnt;
struct mscp *cpp;
......@@ -1666,7 +1671,7 @@ static void flush_dev(Scsi_Device *dev, unsigned long cursec, unsigned int j,
}
static inline void ihdlr(int irq, unsigned int j) {
static void ihdlr(int irq, unsigned int j) {
Scsi_Cmnd *SCpnt;
unsigned int i, k, c, status, tstatus, reg, ret;
struct mscp *spp, *cpp;
......@@ -1746,7 +1751,7 @@ static inline void ihdlr(int irq, unsigned int j) {
sync_dma(i, j);
if (linked_comm && SCpnt->device->queue_depth > 2
if (linked_comm && SCpnt->device->new_queue_depth > 2
&& TLDEV(SCpnt->device->type))
flush_dev(SCpnt->device, SCpnt->request->sector, j, TRUE);
......@@ -1888,7 +1893,7 @@ static void do_interrupt_handler(int irq, void *shap, struct pt_regs *regs) {
spin_unlock_irqrestore(sh[j]->host_lock, spin_flags);
}
int u14_34f_release(struct Scsi_Host *shpnt) {
static int u14_34f_release(struct Scsi_Host *shpnt) {
unsigned int i, j;
for (j = 0; sh[j] != NULL && sh[j] != shpnt; j++);
......
/*
* u14-34f.h - used by the low-level driver for UltraStor 14F/34F
*/
#ifndef _U14_34F_H
#define _U14_34F_H
#include <scsi/scsicam.h>
static int u14_34f_detect(Scsi_Host_Template *);
static int u14_34f_release(struct Scsi_Host *);
static int u14_34f_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
static int u14_34f_eh_abort(Scsi_Cmnd *);
static int u14_34f_eh_host_reset(Scsi_Cmnd *);
static int u14_34f_bios_param(Disk *, struct block_device *, int *);
static int u14_34f_slave_attach(Scsi_Device *);
int u14_34f_detect(Scsi_Host_Template *);
int u14_34f_release(struct Scsi_Host *);
int u14_34f_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
int u14_34f_abort(Scsi_Cmnd *);
int u14_34f_reset(Scsi_Cmnd *);
int u14_34f_biosparam(struct scsi_device *, struct block_device *,
sector_t, int *);
#define U14_34F_VERSION "7.70.00"
#define U14_34F_VERSION "8.00.00"
#define ULTRASTOR_14_34F { \
name: "UltraStor 14F/34F rev. " U14_34F_VERSION " ", \
......@@ -23,14 +19,13 @@ int u14_34f_biosparam(struct scsi_device *, struct block_device *,
queuecommand: u14_34f_queuecommand, \
abort: NULL, \
reset: NULL, \
eh_abort_handler: u14_34f_abort, \
eh_abort_handler: u14_34f_eh_abort, \
eh_device_reset_handler: NULL, \
eh_bus_reset_handler: NULL, \
eh_host_reset_handler: u14_34f_reset, \
bios_param: u14_34f_biosparam, \
eh_host_reset_handler: u14_34f_eh_host_reset, \
bios_param: u14_34f_bios_param, \
slave_attach: u14_34f_slave_attach, \
this_id: 7, \
unchecked_isa_dma: 1, \
use_clustering: ENABLE_CLUSTERING, \
use_clustering: ENABLE_CLUSTERING \
}
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment