fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / scsi / 53c700.c
index f623d8c..68103e5 100644 (file)
  * */
 #define NCR_700_VERSION "2.8"
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/proc_fs.h>
+#include <linux/blkdev.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
 #include <asm/dma.h>
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
 #include <asm/byteorder.h>
-#include <linux/blkdev.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-
-#include "scsi.h"
-#include "hosts.h"
 
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_dbg.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_tcq.h>
 #include <scsi/scsi_transport.h>
 #include <scsi/scsi_transport_spi.h>
 
@@ -164,15 +167,17 @@ MODULE_LICENSE("GPL");
 #include "53c700_d.h"
 
 
-STATIC int NCR_700_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-STATIC int NCR_700_abort(Scsi_Cmnd * SCpnt);
-STATIC int NCR_700_bus_reset(Scsi_Cmnd * SCpnt);
-STATIC int NCR_700_dev_reset(Scsi_Cmnd * SCpnt);
-STATIC int NCR_700_host_reset(Scsi_Cmnd * SCpnt);
+STATIC int NCR_700_queuecommand(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *));
+STATIC int NCR_700_abort(struct scsi_cmnd * SCpnt);
+STATIC int NCR_700_bus_reset(struct scsi_cmnd * SCpnt);
+STATIC int NCR_700_host_reset(struct scsi_cmnd * SCpnt);
 STATIC void NCR_700_chip_setup(struct Scsi_Host *host);
 STATIC void NCR_700_chip_reset(struct Scsi_Host *host);
-STATIC int NCR_700_slave_configure(Scsi_Device *SDpnt);
-STATIC void NCR_700_slave_destroy(Scsi_Device *SDpnt);
+STATIC int NCR_700_slave_alloc(struct scsi_device *SDpnt);
+STATIC int NCR_700_slave_configure(struct scsi_device *SDpnt);
+STATIC void NCR_700_slave_destroy(struct scsi_device *SDpnt);
+static int NCR_700_change_queue_depth(struct scsi_device *SDpnt, int depth);
+static int NCR_700_change_queue_type(struct scsi_device *SDpnt, int depth);
 
 STATIC struct device_attribute *NCR_700_dev_attrs[];
 
@@ -233,14 +238,6 @@ static char *NCR_700_SBCL_to_phase[] = {
        "MSG IN",
 };
 
-static __u8 NCR_700_SDTR_msg[] = {
-       0x01,                   /* Extended message */
-       0x03,                   /* Extended message Length */
-       0x01,                   /* SDTR Extended message */
-       NCR_700_MIN_PERIOD,
-       NCR_700_MAX_OFFSET
-};
-
 /* This translates the SDTR message offset and period to a value
  * which can be loaded into the SXFER_REG.
  *
@@ -261,7 +258,7 @@ NCR_700_offset_period_to_sxfer(struct NCR_700_Host_Parameters *hostdata,
                return 0;
 
        if(period < hostdata->min_period) {
-               printk(KERN_WARNING "53c700: Period %dns is less than this chip's minimum, setting to %d\n", period*4, NCR_700_SDTR_msg[3]*4);
+               printk(KERN_WARNING "53c700: Period %dns is less than this chip's minimum, setting to %d\n", period*4, NCR_700_MIN_PERIOD*4);
                period = hostdata->min_period;
        }
        XFERP = (period*4 * hostdata->sync_clock)/1000 - 4;
@@ -279,18 +276,19 @@ NCR_700_offset_period_to_sxfer(struct NCR_700_Host_Parameters *hostdata,
 }
 
 static inline __u8
-NCR_700_get_SXFER(Scsi_Device *SDp)
+NCR_700_get_SXFER(struct scsi_device *SDp)
 {
        struct NCR_700_Host_Parameters *hostdata = 
                (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0];
 
-       return NCR_700_offset_period_to_sxfer(hostdata, spi_offset(SDp),
-                                             spi_period(SDp));
+       return NCR_700_offset_period_to_sxfer(hostdata,
+                                             spi_offset(SDp->sdev_target),
+                                             spi_period(SDp->sdev_target));
 }
 
 struct Scsi_Host *
-NCR_700_detect(Scsi_Host_Template *tpnt,
-              struct NCR_700_Host_Parameters *hostdata)
+NCR_700_detect(struct scsi_host_template *tpnt,
+              struct NCR_700_Host_Parameters *hostdata, struct device *dev)
 {
        dma_addr_t pScript, pSlots;
        __u8 *memory;
@@ -315,36 +313,38 @@ NCR_700_detect(Scsi_Host_Template *tpnt,
        hostdata->status = memory + STATUS_OFFSET;
        /* all of these offsets are L1_CACHE_BYTES separated.  It is fatal
         * if this isn't sufficient separation to avoid dma flushing issues */
-       BUG_ON(!dma_is_consistent(pScript) && L1_CACHE_BYTES < dma_get_cache_alignment());
+       BUG_ON(!dma_is_consistent(hostdata->dev, pScript) && L1_CACHE_BYTES < dma_get_cache_alignment());
        hostdata->slots = (struct NCR_700_command_slot *)(memory + SLOTS_OFFSET);
-               
+       hostdata->dev = dev;
+
        pSlots = pScript + SLOTS_OFFSET;
 
        /* Fill in the missing routines from the host template */
        tpnt->queuecommand = NCR_700_queuecommand;
        tpnt->eh_abort_handler = NCR_700_abort;
-       tpnt->eh_device_reset_handler = NCR_700_dev_reset;
        tpnt->eh_bus_reset_handler = NCR_700_bus_reset;
        tpnt->eh_host_reset_handler = NCR_700_host_reset;
        tpnt->can_queue = NCR_700_COMMAND_SLOTS_PER_HOST;
        tpnt->sg_tablesize = NCR_700_SG_SEGMENTS;
        tpnt->cmd_per_lun = NCR_700_CMD_PER_LUN;
-       tpnt->use_clustering = DISABLE_CLUSTERING;
+       tpnt->use_clustering = ENABLE_CLUSTERING;
        tpnt->slave_configure = NCR_700_slave_configure;
        tpnt->slave_destroy = NCR_700_slave_destroy;
-       
+       tpnt->slave_alloc = NCR_700_slave_alloc;
+       tpnt->change_queue_depth = NCR_700_change_queue_depth;
+       tpnt->change_queue_type = NCR_700_change_queue_type;
+
        if(tpnt->name == NULL)
                tpnt->name = "53c700";
        if(tpnt->proc_name == NULL)
                tpnt->proc_name = "53c700";
-       
 
        host = scsi_host_alloc(tpnt, 4);
        if (!host)
                return NULL;
        memset(hostdata->slots, 0, sizeof(struct NCR_700_command_slot)
               * NCR_700_COMMAND_SLOTS_PER_HOST);
