[SCSI] lpfc 8.3.25: Adapter Interface fixes and changes
[linux-2.6.git] / drivers / scsi / NCR5380.c
index bb3cb33..165e4dd 100644 (file)
@@ -30,7 +30,7 @@
  * $Log: NCR5380.c,v $
 
  * Revision 1.10 1998/9/2      Alan Cox
- *                             (alan@redhat.com)
+ *                             (alan@lxorguk.ukuu.org.uk)
  * Fixed up the timer lockups reported so far. Things still suck. Looking 
  * forward to 2.3 and per device request queues. Then it'll be possible to
  * SMP thread this beast and improve life no end.
@@ -295,17 +295,16 @@ static __inline__ void initialize_SCp(Scsi_Cmnd * cmd)
         * various queues are valid.
         */
 
-       if (cmd->use_sg) {
-               cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
-               cmd->SCp.buffers_residual = cmd->use_sg - 1;
-               cmd->SCp.ptr = page_address(cmd->SCp.buffer->page)+
-                              cmd->SCp.buffer->offset;
+       if (scsi_bufflen(cmd)) {
+               cmd->SCp.buffer = scsi_sglist(cmd);
+               cmd->SCp.buffers_residual = scsi_sg_count(cmd) - 1;
+               cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
                cmd->SCp.this_residual = cmd->SCp.buffer->length;
        } else {
                cmd->SCp.buffer = NULL;
                cmd->SCp.buffers_residual = 0;
-               cmd->SCp.ptr = (char *) cmd->request_buffer;
-               cmd->SCp.this_residual = cmd->request_bufflen;
+               cmd->SCp.ptr = NULL;
+               cmd->SCp.this_residual = 0;
        }
 }
 
@@ -347,7 +346,7 @@ static int NCR5380_poll_politely(struct Scsi_Host *instance, int reg, int bit, i
                if((r & bit) == val)
                        return 0;
                if(!in_interrupt())
-                       yield();
+                       cond_resched();
                else
                        cpu_relax();
        }
