PATCH: first pass over the in2000

From: Alan Cox (alan@lxorguk.ukuu.org.uk)
Date: Wed Oct 09 2002 - 13:22:38 EST


- new locking
- new_eh
- use ->page/->offset

diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.2.5.41/drivers/scsi/in2000.c linux.2.5.41-ac2/drivers/scsi/in2000.c
--- linux.2.5.41/drivers/scsi/in2000.c 2002-10-02 21:32:55.000000000 +0100
+++ linux.2.5.41-ac2/drivers/scsi/in2000.c 2002-10-09 16:23:17.000000000 +0100
@@ -317,13 +317,15 @@
 
 static void in2000_execute(struct Scsi_Host *instance);
 
-int in2000_queuecommand (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
+static int in2000_queuecommand (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
 {
+struct Scsi_Host *instance;
 struct IN2000_hostdata *hostdata;
 Scsi_Cmnd *tmp;
 unsigned long flags;
 
- hostdata = (struct IN2000_hostdata *)cmd->host->hostdata;
+ instance = cmd->host;
+ hostdata = (struct IN2000_hostdata *)instance->hostdata;
 
 DB(DB_QUEUE_COMMAND,printk("Q-%d-%02x-%ld(",cmd->target,cmd->cmnd[0],cmd->pid))
 
@@ -355,7 +357,7 @@
    if (cmd->use_sg) {
       cmd->SCp.buffer = (struct scatterlist *)cmd->buffer;
       cmd->SCp.buffers_residual = cmd->use_sg - 1;
- cmd->SCp.ptr = (char *)cmd->SCp.buffer->address;
+ cmd->SCp.ptr = (char *)page_address(cmd->SCp.buffer->page)+cmd->SCp.buffer->offset;
       cmd->SCp.this_residual = cmd->SCp.buffer->length;
       }
    else {
@@ -391,9 +393,7 @@
  * queue and calling in2000_execute().
  */
 
- save_flags(flags);
- cli();
-
+ spin_lock_irqsave(instance->host_lock, flags);
    /*
     * Add the cmd to the end of 'input_Q'. Note that REQUEST_SENSE
     * commands are added to the head of the queue so that the desired
@@ -418,8 +418,7 @@
    in2000_execute(cmd->host);
 
 DB(DB_QUEUE_COMMAND,printk(")Q-%ld ",cmd->pid))
-
- restore_flags(flags);
+ spin_unlock_irqrestore(instance->host_lock, flags);
    return 0;
 }
 
@@ -762,7 +761,7 @@
       ++cmd->SCp.buffer;
       --cmd->SCp.buffers_residual;
       cmd->SCp.this_residual = cmd->SCp.buffer->length;
- cmd->SCp.ptr = cmd->SCp.buffer->address;
+ cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset;
       }
 
 /* Set up hardware registers */
@@ -855,7 +854,7 @@
 
 /* Get the spin_lock and disable further ints, for SMP */
 
- CLISPIN_LOCK(instance, flags);
+ spin_lock_irqsave(instance->host_lock, flags);
 
 #ifdef PROC_STATISTICS
    hostdata->int_cnt++;
@@ -993,7 +992,7 @@
       write1_io(0, IO_LED_OFF);
 
 /* release the SMP spin_lock and restore irq state */
- CLISPIN_UNLOCK(instance, flags);
+ spin_unlock_irqrestore(instance->host_lock, flags);
       return;
       }
 
@@ -1011,7 +1010,7 @@
       write1_io(0, IO_LED_OFF);
 
 /* release the SMP spin_lock and restore irq state */
- CLISPIN_UNLOCK(instance, flags);
+ spin_unlock_irqrestore(instance->host_lock, flags);
       return;
       }
 
@@ -1433,7 +1432,7 @@
             hostdata->state = S_UNCONNECTED;
 
 /* release the SMP spin_lock and restore irq state */
- CLISPIN_UNLOCK(instance, flags);
+ spin_unlock_irqrestore(instance->host_lock, flags);
             return;
             }
 DB(DB_INTR,printk("UNEXP_DISC-%ld",cmd->pid))
@@ -1609,7 +1608,7 @@
 DB(DB_INTR,printk("} "))
 
 /* release the SMP spin_lock and restore irq state */
- CLISPIN_UNLOCK(instance, flags);
+ spin_unlock_irqrestore(instance->host_lock, flags);
 
 }
 
