*
  *      Returns SUCCESS if command aborted else FAILED
  *
- *      Locks: struct Scsi_Host::host_lock held (with irqsave) on entry 
- *      and assumed to be held on return.
+ *      Locks: None held
  *
  *      Calling context: kernel thread
  *
 
        fc->rst_pkt->request->rq_status = RQ_SCSI_BUSY;
 
        fc->rst_pkt->done = fcp_scsi_reset_done;
+
+       spin_lock_irqsave(SCpnt->device->host->host_lock, flags);
        fcp_scsi_queue_it(fc, fc->rst_pkt, fcmd, 0);
+       spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags);
        
        down(&sem);
 
 
                hd->timeouts++;
 
        /* We are now ready to execute the task management request. */
-       spin_unlock_irq(host_lock);
        if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
                SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */)
            < 0){
                spin_lock_irq(host_lock);
                return FAILED;
        }
-       spin_lock_irq(host_lock);
+
        return SUCCESS;
 }
 
 
        struct zfcp_unit *unit;
        struct Scsi_Host *scsi_host = scpnt->device->host;
 
-       spin_unlock_irq(scsi_host->host_lock);
-
        unit = (struct zfcp_unit *) scpnt->device->hostdata;
        ZFCP_LOG_NORMAL("bus reset because of problems with "
                        "unit 0x%016Lx\n", unit->fcp_lun);
        zfcp_erp_wait(unit->port->adapter);
        retval = SUCCESS;
 
-       spin_lock_irq(scsi_host->host_lock);
        return retval;
 }
 
 
        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);
        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);
                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;
 }
 
 
  * Locks: host lock taken by caller
  */
 
-static int NCR5380_bus_reset(Scsi_Cmnd * cmd) {
+static int NCR5380_bus_reset(Scsi_Cmnd * cmd)
+{
+       struct Scsi_Host *instance = cmd->device->host;
+
        NCR5380_local_declare();
-       NCR5380_setup(cmd->device->host);
+       NCR5380_setup(instance);
+       NCR5380_print_status(instance);
+
+       spin_lock_irq(instance->host_lock);
+       do_reset(instance);
+       spin_unlock_irq(instance->host_lock);
 
-       NCR5380_print_status(cmd->device->host);
-       do_reset(cmd->device->host);
        return SUCCESS;
 }
 
 {
        struct NCR_ESP *esp = (struct NCR_ESP *) SCptr->device->host->hostdata;
 
+       spin_lock_irq(esp->ehost->host_lock);
        (void) esp_do_resetbus(esp, esp->eregs);
-
        spin_unlock_irq(esp->ehost->host_lock);
 
        wait_event(esp->reset_queue, (esp->resetting_bus == 0));
 
-       spin_lock_irq(esp->ehost->host_lock);
-
        return SUCCESS;
 }
 
 
 static int a2091_bus_reset(Scsi_Cmnd *cmd)
 {
        /* FIXME perform bus-specific reset */
+
+       spin_lock_irq(cmd->device->host->host_lock);
        wd33c93_host_reset(cmd);
+       spin_unlock_irq(cmd->device->host->host_lock);
+
        return SUCCESS;
 }
 
 
 static int a3000_bus_reset(Scsi_Cmnd *cmd)
 {
        /* FIXME perform bus-specific reset */
+
+       spin_lock_irq(cmd->device->host->host_lock);
        wd33c93_host_reset(cmd);
+       spin_unlock_irq(cmd->device->host->host_lock);
+
        return SUCCESS;
 }
 
 
         * check for timeout, and if we are doing something like this
         * we are pretty desperate anyways.
         */
-       spin_unlock_irq(SCpnt->device->host->host_lock);
        ssleep(4);
+
        spin_lock_irq(SCpnt->device->host->host_lock);
 
        WAIT(STATUS(SCpnt->device->host->io_port),
                }
        }
 
+       spin_unlock_irq(SCpnt->device->host->host_lock);
        return SUCCESS;
 
 fail:
+       spin_unlock_irq(SCpnt->device->host->host_lock);
        return FAILED;
 }
 
 
                printf("%s: Bus reset called for cmd %p\n",
                       ahd_name(ahd), cmd);
 #endif