@@ -357,7 +356,7 @@ static int NCR5380_poll_politely(struct Scsi_Host *instance, int reg, int bit, i
 static struct {
        unsigned char value;
        const char *name;
-} phases[] = {
+} phases[] __maybe_unused = {
        {PHASE_DATAOUT, "DATAOUT"}, 
        {PHASE_DATAIN, "DATAIN"}, 
        {PHASE_CMDOUT, "CMDOUT"}, 
@@ -575,7 +574,8 @@ static irqreturn_t __init probe_intr(int irq, void *dev_id)
  *     Locks: none, irqs must be enabled on entry
  */
 
-static int __init NCR5380_probe_irq(struct Scsi_Host *instance, int possible)
+static int __init __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance,
+                                               int possible)
 {
        NCR5380_local_declare();
        struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
@@ -629,7 +629,8 @@ static int __init NCR5380_probe_irq(struct Scsi_Host *instance, int possible)
  *     Locks: none
  */
 
-static void __init NCR5380_print_options(struct Scsi_Host *instance)
+static void __init __maybe_unused
+NCR5380_print_options(struct Scsi_Host *instance)
 {
        printk(" generic options"
 #ifdef AUTOPROBE_IRQ
@@ -703,8 +704,8 @@ char *lprint_command(unsigned char *cmd, char *pos, char *buffer, int len);
 static
 char *lprint_opcode(int opcode, char *pos, char *buffer, int length);
 
-static
-int NCR5380_proc_info(struct Scsi_Host *instance, char *buffer, char **start, off_t offset, int length, int inout)
+static int __maybe_unused NCR5380_proc_info(struct Scsi_Host *instance,
+       char *buffer, char **start, off_t offset, int length, int inout)
 {
        char *pos = buffer;
        struct NCR5380_hostdata *hostdata;
@@ -931,12 +932,11 @@ static int __devinit NCR5380_init(struct Scsi_Host *instance, int flags)
  *     @instance: adapter to remove
  */
 
-static void __devexit NCR5380_exit(struct Scsi_Host *instance)
+static void NCR5380_exit(struct Scsi_Host *instance)
 {
        struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 
-       cancel_delayed_work(&hostdata->coroutine);
-       flush_scheduled_work();
+       cancel_delayed_work_sync(&hostdata->coroutine);
 }
 
 /**
@@ -951,7 +951,7 @@ static void __devexit NCR5380_exit(struct Scsi_Host *instance)
  *     Locks: host lock taken by caller
  */
 
-static int NCR5380_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) 
+static int NCR5380_queue_command_lck(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
 {
        struct Scsi_Host *instance = cmd->device->host;
        struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
@@ -974,14 +974,14 @@ static int NCR5380_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
                case WRITE_6:
                case WRITE_10:
                        hostdata->time_write[cmd->device->id] -= (jiffies - hostdata->timebase);
-                       hostdata->bytes_write[cmd->device->id] += cmd->request_bufflen;
+                       hostdata->bytes_write[cmd->device->id] += scsi_bufflen(cmd);
                        hostdata->pendingw++;
                        break;
                case READ:
                case READ_6:
                case READ_10:
                        hostdata->time_read[cmd->device->id] -= (jiffies - hostdata->timebase);
-                       hostdata->bytes_read[cmd->device->id] += cmd->request_bufflen;
+                       hostdata->bytes_read[cmd->device->id] += scsi_bufflen(cmd);
                        hostdata->pendingr++;
                        break;
        }
@@ -1020,6 +1020,7 @@ static int NCR5380_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
        return 0;
 }
 
+static DEF_SCSI_QCMD(NCR5380_queue_command)
 
 /**
  *     NCR5380_main    -       NCR state machines
@@ -1156,16 +1157,17 @@ static void NCR5380_main(struct work_struct *work)
  *     Locks: takes the needed instance locks
  */
 
-static irqreturn_t NCR5380_intr(int irq, void *dev_id) 
+static irqreturn_t NCR5380_intr(int dummy, void *dev_id)
 {
        NCR5380_local_declare();
-       struct Scsi_Host *instance = (struct Scsi_Host *)dev_id;
+       struct Scsi_Host *instance = dev_id;
        struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
        int done;
        unsigned char basr;
        unsigned long flags;
 
-       dprintk(NDEBUG_INTR, ("scsi : NCR5380 irq %d triggered\n", irq));
+       dprintk(NDEBUG_INTR, ("scsi : NCR5380 irq %d triggered\n",
+               instance->irq));
 
        do {
                done = 1;
@@ -1196,12 +1198,12 @@ static irqreturn_t NCR5380_intr(int irq, void *dev_id)
                                 */
 
                                if ((NCR5380_read(MODE_REG) & MR_DMA) && ((basr & BASR_END_DMA_TRANSFER) || !(basr & BASR_PHASE_MATCH))) {
-                                       int transfered;
+                                       int transferred;
 
                                        if (!hostdata->connected)
                                                panic("scsi%d : received end of DMA interrupt with no connected cmd\n", instance->hostno);
 
-                                       transfered = (hostdata->dmalen - NCR5380_dma_residual(instance));
+                                       transferred = (hostdata->dmalen - NCR5380_dma_residual(instance));
                                        hostdata->connected->SCp.this_residual -= transferred;
                                        hostdata->connected->SCp.ptr += transferred;
                                        hostdata->dmalen = 0;
@@ -1540,9 +1542,7 @@ part2:
        hostdata->connected = cmd;
        hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
 
-       if (cmd->SCp.ptr != (char *)cmd->sense_buffer) {
-               initialize_SCp(cmd);
-       }
+       initialize_SCp(cmd);
 
        return 0;
 
@@ -1563,7 +1563,7 @@ failed:
  *      bytes to transfer, **data - pointer to data pointer.
  * 
  * Returns : -1 when different phase is entered without transferring
- *      maximum number of bytes, 0 if all bytes or transfered or exit
+ *      maximum number of bytes, 0 if all bytes or transferred or exit
  *      is in same phase.
  *
  *      Also, *phase, *count, *data are modified in place.
@@ -1800,7 +1800,7 @@ static int do_abort(struct Scsi_Host *host) {
  *      bytes to transfer, **data - pointer to data pointer.
  * 
  * Returns : -1 when different phase is entered without transferring
- *      maximum number of bytes, 0 if all bytes or transfered or exit
+ *      maximum number of bytes, 0 if all bytes or transferred or exit
  *      is in same phase.
  *
  *      Also, *phase, *count, *data are modified in place.
@@ -1857,7 +1857,9 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase
 #endif
        /* KLL May need eop and parity in 53c400 */
        if (hostdata->flags & FLAG_NCR53C400)
-               NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_ENABLE_PAR_CHECK | MR_ENABLE_PAR_INTR | MR_ENABLE_EOP_INTR | MR_DMA_MODE | MR_MONITOR_BSY);
+               NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE |
+                               MR_ENABLE_PAR_CHECK | MR_ENABLE_PAR_INTR |
+                               MR_ENABLE_EOP_INTR | MR_MONITOR_BSY);
        else
                NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE);
 #endif                         /* def REAL_DMA */
@@ -2131,7 +2133,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
                                sink = 1;
                                do_abort(instance);
                                cmd->result = DID_ERROR << 16;
-                               cmd->done(cmd);
+                               cmd->scsi_done(cmd);
                                return;
 #endif
                                /* 
@@ -2143,8 +2145,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
                                        ++cmd->SCp.buffer;
                                        --cmd->SCp.buffers_residual;
                                        cmd->SCp.this_residual = cmd->SCp.buffer->length;
-                                       cmd->SCp.ptr = page_address(cmd->SCp.buffer->page)+
-                                                      cmd->SCp.buffer->offset;
+                                       cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
                                        dprintk(NDEBUG_INFORMATION, ("scsi%d : %d bytes and %d buffers left\n", instance->host_no, cmd->SCp.this_residual, cmd->SCp.buffers_residual));
                                }
                                /*
@@ -2194,7 +2195,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
                                                sink = 1;
                                                do_abort(instance);
                                                cmd->result = DID_ERROR << 16;
-                                               cmd->done(cmd);
+                                               cmd->scsi_done(cmd);
                                                /* XXX - need to source or sink data here, as appropriate */
                                        } else
                                                cmd->SCp.this_residual -= transfersize - len;
@@ -2278,19 +2279,16 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
                                                cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);
 
 #ifdef AUTOSENSE
+                                       if ((cmd->cmnd[0] == REQUEST_SENSE) &&
+                                               hostdata->ses.cmd_len) {
+                                               scsi_eh_restore_cmnd(cmd, &hostdata->ses);
+                                               hostdata->ses.cmd_len = 0 ;
+                                       }
+
                                        if ((cmd->cmnd[0] != REQUEST_SENSE) && (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
+                                               scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
+
                                                dprintk(NDEBUG_AUTOSENSE, ("scsi%d : performing request sense\n", instance->host_no));
-                                               cmd->cmnd[0] = REQUEST_SENSE;
-                                               cmd->cmnd[1] &= 0xe0;
-                                               cmd->cmnd[2] = 0;
-                                               cmd->cmnd[3] = 0;
-                                               cmd->cmnd[4] = sizeof(cmd->sense_buffer);
-                                               cmd->cmnd[5] = 0;
-
-                                               cmd->SCp.buffer = NULL;
-                                               cmd->SCp.buffers_residual = 0;
-                                               cmd->SCp.ptr = (char *) cmd->sense_buffer;
-                                               cmd->SCp.this_residual = sizeof(cmd->sense_buffer);
 
                                                LIST(cmd, hostdata->issue_queue);
                                                cmd->host_scribble = (unsigned char *)
@@ -2625,7 +2623,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance) {
 #ifdef REAL_DMA
 static void NCR5380_dma_complete(NCR5380_instance * instance) {
        NCR5380_local_declare();
-       struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata * instance->hostdata);
+       struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
        int transferred;
        NCR5380_setup(instance);
 
@@ -2738,7 +2736,7 @@ static int NCR5380_abort(Scsi_Cmnd * cmd) {
                        tmp->host_scribble = NULL;
                        tmp->result = DID_ABORT << 16;
                        dprintk(NDEBUG_ABORT, ("scsi%d : abort removed command from issue queue.\n", instance->host_no));
-                       tmp->done(tmp);
+                       tmp->scsi_done(tmp);
                        return SUCCESS;
                }
 #if (NDEBUG  & NDEBUG_ABORT)
@@ -2803,7 +2801,7 @@ static int NCR5380_abort(Scsi_Cmnd * cmd) {
                                        *prev = (Scsi_Cmnd *) tmp->host_scribble;
                                        tmp->host_scribble = NULL;
                                        tmp->result = DID_ABORT << 16;
-                                       tmp->done(tmp);
+                                       tmp->scsi_done(tmp);
                                        return SUCCESS;
                                }
                }