]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/scsi/atari_NCR5380.c
ncr5380: Remove LIST and REMOVE macros
[karo-tx-linux.git] / drivers / scsi / atari_NCR5380.c
index 08e8ace2681bffe89831513107591e188d971e64..0347c87c7b537a804c2907aedaffb0692014dfad 100644 (file)
 
 /* Adapted for the sun3 by Sam Creasey. */
 
-#if (NDEBUG & NDEBUG_LISTS)
-#define LIST(x, y)                                             \
-       do {                                                    \
-               printk("LINE:%d   Adding %p to %p\n",           \
-                      __LINE__, (void*)(x), (void*)(y));       \
-               if ((x) == (y))                                 \
-                       udelay(5);                              \
-       } while (0)
-#define REMOVE(w, x, y, z)                                     \
-       do {                                                    \
-               printk("LINE:%d   Removing: %p->%p  %p->%p \n", \
-                      __LINE__, (void*)(w), (void*)(x),        \
-                      (void*)(y), (void*)(z));                 \
-               if ((x) == (y))                                 \
-                       udelay(5);                              \
-       } while (0)
-#else
-#define LIST(x,y)
-#define REMOVE(w,x,y,z)
-#endif
-
 /*
  * Design
  *
  * possible) function may be used.
  */
 
-/* Macros ease life... :-) */
-#define        SETUP_HOSTDATA(in)                              \
-    struct NCR5380_hostdata *hostdata =                        \
-       (struct NCR5380_hostdata *)(in)->hostdata
-#define        HOSTDATA(in) ((struct NCR5380_hostdata *)(in)->hostdata)
-
 #define        NEXT(cmd)               ((struct scsi_cmnd *)(cmd)->host_scribble)
 #define        SET_NEXT(cmd,next)      ((cmd)->host_scribble = (void *)(next))
 #define        NEXTADDR(cmd)           ((struct scsi_cmnd **)&(cmd)->host_scribble)
 
 #define        HOSTNO          instance->host_no
-#define        H_NO(cmd)       (cmd)->device->host->host_no
 
 static int do_abort(struct Scsi_Host *);
 static void do_reset(struct Scsi_Host *);
@@ -280,7 +252,8 @@ static void __init init_tags(struct NCR5380_hostdata *hostdata)
 static int is_lun_busy(struct scsi_cmnd *cmd, int should_be_tagged)
 {
        u8 lun = cmd->device->lun;
-       SETUP_HOSTDATA(cmd->device->host);
+       struct Scsi_Host *instance = cmd->device->host;
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
        if (hostdata->busy[cmd->device->id] & (1 << lun))
                return 1;
@@ -290,8 +263,8 @@ static int is_lun_busy(struct scsi_cmnd *cmd, int should_be_tagged)
                return 0;
        if (hostdata->TagAlloc[scmd_id(cmd)][lun].nr_allocated >=
            hostdata->TagAlloc[scmd_id(cmd)][lun].queue_size) {
-               dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d: no free tags\n",
-                          H_NO(cmd), cmd->device->id, lun);
+               dsprintk(NDEBUG_TAGS, instance, "target %d lun %d: no free tags\n",
+                        scmd_id(cmd), lun);
                return 1;
        }
        return 0;