-       ahd_midlayer_entrypoint_lock(ahd, &s);
+       ahd_lock(ahd, &s);
        found = ahd_reset_channel(ahd, cmd->device->channel + 'A',
                                  /*initiate reset*/TRUE);
        ahd_linux_run_complete_queue(ahd);
-       ahd_midlayer_entrypoint_unlock(ahd, &s);
+       ahd_unlock(ahd, &s);
 
        if (bootverbose)
                printf("%s: SCSI bus reset delivered. "
 
 {
        struct ahc_softc *ahc;
        int    found;
+       unsigned long flags;
 
        ahc = *(struct ahc_softc **)cmd->device->host->hostdata;
+
+       ahc_lock(ahc, &flags);
        found = ahc_reset_channel(ahc, cmd->device->channel + 'A',
                                  /*initiate reset*/TRUE);
+       ahc_unlock(ahc, &flags);
 
        if (bootverbose)
                printf("%s: SCSI bus reset delivered. "
 
  * @cmd - some command for this host (for fetching hooks)
  * Returns: SUCCESS (0x2002) on success, else FAILED (0x2003).
  */
-static int dc395x_eh_bus_reset(struct scsi_cmnd *cmd)
+static int __dc395x_eh_bus_reset(struct scsi_cmnd *cmd)
 {
        struct AdapterCtlBlk *acb =
                (struct AdapterCtlBlk *)cmd->device->host->hostdata;
        return SUCCESS;
 }
 
+static int dc395x_eh_bus_reset(struct scsi_cmnd *cmd)
+{
+       int rc;
+
+       spin_lock_irq(cmd->device->host->host_lock);
+       rc = __dc395x_eh_bus_reset(cmd);
+       spin_unlock_irq(cmd->device->host->host_lock);
+
+       return rc;
+}
 
 /*
  * abort an errant SCSI command
 
 
 static int fd_mcs_bus_reset(Scsi_Cmnd * SCpnt) {
        struct Scsi_Host *shpnt = SCpnt->device->host;
+       unsigned long flags;
 
 #if DEBUG_RESET
        static int called_once = 0;
        called_once = 1;
 #endif
 
+       spin_lock_irqsave(shpnt->host_lock, flags);
+
        outb(1, SCSI_Cntl_port);
        do_pause(2);
        outb(0, SCSI_Cntl_port);
        outb(0, SCSI_Mode_Cntl_port);
        outb(PARITY_MASK, TMC_Cntl_port);
 
+       spin_unlock_irqrestore(shpnt->host_lock, flags);
+
        /* Unless this is the very first call (i.e., SCPnt == NULL), everything
           is probably hosed at this point.  We will, however, try to keep
           things going by informing the high-level code that we need help. */
 
 
 int fdomain_16x0_bus_reset(struct scsi_cmnd *SCpnt)
 {
+   unsigned long flags;
+
+   local_irq_save(flags);
+
    outb(1, port_base + SCSI_Cntl);
    do_pause( 2 );
    outb(0, port_base + SCSI_Cntl);
    do_pause( 115 );
    outb(0, port_base + SCSI_Mode_Cntl);
    outb(PARITY_MASK, port_base + TMC_Cntl);
+
+   local_irq_restore(flags);
    return SUCCESS;
 }
 
 
 static int gvp11_bus_reset(Scsi_Cmnd *cmd)
 {
        /* FIXME perform bus-specific reset */
+
+       spin_lock_irq(cmd->device->host->host_lock);
        wd33c93_host_reset(cmd);
+       spin_unlock_irq(cmd->device->host->host_lock);
+
        return SUCCESS;
 }
 
 
 #include <linux/blkdev.h>
 #include <linux/parport.h>
 #include <linux/workqueue.h>
+#include <linux/delay.h>
 #include <asm/io.h>
 
 #include <scsi/scsi.h>
        if (imm_connect(dev, 0) != 1)
                return -EIO;
        imm_reset_pulse(dev->base);
-       udelay(1000);   /* Delay to allow devices to settle */
+       mdelay(1);      /* Delay to allow devices to settle */
        imm_disconnect(dev);
-       udelay(1000);   /* Another delay to allow devices to settle */
+       mdelay(1);      /* Another delay to allow devices to settle */
        return device_check(dev);
 }
 
 
        imm_connect(dev, CONNECT_NORMAL);
        imm_reset_pulse(dev->base);
-       udelay(1000);           /* device settle delay */
+       mdelay(1);              /* device settle delay */
        imm_disconnect(dev);
-       udelay(1000);           /* device settle delay */
+       mdelay(1);              /* device settle delay */
        return SUCCESS;
 }
 
 
        struct Scsi_Host *instance;
        struct IN2000_hostdata *hostdata;
        int x;
+       unsigned long flags;
 
        instance = cmd->device->host;
        hostdata = (struct IN2000_hostdata *) instance->hostdata;
 
        printk(KERN_WARNING "scsi%d: Reset. ", instance->host_no);
 
-       /* do scsi-reset here */
+       spin_lock_irqsave(instance->host_lock, flags);
 
+       /* do scsi-reset here */
        reset_hardware(instance, RESET_CARD_AND_BUS);
        for (x = 0; x < 8; x++) {
                hostdata->busy[x] = 0;
        hostdata->outgoing_len = 0;
 
        cmd->result = DID_RESET << 16;
+
+       spin_unlock_irqrestore(instance->host_lock, flags);
        return SUCCESS;
 }
 
 
        HCS *pHCB;
 
        pHCB = (HCS *) SCpnt->device->host->base;
+
+       spin_lock_irq(SCpnt->device->host->host_lock);
        tul_reset_scsi(pHCB, 0);
+       spin_unlock_irq(SCpnt->device->host->host_lock);
+
        return SUCCESS;
 }
 
 
  * Note: midlayer calls this function with the host_lock held
  */
 static int
-lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
+__lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
 {
        struct Scsi_Host *shost = cmnd->device->host;
        struct lpfc_hba *phba = (struct lpfc_hba *)shost->hostdata[0];
        return ret;
 }
 
+static int
+lpfc_reset_bus_handler(struct scsi_cmnd *cmnd)
+{
+       int rc;
+       spin_lock_irq(cmnd->device->host->host_lock);
+       rc = __lpfc_reset_bus_handler(cmnd);
+       spin_unlock_irq(cmnd->device->host->host_lock);
+       return rc;
+}
+
 static int
 lpfc_slave_alloc(struct scsi_device *sdev)
 {
 
 static int mvme147_bus_reset(Scsi_Cmnd *cmd)
 {
        /* FIXME perform bus-specific reset */
+
+       spin_lock_irq(cmd->device->host->host_lock);
        wd33c93_host_reset(cmd);
+       spin_unlock_irq(cmd->device->host->host_lock);
+
        return SUCCESS;
 }
 
 
        nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
        unsigned int   base = SCpnt->device->host->io_port;
 
+       spin_lock_irq(SCpnt->device->host->host_lock);
+
        nsp32_msg(KERN_INFO, "Bus Reset");      
        nsp32_dbg(NSP32_DEBUG_BUSRESET, "SCpnt=0x%x", SCpnt);
 
        nsp32_do_bus_reset(data);
        nsp32_write2(base, IRQ_CONTROL, 0);
 
+       spin_unlock_irq(SCpnt->device->host->host_lock);
        return SUCCESS; /* SCSI bus reset is succeeded at any time. */
 }
 
 
 #include <linux/blkdev.h>
 #include <linux/parport.h>
 #include <linux/workqueue.h>
+#include <linux/delay.h>
 #include <asm/io.h>
 
 #include <scsi/scsi.h>
 
        ppa_connect(dev, CONNECT_NORMAL);
        ppa_reset_pulse(dev->base);
-       udelay(1000);           /* device settle delay */
+       mdelay(1);              /* device settle delay */
        ppa_disconnect(dev);