-       for(j = 0; j < NCR_700_COMMAND_SLOTS_PER_HOST; j++) {
+       for (j = 0; j < NCR_700_COMMAND_SLOTS_PER_HOST; j++) {
                dma_addr_t offset = (dma_addr_t)((unsigned long)&hostdata->slots[j].SG[0]
                                          - (unsigned long)&hostdata->slots[0].SG[0]);
                hostdata->slots[j].pSG = (struct NCR_700_SG_List *)((unsigned long)(pSlots + offset));
@@ -355,20 +355,18 @@ NCR_700_detect(Scsi_Host_Template *tpnt,
                hostdata->slots[j].state = NCR_700_SLOT_FREE;
        }
 
-       for(j = 0; j < sizeof(SCRIPT)/sizeof(SCRIPT[0]); j++) {
+       for (j = 0; j < ARRAY_SIZE(SCRIPT); j++)
                script[j] = bS_to_host(SCRIPT[j]);
-       }
 
        /* adjust all labels to be bus physical */
-       for(j = 0; j < PATCHES; j++) {
+       for (j = 0; j < PATCHES; j++)
                script[LABELPATCHES[j]] = bS_to_host(pScript + SCRIPT[LABELPATCHES[j]]);
-       }
        /* now patch up fixed addresses. */
-       script_patch_32(script, MessageLocation,
+       script_patch_32(hostdata->dev, script, MessageLocation,
                        pScript + MSGOUT_OFFSET);
-       script_patch_32(script, StatusAddress,
+       script_patch_32(hostdata->dev, script, StatusAddress,
                        pScript + STATUS_OFFSET);
-       script_patch_32(script, ReceiveMsgAddress,
+       script_patch_32(hostdata->dev, script, ReceiveMsgAddress,
                        pScript + MSGIN_OFFSET);
 
        hostdata->script = script;
@@ -376,33 +374,41 @@ NCR_700_detect(Scsi_Host_Template *tpnt,
        dma_sync_single_for_device(hostdata->dev, pScript, sizeof(SCRIPT), DMA_TO_DEVICE);
        hostdata->state = NCR_700_HOST_FREE;
        hostdata->cmd = NULL;
-       host->max_id = 7;
+       host->max_id = 8;
        host->max_lun = NCR_700_MAX_LUNS;
        BUG_ON(NCR_700_transport_template == NULL);
        host->transportt = NCR_700_transport_template;
-       host->unique_id = hostdata->base;
-       host->base = hostdata->base;
+       host->unique_id = (unsigned long)hostdata->base;
        hostdata->eh_complete = NULL;
        host->hostdata[0] = (unsigned long)hostdata;
        /* kick the chip */
        NCR_700_writeb(0xff, host, CTEST9_REG);
-       if(hostdata->chip710) 
+       if (hostdata->chip710)
                hostdata->rev = (NCR_700_readb(host, CTEST8_REG)>>4) & 0x0f;
        else
                hostdata->rev = (NCR_700_readb(host, CTEST7_REG)>>4) & 0x0f;
        hostdata->fast = (NCR_700_readb(host, CTEST9_REG) == 0);
-       if(banner == 0) {
+       if (banner == 0) {
                printk(KERN_NOTICE "53c700: Version " NCR_700_VERSION " By James.Bottomley@HansenPartnership.com\n");
                banner = 1;
        }
        printk(KERN_NOTICE "scsi%d: %s rev %d %s\n", host->host_no,
-              hostdata->chip710 ? "53c710" : 
+              hostdata->chip710 ? "53c710" :
               (hostdata->fast ? "53c700-66" : "53c700"),
               hostdata->rev, hostdata->differential ?
               "(Differential)" : "");
        /* reset the chip */
        NCR_700_chip_reset(host);
 
+       if (scsi_add_host(host, dev)) {
+               dev_printk(KERN_ERR, dev, "53c700: scsi_add_host failed\n");
+               scsi_host_put(host);
+               return NULL;
+       }
+
+       spi_signalling(host) = hostdata->differential ? SPI_SIGNAL_HVD :
+               SPI_SIGNAL_SE;
+
        return host;
 }
 
@@ -532,6 +538,7 @@ find_empty_slot(struct NCR_700_Host_Parameters *hostdata)
         * finish routine.  If we cannot queue the command when it
         * is properly build, we then change to NCR_700_SLOT_QUEUED */
        slot->state = NCR_700_SLOT_BUSY;
+       slot->flags = 0;
        hostdata->command_slot_count++;
        
        return slot;
@@ -561,7 +568,7 @@ free_slot(struct NCR_700_command_slot *slot,
    the ITL and (if tagged) the ITLQ lists in _queuecommand */
 STATIC void
 save_for_reselection(struct NCR_700_Host_Parameters *hostdata,
-                    Scsi_Cmnd *SCp, __u32 dsp)
+                    struct scsi_cmnd *SCp, __u32 dsp)
 {
        /* Its just possible that this gets executed twice */
        if(SCp != NULL) {
@@ -575,27 +582,25 @@ save_for_reselection(struct NCR_700_Host_Parameters *hostdata,
 }
 
 STATIC inline void
-NCR_700_unmap(struct NCR_700_Host_Parameters *hostdata, Scsi_Cmnd *SCp,
+NCR_700_unmap(struct NCR_700_Host_Parameters *hostdata, struct scsi_cmnd *SCp,
              struct NCR_700_command_slot *slot)
 {
-       if(SCp->sc_data_direction != SCSI_DATA_NONE &&
-          SCp->sc_data_direction != SCSI_DATA_UNKNOWN) {
-               enum dma_data_direction direction = SCp->sc_data_direction;
+       if(SCp->sc_data_direction != DMA_NONE &&
+          SCp->sc_data_direction != DMA_BIDIRECTIONAL) {
                if(SCp->use_sg) {
-                       dma_unmap_sg(hostdata->dev, SCp->buffer,
-                                    SCp->use_sg, direction);
+                       dma_unmap_sg(hostdata->dev, SCp->request_buffer,
+                                    SCp->use_sg, SCp->sc_data_direction);
                } else {
-                       dma_unmap_single(hostdata->dev,
-                                        slot->dma_handle,
+                       dma_unmap_single(hostdata->dev, slot->dma_handle,
                                         SCp->request_bufflen,
-                                        direction);
+                                        SCp->sc_data_direction);
                }
        }
 }
 
 STATIC inline void
 NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata,
-              Scsi_Cmnd *SCp, int result)
+              struct scsi_cmnd *SCp, int result)
 {
        hostdata->state = NCR_700_HOST_FREE;
        hostdata->cmd = NULL;
@@ -604,31 +609,26 @@ NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata,
                struct NCR_700_command_slot *slot = 
                        (struct NCR_700_command_slot *)SCp->host_scribble;
                
-               NCR_700_unmap(hostdata, SCp, slot);
                dma_unmap_single(hostdata->dev, slot->pCmd,
                                 sizeof(SCp->cmnd), DMA_TO_DEVICE);
-               if(SCp->cmnd[0] == REQUEST_SENSE && SCp->cmnd[6] == NCR_700_INTERNAL_SENSE_MAGIC) {
+               if (slot->flags == NCR_700_FLAG_AUTOSENSE) {
+                       char *cmnd = NCR_700_get_sense_cmnd(SCp->device);
 #ifdef NCR_700_DEBUG
                        printk(" ORIGINAL CMD %p RETURNED %d, new return is %d sense is\n",
                               SCp, SCp->cmnd[7], result);
-                       print_sense("53c700", SCp);
+                       scsi_print_sense("53c700", SCp);
 
 #endif
+                       dma_unmap_single(hostdata->dev, slot->dma_handle, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE);
                        /* restore the old result if the request sense was
                         * successful */
-                       if(result == 0)
-                               result = SCp->cmnd[7];
-                       /* now restore the original command */
-                       memcpy((void *) SCp->cmnd, (void *) SCp->data_cmnd,
-                              sizeof(SCp->data_cmnd));
-                       SCp->request_buffer = SCp->buffer;
-                       SCp->request_bufflen = SCp->bufflen;
-                       SCp->use_sg = SCp->old_use_sg;
-                       SCp->cmd_len = SCp->old_cmd_len;
-                       SCp->sc_data_direction = SCp->sc_old_data_direction;
-                       SCp->underflow = SCp->old_underflow;
-                       
-               }
+                       if (result == 0)
+                               result = cmnd[7];
+                       /* restore the original length */
+                       SCp->cmd_len = cmnd[8];
+               } else
+                       NCR_700_unmap(hostdata, SCp, slot);
+
                free_slot(slot, hostdata);
 #ifdef NCR_700_DEBUG
                if(NCR_700_get_depth(SCp->device) == 0 ||
@@ -780,7 +780,7 @@ NCR_700_chip_reset(struct Scsi_Host *host)
 STATIC __u32
 process_extended_message(struct Scsi_Host *host, 
                         struct NCR_700_Host_Parameters *hostdata,
-                        Scsi_Cmnd *SCp, __u32 dsp, __u32 dsps)
+                        struct scsi_cmnd *SCp, __u32 dsp, __u32 dsps)
 {
        __u32 resume_offset = dsp, temp = dsp + 8;
        __u8 pun = 0xff, lun = 0xff;
@@ -793,6 +793,7 @@ process_extended_message(struct Scsi_Host *host,
        switch(hostdata->msgin[2]) {
        case A_SDTR_MSG:
                if(SCp != NULL && NCR_700_is_flag_set(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION)) {
+                       struct scsi_target *starget = SCp->device->sdev_target;
                        __u8 period = hostdata->msgin[3];
                        __u8 offset = hostdata->msgin[4];
 
@@ -800,22 +801,15 @@ process_extended_message(struct Scsi_Host *host,
                                offset = 0;
                                period = 0;
                        }
+
+                       spi_offset(starget) = offset;
+                       spi_period(starget) = period;
                        
                        if(NCR_700_is_flag_set(SCp->device, NCR_700_DEV_PRINT_SYNC_NEGOTIATION)) {
-                               if(spi_offset(SCp->device) != 0)
-                                       printk(KERN_INFO "scsi%d: (%d:%d) Synchronous at offset %d, period %dns\n",
-                                              host->host_no, pun, lun,
-                                              offset, period*4);
-                               else
-                                       printk(KERN_INFO "scsi%d: (%d:%d) Asynchronous\n",
-                                              host->host_no, pun, lun);
+                               spi_display_xfer_agreement(starget);
                                NCR_700_clear_flag(SCp->device, NCR_700_DEV_PRINT_SYNC_NEGOTIATION);
                        }
-                               
-                       spi_offset(SCp->device) = offset;
-                       spi_period(SCp->device) = period;
                        
-
                        NCR_700_set_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC);
                        NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
                        
@@ -824,11 +818,12 @@ process_extended_message(struct Scsi_Host *host,
 
                } else {
                        /* SDTR message out of the blue, reject it */
-                       printk(KERN_WARNING "scsi%d Unexpected SDTR msg\n",
-                              host->host_no);
+                       shost_printk(KERN_WARNING, host,
+                               "Unexpected SDTR msg\n");
                        hostdata->msgout[0] = A_REJECT_MSG;
-                       dma_cache_sync(hostdata->msgout, 1, DMA_TO_DEVICE);
-                       script_patch_16(hostdata->script, MessageCount, 1);
+                       dma_cache_sync(hostdata->dev, hostdata->msgout, 1, DMA_TO_DEVICE);
+                       script_patch_16(hostdata->dev, hostdata->script,
+                                       MessageCount, 1);
                        /* SendMsgOut returns, so set up the return
                         * address */
                        resume_offset = hostdata->pScript + Ent_SendMessageWithATN;
@@ -839,8 +834,9 @@ process_extended_message(struct Scsi_Host *host,
                printk(KERN_INFO "scsi%d: (%d:%d), Unsolicited WDTR after CMD, Rejecting\n",
                       host->host_no, pun, lun);
                hostdata->msgout[0] = A_REJECT_MSG;
-               dma_cache_sync(hostdata->msgout, 1, DMA_TO_DEVICE);
-               script_patch_16(hostdata->script, MessageCount, 1);
+               dma_cache_sync(hostdata->dev, hostdata->msgout, 1, DMA_TO_DEVICE);
+               script_patch_16(hostdata->dev, hostdata->script, MessageCount,
+                               1);
                resume_offset = hostdata->pScript + Ent_SendMessageWithATN;
 
                break;
@@ -849,12 +845,13 @@ process_extended_message(struct Scsi_Host *host,
                printk(KERN_INFO "scsi%d (%d:%d): Unexpected message %s: ",
                       host->host_no, pun, lun,
                       NCR_700_phase[(dsps & 0xf00) >> 8]);
-               print_msg(hostdata->msgin);
+               spi_print_msg(hostdata->msgin);
                printk("\n");
                /* just reject it */
                hostdata->msgout[0] = A_REJECT_MSG;
-               dma_cache_sync(hostdata->msgout, 1, DMA_TO_DEVICE);
-               script_patch_16(hostdata->script, MessageCount, 1);
+               dma_cache_sync(hostdata->dev, hostdata->msgout, 1, DMA_TO_DEVICE);
+               script_patch_16(hostdata->dev, hostdata->script, MessageCount,
+                               1);
                /* SendMsgOut returns, so set up the return
                 * address */
                resume_offset = hostdata->pScript + Ent_SendMessageWithATN;
@@ -865,7 +862,7 @@ process_extended_message(struct Scsi_Host *host,
 
 STATIC __u32
 process_message(struct Scsi_Host *host,        struct NCR_700_Host_Parameters *hostdata,
-               Scsi_Cmnd *SCp, __u32 dsp, __u32 dsps)
+               struct scsi_cmnd *SCp, __u32 dsp, __u32 dsps)
 {
        /* work out where to return to */
        __u32 temp = dsp + 8, resume_offset = dsp;
@@ -879,7 +876,7 @@ process_message(struct Scsi_Host *host,     struct NCR_700_Host_Parameters *hostdata
 #ifdef NCR_700_DEBUG
        printk("scsi%d (%d:%d): message %s: ", host->host_no, pun, lun,
               NCR_700_phase[(dsps & 0xf00) >> 8]);
-       print_msg(hostdata->msgin);
+       spi_print_msg(hostdata->msgin);
        printk("\n");
 #endif
 
@@ -893,19 +890,23 @@ process_message(struct Scsi_Host *host,   struct NCR_700_Host_Parameters *hostdata
        case A_REJECT_MSG:
                if(SCp != NULL && NCR_700_is_flag_set(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION)) {
                        /* Rejected our sync negotiation attempt */
-                       spi_period(SCp->device) = spi_offset(SCp->device) = 0;
+                       spi_period(SCp->device->sdev_target) =
+                               spi_offset(SCp->device->sdev_target) = 0;
                        NCR_700_set_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC);
                        NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
-               } else if(SCp != NULL && NCR_700_is_flag_set(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING)) {
+               } else if(SCp != NULL && NCR_700_get_tag_neg_state(SCp->device) == NCR_700_DURING_TAG_NEGOTIATION) {
                        /* rejected our first simple tag message */
-                       printk(KERN_WARNING "scsi%d (%d:%d) Rejected first tag queue attempt, turning off tag queueing\n", host->host_no, pun, lun);
-                       NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);
-                       hostdata->tag_negotiated &= ~(1<<SCp->device->id);
+                       scmd_printk(KERN_WARNING, SCp,
+                               "Rejected first tag queue attempt, turning off tag queueing\n");
+                       /* we're done negotiating */
+                       NCR_700_set_tag_neg_state(SCp->device, NCR_700_FINISHED_TAG_NEGOTIATION);
+                       hostdata->tag_negotiated &= ~(1<<scmd_id(SCp));
                        SCp->device->tagged_supported = 0;
                        scsi_deactivate_tcq(SCp->device, host->cmd_per_lun);
                } else {
-                       printk(KERN_WARNING "scsi%d (%d:%d) Unexpected REJECT Message %s\n",
-                              host->host_no, pun, lun,
+                       shost_printk(KERN_WARNING, host,
+                               "(%d:%d) Unexpected REJECT Message %s\n",
+                              pun, lun,
                               NCR_700_phase[(dsps & 0xf00) >> 8]);
                        /* however, just ignore it */
                }
@@ -927,12 +928,13 @@ process_message(struct Scsi_Host *host,   struct NCR_700_Host_Parameters *hostdata
                       host->host_no, pun, lun,
                       NCR_700_phase[(dsps & 0xf00) >> 8]);
 
-               print_msg(hostdata->msgin);
+               spi_print_msg(hostdata->msgin);
                printk("\n");
                /* just reject it */
                hostdata->msgout[0] = A_REJECT_MSG;
-               dma_cache_sync(hostdata->msgout, 1, DMA_TO_DEVICE);
-               script_patch_16(hostdata->script, MessageCount, 1);
+               dma_cache_sync(hostdata->dev, hostdata->msgout, 1, DMA_TO_DEVICE);
+               script_patch_16(hostdata->dev, hostdata->script, MessageCount,
+                               1);
                /* SendMsgOut returns, so set up the return
                 * address */
                resume_offset = hostdata->pScript + Ent_SendMessageWithATN;
@@ -941,12 +943,12 @@ process_message(struct Scsi_Host *host,   struct NCR_700_Host_Parameters *hostdata
        }
        NCR_700_writel(temp, host, TEMP_REG);
        /* set us up to receive another message */
-       dma_cache_sync(hostdata->msgin, MSG_ARRAY_SIZE, DMA_FROM_DEVICE);
+       dma_cache_sync(hostdata->dev, hostdata->msgin, MSG_ARRAY_SIZE, DMA_FROM_DEVICE);
        return resume_offset;
 }
 
 STATIC __u32
-process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
+process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
                         struct Scsi_Host *host,
                         struct NCR_700_Host_Parameters *hostdata)
 {
@@ -961,21 +963,27 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
        if(dsps == A_GOOD_STATUS_AFTER_STATUS) {
                DEBUG(("  COMMAND COMPLETE, status=%02x\n",
                       hostdata->status[0]));
-               /* OK, if TCQ still on, we know it works */
-               NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);
+               /* OK, if TCQ still under negotiation, we now know it works */
+               if (NCR_700_get_tag_neg_state(SCp->device) == NCR_700_DURING_TAG_NEGOTIATION)
+                       NCR_700_set_tag_neg_state(SCp->device,
+                                                 NCR_700_FINISHED_TAG_NEGOTIATION);
+                       
                /* check for contingent allegiance contitions */
                if(status_byte(hostdata->status[0]) == CHECK_CONDITION ||
                   status_byte(hostdata->status[0]) == COMMAND_TERMINATED) {
                        struct NCR_700_command_slot *slot =
                                (struct NCR_700_command_slot *)SCp->host_scribble;
-                       if(SCp->cmnd[0] == REQUEST_SENSE) {
+                       if(slot->flags == NCR_700_FLAG_AUTOSENSE) {
                                /* OOPS: bad device, returning another
                                 * contingent allegiance condition */
-                               printk(KERN_ERR "scsi%d (%d:%d) broken device is looping in contingent allegiance: ignoring\n", host->host_no, pun, lun);
+                               scmd_printk(KERN_ERR, SCp,
+                                       "broken device is looping in contingent allegiance: ignoring\n");
                                NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]);
                        } else {
+                               char *cmnd =
+                                       NCR_700_get_sense_cmnd(SCp->device);
 #ifdef NCR_DEBUG
-                               print_command(SCp->cmnd);
+                               scsi_print_command(SCp);
                                printk("  cmd %p has status %d, requesting sense\n",
                                       SCp, hostdata->status[0]);
 #endif
@@ -987,38 +995,40 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
                                 * data associated with the command
                                 * here */
                                NCR_700_unmap(hostdata, SCp, slot);
-
-                               SCp->cmnd[0] = REQUEST_SENSE;
-                               SCp->cmnd[1] = (SCp->device->lun & 0x7) << 5;
-                               SCp->cmnd[2] = 0;
-                               SCp->cmnd[3] = 0;
-                               SCp->cmnd[4] = sizeof(SCp->sense_buffer);
-                               SCp->cmnd[5] = 0;
-                               SCp->cmd_len = 6;
+                               dma_unmap_single(hostdata->dev, slot->pCmd,
+                                                sizeof(SCp->cmnd),
+                                                DMA_TO_DEVICE);
+
+                               cmnd[0] = REQUEST_SENSE;
+                               cmnd[1] = (SCp->device->lun & 0x7) << 5;
+                               cmnd[2] = 0;
+                               cmnd[3] = 0;
+                               cmnd[4] = sizeof(SCp->sense_buffer);
+                               cmnd[5] = 0;
                                /* Here's a quiet hack: the
                                 * REQUEST_SENSE command is six bytes,
                                 * so store a flag indicating that
                                 * this was an internal sense request
                                 * and the original status at the end
                                 * of the command */
-                               SCp->cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC;
-                               SCp->cmnd[7] = hostdata->status[0];
-                               SCp->use_sg = 0;
-                               SCp->sc_data_direction = SCSI_DATA_READ;
-                               dma_sync_single_for_device(hostdata->dev, slot->pCmd,
-                                                          SCp->cmd_len, DMA_TO_DEVICE);
-                               SCp->request_bufflen = sizeof(SCp->sense_buffer);
+                               cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC;
+                               cmnd[7] = hostdata->status[0];
+                               cmnd[8] = SCp->cmd_len;
+                               SCp->cmd_len = 6; /* command length for
+                                                  * REQUEST_SENSE */
+                               slot->pCmd = dma_map_single(hostdata->dev, cmnd, MAX_COMMAND_SIZE, DMA_TO_DEVICE);
                                slot->dma_handle = dma_map_single(hostdata->dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE);
                                slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer));
                                slot->SG[0].pAddr = bS_to_host(slot->dma_handle);
                                slot->SG[1].ins = bS_to_host(SCRIPT_RETURN);
                                slot->SG[1].pAddr = 0;
                                slot->resume_offset = hostdata->pScript;
-                               dma_cache_sync(slot->SG, sizeof(slot->SG[0])*2, DMA_TO_DEVICE);
-                               dma_cache_sync(SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE);
-                               
+                               dma_cache_sync(hostdata->dev, slot->SG, sizeof(slot->SG[0])*2, DMA_TO_DEVICE);
+                               dma_cache_sync(hostdata->dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE);
+
                                /* queue the command for reissue */
                                slot->state = NCR_700_SLOT_QUEUED;
+                               slot->flags = NCR_700_FLAG_AUTOSENSE;
                                hostdata->state = NCR_700_HOST_FREE;
                                hostdata->cmd = NULL;
                        }
@@ -1035,12 +1045,13 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
                        //                          SCp->request_bufflen,
                        //                          DMA_FROM_DEVICE);
                        //      if(((char *)SCp->request_buffer)[7] & 0x02) {
-                       //              printk(KERN_INFO "scsi%d: (%d:%d) Enabling Tag Command Queuing\n", host->host_no, pun, lun);
-                       //              hostdata->tag_negotiated |= (1<<SCp->device->id);
+                       //              scmd_printk(KERN_INFO, SCp,
+                       //                   "Enabling Tag Command Queuing\n");
+                       //              hostdata->tag_negotiated |= (1<<scmd_id(SCp));
                        //              NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);
                        //      } else {
                        //              NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);
-                       //              hostdata->tag_negotiated &= ~(1<<SCp->device->id);
+                       //              hostdata->tag_negotiated &= ~(1<<scmd_id(SCp));
                        //      }
                        //}
                        NCR_700_scsi_done(hostdata, SCp, hostdata->status[0]);
@@ -1048,12 +1059,12 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
        } else if((dsps & 0xfffff0f0) == A_UNEXPECTED_PHASE) {
                __u8 i = (dsps & 0xf00) >> 8;
 
-               printk(KERN_ERR "scsi%d: (%d:%d), UNEXPECTED PHASE %s (%s)\n",
-                      host->host_no, pun, lun,
+               scmd_printk(KERN_ERR, SCp, "UNEXPECTED PHASE %s (%s)\n",
                       NCR_700_phase[i],
                       sbcl_to_string(NCR_700_readb(host, SBCL_REG)));
-               printk(KERN_ERR "         len = %d, cmd =", SCp->cmd_len);
-               print_command(SCp->cmnd);
+               scmd_printk(KERN_ERR, SCp, "         len = %d, cmd =",
+                       SCp->cmd_len);
+               scsi_print_command(SCp);
 
                NCR_700_internal_bus_reset(host);
        } else if((dsps & 0xfffff000) == A_FATAL) {
@@ -1080,7 +1091,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
                __u8 lun;
                struct NCR_700_command_slot *slot;
                __u8 reselection_id = hostdata->reselection_id;
-               Scsi_Device *SDp;
+               struct scsi_device *SDp;
 
                lun = hostdata->msgin[0] & 0x1f;
 
@@ -1095,7 +1106,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
                        BUG();
                }
                if(hostdata->msgin[1] == A_SIMPLE_TAG_MSG) {
-                       Scsi_Cmnd *SCp = scsi_find_tag(SDp, hostdata->msgin[2]);
+                       struct scsi_cmnd *SCp = scsi_find_tag(SDp, hostdata->msgin[2]);
                        if(unlikely(SCp == NULL)) {
                                printk(KERN_ERR "scsi%d: (%d:%d) no saved request for tag %d\n", 
                                       host->host_no, reselection_id, lun, hostdata->msgin[2]);
@@ -1103,14 +1114,14 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
                        }
 
                        slot = (struct NCR_700_command_slot *)SCp->host_scribble;
-                       DEBUG(("53c700: %d:%d:%d, reselection is tag %d, slot %p(%d)\n",
-                              host->host_no, SDp->id, SDp->lun,
-                              hostdata->msgin[2], slot, slot->tag));
+                       DDEBUG(KERN_DEBUG, SDp,
+                               "reselection is tag %d, slot %p(%d)\n",
+                               hostdata->msgin[2], slot, slot->tag);
                } else {
-                       Scsi_Cmnd *SCp = scsi_find_tag(SDp, SCSI_NO_TAG);
+                       struct scsi_cmnd *SCp = scsi_find_tag(SDp, SCSI_NO_TAG);
                        if(unlikely(SCp == NULL)) {
-                               printk(KERN_ERR "scsi%d: (%d:%d) no saved request for untagged cmd\n", 
-                                      host->host_no, reselection_id, lun);
+                               sdev_printk(KERN_ERR, SDp,
+                                       "no saved request for untagged cmd\n");
                                BUG();
                        }
                        slot = (struct NCR_700_command_slot *)SCp->host_scribble;
@@ -1129,11 +1140,12 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
                        hostdata->cmd = slot->cmnd;
 
                        /* re-patch for this command */
-                       script_patch_32_abs(hostdata->script, CommandAddress, 
-                                           slot->pCmd);
-                       script_patch_16(hostdata->script,
+                       script_patch_32_abs(hostdata->dev, hostdata->script,
+                                           CommandAddress, slot->pCmd);
+                       script_patch_16(hostdata->dev, hostdata->script,
                                        CommandCount, slot->cmnd->cmd_len);
-                       script_patch_32_abs(hostdata->script, SGScriptStartAddress,
+                       script_patch_32_abs(hostdata->dev, hostdata->script,
+                                           SGScriptStartAddress,
                                            to32bit(&slot->pSG[0].ins));
 
                        /* Note: setting SXFER only works if we're
@@ -1143,13 +1155,13 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
                         * should therefore always clear ACK */
                        NCR_700_writeb(NCR_700_get_SXFER(hostdata->cmd->device),
                                       host, SXFER_REG);
-                       dma_cache_sync(hostdata->msgin,
+                       dma_cache_sync(hostdata->dev, hostdata->msgin,
                                       MSG_ARRAY_SIZE, DMA_FROM_DEVICE);
-                       dma_cache_sync(hostdata->msgout,
+                       dma_cache_sync(hostdata->dev, hostdata->msgout,
                                       MSG_ARRAY_SIZE, DMA_TO_DEVICE);
                        /* I'm just being paranoid here, the command should
                         * already have been flushed from the cache */
-                       dma_cache_sync(slot->cmnd->cmnd,
+                       dma_cache_sync(hostdata->dev, slot->cmnd->cmnd,
                                       slot->cmnd->cmd_len, DMA_TO_DEVICE);
 
 
@@ -1213,7 +1225,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
                hostdata->reselection_id = reselection_id;
                /* just in case we have a stale simple tag message, clear it */
                hostdata->msgin[1] = 0;
-               dma_cache_sync(hostdata->msgin,
+               dma_cache_sync(hostdata->dev, hostdata->msgin,
                               MSG_ARRAY_SIZE, DMA_BIDIRECTIONAL);
                if(hostdata->tag_negotiated & (1<<reselection_id)) {
                        resume_offset = hostdata->pScript + Ent_GetReselectionWithTag;
@@ -1234,11 +1246,11 @@ process_script_interrupt(__u32 dsps, __u32 dsp, Scsi_Cmnd *SCp,
                       host->host_no, pun, lun, NCR_700_condition[i],
                       NCR_700_phase[j], dsp - hostdata->pScript);
                if(SCp != NULL) {
-                       print_command(SCp->cmnd);
+                       scsi_print_command(SCp);
 
                        if(SCp->use_sg) {
                                for(i = 0; i < SCp->use_sg + 1; i++) {
-                                       printk(KERN_INFO " SG[%d].length = %d, move_insn=%08x, addr %08x\n", i, ((struct scatterlist *)SCp->buffer)[i].length, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].ins, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].pAddr);
+                                       printk(KERN_INFO " SG[%d].length = %d, move_insn=%08x, addr %08x\n", i, ((struct scatterlist *)SCp->request_buffer)[i].length, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].ins, ((struct NCR_700_command_slot *)SCp->host_scribble)->SG[i].pAddr);
                                }
                        }
                }              
@@ -1270,7 +1282,7 @@ process_selection(struct Scsi_Host *host, __u32 dsp)
        __u32 resume_offset = 0;
        struct NCR_700_Host_Parameters *hostdata =
                (struct NCR_700_Host_Parameters *)host->hostdata[0];
-       Scsi_Cmnd *SCp = hostdata->cmd;
+       struct scsi_cmnd *SCp = hostdata->cmd;
        __u8 sbcl;
 
        for(count = 0; count < 5; count++) {
@@ -1329,7 +1341,7 @@ process_selection(struct Scsi_Host *host, __u32 dsp)
        hostdata->cmd = NULL;
        /* clear any stale simple tag message */
        hostdata->msgin[1] = 0;
-       dma_cache_sync(hostdata->msgin, MSG_ARRAY_SIZE,
+       dma_cache_sync(hostdata->dev, hostdata->msgin, MSG_ARRAY_SIZE,
                       DMA_BIDIRECTIONAL);
 
        if(id == 0xff) {
@@ -1373,7 +1385,7 @@ NCR_700_flush_fifo(struct Scsi_Host *host) {
 /* The queue lock with interrupts disabled must be held on entry to
  * this function */
 STATIC int
-NCR_700_start_command(Scsi_Cmnd *SCp)
+NCR_700_start_command(struct scsi_cmnd *SCp)
 {
        struct NCR_700_command_slot *slot =
                (struct NCR_700_command_slot *)SCp->host_scribble;
@@ -1397,12 +1409,14 @@ NCR_700_start_command(Scsi_Cmnd *SCp)
        /* keep interrupts disabled until we have the command correctly
         * set up so we cannot take a selection interrupt */
 
-       hostdata->msgout[0] = NCR_700_identify(SCp->cmnd[0] != REQUEST_SENSE,
+       hostdata->msgout[0] = NCR_700_identify((SCp->cmnd[0] != REQUEST_SENSE &&
+                                               slot->flags != NCR_700_FLAG_AUTOSENSE),
                                               SCp->device->lun);
        /* for INQUIRY or REQUEST_SENSE commands, we cannot be sure
         * if the negotiated transfer parameters still hold, so
         * always renegotiate them */
-       if(SCp->cmnd[0] == INQUIRY || SCp->cmnd[0] == REQUEST_SENSE) {
+       if(SCp->cmnd[0] == INQUIRY || SCp->cmnd[0] == REQUEST_SENSE ||
+          slot->flags == NCR_700_FLAG_AUTOSENSE) {
                NCR_700_clear_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC);
        }
 
@@ -1410,44 +1424,44 @@ NCR_700_start_command(Scsi_Cmnd *SCp)
         * If a contingent allegiance condition exists, the device
         * will refuse all tags, so send the request sense as untagged
         * */
-       if((hostdata->tag_negotiated & (1<<SCp->device->id))
-          && (slot->tag != SCSI_NO_TAG && SCp->cmnd[0] != REQUEST_SENSE)) {
+       if((hostdata->tag_negotiated & (1<<scmd_id(SCp)))
+          && (slot->tag != SCSI_NO_TAG && SCp->cmnd[0] != REQUEST_SENSE &&
+              slot->flags != NCR_700_FLAG_AUTOSENSE)) {
                count += scsi_populate_tag_msg(SCp, &hostdata->msgout[count]);
        }
 
        if(hostdata->fast &&
           NCR_700_is_flag_clear(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC)) {
-               memcpy(&hostdata->msgout[count], NCR_700_SDTR_msg,
-                      sizeof(NCR_700_SDTR_msg));
-               hostdata->msgout[count+3] = spi_period(SCp->device);
-               hostdata->msgout[count+4] = spi_offset(SCp->device);
-               count += sizeof(NCR_700_SDTR_msg);
+               count += spi_populate_sync_msg(&hostdata->msgout[count],
+                               spi_period(SCp->device->sdev_target),
+                               spi_offset(SCp->device->sdev_target));
                NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
        }
 
-       script_patch_16(hostdata->script, MessageCount, count);
+       script_patch_16(hostdata->dev, hostdata->script, MessageCount, count);
 
 
-       script_patch_ID(hostdata->script,
-                       Device_ID, 1<<SCp->device->id);
+       script_patch_ID(hostdata->dev, hostdata->script,
+                       Device_ID, 1<<scmd_id(SCp));
 
-       script_patch_32_abs(hostdata->script, CommandAddress, 
+       script_patch_32_abs(hostdata->dev, hostdata->script, CommandAddress,
                            slot->pCmd);
-       script_patch_16(hostdata->script, CommandCount, SCp->cmd_len);
+       script_patch_16(hostdata->dev, hostdata->script, CommandCount,
+                       SCp->cmd_len);
        /* finally plumb the beginning of the SG list into the script
         * */
-       script_patch_32_abs(hostdata->script, SGScriptStartAddress,
-                           to32bit(&slot->pSG[0].ins));
+       script_patch_32_abs(hostdata->dev, hostdata->script,
+                           SGScriptStartAddress, to32bit(&slot->pSG[0].ins));
        NCR_700_clear_fifo(SCp->device->host);
 
        if(slot->resume_offset == 0)
                slot->resume_offset = hostdata->pScript;
        /* now perform all the writebacks and invalidates */
-       dma_cache_sync(hostdata->msgout, count, DMA_TO_DEVICE);
-       dma_cache_sync(hostdata->msgin, MSG_ARRAY_SIZE,
+       dma_cache_sync(hostdata->dev, hostdata->msgout, count, DMA_TO_DEVICE);
+       dma_cache_sync(hostdata->dev, hostdata->msgin, MSG_ARRAY_SIZE,
                       DMA_FROM_DEVICE);
-       dma_cache_sync(SCp->cmnd, SCp->cmd_len, DMA_TO_DEVICE);
-       dma_cache_sync(hostdata->status, 1, DMA_FROM_DEVICE);
+       dma_cache_sync(hostdata->dev, SCp->cmnd, SCp->cmd_len, DMA_TO_DEVICE);
+       dma_cache_sync(hostdata->dev, hostdata->status, 1, DMA_FROM_DEVICE);
 
        /* set the synchronous period/offset */
        NCR_700_writeb(NCR_700_get_SXFER(SCp->device),
@@ -1459,7 +1473,7 @@ NCR_700_start_command(Scsi_Cmnd *SCp)
 }
 
 irqreturn_t
-NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs)
+NCR_700_intr(int irq, void *dev_id)
 {
        struct Scsi_Host *host = (struct Scsi_Host *)dev_id;
        struct NCR_700_Host_Parameters *hostdata =
@@ -1481,7 +1495,7 @@ NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs)
                __u32 dsps;
                __u8 sstat0 = 0, dstat = 0;
                __u32 dsp;
-               Scsi_Cmnd *SCp = hostdata->cmd;
+               struct scsi_cmnd *SCp = hostdata->cmd;
                enum NCR_700_Host_State state;
 
                handled = 1;
@@ -1514,7 +1528,7 @@ NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs)
                }
 
                if(sstat0 & SCSI_RESET_DETECTED) {
-                       Scsi_Device *SDp;
+                       struct scsi_device *SDp;
                        int i;
 
                        hostdata->state = NCR_700_HOST_BUSY;
@@ -1526,11 +1540,11 @@ NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs)
 
                        /* clear all the negotiated parameters */
                        __shost_for_each_device(SDp, host)
-                               SDp->hostdata = 0;
+                               NCR_700_clear_flag(SDp, ~0);
                        
                        /* clear all the slots and their pending commands */
                        for(i = 0; i < NCR_700_COMMAND_SLOTS_PER_HOST; i++) {
-                               Scsi_Cmnd *SCp;
+                               struct scsi_cmnd *SCp;
                                struct NCR_700_command_slot *slot =
                                        &hostdata->slots[i];
 
@@ -1590,7 +1604,7 @@ NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs)
                                printk("scsi%d: (%d:%d) Expected phase mismatch in slot->SG[%d], transferred 0x%x\n",
                                       host->host_no, pun, lun,
                                       SGcount, data_transfer);
-                               print_command(SCp->cmnd);
+                               scsi_print_command(SCp);
                                if(residual) {
                                        printk("scsi%d: (%d:%d) Expected phase mismatch in slot->SG[%d], transferred 0x%x, residual %d\n",
                                       host->host_no, pun, lun,
@@ -1623,7 +1637,7 @@ NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs)
                                        slot->SG[i].ins = bS_to_host(SCRIPT_NOP);
                                        slot->SG[i].pAddr = 0;
                                }
-                               dma_cache_sync(slot->SG, sizeof(slot->SG), DMA_TO_DEVICE);
+                               dma_cache_sync(hostdata->dev, slot->SG, sizeof(slot->SG), DMA_TO_DEVICE);
                                /* and pretend we disconnected after
                                 * the command phase */
                                resume_offset = hostdata->pScript + Ent_MsgInDuringData;
@@ -1731,7 +1745,7 @@ NCR_700_intr(int irq, void *dev_id, struct pt_regs *regs)
 }
 
 STATIC int
-NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *))
+NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
 {
        struct NCR_700_Host_Parameters *hostdata = 
                (struct NCR_700_Host_Parameters *)SCp->device->host->hostdata[0];
@@ -1752,17 +1766,15 @@ NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *))
         * - The blk layer sent and untagged command
         */
        if(NCR_700_get_depth(SCp->device) != 0
-          && (!(hostdata->tag_negotiated & (1<<SCp->device->id))
+          && (!(hostdata->tag_negotiated & (1<<scmd_id(SCp)))
               || !blk_rq_tagged(SCp->request))) {
-               DEBUG((KERN_ERR "scsi%d (%d:%d) has non zero depth %d\n",
-                      SCp->device->host->host_no, SCp->device->id, SCp->device->lun,
-                      NCR_700_get_depth(SCp->device)));
+               CDEBUG(KERN_ERR, SCp, "has non zero depth %d\n",
+                      NCR_700_get_depth(SCp->device));
                return SCSI_MLQUEUE_DEVICE_BUSY;
        }
        if(NCR_700_get_depth(SCp->device) >= SCp->device->queue_depth) {
-               DEBUG((KERN_ERR "scsi%d (%d:%d) has max tag depth %d\n",
-                      SCp->device->host->host_no, SCp->device->id, SCp->device->lun,
-                      NCR_700_get_depth(SCp->device)));
+               CDEBUG(KERN_ERR, SCp, "has max tag depth %d\n",
+                      NCR_700_get_depth(SCp->device));
                return SCSI_MLQUEUE_DEVICE_BUSY;
        }
        NCR_700_set_depth(SCp->device, NCR_700_get_depth(SCp->device) + 1);
@@ -1781,25 +1793,14 @@ NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *))
 
 #ifdef NCR_700_DEBUG
        printk("53c700: scsi%d, command ", SCp->device->host->host_no);
-       print_command(SCp->cmnd);
+       scsi_print_command(SCp);
 #endif
-       if(SCp->device->tagged_supported && !SCp->device->simple_tags
-          && (hostdata->tag_negotiated &(1<<SCp->device->id)) == 0
-          && NCR_700_is_flag_clear(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING)) {
-               /* upper layer has indicated tags are supported.  We don't
-                * necessarily believe it yet.
-                *
-                * NOTE: There is a danger here: the mid layer supports
-                * tag queuing per LUN.  We only support it per PUN because
-                * of potential reselection issues */
-               scsi_activate_tcq(SCp->device, NCR_700_DEFAULT_TAGS);
-       }
-
        if(blk_rq_tagged(SCp->request)
-          && (hostdata->tag_negotiated &(1<<SCp->device->id)) == 0) {
-               printk(KERN_INFO "scsi%d: (%d:%d) Enabling Tag Command Queuing\n", SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
-               hostdata->tag_negotiated |= (1<<SCp->device->id);
-               NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING);
+          && (hostdata->tag_negotiated &(1<<scmd_id(SCp))) == 0
+          && NCR_700_get_tag_neg_state(SCp->device) == NCR_700_START_TAG_NEGOTIATION) {
+               scmd_printk(KERN_ERR, SCp, "Enabling Tag Command Queuing\n");
+               hostdata->tag_negotiated |= (1<<scmd_id(SCp));
+               NCR_700_set_tag_neg_state(SCp->device, NCR_700_DURING_TAG_NEGOTIATION);
        }
 
        /* here we may have to process an untagged command.  The gate
@@ -1809,16 +1810,16 @@ NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *))
         * FIXME: This will royally screw up on multiple LUN devices
         * */
        if(!blk_rq_tagged(SCp->request)
-          && (hostdata->tag_negotiated &(1<<SCp->device->id))) {
-               printk(KERN_INFO "scsi%d: (%d:%d) Disabling Tag Command Queuing\n", SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
-               hostdata->tag_negotiated &= ~(1<<SCp->device->id);
+          && (hostdata->tag_negotiated &(1<<scmd_id(SCp)))) {
+               scmd_printk(KERN_INFO, SCp, "Disabling Tag Command Queuing\n");
+               hostdata->tag_negotiated &= ~(1<<scmd_id(SCp));
        }
 
-       if((hostdata->tag_negotiated &(1<<SCp->device->id))) {
+       if((hostdata->tag_negotiated &(1<<scmd_id(SCp)))
+          && scsi_get_tag_type(SCp->device)) {
                slot->tag = SCp->request->tag;
-               DEBUG(("53c700 %d:%d:%d, sending out tag %d, slot %p\n",
-                      SCp->device->host->host_no, SCp->device->id, SCp->device->lun, slot->tag,
-                      slot));
+               CDEBUG(KERN_DEBUG, SCp, "sending out tag %d, slot %p\n",
+                      slot->tag, slot);
        } else {
                slot->tag = SCSI_NO_TAG;
                /* must populate current_cmnd for scsi_find_tag to work */
@@ -1827,13 +1828,13 @@ NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *))
        /* sanity check: some of the commands generated by the mid-layer
         * have an eccentric idea of their sc_data_direction */
        if(!SCp->use_sg && !SCp->request_bufflen 
-          && SCp->sc_data_direction != SCSI_DATA_NONE) {
+          && SCp->sc_data_direction != DMA_NONE) {
 #ifdef NCR_700_DEBUG
                printk("53c700: Command");
-               print_command(SCp->cmnd);
+               scsi_print_command(SCp);
                printk("Has wrong data direction %d\n", SCp->sc_data_direction);
 #endif
-               SCp->sc_data_direction = SCSI_DATA_NONE;
+               SCp->sc_data_direction = DMA_NONE;
        }
 
        switch (SCp->cmnd[0]) {
@@ -1844,20 +1845,20 @@ NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *))
        default:
                /* OK, get it from the command */
                switch(SCp->sc_data_direction) {
-               case SCSI_DATA_UNKNOWN:
+               case DMA_BIDIRECTIONAL:
                default:
                        printk(KERN_ERR "53c700: Unknown command for data direction ");
-                       print_command(SCp->cmnd);
+                       scsi_print_command(SCp);
                        
                        move_ins = 0;
                        break;
-               case SCSI_DATA_NONE:
+               case DMA_NONE:
                        move_ins = 0;
                        break;
-               case SCSI_DATA_READ:
+               case DMA_FROM_DEVICE:
                        move_ins = SCRIPT_MOVE_DATA_IN;
                        break;
-               case SCSI_DATA_WRITE:
+               case DMA_TO_DEVICE:
                        move_ins = SCRIPT_MOVE_DATA_OUT;
                        break;
                }
@@ -1872,8 +1873,9 @@ NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *))
                __u32 count = 0;
 
                if(SCp->use_sg) {
-                       sg_count = dma_map_sg(hostdata->dev, SCp->buffer,
-                                             SCp->use_sg, direction);
+                       sg_count = dma_map_sg(hostdata->dev,
+                                             SCp->request_buffer, SCp->use_sg,
+                                             direction);
                } else {
                        vPtr = dma_map_single(hostdata->dev,
                                              SCp->request_buffer, 
@@ -1888,7 +1890,7 @@ NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *))
                for(i = 0; i < sg_count; i++) {
 
                        if(SCp->use_sg) {
-                               struct scatterlist *sg = SCp->buffer;
+                               struct scatterlist *sg = SCp->request_buffer;
 
                                vPtr = sg_dma_address(&sg[i]);
                                count = sg_dma_len(&sg[i]);
@@ -1901,9 +1903,9 @@ NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *))
                }
                slot->SG[i].ins = bS_to_host(SCRIPT_RETURN);
                slot->SG[i].pAddr = 0;
-               dma_cache_sync(slot->SG, sizeof(slot->SG), DMA_TO_DEVICE);
+               dma_cache_sync(hostdata->dev, slot->SG, sizeof(slot->SG), DMA_TO_DEVICE);
                DEBUG((" SETTING %08lx to %x\n",
-                      (&slot->pSG[i].ins), 
+                      (&slot->pSG[i].ins),
                       slot->SG[i].ins));
        }
        slot->resume_offset = 0;
@@ -1914,13 +1916,13 @@ NCR_700_queuecommand(Scsi_Cmnd *SCp, void (*done)(Scsi_Cmnd *))
 }
 
 STATIC int
-NCR_700_abort(Scsi_Cmnd * SCp)
+NCR_700_abort(struct scsi_cmnd * SCp)
 {
        struct NCR_700_command_slot *slot;
 
-       printk(KERN_INFO "scsi%d (%d:%d) New error handler wants to abort command\n\t",
-              SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
-       print_command(SCp->cmnd);
+       scmd_printk(KERN_INFO, SCp,
+               "New error handler wants to abort command\n\t");
+       scsi_print_command(SCp);
 
        slot = (struct NCR_700_command_slot *)SCp->host_scribble;
 
@@ -1946,62 +1948,64 @@ NCR_700_abort(Scsi_Cmnd * SCp)
 }
 
 STATIC int
-NCR_700_bus_reset(Scsi_Cmnd * SCp)
+NCR_700_bus_reset(struct scsi_cmnd * SCp)
 {
-       DECLARE_COMPLETION(complete);
+       DECLARE_COMPLETION_ONSTACK(complete);
        struct NCR_700_Host_Parameters *hostdata = 
                (struct NCR_700_Host_Parameters *)SCp->device->host->hostdata[0];
 
-       printk(KERN_INFO "scsi%d (%d:%d) New error handler wants BUS reset, cmd %p\n\t",
-              SCp->device->host->host_no, SCp->device->id, SCp->device->lun, SCp);
-       print_command(SCp->cmnd);
+       scmd_printk(KERN_INFO, SCp,
+               "New error handler wants BUS reset, cmd %p\n\t", SCp);
+       scsi_print_command(SCp);
+
        /* In theory, eh_complete should always be null because the
         * eh is single threaded, but just in case we're handling a
         * reset via sg or something */
-       while(hostdata->eh_complete != NULL) {
+       spin_lock_irq(SCp->device->host->host_lock);
+       while (hostdata->eh_complete != NULL) {
                spin_unlock_irq(SCp->device->host->host_lock);
-               schedule_timeout(HZ/10);
+               msleep_interruptible(100);
                spin_lock_irq(SCp->device->host->host_lock);
        }
+
        hostdata->eh_complete = &complete;
        NCR_700_internal_bus_reset(SCp->device->host);
+
        spin_unlock_irq(SCp->device->host->host_lock);
        wait_for_completion(&complete);
        spin_lock_irq(SCp->device->host->host_lock);
+
        hostdata->eh_complete = NULL;
        /* Revalidate the transport parameters of the failing device */
        if(hostdata->fast)
                spi_schedule_dv_device(SCp->device);
+
+       spin_unlock_irq(SCp->device->host->host_lock);
        return SUCCESS;
 }
 
 STATIC int
-NCR_700_dev_reset(Scsi_Cmnd * SCp)
+NCR_700_host_reset(struct scsi_cmnd * SCp)
 {
-       printk(KERN_INFO "scsi%d (%d:%d) New error handler wants device reset\n\t",
-              SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
-       print_command(SCp->cmnd);
-       
-       return FAILED;
-}
+       scmd_printk(KERN_INFO, SCp, "New error handler wants HOST reset\n\t");
+       scsi_print_command(SCp);
 
-STATIC int
-NCR_700_host_reset(Scsi_Cmnd * SCp)
-{
-       printk(KERN_INFO "scsi%d (%d:%d) New error handler wants HOST reset\n\t",
-              SCp->device->host->host_no, SCp->device->id, SCp->device->lun);
-       print_command(SCp->cmnd);
+       spin_lock_irq(SCp->device->host->host_lock);
 
        NCR_700_internal_bus_reset(SCp->device->host);
        NCR_700_chip_reset(SCp->device->host);
+
+       spin_unlock_irq(SCp->device->host->host_lock);
+
        return SUCCESS;
 }
 
 STATIC void
-NCR_700_set_period(struct scsi_device *SDp, int period)
+NCR_700_set_period(struct scsi_target *STp, int period)
 {
+       struct Scsi_Host *SHp = dev_to_shost(STp->dev.parent);
        struct NCR_700_Host_Parameters *hostdata = 
-               (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0];
+               (struct NCR_700_Host_Parameters *)SHp->hostdata[0];
        
        if(!hostdata->fast)
                return;
@@ -2009,17 +2013,18 @@ NCR_700_set_period(struct scsi_device *SDp, int period)
        if(period < hostdata->min_period)
                period = hostdata->min_period;
 
-       spi_period(SDp) = period;
-       NCR_700_clear_flag(SDp, NCR_700_DEV_NEGOTIATED_SYNC);
-       NCR_700_clear_flag(SDp, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
-       NCR_700_set_flag(SDp, NCR_700_DEV_PRINT_SYNC_NEGOTIATION);
+       spi_period(STp) = period;
+       spi_flags(STp) &= ~(NCR_700_DEV_NEGOTIATED_SYNC |
+                           NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
+       spi_flags(STp) |= NCR_700_DEV_PRINT_SYNC_NEGOTIATION;
 }
 
 STATIC void
-NCR_700_set_offset(struct scsi_device *SDp, int offset)
+NCR_700_set_offset(struct scsi_target *STp, int offset)
 {
+       struct Scsi_Host *SHp = dev_to_shost(STp->dev.parent);
        struct NCR_700_Host_Parameters *hostdata = 
-               (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0];
+               (struct NCR_700_Host_Parameters *)SHp->hostdata[0];
        int max_offset = hostdata->chip710
                ? NCR_710_MAX_OFFSET : NCR_700_MAX_OFFSET;
        
@@ -2030,77 +2035,113 @@ NCR_700_set_offset(struct scsi_device *SDp, int offset)
                offset = max_offset;
 
        /* if we're currently async, make sure the period is reasonable */
-       if(spi_offset(SDp) == 0 && (spi_period(SDp) < hostdata->min_period ||
-                                   spi_period(SDp) > 0xff))
-               spi_period(SDp) = hostdata->min_period;
-
-       spi_offset(SDp) = offset;
-       NCR_700_clear_flag(SDp, NCR_700_DEV_NEGOTIATED_SYNC);
-       NCR_700_clear_flag(SDp, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
-       NCR_700_set_flag(SDp, NCR_700_DEV_PRINT_SYNC_NEGOTIATION);
+       if(spi_offset(STp) == 0 && (spi_period(STp) < hostdata->min_period ||
+                                   spi_period(STp) > 0xff))
+               spi_period(STp) = hostdata->min_period;
+
+       spi_offset(STp) = offset;
+       spi_flags(STp) &= ~(NCR_700_DEV_NEGOTIATED_SYNC |
+                           NCR_700_DEV_BEGIN_SYNC_NEGOTIATION);
+       spi_flags(STp) |= NCR_700_DEV_PRINT_SYNC_NEGOTIATION;
 }
 
+STATIC int
+NCR_700_slave_alloc(struct scsi_device *SDp)
+{
+       SDp->hostdata = kzalloc(sizeof(struct NCR_700_Device_Parameters),
+                               GFP_KERNEL);
 
+       if (!SDp->hostdata)
+               return -ENOMEM;
+
+       return 0;
+}
 
 STATIC int
-NCR_700_slave_configure(Scsi_Device *SDp)
+NCR_700_slave_configure(struct scsi_device *SDp)
 {
        struct NCR_700_Host_Parameters *hostdata = 
                (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0];
 
        /* to do here: allocate memory; build a queue_full list */
        if(SDp->tagged_supported) {
-               /* do TCQ stuff here */
+               scsi_set_tag_type(SDp, MSG_ORDERED_TAG);
+               scsi_activate_tcq(SDp, NCR_700_DEFAULT_TAGS);
+               NCR_700_set_tag_neg_state(SDp, NCR_700_START_TAG_NEGOTIATION);
        } else {
                /* initialise to default depth */
                scsi_adjust_queue_depth(SDp, 0, SDp->host->cmd_per_lun);
        }
        if(hostdata->fast) {
                /* Find the correct offset and period via domain validation */
-               spi_dv_device(SDp);
+               if (!spi_initial_dv(SDp->sdev_target))
+                       spi_dv_device(SDp);
        } else {
-               spi_offset(SDp) = 0;
-               spi_period(SDp) = 0;
+               spi_offset(SDp->sdev_target) = 0;
+               spi_period(SDp->sdev_target) = 0;
        }
        return 0;
 }
 
 STATIC void
-NCR_700_slave_destroy(Scsi_Device *SDp)
+NCR_700_slave_destroy(struct scsi_device *SDp)
 {
-       /* to do here: deallocate memory */
+       kfree(SDp->hostdata);
+       SDp->hostdata = NULL;
 }
 
-static ssize_t
-NCR_700_store_queue_depth(struct device *dev, const char *buf, size_t count)
+static int
+NCR_700_change_queue_depth(struct scsi_device *SDp, int depth)
 {
-       int depth;
+       if (depth > NCR_700_MAX_TAGS)
+               depth = NCR_700_MAX_TAGS;
 
-       struct scsi_device *SDp = to_scsi_device(dev);
-       depth = simple_strtoul(buf, NULL, 0);
-       if(depth > NCR_700_MAX_TAGS)
-               return -EINVAL;
-       scsi_adjust_queue_depth(SDp, MSG_ORDERED_TAG, depth);
+       scsi_adjust_queue_depth(SDp, scsi_get_tag_type(SDp), depth);
+       return depth;
+}
 
-       return count;
+static int NCR_700_change_queue_type(struct scsi_device *SDp, int tag_type)
+{
+       int change_tag = ((tag_type ==0 &&  scsi_get_tag_type(SDp) != 0)
+                         || (tag_type != 0 && scsi_get_tag_type(SDp) == 0));
+       struct NCR_700_Host_Parameters *hostdata = 
+               (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0];
+
+       scsi_set_tag_type(SDp, tag_type);
+
+       /* We have a global (per target) flag to track whether TCQ is
+        * enabled, so we'll be turning it off for the entire target here.
+        * our tag algorithm will fail if we mix tagged and untagged commands,
+        * so quiesce the device before doing this */
+       if (change_tag)
+               scsi_target_quiesce(SDp->sdev_target);
+
+       if (!tag_type) {
+               /* shift back to the default unqueued number of commands
+                * (the user can still raise this) */
+               scsi_deactivate_tcq(SDp, SDp->host->cmd_per_lun);
+               hostdata->tag_negotiated &= ~(1 << sdev_id(SDp));
+       } else {
+               /* Here, we cleared the negotiation flag above, so this
+                * will force the driver to renegotiate */
+               scsi_activate_tcq(SDp, SDp->queue_depth);
+               if (change_tag)
+                       NCR_700_set_tag_neg_state(SDp, NCR_700_START_TAG_NEGOTIATION);
+       }
+       if (change_tag)
+               scsi_target_resume(SDp->sdev_target);
+
+       return tag_type;
 }
 
 static ssize_t
-NCR_700_show_active_tags(struct device *dev, char *buf)
+NCR_700_show_active_tags(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct scsi_device *SDp = to_scsi_device(dev);
 
        return snprintf(buf, 20, "%d\n", NCR_700_get_depth(SDp));
 }
 
-static struct device_attribute NCR_700_queue_depth_attr = {
-       .attr = {
-               .name =         "queue_depth",
-               .mode =         S_IWUSR,
-       },
-       .store = NCR_700_store_queue_depth,
-};
-
 static struct device_attribute NCR_700_active_tags_attr = {
        .attr = {
                .name =         "active_tags",
@@ -2110,7 +2151,6 @@ static struct device_attribute NCR_700_active_tags_attr = {
 };
 
 STATIC struct device_attribute *NCR_700_dev_attrs[] = {
-       &NCR_700_queue_depth_attr,
        &NCR_700_active_tags_attr,
        NULL,
 };