@@ -306,7 +279,8 @@ static int is_lun_busy(struct scsi_cmnd *cmd, int should_be_tagged)
 static void cmd_get_tag(struct scsi_cmnd *cmd, int should_be_tagged)
 {
        u8 lun = cmd->device->lun;
-       SETUP_HOSTDATA(cmd->device->host);
+       struct Scsi_Host *instance = cmd->device->host;
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
        /* If we or the target don't support tagged queuing, allocate the LUN for
         * an untagged command.
@@ -316,18 +290,16 @@ static void cmd_get_tag(struct scsi_cmnd *cmd, int should_be_tagged)
            !cmd->device->tagged_supported) {
                cmd->tag = TAG_NONE;
                hostdata->busy[cmd->device->id] |= (1 << lun);
-               dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d now allocated by untagged "
-                          "command\n", H_NO(cmd), cmd->device->id, lun);
+               dsprintk(NDEBUG_TAGS, instance, "target %d lun %d now allocated by untagged command\n",
+                        scmd_id(cmd), lun);
        } else {
                struct tag_alloc *ta = &hostdata->TagAlloc[scmd_id(cmd)][lun];
 
                cmd->tag = find_first_zero_bit(ta->allocated, MAX_TAGS);
                set_bit(cmd->tag, ta->allocated);
                ta->nr_allocated++;
-               dprintk(NDEBUG_TAGS, "scsi%d: using tag %d for target %d lun %d "
-                          "(now %d tags in use)\n",
-                          H_NO(cmd), cmd->tag, cmd->device->id,
-                          lun, ta->nr_allocated);
+               dsprintk(NDEBUG_TAGS, instance, "using tag %d for target %d lun %d (%d tags allocated)\n",
+                        cmd->tag, scmd_id(cmd), lun, ta->nr_allocated);
        }
 }
 
@@ -339,21 +311,22 @@ static void cmd_get_tag(struct scsi_cmnd *cmd, int should_be_tagged)
 static void cmd_free_tag(struct scsi_cmnd *cmd)
 {
        u8 lun = cmd->device->lun;
-       SETUP_HOSTDATA(cmd->device->host);
+       struct Scsi_Host *instance = cmd->device->host;
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
        if (cmd->tag == TAG_NONE) {
                hostdata->busy[cmd->device->id] &= ~(1 << lun);
-               dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %d untagged cmd finished\n",
-                          H_NO(cmd), cmd->device->id, lun);
+               dsprintk(NDEBUG_TAGS, instance, "target %d lun %d untagged cmd freed\n",
+                        scmd_id(cmd), lun);
        } else if (cmd->tag >= MAX_TAGS) {
-               printk(KERN_NOTICE "scsi%d: trying to free bad tag %d!\n",
-                      H_NO(cmd), cmd->tag);
+               shost_printk(KERN_NOTICE, instance,
+                            "trying to free bad tag %d!\n", cmd->tag);
        } else {
                struct tag_alloc *ta = &hostdata->TagAlloc[scmd_id(cmd)][lun];
                clear_bit(cmd->tag, ta->allocated);
                ta->nr_allocated--;
-               dprintk(NDEBUG_TAGS, "scsi%d: freed tag %d for target %d lun %d\n",
-                          H_NO(cmd), cmd->tag, cmd->device->id, lun);
+               dsprintk(NDEBUG_TAGS, instance, "freed tag %d for target %d lun %d\n",
+                        cmd->tag, scmd_id(cmd), lun);
        }
 }
 
@@ -546,15 +519,13 @@ static struct {
 static void NCR5380_print(struct Scsi_Host *instance)
 {
        unsigned char status, data, basr, mr, icr, i;
-       unsigned long flags;
 
-       local_irq_save(flags);
        data = NCR5380_read(CURRENT_SCSI_DATA_REG);
        status = NCR5380_read(STATUS_REG);
        mr = NCR5380_read(MODE_REG);
        icr = NCR5380_read(INITIATOR_COMMAND_REG);
        basr = NCR5380_read(BUS_AND_STATUS_REG);
-       local_irq_restore(flags);
+
        printk("STATUS_REG: %02x ", status);
        for (i = 0; signals[i].mask; ++i)
                if (status & signals[i].mask)
@@ -658,98 +629,6 @@ static void prepare_info(struct Scsi_Host *instance)
                 "");
 }
 
-/**
- * NCR5380_print_status - dump controller info
- * @instance: controller to dump
- *
- * Print commands in the various queues, called from NCR5380_abort
- * to aid debugging.
- */
-
-static void lprint_Scsi_Cmnd(struct scsi_cmnd *cmd)
-{
-       int i, s;
-       unsigned char *command;
-       printk("scsi%d: destination target %d, lun %llu\n",
-               H_NO(cmd), cmd->device->id, cmd->device->lun);
-       printk(KERN_CONT "        command = ");
-       command = cmd->cmnd;
-       printk(KERN_CONT "%2d (0x%02x)", command[0], command[0]);
-       for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
-               printk(KERN_CONT " %02x", command[i]);
-       printk("\n");
-}
-
-static void __maybe_unused NCR5380_print_status(struct Scsi_Host *instance)
-{
-       struct NCR5380_hostdata *hostdata;
-       struct scsi_cmnd *ptr;
-       unsigned long flags;
-
-       NCR5380_dprint(NDEBUG_ANY, instance);
-       NCR5380_dprint_phase(NDEBUG_ANY, instance);
-
-       hostdata = (struct NCR5380_hostdata *)instance->hostdata;
-
-       local_irq_save(flags);
-       if (!hostdata->connected)
-               printk("scsi%d: no currently connected command\n", HOSTNO);
-       else
-               lprint_Scsi_Cmnd((struct scsi_cmnd *) hostdata->connected);
-       printk("scsi%d: issue_queue\n", HOSTNO);
-       for (ptr = (struct scsi_cmnd *)hostdata->issue_queue; ptr; ptr = NEXT(ptr))
-               lprint_Scsi_Cmnd(ptr);
-
-       printk("scsi%d: disconnected_queue\n", HOSTNO);
-       for (ptr = (struct scsi_cmnd *) hostdata->disconnected_queue; ptr;
-            ptr = NEXT(ptr))
-               lprint_Scsi_Cmnd(ptr);
-
-       local_irq_restore(flags);
-       printk("\n");
-}
-
-static void show_Scsi_Cmnd(struct scsi_cmnd *cmd, struct seq_file *m)
-{
-       int i, s;
-       unsigned char *command;
-       seq_printf(m, "scsi%d: destination target %d, lun %llu\n",
-               H_NO(cmd), cmd->device->id, cmd->device->lun);
-       seq_puts(m, "        command = ");
-       command = cmd->cmnd;
-       seq_printf(m, "%2d (0x%02x)", command[0], command[0]);
-       for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
-               seq_printf(m, " %02x", command[i]);
-       seq_putc(m, '\n');
-}
-
-static int __maybe_unused NCR5380_show_info(struct seq_file *m,
-                                            struct Scsi_Host *instance)
-{
-       struct NCR5380_hostdata *hostdata;
-       struct scsi_cmnd *ptr;
-       unsigned long flags;
-
-       hostdata = (struct NCR5380_hostdata *)instance->hostdata;
-
-       local_irq_save(flags);
-       if (!hostdata->connected)
-               seq_printf(m, "scsi%d: no currently connected command\n", HOSTNO);
-       else
-               show_Scsi_Cmnd((struct scsi_cmnd *) hostdata->connected, m);
-       seq_printf(m, "scsi%d: issue_queue\n", HOSTNO);
-       for (ptr = (struct scsi_cmnd *)hostdata->issue_queue; ptr; ptr = NEXT(ptr))
-               show_Scsi_Cmnd(ptr, m);
-
-       seq_printf(m, "scsi%d: disconnected_queue\n", HOSTNO);
-       for (ptr = (struct scsi_cmnd *) hostdata->disconnected_queue; ptr;
-            ptr = NEXT(ptr))
-               show_Scsi_Cmnd(ptr, m);
-
-       local_irq_restore(flags);
-       return 0;
-}
-
 /**
  * NCR5380_init - initialise an NCR5380
  * @instance: adapter to configure
@@ -766,8 +645,8 @@ static int __maybe_unused NCR5380_show_info(struct seq_file *m,
 
 static int __init NCR5380_init(struct Scsi_Host *instance, int flags)
 {
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
        int i;
-       SETUP_HOSTDATA(instance);
        unsigned long deadline;
 
        hostdata->host = instance;
@@ -784,6 +663,7 @@ static int __init NCR5380_init(struct Scsi_Host *instance, int flags)
 #if defined (REAL_DMA)
        hostdata->dma_len = 0;
 #endif
+       spin_lock_init(&hostdata->lock);
        hostdata->connected = NULL;
        hostdata->issue_queue = NULL;
        hostdata->disconnected_queue = NULL;
@@ -908,8 +788,7 @@ static int NCR5380_queue_command(struct Scsi_Host *instance,
        switch (cmd->cmnd[0]) {
        case WRITE_6:
        case WRITE_10:
-               printk(KERN_NOTICE "scsi%d: WRITE attempted with NO_WRITE debugging flag set\n",
-                      H_NO(cmd));
+               shost_printk(KERN_DEBUG, instance, "WRITE attempted with NDEBUG_NO_WRITE set\n");
                cmd->result = (DID_ERROR << 16);
                cmd->scsi_done(cmd);
                return 0;
@@ -946,7 +825,7 @@ static int NCR5380_queue_command(struct Scsi_Host *instance,
        if (!NCR5380_acquire_dma_irq(instance))
                return SCSI_MLQUEUE_HOST_BUSY;
 
-       local_irq_save(flags);
+       spin_lock_irqsave(&hostdata->lock, flags);
 
        /*
         * Insert the cmd into the issue queue. Note that REQUEST SENSE
@@ -956,20 +835,18 @@ static int NCR5380_queue_command(struct Scsi_Host *instance,
         */
 
        if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
-               LIST(cmd, hostdata->issue_queue);
                SET_NEXT(cmd, hostdata->issue_queue);
                hostdata->issue_queue = cmd;
        } else {
                for (tmp = (struct scsi_cmnd *)hostdata->issue_queue;
                     NEXT(tmp); tmp = NEXT(tmp))
                        ;
-               LIST(cmd, tmp);
                SET_NEXT(tmp, cmd);
        }