-       udelay(1000);           /* device settle delay */
+       mdelay(1);              /* device settle delay */
        return SUCCESS;
 }
 
 
 static int
 qla1280_eh_bus_reset(struct scsi_cmnd *cmd)
 {
-       return qla1280_error_action(cmd, BUS_RESET);
+       int rc;
+
+       spin_lock_irq(cmd->device->host->host_lock);
+       rc = qla1280_error_action(cmd, BUS_RESET);
+       spin_unlock_irq(cmd->device->host->host_lock);
+
+       return rc;
 }
 
 /**************************************************************************
 
        qla_printk(KERN_INFO, ha,
            "scsi(%ld:%d:%d): LOOP RESET ISSUED.\n", ha->host_no, id, lun);
 
-       spin_unlock_irq(ha->host->host_lock);
-
        if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS) {
                DEBUG2(printk("%s failed:board disabled\n",__func__));
                goto eh_bus_reset_done;
        qla_printk(KERN_INFO, ha, "%s: reset %s\n", __func__,
            (ret == FAILED) ? "failed" : "succeded");
 
-       spin_lock_irq(ha->host->host_lock);
-
        return ret;
 }
 
 
 int qlogicfas408_bus_reset(Scsi_Cmnd * cmd)
 {
        struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd);
+       unsigned long flags;
+
        priv->qabort = 2;
+
+       spin_lock_irqsave(cmd->device->host->host_lock, flags);
        ql_zap(priv);
+       spin_unlock_irqrestore(cmd->device->host->host_lock, flags);
+
        return SUCCESS;
 }
 
 
        if (!scmd->device->host->hostt->eh_bus_reset_handler)
                return FAILED;
 
-       spin_lock_irqsave(scmd->device->host->host_lock, flags);
        rtn = scmd->device->host->hostt->eh_bus_reset_handler(scmd);
-       spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
 
        if (rtn == SUCCESS) {
                if (!scmd->device->host->hostt->skip_settle_delay)
 
 #include <linux/delay.h>
 #include <linux/blkdev.h>
 #include <linux/stat.h>
+#include <linux/delay.h>
 
 #include <asm/io.h>
 #include <asm/system.h>
        /* assert  RESET signal on SCSI bus.  */
        WRITE_CONTROL (BASE_CMD | CMD_RST);
 
-       udelay (20 * 1000);
+       mdelay (20);
 
        WRITE_CONTROL (BASE_CMD);
        st0x_aborted = DID_RESET;
 
 static int sgiwd93_bus_reset(Scsi_Cmnd *cmd)
 {
        /* FIXME perform bus-specific reset */
+
+       spin_lock_irq(cmd->device->host->host_lock);
        wd33c93_host_reset(cmd);
+       spin_unlock_irq(cmd->device->host->host_lock);
+
        return SUCCESS;
 }
 
 
 
 static int sym53c8xx_eh_bus_reset_handler(struct scsi_cmnd *cmd)
 {
-       return sym_eh_handler(SYM_EH_BUS_RESET, "BUS RESET", cmd);
+       int rc;
+
+       spin_lock_irq(cmd->device->host->host_lock);
+       rc = sym_eh_handler(SYM_EH_BUS_RESET, "BUS RESET", cmd);
+       spin_unlock_irq(cmd->device->host->host_lock);
+
+       return rc;
 }
 
 static int sym53c8xx_eh_host_reset_handler(struct scsi_cmnd *cmd)
 
        struct dc390_acb*    pACB = (struct dc390_acb*) cmd->device->host->hostdata;
        u8   bval;
 
+       spin_lock_irq(cmd->device->host->host_lock);
+
        bval = DC390_read8(CtrlReg1) | DIS_INT_ON_SCSI_RST;
        DC390_write8(CtrlReg1, bval);   /* disable IRQ on bus reset */
 
        dc390_ResetSCSIBus(pACB);
 
        dc390_ResetDevParam(pACB);
-       udelay(1000);
+       mdelay(1);
        pACB->pScsiHost->last_reset = jiffies + 3*HZ/2 
                + HZ * dc390_eepromBuf[pACB->AdapterIndex][EE_DELAY];
     
        bval = DC390_read8(CtrlReg1) & ~DIS_INT_ON_SCSI_RST;
        DC390_write8(CtrlReg1, bval);   /* re-enable interrupt */
 
+       spin_unlock_irq(cmd->device->host->host_lock);
+
        return SUCCESS;
 }
 
 
 
        US_DEBUGP("%s called\n", __FUNCTION__);
 
-       scsi_unlock(us_to_host(us));
-
        /* The USB subsystem doesn't handle synchronisation between
         * a device's several drivers. Therefore we reset only devices
         * with just one interface, which we of course own. */
        up(&(us->dev_semaphore));
 
        /* lock the host for the return */
-       scsi_lock(us_to_host(us));
        return result < 0 ? FAILED : SUCCESS;
 }