@@ -1619,11 +1618,14 @@
 #define RESET_CARD_AND_BUS 1
 #define B_FLAG 0x80
 
+/*
+ * Caller must hold instance lock!
+ */
+
 static int reset_hardware(struct Scsi_Host *instance, int type)
 {
 struct IN2000_hostdata *hostdata;
 int qt,x;
-unsigned long flags;
 
    hostdata = (struct IN2000_hostdata *)instance->hostdata;
 
@@ -1638,16 +1640,16 @@
    write_3393(hostdata,WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
    write_3393(hostdata,WD_SYNCHRONOUS_TRANSFER,
               calc_sync_xfer(hostdata->default_sx_per/4,DEFAULT_SX_OFF));
- save_flags(flags);
- cli();
+
    write1_io(0,IO_FIFO_WRITE); /* clear fifo counter */
    write1_io(0,IO_FIFO_READ); /* start fifo out in read mode */
    write_3393(hostdata,WD_COMMAND, WD_CMD_RESET);
+ /* FIXME: timeout ?? */
    while (!(READ_AUX_STAT() & ASR_INT))
- ; /* wait for RESET to complete */
+ cpu_relax(); /* wait for RESET to complete */
 
    x = read_3393(hostdata,WD_SCSI_STATUS); /* clear interrupt */
- restore_flags(flags);
+
    write_3393(hostdata,WD_QUEUE_TAG,0xa5); /* any random number */
    qt = read_3393(hostdata,WD_QUEUE_TAG);
    if (qt == 0xa5) {
@@ -1662,7 +1664,7 @@
 
 
 
-int in2000_reset(Scsi_Cmnd *cmd, unsigned int reset_flags)
+static int in2000_bus_reset(Scsi_Cmnd *cmd)
 {
 unsigned long flags;
 struct Scsi_Host *instance;
@@ -1672,10 +1674,9 @@
    instance = cmd->host;
    hostdata = (struct IN2000_hostdata *)instance->hostdata;
 
- printk("scsi%d: Reset. ", instance->host_no);
- save_flags(flags);
- cli();
+ printk(KERN_WARNING "scsi%d: Reset. ", instance->host_no);
 
+ spin_lock_irqsave(instance->host_lock, flags);
    /* do scsi-reset here */
 
    reset_hardware(instance, RESET_CARD_AND_BUS);
@@ -1694,13 +1695,22 @@
    hostdata->outgoing_len = 0;
 
    cmd->result = DID_RESET << 16;
- restore_flags(flags);
- return 0;
+ spin_unlock_irqrestore(instance->host_lock, flags);
+ return SUCCESS;
 }
 
+static int in2000_host_reset(Scsi_Cmnd *cmd)
+{
+ return FAILED;
+}
 
+static int in2000_device_reset(Scsi_Cmnd *cmd)
+{
+ return FAILED;
+}
 
-int in2000_abort (Scsi_Cmnd *cmd)
+
+static int in2000_abort (Scsi_Cmnd *cmd)
 {
 struct Scsi_Host *instance;
 struct IN2000_hostdata *hostdata;
@@ -1709,13 +1719,10 @@
 uchar sr, asr;
 unsigned long timeout;
 
- save_flags (flags);
- cli();
-
    instance = cmd->host;
    hostdata = (struct IN2000_hostdata *)instance->hostdata;
 
- printk ("scsi%d: Abort-", instance->host_no);
+ printk(KERN_DEBUG "scsi%d: Abort-", instance->host_no);
    printk("(asr=%02x,count=%ld,resid=%d,buf_resid=%d,have_data=%d,FC=%02x)- ",
             READ_AUX_STAT(),read_3393_count(hostdata),cmd->SCp.this_residual,cmd->SCp.buffers_residual,
             cmd->SCp.have_data_in,read1_io(IO_FIFO_COUNT));
@@ -1725,6 +1732,7 @@
  * from the inout_Q.
  */
 
+ spin_lock_irqsave(instance->host_lock, flags);
    tmp = (Scsi_Cmnd *)hostdata->input_Q;
    prev = 0;
    while (tmp) {
@@ -1733,11 +1741,11 @@
             prev->host_scribble = cmd->host_scribble;
          cmd->host_scribble = NULL;
          cmd->result = DID_ABORT << 16;
- printk("scsi%d: Abort - removing command %ld from input_Q. ",
+ printk(KERN_WARNING "scsi%d: Abort - removing command %ld from input_Q. ",
            instance->host_no, cmd->pid);
          cmd->scsi_done(cmd);
- restore_flags(flags);
- return SCSI_ABORT_SUCCESS;
+ spin_unlock_irqrestore(instance->host_lock, flags);
+ return SUCCESS;
          }
       prev = tmp;
       tmp = (Scsi_Cmnd *)tmp->host_scribble;
@@ -1756,7 +1764,7 @@
 
    if (hostdata->connected == cmd) {
 
- printk("scsi%d: Aborting connected command %ld - ",
+ printk(KERN_WARNING "scsi%d: Aborting connected command %ld - ",
               instance->host_no, cmd->pid);
 
       printk("sending wd33c93 ABORT command - ");
@@ -1800,7 +1808,6 @@
 
       in2000_execute (instance);
 
- restore_flags(flags);
       return SCSI_ABORT_SUCCESS;
       }
 
@@ -1813,9 +1820,9 @@
    for (tmp=(Scsi_Cmnd *)hostdata->disconnected_Q; tmp;
          tmp=(Scsi_Cmnd *)tmp->host_scribble)
       if (cmd == tmp) {
- restore_flags(flags);
- printk("Sending ABORT_SNOOZE. ");
- return SCSI_ABORT_SNOOZE;
+ spin_unlock_irqrestore(instance->host_lock, flags);
+ printk(KERN_DEBUG "scsi%d: unable to abort disconnected command.\n", instance->host_no);
+ return FAILED;
          }
 
 /*
@@ -1830,10 +1837,10 @@
 
    in2000_execute (instance);
 
- restore_flags(flags);
+ spin_unlock_irqrestore(instance->host_lock, flags);
    printk("scsi%d: warning : SCSI command probably completed successfully"
       " before abortion. ", instance->host_no);
- return SCSI_ABORT_NOT_RUNNING;
+ return SUCCESS;
 }
 
 
@@ -1845,7 +1852,7 @@
 static char setup_used[MAX_SETUP_ARGS];
 static int done_setup = 0;
 
-void __init in2000_setup (char *str, int *ints)
+static void __init in2000_setup (char *str, int *ints)
 {
 int i;
 char *p1,*p2;
@@ -1931,7 +1938,7 @@
    };
 
 
-int __init in2000_detect(Scsi_Host_Template * tpnt)
+static int __init in2000_detect(Scsi_Host_Template * tpnt)
 {
 struct Scsi_Host *instance;
 struct IN2000_hostdata *hostdata;
@@ -2115,7 +2122,11 @@
 #endif
 
 
+ /* FIXME: not strictly needed I think but the called code expects
+ to be locked */
+ spin_lock_irqsave(instance->host_lock, flags);
       x = reset_hardware(instance,(hostdata->args & A_NO_SCSI_RESET)?RESET_CARD:RESET_CARD_AND_BUS);
+ spin_unlock_irqrestore(instance->host_lock, flags);
 
       hostdata->microcode = read_3393(hostdata,WD_CDB_1);
       if (x & 0x01) {
@@ -2158,7 +2169,7 @@
  * supposed to do...
  */
 
-int in2000_biosparam(Disk *disk, struct block_device *dev, int *iinfo)
+static int in2000_biosparam(Disk *disk, struct block_device *dev, int *iinfo)
 {
 int size;
 
@@ -2190,7 +2201,7 @@
 }
 
 
-int in2000_proc_info(char *buf, char **start, off_t off, int len, int hn, int in)
+static int in2000_proc_info(char *buf, char **start, off_t off, int len, int hn, int in)
 {
 
 #ifdef PROC_INTERFACE
@@ -2260,8 +2271,7 @@
       return len;
       }
 
- save_flags(flags);
- cli();
+ spin_lock_irqsave(instance->host_lock, flags);
    bp = buf;
    *bp = '\0';
    if (hd->proc & PR_VERSION) {
@@ -2340,7 +2350,7 @@
       ; /* insert your own custom function here */
       }
    strcat(bp,"\n");
- restore_flags(flags);
+ spin_unlock_irqrestore(instance->host_lock, flags);
    *start = buf;
    if (stop) {
       stop = 0;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.2.5.41/drivers/scsi/in2000.h linux.2.5.41-ac2/drivers/scsi/in2000.h
--- linux.2.5.41/drivers/scsi/in2000.h 2002-10-02 21:32:55.000000000 +0100
+++ linux.2.5.41-ac2/drivers/scsi/in2000.h 2002-10-09 16:17:42.000000000 +0100
@@ -397,13 +397,15 @@
 # define CLISPIN_UNLOCK(host,flags) spin_unlock_irqrestore(host->host_lock, \
                                                            flags)
 
-int in2000_detect(Scsi_Host_Template *) in2000__INIT;
-int in2000_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int in2000_abort(Scsi_Cmnd *);
-void in2000_setup(char *, int *) in2000__INIT;
-int in2000_proc_info(char *, char **, off_t, int, int, int);
-int in2000_biosparam(struct scsi_disk *, struct block_device *, int *);
-int in2000_reset(Scsi_Cmnd *, unsigned int);
+static int in2000_detect(Scsi_Host_Template *) in2000__INIT;
+static int in2000_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static int in2000_abort(Scsi_Cmnd *);
+static void in2000_setup(char *, int *) in2000__INIT;
+static int in2000_proc_info(char *, char **, off_t, int, int, int);
+static int in2000_biosparam(struct scsi_disk *, struct block_device *, int *);
+static int in2000_host_reset(Scsi_Cmnd *);
+static int in2000_bus_reset(Scsi_Cmnd *);
+static int in2000_device_reset(Scsi_Cmnd *);
 
 
 #define IN2000_CAN_Q 16
@@ -411,19 +413,21 @@
 #define IN2000_CPL 2
 #define IN2000_HOST_ID 7
 
-#define IN2000 { proc_name: "in2000", /* name of /proc/scsi directory entry */ \
- proc_info: in2000_proc_info, /* pointer to proc info function */ \
- name: "Always IN2000", /* device name */ \
- detect: in2000_detect, /* returns number of in2000's found */ \
- queuecommand: in2000_queuecommand, /* queue scsi command, don't wait */ \
- abort: in2000_abort, /* abort current command */ \
- reset: in2000_reset, /* reset scsi bus */ \
- bios_param: in2000_biosparam, /* figures out BIOS parameters for lilo, etc */ \
- can_queue: IN2000_CAN_Q, /* max commands we can queue up */ \
- this_id: IN2000_HOST_ID, /* host-adapter scsi id */ \
- sg_tablesize: IN2000_SG, /* scatter-gather table size */ \
- cmd_per_lun: IN2000_CPL, /* commands per lun */ \
- use_clustering: DISABLE_CLUSTERING, /* ENABLE_CLUSTERING may speed things up */ \
+#define IN2000 { proc_name: "in2000", /* name of /proc/scsi directory entry */ \
+ proc_info: in2000_proc_info, /* pointer to proc info function */ \
+ name: "Always IN2000", /* device name */ \
+ detect: in2000_detect, /* returns number of in2000's found */ \
+ queuecommand: in2000_queuecommand, /* queue scsi command, don't wait */ \
+ eh_abort_handler: in2000_abort, /* abort current command */ \
+ eh_bus_reset_handler: in2000_bus_reset, /* reset scsi bus */ \
+ eh_device_reset_handler: in2000_device_reset, /* reset scsi device */ \
+ eh_host_reset_handler: in2000_host_reset, /* reset scsi hba */ \
+ bios_param: in2000_biosparam, /* figures out BIOS parameters for lilo, etc */ \
+ can_queue: IN2000_CAN_Q, /* max commands we can queue up */ \
+ this_id: IN2000_HOST_ID, /* host-adapter scsi id */ \
+ sg_tablesize: IN2000_SG, /* scatter-gather table size */ \
+ cmd_per_lun: IN2000_CPL, /* commands per lun */ \
+ use_clustering: DISABLE_CLUSTERING, /* ENABLE_CLUSTERING may speed things up */ \
                 }
 
 #endif /* IN2000_H */
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Tue Oct 15 2002 - 22:00:32 EST