-       local_irq_restore(flags);
+       spin_unlock_irqrestore(&hostdata->lock, flags);
 
-       dprintk(NDEBUG_QUEUES, "scsi%d: command added to %s of queue\n", H_NO(cmd),
-                 (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
+       dsprintk(NDEBUG_QUEUES, instance, "command %p added to %s of queue\n",
+                cmd, (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
 
        /* Kick off command processing */
        queue_work(hostdata->work_q, &hostdata->main_task);
@@ -1006,7 +883,6 @@ static void NCR5380_main(struct work_struct *work)
        struct Scsi_Host *instance = hostdata->host;
        struct scsi_cmnd *tmp, *prev;
        int done;
-       unsigned long flags;
 
        /*
         * ++roman: Just disabling the NCR interrupt isn't sufficient here,
@@ -1014,9 +890,8 @@ static void NCR5380_main(struct work_struct *work)
         * alter queues and touch the Falcon lock.
         */
 
-       local_save_flags(flags);
+       spin_lock_irq(&hostdata->lock);
        do {
-               local_irq_disable();    /* Freeze request queues */
                done = 1;
 
                if (!hostdata->connected) {
@@ -1038,12 +913,9 @@ static void NCR5380_main(struct work_struct *work)
                             prev = NULL; tmp; prev = tmp, tmp = NEXT(tmp)) {
                                u8 lun = tmp->device->lun;
 
-                               dprintk(NDEBUG_LISTS,
-                                       "MAIN tmp=%p target=%d busy=%d lun=%d\n",
-                                       tmp, scmd_id(tmp), hostdata->busy[scmd_id(tmp)],
-                                       lun);
+                               dsprintk(NDEBUG_QUEUES, instance, "main: tmp=%p target=%d busy=%d lun=%d\n",
+                                        tmp, scmd_id(tmp), hostdata->busy[scmd_id(tmp)], lun);
                                /*  When we find one, remove it from the issue queue. */
-                               /* ++guenther: possible race with Falcon locking */
                                if (
 #ifdef SUPPORT_TAGS
                                    !is_lun_busy( tmp, tmp->cmnd[0] != REQUEST_SENSE)
@@ -1051,20 +923,17 @@ static void NCR5380_main(struct work_struct *work)
                                    !(hostdata->busy[tmp->device->id] & (1 << lun))
 #endif
                                    ) {
-                                       /* ++guenther: just to be sure, this must be atomic */
-                                       local_irq_disable();
                                        if (prev) {
-                                               REMOVE(prev, NEXT(prev), tmp, NEXT(tmp));
                                                SET_NEXT(prev, NEXT(tmp));
                                        } else {
-                                               REMOVE(-1, hostdata->issue_queue, tmp, NEXT(tmp));
                                                hostdata->issue_queue = NEXT(tmp);
                                        }
                                        SET_NEXT(tmp, NULL);
-                                       hostdata->retain_dma_intr++;
+                                       dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
+                                                instance, "main: removed %p from issue queue %p\n",
+                                                tmp, prev);
 
-                                       /* reenable interrupts after finding one */
-                                       local_irq_restore(flags);
+                                       hostdata->retain_dma_intr++;
 
                                        /*
                                         * Attempt to establish an I_T_L nexus here.
@@ -1072,9 +941,6 @@ static void NCR5380_main(struct work_struct *work)
                                         * On failure, we must add the command back to the
                                         *   issue queue so we can keep trying.
                                         */
-                                       dprintk(NDEBUG_MAIN, "scsi%d: main(): command for target %d "
-                                                   "lun %d removed from issue_queue\n",
-                                                   HOSTNO, tmp->device->id, lun);
                                        /*
                                         * REQUEST SENSE commands are issued without tagged
                                         * queueing, even on SCSI-II devices because the
@@ -1090,24 +956,20 @@ static void NCR5380_main(struct work_struct *work)
 #endif
                                        if (!NCR5380_select(instance, tmp)) {
                                                /* OK or bad target */
-                                               local_irq_disable();
                                                hostdata->retain_dma_intr--;
                                                maybe_release_dma_irq(instance);
-                                               local_irq_restore(flags);
                                        } else {
                                                /* Need to retry */
-                                               local_irq_disable();
-                                               LIST(tmp, hostdata->issue_queue);
                                                SET_NEXT(tmp, hostdata->issue_queue);
                                                hostdata->issue_queue = tmp;
+                                               dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
+                                                        instance, "main: select() failed, %p returned to issue queue\n",
+                                                        tmp);
 #ifdef SUPPORT_TAGS
                                                cmd_free_tag(tmp);
 #endif
                                                hostdata->retain_dma_intr--;
-                                               local_irq_restore(flags);
                                                done = 0;
-                                               dprintk(NDEBUG_MAIN, "scsi%d: main(): select() failed, "
-                                                           "returned to issue_queue\n", HOSTNO);
                                        }
                                        if (hostdata->connected)
                                                break;
@@ -1120,7 +982,6 @@ static void NCR5380_main(struct work_struct *work)
                    && !hostdata->dma_len
 #endif
                    ) {
-                       local_irq_restore(flags);
                        dprintk(NDEBUG_MAIN, "scsi%d: main: performing information transfer\n",
                                    HOSTNO);
                        NCR5380_information_transfer(instance);
@@ -1128,7 +989,7 @@ static void NCR5380_main(struct work_struct *work)
                        done = 0;
                }
        } while (!done);
-       local_irq_restore(flags);
+       spin_unlock_irq(&hostdata->lock);
 }
 
 
@@ -1145,7 +1006,7 @@ static void NCR5380_main(struct work_struct *work)
 
 static void NCR5380_dma_complete(struct Scsi_Host *instance)
 {
-       SETUP_HOSTDATA(instance);
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
        int transferred;
        unsigned char **data;
        volatile int *count;
@@ -1257,6 +1118,9 @@ static irqreturn_t NCR5380_intr(int irq, void *dev_id)
        struct NCR5380_hostdata *hostdata = shost_priv(instance);
        int handled = 0;
        unsigned char basr;
+       unsigned long flags;
+
+       spin_lock_irqsave(&hostdata->lock, flags);
 
        basr = NCR5380_read(BUS_AND_STATUS_REG);
        if (basr & BASR_IRQ) {
@@ -1316,6 +1180,8 @@ static irqreturn_t NCR5380_intr(int irq, void *dev_id)
 #endif
        }
 
+       spin_unlock_irqrestore(&hostdata->lock, flags);
+
        return IRQ_RETVAL(handled);
 }
 
@@ -1350,12 +1216,11 @@ static irqreturn_t NCR5380_intr(int irq, void *dev_id)
 
 static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
 {
-       SETUP_HOSTDATA(instance);
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
        unsigned char tmp[3], phase;
        unsigned char *data;
        int len;
        int err;
-       unsigned long flags;
 
        NCR5380_dprint(NDEBUG_ARBITRATION, instance);
        dprintk(NDEBUG_ARBITRATION, "scsi%d: starting arbitration, id = %d\n", HOSTNO,
@@ -1366,11 +1231,6 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
         * data bus during SELECTION.
         */
 
-       local_irq_save(flags);
-       if (hostdata->connected) {
-               local_irq_restore(flags);
-               return -1;
-       }
        NCR5380_write(TARGET_COMMAND_REG, 0);
 
        /*
@@ -1384,10 +1244,11 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
         * Bus Free Delay, arbitration will begin.
         */
 
-       local_irq_restore(flags);
+       spin_unlock_irq(&hostdata->lock);
        err = NCR5380_poll_politely2(instance, MODE_REG, MR_ARBITRATE, 0,
                        INITIATOR_COMMAND_REG, ICR_ARBITRATION_PROGRESS,
                                               ICR_ARBITRATION_PROGRESS, HZ);
+       spin_lock_irq(&hostdata->lock);
        if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
                /* Reselection interrupt */
                return -1;
@@ -1398,6 +1259,7 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
                             "select: arbitration timeout\n");
                return -1;
        }
+       spin_unlock_irq(&hostdata->lock);
 
        /* The SCSI-2 arbitration delay is 2.4 us */
        udelay(3);
@@ -1405,11 +1267,11 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
        /* Check for lost arbitration */
        if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
            (NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) ||
-           (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
-           hostdata->connected) {
+           (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
                NCR5380_write(MODE_REG, MR_BASE);
                dprintk(NDEBUG_ARBITRATION, "scsi%d: lost arbitration, deasserting MR_ARBITRATE\n",
                           HOSTNO);
+               spin_lock_irq(&hostdata->lock);
                return -1;
        }
 
@@ -1430,6 +1292,8 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
        else
                udelay(2);
 
+       spin_lock_irq(&hostdata->lock);
+
        /* NCR5380_reselect() clears MODE_REG after a reselection interrupt */
        if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE))
                return -1;
@@ -1457,14 +1321,10 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
         * Reselect interrupts must be turned off prior to the dropping of BSY,
         * otherwise we will trigger an interrupt.
         */
-
-       if (hostdata->connected) {
-               NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-               return -1;
-       }
-
        NCR5380_write(SELECT_ENABLE_REG, 0);
 
+       spin_unlock_irq(&hostdata->lock);
+
        /*
         * The initiator shall then wait at least two deskew delays and release
         * the BSY signal.
@@ -1505,6 +1365,7 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
                                    msecs_to_jiffies(250));
 
        if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) {
+               spin_lock_irq(&hostdata->lock);
                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
                NCR5380_reselect(instance);
                if (!hostdata->connected)
@@ -1515,6 +1376,7 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
        }
 
        if (err < 0) {
+               spin_lock_irq(&hostdata->lock);
                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
                cmd->result = DID_BAD_TARGET << 16;
 #ifdef SUPPORT_TAGS
@@ -1554,6 +1416,7 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
        /* Wait for start of REQ/ACK handshake */
 
        err = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
+       spin_lock_irq(&hostdata->lock);
        if (err < 0) {
                shost_printk(KERN_ERR, instance, "select: REQ timeout\n");
                NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
@@ -1583,6 +1446,7 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
        NCR5380_transfer_pio(instance, &phase, &len, &data);
        dprintk(NDEBUG_SELECTION, "scsi%d: nexus established.\n", HOSTNO);
        /* XXX need to handle errors here */
+
        hostdata->connected = cmd;
 #ifndef SUPPORT_TAGS
        hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
@@ -1846,10 +1710,9 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance,
                                unsigned char *phase, int *count,
                                unsigned char **data)
 {
-       SETUP_HOSTDATA(instance);
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
        register int c = *count;
        register unsigned char p = *phase;
-       unsigned long flags;
 
 #if defined(CONFIG_SUN3)
        /* sanity check */
@@ -1865,7 +1728,6 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance,
                c, (p & SR_IO) ? "to" : "from", *data);
 
        /* netbsd turns off ints here, why not be safe and do it too */
-       local_irq_save(flags);
 
        /* send start chain */
        sun3scsi_dma_start(c, *data);
@@ -1885,8 +1747,6 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance,
        dregs->csr |= CSR_DMA_ENABLE;
 #endif
 
-       local_irq_restore(flags);
-
        sun3_dma_active = 1;
 
 #else /* !defined(CONFIG_SUN3) */
@@ -1913,11 +1773,9 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance,
                /* On the Medusa, it is a must to initialize the DMA before
                 * starting the NCR. This is also the cleaner way for the TT.
                 */
-               local_irq_save(flags);
                hostdata->dma_len = (p & SR_IO) ?
                        NCR5380_dma_read_setup(instance, d, c) :
                        NCR5380_dma_write_setup(instance, d, c);
-               local_irq_restore(flags);
        }
 
        if (p & SR_IO)
@@ -1931,11 +1789,9 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance,
                /* On the Falcon, the DMA setup must be done after the last */
                /* NCR access, else the DMA setup gets trashed!
                 */
-               local_irq_save(flags);
                hostdata->dma_len = (p & SR_IO) ?
                        NCR5380_dma_read_setup(instance, d, c) :
                        NCR5380_dma_write_setup(instance, d, c);
-               local_irq_restore(flags);
        }
 #endif /* !defined(CONFIG_SUN3) */
 
@@ -1962,8 +1818,7 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance,
 
 static void NCR5380_information_transfer(struct Scsi_Host *instance)
 {
-       SETUP_HOSTDATA(instance);
-       unsigned long flags;
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
        unsigned char msgout = NOP;
        int sink = 0;
        int len;
@@ -1972,13 +1827,13 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
 #endif
        unsigned char *data;
        unsigned char phase, tmp, extended_msg[10], old_phase = 0xff;
-       struct scsi_cmnd *cmd = (struct scsi_cmnd *) hostdata->connected;
+       struct scsi_cmnd *cmd;
 
 #ifdef SUN3_SCSI_VME
        dregs->csr |= CSR_INTR;
 #endif
 
-       while (1) {
+       while ((cmd = hostdata->connected)) {
                tmp = NCR5380_read(STATUS_REG);
                /* We only have a valid SCSI phase when REQ is asserted */
                if (tmp & SR_REQ) {
@@ -2112,9 +1967,13 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                                        }
                                } else
 #endif /* defined(REAL_DMA) */
+                               {
+                                       spin_unlock_irq(&hostdata->lock);
                                        NCR5380_transfer_pio(instance, &phase,
                                                             (int *)&cmd->SCp.this_residual,
                                                             (unsigned char **)&cmd->SCp.ptr);
+                                       spin_lock_irq(&hostdata->lock);
+                               }
 #if defined(CONFIG_SUN3) && defined(REAL_DMA)
                                /* if we had intended to dma that command clear it */
                                if (sun3_dma_setup_done == cmd)
@@ -2124,7 +1983,6 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                        case PHASE_MSGIN:
                                len = 1;
                                data = &tmp;
-                               NCR5380_write(SELECT_ENABLE_REG, 0);    /* disable reselects */
                                NCR5380_transfer_pio(instance, &phase, &len, &data);
                                cmd->SCp.Message = tmp;
 
@@ -2133,10 +1991,10 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                                case COMMAND_COMPLETE:
                                        /* Accept message by clearing ACK */
                                        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-                                       dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d, lun %llu "
-                                                 "completed\n", HOSTNO, cmd->device->id, cmd->device->lun);
+                                       dsprintk(NDEBUG_QUEUES, instance,
+                                                "COMMAND COMPLETE %p target %d lun %llu\n",
+                                                cmd, scmd_id(cmd), cmd->device->lun);
 
-                                       local_irq_save(flags);
                                        hostdata->connected = NULL;
 #ifdef SUPPORT_TAGS
                                        cmd_free_tag(cmd);
@@ -2152,8 +2010,6 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
 #else
                                        hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 #endif
-                                       /* Enable reselect interrupts */
-                                       NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 
                                        /*
                                         * I'm not sure what the correct thing to do here is :
@@ -2186,13 +2042,11 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                                            (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", HOSTNO);
-
-                                               LIST(cmd,hostdata->issue_queue);
                                                SET_NEXT(cmd, hostdata->issue_queue);
                                                hostdata->issue_queue = (struct scsi_cmnd *) cmd;
-                                               dprintk(NDEBUG_QUEUES, "scsi%d: REQUEST SENSE added to head of "
-                                                         "issue queue\n", H_NO(cmd));
+                                               dsprintk(NDEBUG_AUTOSENSE | NDEBUG_QUEUES,
+                                                        instance, "REQUEST SENSE cmd %p added to head of issue queue\n",
+                                                        cmd);
                                        } else {
                                                cmd->scsi_done(cmd);
                                        }
@@ -2211,13 +2065,10 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                                         * disconnected queue.
                                         */
                                        maybe_release_dma_irq(instance);
-                                       local_irq_restore(flags);
                                        return;
                                case MESSAGE_REJECT:
                                        /* Accept message by clearing ACK */
                                        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-                                       /* Enable reselect interrupts */
-                                       NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
                                        switch (hostdata->last_message) {
                                        case HEAD_OF_QUEUE_TAG:
                                        case ORDERED_QUEUE_TAG:
@@ -2241,16 +2092,13 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                                case DISCONNECT:
                                        /* Accept message by clearing ACK */
                                        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-                                       local_irq_save(flags);
-                                       LIST(cmd,hostdata->disconnected_queue);
                                        SET_NEXT(cmd, hostdata->disconnected_queue);
                                        hostdata->connected = NULL;
                                        hostdata->disconnected_queue = cmd;
-                                       local_irq_restore(flags);
-                                       dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d lun %llu was "
-                                                 "moved from connected to the "
-                                                 "disconnected_queue\n", HOSTNO,
-                                                 cmd->device->id, cmd->device->lun);
+                                       dsprintk(NDEBUG_INFORMATION | NDEBUG_QUEUES,
+                                                instance, "connected command %p for target %d lun %llu moved to disconnected queue\n",
+                                                cmd, scmd_id(cmd), cmd->device->lun);
+
                                        /*
                                         * Restore phase bits to 0 so an interrupted selection,
                                         * arbitration can resume.
@@ -2277,8 +2125,6 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                                case RESTORE_POINTERS:
                                        /* Accept message by clearing ACK */
                                        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-                                       /* Enable reselect interrupts */
-                                       NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
                                        break;
                                case EXTENDED_MESSAGE:
                                        /*
@@ -2297,6 +2143,8 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                                        /* Accept first byte by clearing ACK */
                                        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
 
+                                       spin_unlock_irq(&hostdata->lock);
+
                                        dprintk(NDEBUG_EXTENDED, "scsi%d: receiving extended message\n", HOSTNO);
 
                                        len = 2;
@@ -2335,6 +2183,11 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                                                           HOSTNO, extended_msg[2], extended_msg[1]);
                                                tmp = 0;
                                        }
+
+                                       spin_lock_irq(&hostdata->lock);
+                                       if (!hostdata->connected)
+                                               return;
+
                                        /* Fall through to reject message */
 
                                        /*
@@ -2367,7 +2220,6 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                                hostdata->last_message = msgout;
                                NCR5380_transfer_pio(instance, &phase, &len, &data);
                                if (msgout == ABORT) {
-                                       local_irq_save(flags);
 #ifdef SUPPORT_TAGS
                                        cmd_free_tag(cmd);
 #else
@@ -2376,7 +2228,6 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                                        hostdata->connected = NULL;
                                        cmd->result = DID_ERROR << 16;
                                        maybe_release_dma_irq(instance);
-                                       local_irq_restore(flags);
                                        cmd->scsi_done(cmd);
                                        NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
                                        return;
@@ -2404,9 +2255,11 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                                NCR5380_dprint(NDEBUG_ANY, instance);
                        } /* switch(phase) */
                } else {
+                       spin_unlock_irq(&hostdata->lock);
                        NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
+                       spin_lock_irq(&hostdata->lock);
                }
-       } /* while (1) */
+       }
 }
 
 /*
@@ -2426,7 +2279,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
 
 static void NCR5380_reselect(struct Scsi_Host *instance)
 {
-       SETUP_HOSTDATA(instance);
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
        unsigned char target_mask;
        unsigned char lun;
 #ifdef SUPPORT_TAGS
@@ -2534,10 +2387,8 @@ static void NCR5380_reselect(struct Scsi_Host *instance)
 #endif
                    ) {
                        if (prev) {
-                               REMOVE(prev, NEXT(prev), tmp, NEXT(tmp));
                                SET_NEXT(prev, NEXT(tmp));
                        } else {
-                               REMOVE(-1, hostdata->disconnected_queue, tmp, NEXT(tmp));
                                hostdata->disconnected_queue = NEXT(tmp);
                        }
                        SET_NEXT(tmp, NULL);
@@ -2545,7 +2396,11 @@ static void NCR5380_reselect(struct Scsi_Host *instance)
                }
        }
 
-       if (!tmp) {
+       if (tmp) {
+               dsprintk(NDEBUG_RESELECTION | NDEBUG_QUEUES, instance,
+                        "reselect: removed %p from disconnected queue\n", tmp);
+       } else {
+
 #ifdef SUPPORT_TAGS
                shost_printk(KERN_ERR, instance, "target bitmask 0x%02x lun %d tag %d not in disconnected queue.\n",
                             target_mask, lun, tag);
@@ -2633,15 +2488,16 @@ static
 int NCR5380_abort(struct scsi_cmnd *cmd)
 {
        struct Scsi_Host *instance = cmd->device->host;
-       SETUP_HOSTDATA(instance);
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
        struct scsi_cmnd *tmp, **prev;
        unsigned long flags;
 
        scmd_printk(KERN_NOTICE, cmd, "aborting command\n");
 
-       NCR5380_print_status(instance);
+       spin_lock_irqsave(&hostdata->lock, flags);
 
-       local_irq_save(flags);
+       NCR5380_dprint(NDEBUG_ANY, instance);
+       NCR5380_dprint_phase(NDEBUG_ANY, instance);
 
        dprintk(NDEBUG_ABORT, "scsi%d: abort called basr 0x%02x, sr 0x%02x\n", HOSTNO,
                    NCR5380_read(BUS_AND_STATUS_REG),
@@ -2683,11 +2539,11 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
                        hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 #endif
                        maybe_release_dma_irq(instance);
-                       local_irq_restore(flags);
+                       spin_unlock_irqrestore(&hostdata->lock, flags);
                        cmd->scsi_done(cmd);
                        return SUCCESS;
                } else {
-                       local_irq_restore(flags);
+                       spin_unlock_irqrestore(&hostdata->lock, flags);
                        printk("scsi%d: abort of connected command failed!\n", HOSTNO);
                        return FAILED;
                }
@@ -2702,12 +2558,11 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
             tmp = (struct scsi_cmnd *)hostdata->issue_queue;
             tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp)) {
                if (cmd == tmp) {
-                       REMOVE(5, *prev, tmp, NEXT(tmp));
                        (*prev) = NEXT(tmp);
                        SET_NEXT(tmp, NULL);
                        tmp->result = DID_ABORT << 16;
                        maybe_release_dma_irq(instance);
-                       local_irq_restore(flags);
+                       spin_unlock_irqrestore(&hostdata->lock, flags);
                        dprintk(NDEBUG_ABORT, "scsi%d: abort removed command from issue queue.\n",
                                    HOSTNO);
                        /* Tagged queuing note: no tag to free here, hasn't been assigned
@@ -2729,7 +2584,7 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
         */
 
        if (hostdata->connected) {
-               local_irq_restore(flags);
+               spin_unlock_irqrestore(&hostdata->lock, flags);
                dprintk(NDEBUG_ABORT, "scsi%d: abort failed, command connected.\n", HOSTNO);
                return FAILED;
        }
@@ -2762,22 +2617,20 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
        for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue; tmp;
             tmp = NEXT(tmp)) {
                if (cmd == tmp) {
-                       local_irq_restore(flags);
                        dprintk(NDEBUG_ABORT, "scsi%d: aborting disconnected command.\n", HOSTNO);
 
-                       if (NCR5380_select(instance, cmd))
+                       if (NCR5380_select(instance, cmd)) {
+                               spin_unlock_irq(&hostdata->lock);
                                return FAILED;
-
+                       }
                        dprintk(NDEBUG_ABORT, "scsi%d: nexus reestablished.\n", HOSTNO);
 
                        do_abort(instance);
 
-                       local_irq_save(flags);
                        for (prev = (struct scsi_cmnd **)&(hostdata->disconnected_queue),
                             tmp = (struct scsi_cmnd *)hostdata->disconnected_queue;
                             tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp)) {
                                if (cmd == tmp) {
-                                       REMOVE(5, *prev, tmp, NEXT(tmp));
                                        *prev = NEXT(tmp);
                                        SET_NEXT(tmp, NULL);
                                        tmp->result = DID_ABORT << 16;
@@ -2791,7 +2644,7 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
                                        hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 #endif
                                        maybe_release_dma_irq(instance);
-                                       local_irq_restore(flags);
+                                       spin_unlock_irqrestore(&hostdata->lock, flags);
                                        tmp->scsi_done(tmp);
                                        return SUCCESS;
                                }
@@ -2804,7 +2657,7 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
         * released after the abort, in case it is kept due to some bug.
         */
        maybe_release_dma_irq(instance);
-       local_irq_restore(flags);
+       spin_unlock_irqrestore(&hostdata->lock, flags);
 
        /*
         * Case 5 : If we reached this point, the command was not found in any of
@@ -2836,12 +2689,13 @@ static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
        int i;
        unsigned long flags;
 
-       local_irq_save(flags);
+       spin_lock_irqsave(&hostdata->lock, flags);
 
 #if (NDEBUG & NDEBUG_ANY)
        scmd_printk(KERN_INFO, cmd, "performing bus reset\n");
-       NCR5380_print_status(instance);
 #endif
+       NCR5380_dprint(NDEBUG_ANY, instance);
+       NCR5380_dprint_phase(NDEBUG_ANY, instance);
 
        do_reset(instance);
 
@@ -2857,11 +2711,11 @@ static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
         */
 
        if (hostdata->issue_queue)
-               dprintk(NDEBUG_ABORT, "scsi%d: reset aborted issued command(s)\n", H_NO(cmd));
+               dsprintk(NDEBUG_ABORT, instance, "reset aborted issued command(s)\n");
        if (hostdata->connected)
-               dprintk(NDEBUG_ABORT, "scsi%d: reset aborted a connected command\n", H_NO(cmd));
+               dsprintk(NDEBUG_ABORT, instance, "reset aborted a connected command\n");
        if (hostdata->disconnected_queue)
-               dprintk(NDEBUG_ABORT, "scsi%d: reset aborted disconnected command(s)\n", H_NO(cmd));
+               dsprintk(NDEBUG_ABORT, instance, "reset aborted disconnected command(s)\n");
 
        hostdata->issue_queue = NULL;
        hostdata->connected = NULL;
@@ -2876,7 +2730,7 @@ static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
 #endif
 
        maybe_release_dma_irq(instance);
-       local_irq_restore(flags);
+       spin_unlock_irqrestore(&hostdata->lock, flags);
 
        return SUCCESS;
 }