Re: Full hostlock pushdown available

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Oct 28, 2010 at 02:28:43PM -0500, James Bottomley wrote:
> On Thu, 2010-10-28 at 17:05 +0200, Andi Kleen wrote:
> > Here's the promised attempt to do a full host_lock pushdown. This
> > was done using coccinelle and some manual adjustments.
> > 
> > This is just a dumb pushdown of host lock and serial number into
> > the driver, no attempt to remove any locks yet.
> > 
> > Currently lightly tested, but compiles with allmodconfig on 32bit x86.
> > 
> > I made no attempt to automatically add maintainers to Cc.
> > 
> > I'm not posting the patches because they are numerous and boring,
> > but it's available in git.
> > 
> > This will likely bitrot quickly so if it's decided to do it this
> > way I would prefer if this was merged quickly.
> 
> OK, so can you post an actual diff?  It obviously has to be done in one
> commit rather than the 87 you have.

Why? I'm not sure a single commit is manageable. The multiple commits
are not atomic, but at least they should all compile and boot
and they minimze breakage.

Anyways full diff appended.

-Andi

SCSI: hostlock pushdown

Signed-off-by: Andi Kleen <ak@xxxxxxxxxxxxxxx>

diff --git a/arch/ia64/hp/sim/simscsi.c b/arch/ia64/hp/sim/simscsi.c
index 3a078ad..ce32f2c 100644
--- a/arch/ia64/hp/sim/simscsi.c
+++ b/arch/ia64/hp/sim/simscsi.c
@@ -209,6 +209,8 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
 	size_t disk_size;
 	char *buf;
 	char localbuf[36];
+	unsigned long irqflags;
+
 #if DEBUG_SIMSCSI
 	register long sp asm ("sp");
 
@@ -217,6 +219,9 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
 		       target_id, sc->cmnd[0], sc->serial_number, sp, done);
 #endif
 
+	spin_lock_irqsave(sc->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(sc->device->host);
+
 	sc->result = DID_BAD_TARGET << 16;
 	sc->scsi_done = done;
 	if (target_id <= 15 && sc->device->lun == 0) {
@@ -323,6 +328,8 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
 	wr = (wr + 1) % SIMSCSI_REQ_QUEUE_LEN;
 
 	tasklet_schedule(&simscsi_tasklet);
+
+	spin_unlock_irqrestore(sc->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
index 575495f..0fb12f8 100644
--- a/drivers/block/cciss_scsi.c
+++ b/drivers/block/cciss_scsi.c
@@ -1416,6 +1416,9 @@ cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd
 
 	// Get the ptr to our adapter structure (hba[i]) out of cmd->host.
 	// We violate cmd->host privacy here.  (Is there another way?)
+	unsigned long irqflags;
+	spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmd->device->host, cmd);
 	h = (ctlr_info_t *) cmd->device->host->hostdata[0];
 
 	rc = lookup_scsi3addr(h, cmd->device->channel, cmd->device->id,
@@ -1427,6 +1430,7 @@ cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd
 		done(cmd);
 		/* we might want to think about registering controller itself
 		   as a processor device on the bus so sg binds to it. */
+		spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 		return 0;
 	}
 
@@ -1441,6 +1445,7 @@ cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd
 		/* FIXME: next 3 lines are -> BAD! <- */
 		cmd->result = DID_NO_CONNECT << 16;
 		done(cmd);
+		spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 		return 0;
 	}
 
@@ -1501,6 +1506,7 @@ cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd
 	cciss_scatter_gather(h, c, cmd);
 	enqueue_cmd_and_start_io(h, c);
 	/* the cmd'll come back via intr handler in complete_scsi_command()  */
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c
index bfae4b3..13f6f12 100644
--- a/drivers/firewire/sbp2.c
+++ b/drivers/firewire/sbp2.c
@@ -1479,6 +1479,9 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
 	 * Bidirectional commands are not yet implemented, and unknown
 	 * transfer direction not handled.
 	 */
+	unsigned long irqflags;
+	spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmd->device->host, cmd);
 	if (cmd->sc_data_direction == DMA_BIDIRECTIONAL) {
 		fw_error("Can't handle DMA_BIDIRECTIONAL, rejecting command\n");
 		cmd->result = DID_ERROR << 16;
@@ -1489,6 +1492,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
 	orb = kzalloc(sizeof(*orb), GFP_ATOMIC);
 	if (orb == NULL) {
 		fw_notify("failed to alloc orb\n");
+		spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_HOST_BUSY;
 	}
 
@@ -1531,6 +1535,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
 	retval = 0;
  out:
 	kref_put(&orb->base.kref, free_orb);
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return retval;
 }
 
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index cfc1d65..52c9d2e 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -1132,7 +1132,10 @@ static int srp_queuecommand(struct scsi_cmnd *scmnd,
 	struct srp_cmd *cmd;
 	struct ib_device *dev;
 	int len;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(scmnd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(scmnd->device->host, scmnd);
 	if (target->state == SRP_TARGET_CONNECTING)
 		goto err;
 
@@ -1140,6 +1143,7 @@ static int srp_queuecommand(struct scsi_cmnd *scmnd,
 	    target->state == SRP_TARGET_REMOVED) {
 		scmnd->result = DID_BAD_TARGET << 16;
 		done(scmnd);
+		spin_unlock_irqrestore(scmnd->device->host->host_lock, irqflags);
 		return 0;
 	}
 
@@ -1187,12 +1191,14 @@ static int srp_queuecommand(struct scsi_cmnd *scmnd,
 
 	list_move_tail(&req->list, &target->req_queue);
 
+	spin_unlock_irqrestore(scmnd->device->host->host_lock, irqflags);
 	return 0;
 
 err_unmap:
 	srp_unmap_data(scmnd, target, req);
 
 err:
+	spin_unlock_irqrestore(scmnd->device->host->host_lock, irqflags);
 	return SCSI_MLQUEUE_HOST_BUSY;
 }
 
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index e15220f..3f3705a 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -656,7 +656,10 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 	struct fc_rport	*rport = starget_to_rport(scsi_target(SCpnt->device));
 	int		err;
 	VirtDevice	*vdevice = SCpnt->device->hostdata;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(SCpnt->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(SCpnt->device->host, SCpnt);
 	if (!vdevice || !vdevice->vtarget) {
 		SCpnt->result = DID_NO_CONNECT << 16;
 		done(SCpnt);
@@ -667,6 +670,7 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 	if (unlikely(err)) {
 		SCpnt->result = err;
 		done(SCpnt);
+		spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 		return 0;
 	}
 
@@ -675,9 +679,11 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 	if (unlikely(!ri)) {
 		SCpnt->result = DID_IMM_RETRY << 16;
 		done(SCpnt);
+		spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 		return 0;
 	}
 
+	spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 	return mptscsih_qcmd(SCpnt,done);
 }
 
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 83a5115..006ffa1 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -1894,7 +1894,10 @@ mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 	MPT_SCSI_HOST	*hd;
 	MPT_ADAPTER	*ioc;
 	VirtDevice	*vdevice = SCpnt->device->hostdata;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(SCpnt->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(SCpnt->device->host, SCpnt);
 	if (!vdevice || !vdevice->vtarget || vdevice->vtarget->deleted) {
 		SCpnt->result = DID_NO_CONNECT << 16;
 		done(SCpnt);
@@ -1904,12 +1907,15 @@ mptsas_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 	hd = shost_priv(SCpnt->device->host);
 	ioc = hd->ioc;
 
-	if (ioc->sas_discovery_quiesce_io)
+	if (ioc->sas_discovery_quiesce_io) {
+		spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_HOST_BUSY;
+	}
 
 	if (ioc->debug_level & MPT_DEBUG_SCSI)
 		scsi_print_command(SCpnt);
 
+	spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 	return mptscsih_qcmd(SCpnt,done);
 }
 
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index 0e28031..61d42b9 100644
--- a/drivers/message/fusion/mptspi.c
+++ b/drivers/message/fusion/mptspi.c
@@ -785,7 +785,10 @@ mptspi_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 	struct _MPT_SCSI_HOST *hd = shost_priv(SCpnt->device->host);
 	VirtDevice	*vdevice = SCpnt->device->hostdata;
 	MPT_ADAPTER *ioc = hd->ioc;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(SCpnt->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(SCpnt->device->host, SCpnt);
 	if (!vdevice || !vdevice->vtarget) {
 		SCpnt->result = DID_NO_CONNECT << 16;
 		done(SCpnt);
@@ -796,12 +799,14 @@ mptspi_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 		mptscsih_is_phys_disk(ioc, 0, SCpnt->device->id) == 0) {
 		SCpnt->result = DID_NO_CONNECT << 16;
 		done(SCpnt);
+		spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 		return 0;
 	}
 
 	if (spi_dv_pending(scsi_target(SCpnt->device)))
 		ddvprintk(ioc, scsi_print_command(SCpnt));
 
+	spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 	return mptscsih_qcmd(SCpnt,done);
 }
 
diff --git a/drivers/message/i2o/i2o_scsi.c b/drivers/message/i2o/i2o_scsi.c
index ea6b219..21056dd 100644
--- a/drivers/message/i2o/i2o_scsi.c
+++ b/drivers/message/i2o/i2o_scsi.c
@@ -527,6 +527,9 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
 	/*
 	 *      Do the incoming paperwork
 	 */
+	unsigned long irqflags;
+	spin_lock_irqsave(SCpnt->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(SCpnt->device->host, SCpnt);
 	i2o_dev = SCpnt->device->hostdata;
 
 	SCpnt->scsi_done = done;
@@ -680,6 +683,7 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
 
 	osm_debug("Issued %ld\n", SCpnt->serial_number);
 
+	spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 	return 0;
 
       nomem:
@@ -687,6 +691,7 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
 	i2o_msg_nop(c, msg);
 
       exit:
+	spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 	return rc;
 };
 
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 50286d8..c28e5fe 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -83,6 +83,10 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
 	struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
 	struct fc_rport *rport = starget_to_rport(scsi_target(scpnt->device));
 	int    status, scsi_result, ret;
+	unsigned long irqflags;
+
+	spin_lock_irqsave(scpnt->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(scpnt->device->host, scpnt);
 
 	/* reset the status for this request */
 	scpnt->result = 0;
@@ -94,6 +98,7 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
 		scpnt->result = scsi_result;
 		zfcp_dbf_scsi_fail_send(adapter->dbf, scpnt);
 		scpnt->scsi_done(scpnt);
+		spin_unlock_irqrestore(scpnt->device->host->host_lock, irqflags);
 		return 0;
 	}
 
@@ -104,6 +109,7 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
 		/* only LUN access denied, but port is good
 		 * not covered by FC transport, have to fail here */
 		zfcp_scsi_command_fail(scpnt, DID_ERROR);
+		spin_unlock_irqrestore(scpnt->device->host->host_lock, irqflags);
 		return 0;
 	}
 
@@ -115,10 +121,12 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
 		 * 	fc_remote_port_chkready until rport is BLOCKED
 		 */
 		zfcp_scsi_command_fail(scpnt, DID_IMM_RETRY);
+		spin_unlock_irqrestore(scpnt->device->host->host_lock, irqflags);
 		return 0;
 	}
 
 	ret = zfcp_fsf_fcp_cmnd(scpnt);
+	spin_unlock_irqrestore(scpnt->device->host->host_lock, irqflags);
 	if (unlikely(ret == -EBUSY))
 		return SCSI_MLQUEUE_DEVICE_BUSY;
 	else if (unlikely(ret < 0))
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index fcf08b3..3ad0f51 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -1769,7 +1769,10 @@ static int twa_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd
 {
 	int request_id, retval;
 	TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(SCpnt->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(SCpnt->device->host, SCpnt);
 	/* If we are resetting due to timed out ioctl, report as busy */
 	if (test_bit(TW_IN_RESET, &tw_dev->flags)) {
 		retval = SCSI_MLQUEUE_HOST_BUSY;
@@ -1809,6 +1812,7 @@ static int twa_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd
 		retval = 0;
 	}
 out:
+	spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 	return retval;
 } /* End twa_scsi_queue() */
 
diff --git a/drivers/scsi/3w-sas.c b/drivers/scsi/3w-sas.c
index 6a95d11..de5d845 100644
--- a/drivers/scsi/3w-sas.c
+++ b/drivers/scsi/3w-sas.c
@@ -1505,7 +1505,10 @@ static int twl_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd
 {
 	int request_id, retval;
 	TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(SCpnt->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(SCpnt->device->host, SCpnt);
 	/* If we are resetting due to timed out ioctl, report as busy */
 	if (test_bit(TW_IN_RESET, &tw_dev->flags)) {
 		retval = SCSI_MLQUEUE_HOST_BUSY;
@@ -1533,6 +1536,7 @@ static int twl_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd
 		retval = 0;
 	}
 out:
+	spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 	return retval;
 } /* End twl_scsi_queue() */
 
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index b112534..6812acc 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -1953,7 +1953,10 @@ static int tw_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd
 	int request_id = 0;
 	int retval = 1;
 	TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(SCpnt->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(SCpnt->device->host, SCpnt);
 	/* If we are resetting due to timed out ioctl, report as busy */
 	if (test_bit(TW_IN_RESET, &tw_dev->flags))
 		return SCSI_MLQUEUE_HOST_BUSY;
@@ -2020,6 +2023,7 @@ static int tw_scsi_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd
 		done(SCpnt);
 		retval = 0;
 	}
+	spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 	return retval;
 } /* End tw_scsi_queue() */
 
diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
index 89fc1c8..ac1a0e4 100644
--- a/drivers/scsi/53c700.c
+++ b/drivers/scsi/53c700.c
@@ -1758,6 +1758,9 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
 	enum dma_data_direction direction;
 	struct NCR_700_command_slot *slot;
 
+	unsigned long irqflags;
+	spin_lock_irqsave(SCp->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(SCp->device->host, SCp);
 	if(hostdata->command_slot_count >= NCR_700_COMMAND_SLOTS_PER_HOST) {
 		/* We're over our allocation, this should never happen
 		 * since we report the max allocation to the mid layer */
@@ -1775,11 +1778,13 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
 	       || !blk_rq_tagged(SCp->request))) {
 		CDEBUG(KERN_ERR, SCp, "has non zero depth %d\n",
 		       NCR_700_get_depth(SCp->device));
+		spin_unlock_irqrestore(SCp->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_DEVICE_BUSY;
 	}
 	if(NCR_700_get_depth(SCp->device) >= SCp->device->queue_depth) {
 		CDEBUG(KERN_ERR, SCp, "has max tag depth %d\n",
 		       NCR_700_get_depth(SCp->device));
+		spin_unlock_irqrestore(SCp->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_DEVICE_BUSY;
 	}
 	NCR_700_set_depth(SCp->device, NCR_700_get_depth(SCp->device) + 1);
@@ -1901,6 +1906,7 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *))
 	slot->pCmd = dma_map_single(hostdata->dev, SCp->cmnd,
 				    MAX_COMMAND_SIZE, DMA_TO_DEVICE);
 	NCR_700_start_command(SCp);
+	spin_unlock_irqrestore(SCp->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c
index fc0b4b8..ab1ee41 100644
--- a/drivers/scsi/BusLogic.c
+++ b/drivers/scsi/BusLogic.c
@@ -2824,6 +2824,9 @@ static int BusLogic_QueueCommand(struct scsi_cmnd *Command, void (*CompletionRou
 	   Adapter for any errors, so they should not be executed explicitly unless
 	   the Sense Data is zero indicating that no error occurred.
 	 */
+	unsigned long irqflags;
+	spin_lock_irqsave(Command->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(Command->device->host, Command);
 	if (CDB[0] == REQUEST_SENSE && Command->sense_buffer[0] != 0) {
 		Command->result = DID_OK << 16;
 		CompletionRoutine(Command);
@@ -2844,6 +2847,7 @@ static int BusLogic_QueueCommand(struct scsi_cmnd *Command, void (*CompletionRou
 		if (CCB == NULL) {
 			Command->result = DID_ERROR << 16;
 			CompletionRoutine(Command);
+			spin_unlock_irqrestore(Command->device->host->host_lock, irqflags);
 			return 0;
 		}
 	}
@@ -2991,6 +2995,7 @@ static int BusLogic_QueueCommand(struct scsi_cmnd *Command, void (*CompletionRou
 		if (CCB->Status == BusLogic_CCB_Completed)
 			BusLogic_ProcessCompletedCCBs(HostAdapter);
 	}
+	spin_unlock_irqrestore(Command->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index 5d2f148..f4bd889 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -957,6 +957,10 @@ static int NCR5380_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
 	struct Scsi_Host *instance = cmd->device->host;
 	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
 	Scsi_Cmnd *tmp;
+	unsigned long irqflags;
+
+	spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmd->device->host, cmd);
 
 #if (NDEBUG & NDEBUG_NO_WRITE)
 	switch (cmd->cmnd[0]) {
@@ -965,6 +969,7 @@ static int NCR5380_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
 		printk("scsi%d : WRITE attempted with NO_WRITE debugging flag set\n", instance->host_no);
 		cmd->result = (DID_ERROR << 16);
 		done(cmd);
+		spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 		return 0;
 	}
 #endif				/* (NDEBUG & NDEBUG_NO_WRITE) */
@@ -1018,6 +1023,7 @@ static int NCR5380_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
 	/* Run the coroutine if it isn't already running. */
 	/* Kick off command processing */
 	schedule_delayed_work(&hostdata->coroutine, 0);
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c
index 6961f78..b84bfe6 100644
--- a/drivers/scsi/NCR53c406a.c
+++ b/drivers/scsi/NCR53c406a.c
@@ -696,7 +696,10 @@ static void wait_intr(void)
 static int NCR53c406a_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
 {
 	int i;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(SCpnt->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(SCpnt->device->host, SCpnt);
 	VDEB(printk("NCR53c406a_queue called\n"));
 	DEB(printk("cmd=%02x, cmd_len=%02x, target=%02x, lun=%02x, bufflen=%d\n", SCpnt->cmnd[0], SCpnt->cmd_len, SCpnt->target, SCpnt->lun, scsi_bufflen(SCpnt)));
 
@@ -723,6 +726,7 @@ static int NCR53c406a_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
 	outb(SELECT_NO_ATN, CMD_REG);
 
 	rtrc(1);
+	spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c
index dbbc601..1aa33f0 100644
--- a/drivers/scsi/a100u2w.c
+++ b/drivers/scsi/a100u2w.c
@@ -915,18 +915,25 @@ static int inia100_queue(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd
 {
 	struct orc_scb *scb;
 	struct orc_host *host;		/* Point to Host adapter control block */
+	unsigned long irqflags;
 
+	spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmd->device->host, cmd);
 	host = (struct orc_host *) cmd->device->host->hostdata;
 	cmd->scsi_done = done;
 	/* Get free SCSI control block  */
-	if ((scb = orc_alloc_scb(host)) == NULL)
+	if ((scb = orc_alloc_scb(host)) == NULL) {
+		spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_HOST_BUSY;
+	}
 
 	if (inia100_build_scb(host, scb, cmd)) {
 		orc_release_scb(host, scb);
+		spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_HOST_BUSY;
 	}
 	orc_exec_scb(host, scb);	/* Start execute SCB            */
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 29c0ed1..8679fa5 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -253,6 +253,9 @@ static int aac_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd
 	struct Scsi_Host *host = cmd->device->host;
 	struct aac_dev *dev = (struct aac_dev *)host->hostdata;
 	u32 count = 0;
+	unsigned long irqflags;
+	spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmd->device->host, cmd);
 	cmd->scsi_done = done;
 	for (; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) {
 		struct fib * fib = &dev->fibs[count];
@@ -260,10 +263,13 @@ static int aac_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd
 		if (fib->hw_fib_va->header.XferState &&
 		    ((command = fib->callback_data)) &&
 		    (command == cmd) &&
-		    (cmd->SCp.phase == AAC_OWNER_FIRMWARE))
-			return 0; /* Already owned by Adapter */
+		    (cmd->SCp.phase == AAC_OWNER_FIRMWARE)) {
+		    	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
+		    	return 0;
+		    } /* Already owned by Adapter */
 	}
 	cmd->SCp.phase = AAC_OWNER_LOWLEVEL;
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return (aac_scsi_cmd(cmd) ? FAILED : 0);
 }
 
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
index 0ec3da6..cb5e7c2 100644
--- a/drivers/scsi/advansys.c
+++ b/drivers/scsi/advansys.c
@@ -9504,7 +9504,10 @@ advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
 {
 	struct Scsi_Host *shost = scp->device->host;
 	int asc_res, result = 0;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(scp->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(scp->device->host, scp);
 	ASC_STATS(shost, queuecommand);
 	scp->scsi_done = done;
 
@@ -9522,6 +9525,7 @@ advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
 		break;
 	}
 
+	spin_unlock_irqrestore(scp->device->host->host_lock, irqflags);
 	return result;
 }
 
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
index 8eab858..055e953 100644
--- a/drivers/scsi/aha152x.c
+++ b/drivers/scsi/aha152x.c
@@ -1058,6 +1058,12 @@ static int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct completion *complete,
  */
 static int aha152x_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
 {
+	unsigned long irqflags;
+	int ret;
+
+	spin_lock_irqsave(SCpnt->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(SCpnt->device->host, SCpnt);
+
 #if 0
 	if(*SCpnt->cmnd == REQUEST_SENSE) {
 		SCpnt->result = 0;
@@ -1067,7 +1073,9 @@ static int aha152x_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
 	}
 #endif
 
-	return aha152x_internal_queue(SCpnt, NULL, 0, done);
+	ret = aha152x_internal_queue(SCpnt, NULL, 0, done);
+	spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
+	return ret;
 }
 
 
diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
index 4f785f2..f33b417 100644
--- a/drivers/scsi/aha1542.c
+++ b/drivers/scsi/aha1542.c
@@ -570,7 +570,10 @@ static int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
 	int mbo;
 	struct mailbox *mb;
 	struct ccb *ccb;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(SCpnt->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(SCpnt->device->host, SCpnt);
 	DEB(int i);
 
 	mb = HOSTDATA(SCpnt->device->host)->mb;
@@ -593,6 +596,7 @@ static int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
 #endif
 		SCpnt->result = 0;
 		done(SCpnt);
+		spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 		return 0;
 	}
 #ifdef DEBUG
@@ -611,8 +615,10 @@ static int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
 	for (i = 0; i < SCpnt->cmd_len; i++)
 		printk("%02x ", cmd[i]);
 	printk("\n");
-	if (*cmd == WRITE_10 || *cmd == WRITE_6)
-		return 0;	/* we are still testing, so *don't* write */
+	if (*cmd == WRITE_10 || *cmd == WRITE_6) {
+		spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
+		return 0;
+	}	/* we are still testing, so *don't* write */
 #endif
 	/* Use the outgoing mailboxes in a round-robin fashion, because this
 	   is how the host adapter will scan for them */
@@ -671,6 +677,7 @@ static int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
 		if (cptr == NULL) {
 			/* free the claimed mailbox slot */
 			HOSTDATA(SCpnt->device->host)->SCint[mbo] = NULL;
+			spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 			return SCSI_MLQUEUE_HOST_BUSY;
 		}
 		scsi_for_each_sg(SCpnt, sg, sg_count, i) {
@@ -715,6 +722,7 @@ static int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
 	} else
 		printk("aha1542_queuecommand: done can't be NULL\n");
 
+	spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c
index 0107a4c..b973e15 100644
--- a/drivers/scsi/aha1740.c
+++ b/drivers/scsi/aha1740.c
@@ -331,6 +331,7 @@ static irqreturn_t aha1740_intr_handle(int irq, void *dev_id)
 	return IRQ_RETVAL(handled);
 }
 
+/* AK: Did this driver ever work? */
 static int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
 {
 	unchar direction;
@@ -341,14 +342,21 @@ static int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
 	dma_addr_t sg_dma;
 	struct aha1740_sg *sgptr;
 	int ecbno, nseg;
+	unsigned long irqflags;
 	DEB(int i);
 
+	spin_lock_irqsave(SCpnt->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(SCpnt->device->host, SCpnt);
+
 	if(*cmd == REQUEST_SENSE) {
 		SCpnt->result = 0;
 		done(SCpnt); 
+		spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 		return 0;
 	}
 
+	spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
+
 #ifdef DEBUG
 	if (*cmd == READ_10 || *cmd == WRITE_10)
 		i = xscsi2int(cmd+2);
@@ -406,6 +414,7 @@ static int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
 						   &sg_dma, GFP_ATOMIC);
 	if(SCpnt->host_scribble == NULL) {
 		printk(KERN_WARNING "aha1740: out of memory in queuecommand!\n");
+		spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 		return 1;
 	}
 	sgptr = (struct aha1740_sg *) SCpnt->host_scribble;
@@ -500,6 +509,8 @@ static int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
 		DEB(printk("aha1740[%d] request queued.\n",ecbno));
 	} else
 		printk(KERN_ALERT "aha1740_queuecommand: done can't be NULL\n");
+
+	spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index 88ad848..93e1070 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -578,13 +578,17 @@ ahd_linux_queue(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
 	struct	 ahd_softc *ahd;
 	struct	 ahd_linux_device *dev = scsi_transport_device_data(cmd->device);
 	int rtn = SCSI_MLQUEUE_HOST_BUSY;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmd->device->host, cmd);
 	ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
 
 	cmd->scsi_done = scsi_done;
 	cmd->result = CAM_REQ_INPROG << 16;
 	rtn = ahd_linux_run_command(ahd, dev, cmd);
 
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return rtn;
 }
 
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
index aeea7a6..198390a 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -534,7 +534,10 @@ ahc_linux_queue(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
 	struct	 ahc_linux_device *dev = scsi_transport_device_data(cmd->device);
 	int rtn = SCSI_MLQUEUE_HOST_BUSY;
 	unsigned long flags;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmd->device->host, cmd);
 	ahc = *(struct ahc_softc **)cmd->device->host->hostdata;
 
 	ahc_lock(ahc, &flags);
@@ -545,6 +548,7 @@ ahc_linux_queue(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *))
 	}
 	ahc_unlock(ahc, &flags);
 
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return rtn;
 }
 
diff --git a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c
index aee73fa..97c4efc 100644
--- a/drivers/scsi/aic7xxx_old.c
+++ b/drivers/scsi/aic7xxx_old.c
@@ -10239,7 +10239,10 @@ static int aic7xxx_queue(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *))
   struct aic7xxx_host *p;
   struct aic7xxx_scb *scb;
   struct aic_dev_data *aic_dev;
+  unsigned long irqflags;
 
+  spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+  scsi_cmd_get_serial(cmd->device->host, cmd);
   p = (struct aic7xxx_host *) cmd->device->host->hostdata;
 
   aic_dev = cmd->device->hostdata;  
@@ -10262,6 +10265,7 @@ static int aic7xxx_queue(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *))
     {
       printk(WARN_LEAD "Couldn't get a free SCB.\n", p->host_no,
              CTL_OF_CMD(cmd));
+      spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
       return 1;
     }
   }
@@ -10289,6 +10293,7 @@ static int aic7xxx_queue(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *))
 
   scbq_insert_tail(&p->waiting_scbs, scb);
   aic7xxx_run_waiting_queues(p);
+  spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
   return (0);
 }
 
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index 05a78e5..bbb95db 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -2090,6 +2090,9 @@ static int arcmsr_queue_command(struct scsi_cmnd *cmd,
 	int target = cmd->device->id;
 	int lun = cmd->device->lun;
 	uint8_t scsicmd = cmd->cmnd[0];
+	unsigned long irqflags;
+	spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmd->device->host, cmd);
 	cmd->scsi_done = done;
 	cmd->host_scribble = NULL;
 	cmd->result = 0;
@@ -2098,29 +2101,38 @@ static int arcmsr_queue_command(struct scsi_cmnd *cmd,
     			cmd->result = (DID_NO_CONNECT << 16);
 		}
 		cmd->scsi_done(cmd);
+		spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 		return 0;
 	}
 	if (target == 16) {
 		/* virtual device for iop message transfer */
 		arcmsr_handle_virtual_command(acb, cmd);
+		spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 		return 0;
 	}
 	if (atomic_read(&acb->ccboutstandingcount) >=
-			ARCMSR_MAX_OUTSTANDING_CMD)
-		return SCSI_MLQUEUE_HOST_BUSY;
+			ARCMSR_MAX_OUTSTANDING_CMD) {
+				spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
+				return SCSI_MLQUEUE_HOST_BUSY;
+			}
 	if ((scsicmd == SCSI_CMD_ARECA_SPECIFIC)) {
 		printk(KERN_NOTICE "Receiveing SCSI_CMD_ARECA_SPECIFIC command..\n");
+		spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 		return 0;
 	}
 	ccb = arcmsr_get_freeccb(acb);
-	if (!ccb)
+	if (!ccb) {
+		spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_HOST_BUSY;
+	}
 	if (arcmsr_build_ccb( acb, ccb, cmd ) == FAILED) {
 		cmd->result = (DID_ERROR << 16) | (RESERVATION_CONFLICT << 1);
 		cmd->scsi_done(cmd);
+		spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 		return 0;
 	}
 	arcmsr_post_ccb(acb, ccb);
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c
index 918ccf8..6f1049e 100644
--- a/drivers/scsi/arm/acornscsi.c
+++ b/drivers/scsi/arm/acornscsi.c
@@ -2515,7 +2515,10 @@ int acornscsi_queuecmd(struct scsi_cmnd *SCpnt,
 		       void (*done)(struct scsi_cmnd *))
 {
     AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata;
+    unsigned long irqflags;
 
+    spin_lock_irqsave(SCpnt->device->host->host_lock, irqflags);
+    scsi_cmd_get_serial(SCpnt->device->host, SCpnt);
     if (!done) {
 	/* there should be some way of rejecting errors like this without panicing... */
 	panic("scsi%d: queuecommand called with NULL done function [cmd=%p]",
@@ -2529,6 +2532,7 @@ int acornscsi_queuecmd(struct scsi_cmnd *SCpnt,
 	    host->host->host_no, '0' + SCpnt->device->id);
 	SCpnt->result = DID_NO_CONNECT << 16;
 	done(SCpnt);
+	spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 	return 0;
     }
 #endif
@@ -2551,6 +2555,7 @@ int acornscsi_queuecmd(struct scsi_cmnd *SCpnt,
 	if (!queue_add_cmd_ordered(&host->queues.issue, SCpnt)) {
 	    SCpnt->result = DID_ERROR << 16;
 	    done(SCpnt);
+	    spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 	    return 0;
 	}
 	local_irq_save(flags);
@@ -2558,6 +2563,7 @@ int acornscsi_queuecmd(struct scsi_cmnd *SCpnt,
 	    acornscsi_kick(host);
 	local_irq_restore(flags);
     }
+    spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
     return 0;
 }
 
diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c
index 9e71ac6..8cd9311 100644
--- a/drivers/scsi/arm/fas216.c
+++ b/drivers/scsi/arm/fas216.c
@@ -2203,7 +2203,10 @@ int fas216_queue_command(struct scsi_cmnd *SCpnt,
 {
 	FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
 	int result;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(SCpnt->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(SCpnt->device->host, SCpnt);
 	fas216_checkmagic(info);
 
 	fas216_log_command(info, LOG_CONNECT, SCpnt,
@@ -2237,6 +2240,7 @@ int fas216_queue_command(struct scsi_cmnd *SCpnt,
 	fas216_log_target(info, LOG_CONNECT, -1, "queue %s",
 		result ? "failure" : "success");
 
+	spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 	return result;
 }
 
@@ -2267,7 +2271,10 @@ int fas216_noqueue_command(struct scsi_cmnd *SCpnt,
 			   void (*done)(struct scsi_cmnd *))
 {
 	FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(SCpnt->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(SCpnt->device->host, SCpnt);
 	fas216_checkmagic(info);
 
 	/*
@@ -2307,6 +2314,7 @@ int fas216_noqueue_command(struct scsi_cmnd *SCpnt,
 
 	done(SCpnt);
 
+	spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c
index ab5bdda..0ec5c9d 100644
--- a/drivers/scsi/atp870u.c
+++ b/drivers/scsi/atp870u.c
@@ -612,7 +612,10 @@ static int atp870u_queuecommand(struct scsi_cmnd * req_p,
 	unsigned int tmport,m;	
 	struct atp_unit *dev;
 	struct Scsi_Host *host;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(req_p->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(req_p->device->host, req_p);
 	c = scmd_channel(req_p);
 	req_p->sense_buffer[0]=0;
 	scsi_set_resid(req_p, 0);
@@ -622,6 +625,7 @@ static int atp870u_queuecommand(struct scsi_cmnd * req_p,
 #ifdef ED_DBGP		
 		printk("atp870u_queuecommand : req_p->device->channel > 1\n");	
 #endif			
+		spin_unlock_irqrestore(req_p->device->host->host_lock, irqflags);
 		return 0;
 	}
 
@@ -640,6 +644,7 @@ static int atp870u_queuecommand(struct scsi_cmnd * req_p,
 	if ((m & dev->active_id[c]) == 0) {
 		req_p->result = 0x00040000;
 		done(req_p);
+		spin_unlock_irqrestore(req_p->device->host->host_lock, irqflags);
 		return 0;
 	}
 
@@ -651,6 +656,7 @@ static int atp870u_queuecommand(struct scsi_cmnd * req_p,
 #endif		
 		req_p->result = 0;
 		done(req_p);
+		spin_unlock_irqrestore(req_p->device->host->host_lock, irqflags);
 		return 0;
 	}
 	
@@ -675,6 +681,7 @@ static int atp870u_queuecommand(struct scsi_cmnd * req_p,
 		dev->quend[c]--;
 		req_p->result = 0x00020000;
 		done(req_p);	
+		spin_unlock_irqrestore(req_p->device->host->host_lock, irqflags);
 		return 0;
 	}
 	dev->quereq[c][dev->quend[c]] = req_p;
@@ -691,6 +698,7 @@ static int atp870u_queuecommand(struct scsi_cmnd * req_p,
 #ifdef ED_DBGP	
 	printk("atp870u_queuecommand : exit\n");
 #endif	
+	spin_unlock_irqrestore(req_p->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c
index d950ee4..2796f73 100644
--- a/drivers/scsi/bfa/bfad_im.c
+++ b/drivers/scsi/bfa/bfad_im.c
@@ -1131,17 +1131,23 @@ bfad_im_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
 	int             rc;
 	int       sg_cnt = 0;
 	struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
+	unsigned long irqflags;
 
+	spin_lock_irqsave(cmnd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmnd->device->host, cmnd);
 	rc = fc_remote_port_chkready(rport);
 	if (rc) {
 		cmnd->result = rc;
 		done(cmnd);
+		spin_unlock_irqrestore(cmnd->device->host->host_lock, irqflags);
 		return 0;
 	}
 
 	sg_cnt = scsi_dma_map(cmnd);
-	if (sg_cnt < 0)
+	if (sg_cnt < 0) {
+		spin_unlock_irqrestore(cmnd->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_HOST_BUSY;
+	}
 
 	cmnd->scsi_done = done;
 
@@ -1167,6 +1173,7 @@ bfad_im_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
 		printk(KERN_WARNING "hal_io failure\n");
 		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 		scsi_dma_unmap(cmnd);
+		spin_unlock_irqrestore(cmnd->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_HOST_BUSY;
 	}
 
@@ -1175,6 +1182,7 @@ bfad_im_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
 	bfa_ioim_start(hal_io);
 	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 
+	spin_unlock_irqrestore(cmnd->device->host->host_lock, irqflags);
 	return 0;
 
 out_fail_cmd:
@@ -1183,6 +1191,7 @@ out_fail_cmd:
 	if (done)
 		done(cmnd);
 
+	spin_unlock_irqrestore(cmnd->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
index 54f50b0..15f4d1e 100644
--- a/drivers/scsi/dc395x.c
+++ b/drivers/scsi/dc395x.c
@@ -1086,6 +1086,9 @@ static int dc395x_queue_command(struct scsi_cmnd *cmd, void (*done)(struct scsi_
 	struct ScsiReqBlk *srb;
 	struct AdapterCtlBlk *acb =
 	    (struct AdapterCtlBlk *)cmd->device->host->hostdata;
+	unsigned long irqflags;
+	spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmd->device->host, cmd);
 	dprintkdbg(DBG_0, "queue_command: (pid#%li) <%02i-%i> cmnd=0x%02x\n",
 		cmd->serial_number, cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
 
@@ -1127,6 +1130,7 @@ static int dc395x_queue_command(struct scsi_cmnd *cmd, void (*done)(struct scsi_
 		 * point in time.
 		 */
 		dprintkdbg(DBG_0, "queue_command: No free srb's\n");
+		spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 		return 1;
 	}
 
@@ -1141,6 +1145,7 @@ static int dc395x_queue_command(struct scsi_cmnd *cmd, void (*done)(struct scsi_
 		send_srb(acb, srb);
 	}
 	dprintkdbg(DBG_1, "queue_command: (pid#%li) done\n", cmd->serial_number);
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return 0;
 
 complete:
@@ -1151,6 +1156,7 @@ complete:
 	 * devices.
 	 */
 	done(cmd);
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index 23dec00..901f952 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -427,7 +427,10 @@ static int adpt_queue(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd *))
 {
 	adpt_hba* pHba = NULL;
 	struct adpt_device* pDev = NULL;	/* dpt per device information */
+	unsigned long irqflags;
 
+	spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmd->device->host, cmd);
 	cmd->scsi_done = done;
 	/*
 	 * SCSI REQUEST_SENSE commands will be executed automatically by the 
@@ -439,11 +442,13 @@ static int adpt_queue(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd *))
 	if ((cmd->cmnd[0] == REQUEST_SENSE) && (cmd->sense_buffer[0] != 0)) {
 		cmd->result = (DID_OK << 16);
 		cmd->scsi_done(cmd);
+		spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 		return 0;
 	}
 
 	pHba = (adpt_hba*)cmd->device->host->hostdata[0];
 	if (!pHba) {
+		spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 		return FAILED;
 	}
 
@@ -459,6 +464,7 @@ static int adpt_queue(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd *))
 	if(((pHba->state) & DPTI_STATE_IOCTL) || ((pHba->state) & DPTI_STATE_RESET)) {
 		pHba->host->last_reset = jiffies;
 		pHba->host->resetting = 1;
+		spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 		return 1;
 	}
 
@@ -475,6 +481,7 @@ static int adpt_queue(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd *))
 			// with type 7F (for all luns less than the max for this bus,id) so the lun scan will continue.
 			cmd->result = (DID_NO_CONNECT << 16);
 			cmd->scsi_done(cmd);
+			spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 			return 0;
 		}
 		cmd->device->hostdata = pDev;
@@ -486,8 +493,10 @@ static int adpt_queue(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd *))
 	 * delay processing of the command until later.
 	 */
 	if (pDev->state & DPTI_DEV_RESET ) {
+		spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 		return FAILED;
 	}
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return adpt_scsi_to_i2o(pHba, cmd, pDev);
 }
 
diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c
index d1c3137..6761716 100644
--- a/drivers/scsi/eata.c
+++ b/drivers/scsi/eata.c
@@ -1765,7 +1765,10 @@ static int eata2x_queuecommand(struct scsi_cmnd *SCpnt,
 	struct hostdata *ha = (struct hostdata *)shost->hostdata;
 	unsigned int i, k;
 	struct mscp *cpp;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(SCpnt->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(SCpnt->device->host, SCpnt);
 	if (SCpnt->host_scribble)
 		panic("%s: qcomm, pid %ld, SCpnt %p already active.\n",
 		      ha->board_name, SCpnt->serial_number, SCpnt);
@@ -1785,6 +1788,7 @@ static int eata2x_queuecommand(struct scsi_cmnd *SCpnt,
 
 	if (k == shost->can_queue) {
 		printk("%s: qcomm, no free mailbox.\n", ha->board_name);
+		spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 		return 1;
 	}
 
@@ -1827,6 +1831,7 @@ static int eata2x_queuecommand(struct scsi_cmnd *SCpnt,
 	    && TLDEV(SCpnt->device->type)) {
 		ha->cp_stat[i] = READY;
 		flush_dev(SCpnt->device, blk_rq_pos(SCpnt->request), ha, 0);
+		spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 		return 0;
 	}
 
@@ -1836,10 +1841,12 @@ static int eata2x_queuecommand(struct scsi_cmnd *SCpnt,
 		SCpnt->host_scribble = NULL;
 		scmd_printk(KERN_INFO, SCpnt,
 			"qcomm, pid %ld, adapter busy.\n", SCpnt->serial_number);
+		spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 		return 1;
 	}
 
 	ha->cp_stat[i] = IN_USE;
+	spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/eata_pio.c b/drivers/scsi/eata_pio.c
index 60886c1..72de26e 100644
--- a/drivers/scsi/eata_pio.c
+++ b/drivers/scsi/eata_pio.c
@@ -344,7 +344,10 @@ static int eata_pio_queue(struct scsi_cmnd *cmd,
 	hostdata *hd;
 	struct Scsi_Host *sh;
 	struct eata_ccb *cp;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmd->device->host, cmd);
 	queue_counter++;
 
 	hd = HD(cmd);
@@ -421,6 +424,7 @@ static int eata_pio_queue(struct scsi_cmnd *cmd,
 			"returning DID_BUS_BUSY, done.\n", cmd->serial_number);
 		done(cmd);
 		cp->status = FREE;
+		spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 		return 0;
 	}
 	/* FIXME: timeout */
@@ -435,6 +439,7 @@ static int eata_pio_queue(struct scsi_cmnd *cmd,
 		"Queued base %#.4lx pid: %ld "
 		"slot %d irq %d\n", sh->base, cmd->serial_number, y, sh->irq));
 
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c
index e2bc779..c70efde 100644
--- a/drivers/scsi/esp_scsi.c
+++ b/drivers/scsi/esp_scsi.c
@@ -922,10 +922,15 @@ static int esp_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd
 	struct esp *esp = shost_priv(dev->host);
 	struct esp_cmd_priv *spriv;
 	struct esp_cmd_entry *ent;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmd->device->host, cmd);
 	ent = esp_get_ent(esp);
-	if (!ent)
+	if (!ent) {
+		spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_HOST_BUSY;
+	}
 
 	ent->cmd = cmd;
 
@@ -938,6 +943,7 @@ static int esp_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd
 
 	esp_maybe_execute_command(esp);
 
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/fd_mcs.c b/drivers/scsi/fd_mcs.c
index 2ad95aa..dc61481 100644
--- a/drivers/scsi/fd_mcs.c
+++ b/drivers/scsi/fd_mcs.c
@@ -1075,7 +1075,10 @@ static int fd_mcs_release(struct Scsi_Host *shpnt)
 static int fd_mcs_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
 {
 	struct Scsi_Host *shpnt = SCpnt->device->host;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(SCpnt->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(SCpnt->device->host, SCpnt);
 	if (in_command) {
 		panic("fd_mcs: fd_mcs_queue() NOT REENTRANT!\n");
 	}
@@ -1119,6 +1122,7 @@ static int fd_mcs_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
 	outb(0x20, Interrupt_Cntl_port);
 	outb(0x14 | PARITY_MASK, TMC_Cntl_port);	/* Start arbitration */
 
+	spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c
index e296bcc..153bb64 100644
--- a/drivers/scsi/fdomain.c
+++ b/drivers/scsi/fdomain.c
@@ -1422,6 +1422,9 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id)
 static int fdomain_16x0_queue(struct scsi_cmnd *SCpnt,
 		void (*done)(struct scsi_cmnd *))
 {
+   unsigned long irqflags;
+   spin_lock_irqsave(SCpnt->device->host->host_lock, irqflags);
+   scsi_cmd_get_serial(SCpnt->device->host, SCpnt);
    if (in_command) {
       panic( "scsi: <fdomain> fdomain_16x0_queue() NOT REENTRANT!\n" );
    }
@@ -1466,6 +1469,7 @@ static int fdomain_16x0_queue(struct scsi_cmnd *SCpnt,
    outb(0x20, port_base + Interrupt_Cntl);
    outb(0x14 | PARITY_MASK, port_base + TMC_Cntl); /* Start arbitration */
 
+   spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
    return 0;
 }
 
diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c
index 198cbab..2e4f40b 100644
--- a/drivers/scsi/fnic/fnic_scsi.c
+++ b/drivers/scsi/fnic/fnic_scsi.c
@@ -360,18 +360,24 @@ int fnic_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
 	int sg_count;
 	unsigned long flags;
 	unsigned long ptr;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(sc->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(sc->device->host, sc);
 	rport = starget_to_rport(scsi_target(sc->device));
 	ret = fc_remote_port_chkready(rport);
 	if (ret) {
 		sc->result = ret;
 		done(sc);
+		spin_unlock_irqrestore(sc->device->host->host_lock, irqflags);
 		return 0;
 	}
 
 	lp = shost_priv(sc->device->host);
-	if (lp->state != LPORT_ST_READY || !(lp->link_up))
+	if (lp->state != LPORT_ST_READY || !(lp->link_up)) {
+		spin_unlock_irqrestore(sc->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_HOST_BUSY;
+	}
 
 	/*
 	 * Release host lock, use driver resource specific locks from here.
@@ -454,6 +460,7 @@ int fnic_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
 out:
 	/* acquire host lock before returning to SCSI */
 	spin_lock(lp->host->host_lock);
+	spin_unlock_irqrestore(sc->device->host->host_lock, irqflags);
 	return ret;
 }
 
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 5a3f931..e4a3ecb 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -4009,7 +4009,10 @@ static int gdth_queuecommand(struct scsi_cmnd *scp,
 {
     gdth_ha_str *ha = shost_priv(scp->device->host);
     struct gdth_cmndinfo *cmndinfo;
+    unsigned long irqflags;
 
+    spin_lock_irqsave(scp->device->host->host_lock, irqflags);
+    scsi_cmd_get_serial(scp->device->host, scp);
     TRACE(("gdth_queuecommand() cmd 0x%x\n", scp->cmnd[0]));
 
     cmndinfo = gdth_get_cmndinfo(ha);
@@ -4019,6 +4022,7 @@ static int gdth_queuecommand(struct scsi_cmnd *scp,
     cmndinfo->timeout_count = 0;
     cmndinfo->priority = DEFAULT_PRI;
 
+    spin_unlock_irqrestore(scp->device->host->host_lock, irqflags);
     return __gdth_queuecommand(ha, scp, cmndinfo);
 }
 
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index c5d0606..8d0f51d 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -1934,13 +1934,17 @@ static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd,
 	unsigned char scsi3addr[8];
 	struct CommandList *c;
 	unsigned long flags;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmd->device->host, cmd);
 	/* Get the ptr to our adapter structure out of cmd->host. */
 	h = sdev_to_hba(cmd->device);
 	dev = cmd->device->hostdata;
 	if (!dev) {
 		cmd->result = DID_NO_CONNECT << 16;
 		done(cmd);
+		spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 		return 0;
 	}
 	memcpy(scsi3addr, dev->scsi3addr, sizeof(scsi3addr));
@@ -1951,6 +1955,7 @@ static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd,
 	spin_unlock_irqrestore(&h->lock, flags);
 	if (c == NULL) {			/* trouble... */
 		dev_err(&h->pdev->dev, "cmd_alloc returned NULL!\n");
+		spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_HOST_BUSY;
 	}
 
@@ -2013,10 +2018,12 @@ static int hpsa_scsi_queue_command(struct scsi_cmnd *cmd,
 
 	if (hpsa_scatter_gather(h, c, cmd) < 0) { /* Fill SG list */
 		cmd_free(h, c);
+		spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_HOST_BUSY;
 	}
 	enqueue_cmd_and_start_io(h, c);
 	/* the cmd'll come back via intr handler in complete_scsi_command()  */
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c
index 0729f15..04903e4 100644
--- a/drivers/scsi/hptiop.c
+++ b/drivers/scsi/hptiop.c
@@ -759,13 +759,17 @@ static int hptiop_queuecommand(struct scsi_cmnd *scp,
 	struct hpt_iop_request_scsi_command *req;
 	int sg_count = 0;
 	struct hptiop_request *_req;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(scp->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(scp->device->host, scp);
 	BUG_ON(!done);
 	scp->scsi_done = done;
 
 	_req = get_req(hba);
 	if (_req == NULL) {
 		dprintk("hptiop_queuecmd : no free req\n");
+		spin_unlock_irqrestore(scp->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_HOST_BUSY;
 	}
 
@@ -811,11 +815,13 @@ static int hptiop_queuecommand(struct scsi_cmnd *scp,
 
 	memcpy(req->cdb, scp->cmnd, sizeof(req->cdb));
 	hba->ops->post_req(hba, _req);
+	spin_unlock_irqrestore(scp->device->host->host_lock, irqflags);
 	return 0;
 
 cmd_done:
 	dprintk("scsi_done(scp=%p)\n", scp);
 	scp->scsi_done(scp);
+	spin_unlock_irqrestore(scp->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c
index 9a4b69d..65595e2 100644
--- a/drivers/scsi/ibmmca.c
+++ b/drivers/scsi/ibmmca.c
@@ -1703,6 +1703,10 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
 	int max_pun;
 	int i;
 	struct scatterlist *sg;
+	unsigned long irqflags;
+
+	spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmd->device->host, cmd);
 
 	shpnt = cmd->device->host;
 
@@ -1721,6 +1725,8 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
 		cmd->result = DID_NO_CONNECT << 16;
 		if (done)
 			done(cmd);
+
+		spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 		return 0;
 	}
 
@@ -1743,6 +1749,8 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
 					cmd->result = DID_NO_CONNECT << 16;	/* return no connect */
 					if (done)
 						done(cmd);
+
+					spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 					return 0;
 				}
 			}
@@ -1804,6 +1812,8 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
 			cmd->result = DID_BAD_TARGET << 16;
 			if (done)
 				done(cmd);
+
+			spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 			return 0;
 		}
 	}
@@ -1993,6 +2003,8 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
 		issue_cmd(shpnt, isa_virt_to_bus(scb), IM_SCB | ldn);
 		IBM_DS(shpnt).scbs++;
 	}
+
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 00d08b2..98c9cc7 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -1616,6 +1616,9 @@ static int ibmvfc_queuecommand(struct scsi_cmnd *cmnd,
 	u8 tag[2];
 	int rc;
 
+	unsigned long irqflags;
+	spin_lock_irqsave(cmnd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmnd->device->host, cmnd);
 	if (unlikely((rc = fc_remote_port_chkready(rport))) ||
 	    unlikely((rc = ibmvfc_host_chkready(vhost)))) {
 		cmnd->result = rc;
@@ -1656,12 +1659,16 @@ static int ibmvfc_queuecommand(struct scsi_cmnd *cmnd,
 		};
 	}
 
-	if (likely(!(rc = ibmvfc_map_sg_data(cmnd, evt, vfc_cmd, vhost->dev))))
+	if (likely(!(rc = ibmvfc_map_sg_data(cmnd, evt, vfc_cmd, vhost->dev)))) {
+		spin_unlock_irqrestore(cmnd->device->host->host_lock, irqflags);
 		return ibmvfc_send_event(evt, vhost, 0);
+	}
 
 	ibmvfc_free_event(evt);
-	if (rc == -ENOMEM)
+	if (rc == -ENOMEM) {
+		spin_unlock_irqrestore(cmnd->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_HOST_BUSY;
+	}
 
 	if (vhost->log_level > IBMVFC_DEFAULT_LOG_LEVEL)
 		scmd_printk(KERN_ERR, cmnd,
@@ -1669,6 +1676,7 @@ static int ibmvfc_queuecommand(struct scsi_cmnd *cmnd,
 
 	cmnd->result = DID_ERROR << 16;
 	done(cmnd);
+	spin_unlock_irqrestore(cmnd->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index 67f78a4..c15bf25 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -723,10 +723,15 @@ static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd,
 	u16 lun = lun_from_dev(cmnd->device);
 	u8 out_fmt, in_fmt;
 
+	unsigned long irqflags;
+	spin_lock_irqsave(cmnd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmnd->device->host, cmnd);
 	cmnd->result = (DID_OK << 16);
 	evt_struct = get_event_struct(&hostdata->pool);
-	if (!evt_struct)
+	if (!evt_struct) {
+		spin_unlock_irqrestore(cmnd->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_HOST_BUSY;
+	}
 
 	/* Set up the actual SRP IU */
 	srp_cmd = &evt_struct->iu.srp.cmd;
@@ -740,6 +745,7 @@ static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd,
 			sdev_printk(KERN_ERR, cmnd->device,
 			            "couldn't convert cmd to srp_cmd\n");
 		free_event_struct(&hostdata->pool, evt_struct);
+		spin_unlock_irqrestore(cmnd->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_HOST_BUSY;
 	}
 
@@ -763,6 +769,7 @@ static int ibmvscsi_queuecommand(struct scsi_cmnd *cmnd,
 			offsetof(struct srp_indirect_buf, desc_list);
 	}
 
+	spin_unlock_irqrestore(cmnd->device->host->host_lock, irqflags);
 	return ibmvscsi_send_srp_event(evt_struct, hostdata, 0);
 }
 
diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c
index 4734ab0..57b7b92 100644
--- a/drivers/scsi/imm.c
+++ b/drivers/scsi/imm.c
@@ -930,7 +930,10 @@ static int imm_queuecommand(struct scsi_cmnd *cmd,
 		void (*done)(struct scsi_cmnd *))
 {
 	imm_struct *dev = imm_dev(cmd->device->host);
+	unsigned long irqflags;
 
+	spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmd->device->host, cmd);
 	if (dev->cur_cmd) {
 		printk("IMM: bug in imm_queuecommand\n");
 		return 0;
@@ -946,6 +949,7 @@ static int imm_queuecommand(struct scsi_cmnd *cmd,
 
 	imm_pb_claim(dev);
 
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/in2000.c b/drivers/scsi/in2000.c
index 52bdc6d..2339bb3 100644
--- a/drivers/scsi/in2000.c
+++ b/drivers/scsi/in2000.c
@@ -339,7 +339,10 @@ static int in2000_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
 	struct Scsi_Host *instance;
 	struct IN2000_hostdata *hostdata;
 	Scsi_Cmnd *tmp;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmd->device->host, cmd);
 	instance = cmd->device->host;
 	hostdata = (struct IN2000_hostdata *) instance->hostdata;
 
@@ -428,6 +431,7 @@ static int in2000_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
 	in2000_execute(cmd->device->host);
 
 	DB(DB_QUEUE_COMMAND, printk(")Q-%ld ", cmd->serial_number))
+	    spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	    return 0;
 }
 
diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c
index 1087977..0ef119e 100644
--- a/drivers/scsi/initio.c
+++ b/drivers/scsi/initio.c
@@ -2644,15 +2644,21 @@ static int i91u_queuecommand(struct scsi_cmnd *cmd,
 {
 	struct initio_host *host = (struct initio_host *) cmd->device->host->hostdata;
 	struct scsi_ctrl_blk *cmnd;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmd->device->host, cmd);
 	cmd->scsi_done = done;
 
 	cmnd = initio_alloc_scb(host);
-	if (!cmnd)
+	if (!cmnd) {
+		spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_HOST_BUSY;
+	}
 
 	initio_build_scb(host, cmnd, cmd);
 	initio_exec_scb(host, cmnd);
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index df9a12c..d0ca800 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -5717,7 +5717,10 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd,
 	struct ipr_ioarcb *ioarcb;
 	struct ipr_cmnd *ipr_cmd;
 	int rc = 0;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(&scsi_cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(scsi_cmd->device->host, scsi_cmd);
 	scsi_cmd->scsi_done = done;
 	ioa_cfg = (struct ipr_ioa_cfg *)scsi_cmd->device->host->hostdata;
 	res = scsi_cmd->device->hostdata;
@@ -5728,8 +5731,10 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd,
 	 * We have told the host to stop giving us new requests, but
 	 * ERP ops don't count. FIXME
 	 */
-	if (unlikely(!ioa_cfg->allow_cmds && !ioa_cfg->ioa_is_dead))
+	if (unlikely(!ioa_cfg->allow_cmds && !ioa_cfg->ioa_is_dead)) {
+		spin_unlock_irqrestore(&scsi_cmd->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_HOST_BUSY;
+	}
 
 	/*
 	 * FIXME - Create scsi_set_host_offline interface
@@ -5739,11 +5744,15 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd,
 		memset(scsi_cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
 		scsi_cmd->result = (DID_NO_CONNECT << 16);
 		scsi_cmd->scsi_done(scsi_cmd);
+		spin_unlock_irqrestore(&scsi_cmd->device->host->host_lock, irqflags);
 		return 0;
 	}
 
-	if (ipr_is_gata(res) && res->sata_port)
-		return ata_sas_queuecmd(scsi_cmd, done, res->sata_port->ap);
+	if (ipr_is_gata(res) && res->sata_port) {
+		rc = ata_sas_queuecmd(scsi_cmd, done, res->sata_port->ap);
+		spin_unlock_irqrestore(&scsi_cmd->device->host->host_lock, irqflags);
+		return rc;
+	}
 
 	ipr_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
 	ioarcb = &ipr_cmd->ioarcb;
@@ -5786,9 +5795,11 @@ static int ipr_queuecommand(struct scsi_cmnd *scsi_cmd,
 		ipr_send_command(ipr_cmd);
 	} else {
 		 list_move_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
+		 spin_unlock_irqrestore(&scsi_cmd->device->host->host_lock, irqflags);
 		 return SCSI_MLQUEUE_HOST_BUSY;
 	}
 
+	spin_unlock_irqrestore(&scsi_cmd->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index f83a116..cd83a25 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -1050,28 +1050,37 @@ static int ips_queue(struct scsi_cmnd *SC, void (*done) (struct scsi_cmnd *))
 {
 	ips_ha_t *ha;
 	ips_passthru_t *pt;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(SC->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(SC->device->host, SC);
 	METHOD_TRACE("ips_queue", 1);
 
 	ha = (ips_ha_t *) SC->device->host->hostdata;
 
-	if (!ha)
+	if (!ha) {
+		spin_unlock_irqrestore(SC->device->host->host_lock, irqflags);
 		return (1);
+	}
 
-	if (!ha->active)
+	if (!ha->active) {
+		spin_unlock_irqrestore(SC->device->host->host_lock, irqflags);
 		return (DID_ERROR);
+	}
 
 	if (ips_is_passthru(SC)) {
 		if (ha->copp_waitlist.count == IPS_MAX_IOCTL_QUEUE) {
 			SC->result = DID_BUS_BUSY << 16;
 			done(SC);
 
+			spin_unlock_irqrestore(SC->device->host->host_lock, irqflags);
 			return (0);
 		}
 	} else if (ha->scb_waitlist.count == IPS_MAX_QUEUE) {
 		SC->result = DID_BUS_BUSY << 16;
 		done(SC);
 
+		spin_unlock_irqrestore(SC->device->host->host_lock, irqflags);
 		return (0);
 	}
 
@@ -1089,6 +1098,7 @@ static int ips_queue(struct scsi_cmnd *SC, void (*done) (struct scsi_cmnd *))
 		SC->result = DID_NO_CONNECT << 16;
 		done(SC);
 
+		spin_unlock_irqrestore(SC->device->host->host_lock, irqflags);
 		return (0);
 	}
 
@@ -1105,12 +1115,14 @@ static int ips_queue(struct scsi_cmnd *SC, void (*done) (struct scsi_cmnd *))
 			if (ha->scb_activelist.count != 0) {
 				SC->result = DID_BUS_BUSY << 16;
 				done(SC);
+				spin_unlock_irqrestore(SC->device->host->host_lock, irqflags);
 				return (0);
 			}
 			ha->ioctl_reset = 1;	/* This reset request is from an IOCTL */
 			__ips_eh_reset(SC);
 			SC->result = DID_OK << 16;
 			SC->scsi_done(SC);
+			spin_unlock_irqrestore(SC->device->host->host_lock, irqflags);
 			return (0);
 		}
 
@@ -1121,6 +1133,7 @@ static int ips_queue(struct scsi_cmnd *SC, void (*done) (struct scsi_cmnd *))
 			SC->result = DID_ERROR << 16;
 			done(SC);
 
+			spin_unlock_irqrestore(SC->device->host->host_lock, irqflags);
 			return (0);
 		}
 
@@ -1134,6 +1147,7 @@ static int ips_queue(struct scsi_cmnd *SC, void (*done) (struct scsi_cmnd *))
 
 	ips_next(ha, IPS_INTR_IORL);
 
+	spin_unlock_irqrestore(SC->device->host->host_lock, irqflags);
 	return (0);
 }
 
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index c797f6b..5a91e1d 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -1763,13 +1763,17 @@ int fc_queuecommand(struct scsi_cmnd *sc_cmd, void (*done)(struct scsi_cmnd *))
 	int rval;
 	int rc = 0;
 	struct fcoe_dev_stats *stats;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(sc_cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(sc_cmd->device->host, sc_cmd);
 	lport = shost_priv(sc_cmd->device->host);
 
 	rval = fc_remote_port_chkready(rport);
 	if (rval) {
 		sc_cmd->result = rval;
 		done(sc_cmd);
+		spin_unlock_irqrestore(sc_cmd->device->host->host_lock, irqflags);
 		return 0;
 	}
 	spin_unlock_irq(lport->host->host_lock);
@@ -1850,6 +1854,7 @@ int fc_queuecommand(struct scsi_cmnd *sc_cmd, void (*done)(struct scsi_cmnd *))
 	}
 out:
 	spin_lock_irq(lport->host->host_lock);
+	spin_unlock_irqrestore(sc_cmd->device->host->host_lock, irqflags);
 	return rc;
 }
 EXPORT_SYMBOL(fc_queuecommand);
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 633e090..f8b9dde 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1608,6 +1608,12 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
 	struct iscsi_session *session;
 	struct iscsi_conn *conn;
 	struct iscsi_task *task = NULL;
+	unsigned long irqflags;
+
+	/* remove me */
+	spin_lock_irqsave(sc->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(sc->device->host, sc);
+	spin_unlock_irqrestore(sc->device->host->host_lock, irqflags);
 
 	sc->scsi_done = done;
 	sc->result = 0;
@@ -1615,7 +1621,6 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
 
 	host = sc->device->host;
 	ihost = shost_priv(host);
-	spin_unlock(host->host_lock);
 
 	cls_session = starget_to_session(scsi_target(sc->device));
 	session = cls_session->dd_data;
@@ -1706,7 +1711,6 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
 
 	session->queued_cmdsn++;
 	spin_unlock(&session->lock);
-	spin_lock(host->host_lock);
 	return 0;
 
 prepd_reject:
@@ -1716,7 +1720,6 @@ reject:
 	spin_unlock(&session->lock);
 	ISCSI_DBG_SESSION(session, "cmd 0x%x rejected (%d)\n",
 			  sc->cmnd[0], reason);
-	spin_lock(host->host_lock);
 	return SCSI_MLQUEUE_TARGET_BUSY;
 
 prepd_fault:
@@ -1733,7 +1736,6 @@ fault:
 		scsi_in(sc)->resid = scsi_in(sc)->length;
 	}
 	done(sc);
-	spin_lock(host->host_lock);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(iscsi_queuecommand);
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
index 55f09e9..5b4aaab 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -200,8 +200,12 @@ int sas_queuecommand(struct scsi_cmnd *cmd,
 	struct domain_device *dev = cmd_to_domain_dev(cmd);
 	struct Scsi_Host *host = cmd->device->host;
 	struct sas_internal *i = to_sas_internal(host->transportt);
+	unsigned long irqflags;
 
-	spin_unlock_irq(host->host_lock);
+	/* remove me */
+	spin_lock_irqsave(host->host_lock, irqflags);
+	scsi_cmd_get_serial(host, cmd);
+	spin_unlock_irqrestore(host->host_lock, irqflags);
 
 	{
 		struct sas_ha_struct *sas_ha = dev->port->ha;
@@ -250,7 +254,6 @@ int sas_queuecommand(struct scsi_cmnd *cmd,
 		}
 	}
 out:
-	spin_lock_irq(host->host_lock);
 	return res;
 }
 
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 3a65895..aed5280 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -2906,6 +2906,9 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
 	struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
 	int err;
 
+	unsigned long irqflags;
+	spin_lock_irqsave(cmnd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmnd->device->host, cmnd);
 	err = fc_remote_port_chkready(rport);
 	if (err) {
 		cmnd->result = err;
@@ -3043,16 +3046,19 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
 			lpfc_poll_rearm_timer(phba);
 	}
 
+	spin_unlock_irqrestore(cmnd->device->host->host_lock, irqflags);
 	return 0;
 
  out_host_busy_free_buf:
 	lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd);
 	lpfc_release_scsi_buf(phba, lpfc_cmd);
  out_host_busy:
+	spin_unlock_irqrestore(cmnd->device->host->host_lock, irqflags);
 	return SCSI_MLQUEUE_HOST_BUSY;
 
  out_fail_command:
 	done(cmnd);
+	spin_unlock_irqrestore(cmnd->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c
index 3ddb4dc..37b01bd 100644
--- a/drivers/scsi/mac53c94.c
+++ b/drivers/scsi/mac53c94.c
@@ -82,6 +82,9 @@ static int mac53c94_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *
 	}
 #endif
 
+	unsigned long irqflags;
+	spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmd->device->host, cmd);
 	cmd->scsi_done = done;
 	cmd->host_scribble = NULL;
 
@@ -96,6 +99,7 @@ static int mac53c94_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *
 	if (state->phase == idle)
 		mac53c94_start(state);
 
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 7ceb5cf..070fdd0 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -372,7 +372,10 @@ megaraid_queue(Scsi_Cmnd *scmd, void (*done)(Scsi_Cmnd *))
 	scb_t	*scb;
 	int	busy=0;
 	unsigned long flags;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(scmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(scmd->device->host, scmd);
 	adapter = (adapter_t *)scmd->device->host->hostdata;
 
 	scmd->scsi_done = done;
@@ -406,6 +409,7 @@ megaraid_queue(Scsi_Cmnd *scmd, void (*done)(Scsi_Cmnd *))
 	busy = 0;
  out:
 	spin_unlock_irqrestore(&adapter->lock, flags);
+	spin_unlock_irqrestore(scmd->device->host->host_lock, irqflags);
 	return busy;
 }
 
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
index a7810a1..07ade30 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -1489,7 +1489,10 @@ megaraid_queue_command(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
 	adapter_t	*adapter;
 	scb_t		*scb;
 	int		if_busy;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(scp->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(scp->device->host, scp);
 	adapter		= SCP2ADAPTER(scp);
 	scp->scsi_done	= done;
 	scp->result	= 0;
@@ -1506,10 +1509,12 @@ megaraid_queue_command(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *))
 	scb = megaraid_mbox_build_cmd(adapter, scp, &if_busy);
 	if (!scb) {	// command already completed
 		done(scp);
+		spin_unlock_irqrestore(scp->device->host->host_lock, irqflags);
 		return 0;
 	}
 
 	megaraid_mbox_runpendq(adapter, scb);
+	spin_unlock_irqrestore(scp->device->host->host_lock, irqflags);
 	return if_busy;
 }
 
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index d3c9cde..cb0b400 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -1325,16 +1325,22 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
 	struct megasas_cmd *cmd;
 	struct megasas_instance *instance;
 	unsigned long flags;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(scmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(scmd->device->host, scmd);
 	instance = (struct megasas_instance *)
 	    scmd->device->host->hostdata;
 
-	if (instance->issuepend_done == 0)
+	if (instance->issuepend_done == 0) {
+		spin_unlock_irqrestore(scmd->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_HOST_BUSY;
+	}
 
 	spin_lock_irqsave(&instance->hba_lock, flags);
 	if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL) {
 		spin_unlock_irqrestore(&instance->hba_lock, flags);
+		spin_unlock_irqrestore(scmd->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_HOST_BUSY;
 	}
 
@@ -1362,8 +1368,10 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
 	}
 
 	cmd = megasas_get_cmd(instance);
-	if (!cmd)
+	if (!cmd) {
+		spin_unlock_irqrestore(scmd->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_HOST_BUSY;
+	}
 
 	/*
 	 * Logical drive command
@@ -1393,12 +1401,14 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd *))
 		tasklet_schedule(&instance->isr_tasklet);
 
 
+	spin_unlock_irqrestore(scmd->device->host->host_lock, irqflags);
 	return 0;
 
  out_return_cmd:
 	megasas_return_cmd(instance, cmd);
  out_done:
 	done(scmd);
+	spin_unlock_irqrestore(scmd->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c
index 1f784fd..93e6596 100644
--- a/drivers/scsi/mesh.c
+++ b/drivers/scsi/mesh.c
@@ -1630,7 +1630,10 @@ static void cmd_complete(struct mesh_state *ms)
 static int mesh_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 {
 	struct mesh_state *ms;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmd->device->host, cmd);
 	cmd->scsi_done = done;
 	cmd->host_scribble = NULL;
 
@@ -1645,6 +1648,7 @@ static int mesh_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 	if (ms->phase == idle)
 		mesh_start(ms);
 
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index 16e99b6..e849aa2 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -3323,18 +3323,23 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
 	Mpi2SCSIIORequest_t *mpi_request;
 	u32 mpi_control;
 	u16 smid;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(scmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(scmd->device->host, scmd);
 	scmd->scsi_done = done;
 	sas_device_priv_data = scmd->device->hostdata;
 	if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
 		scmd->result = DID_NO_CONNECT << 16;
 		scmd->scsi_done(scmd);
+		spin_unlock_irqrestore(scmd->device->host->host_lock, irqflags);
 		return 0;
 	}
 
 	if (ioc->pci_error_recovery) {
 		scmd->result = DID_NO_CONNECT << 16;
 		scmd->scsi_done(scmd);
+		spin_unlock_irqrestore(scmd->device->host->host_lock, irqflags);
 		return 0;
 	}
 
@@ -3343,19 +3348,25 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
 	if (sas_target_priv_data->handle == MPT2SAS_INVALID_DEVICE_HANDLE) {
 		scmd->result = DID_NO_CONNECT << 16;
 		scmd->scsi_done(scmd);
+		spin_unlock_irqrestore(scmd->device->host->host_lock, irqflags);
 		return 0;
 	}
 
 	/* host recovery or link resets sent via IOCTLs */
-	if (ioc->shost_recovery || ioc->ioc_link_reset_in_progress)
+	if (ioc->shost_recovery || ioc->ioc_link_reset_in_progress) {
+		spin_unlock_irqrestore(scmd->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_HOST_BUSY;
+	}
 	/* device busy with task management */
-	else if (sas_device_priv_data->block || sas_target_priv_data->tm_busy)
+	else if (sas_device_priv_data->block || sas_target_priv_data->tm_busy) {
+		spin_unlock_irqrestore(scmd->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_DEVICE_BUSY;
+	}
 	/* device has been deleted */
 	else if (sas_target_priv_data->deleted) {
 		scmd->result = DID_NO_CONNECT << 16;
 		scmd->scsi_done(scmd);
+		spin_unlock_irqrestore(scmd->device->host->host_lock, irqflags);
 		return 0;
 	}
 
@@ -3435,9 +3446,11 @@ _scsih_qcmd(struct scsi_cmnd *scmd, void (*done)(struct scsi_cmnd *))
 		    sas_device_priv_data->sas_target->handle);
 	else
 		mpt2sas_base_put_smid_default(ioc, smid);
+	spin_unlock_irqrestore(scmd->device->host->host_lock, irqflags);
 	return 0;
 
  out:
+	spin_unlock_irqrestore(scmd->device->host->host_lock, irqflags);
 	return SCSI_MLQUEUE_HOST_BUSY;
 }
 
diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c
index d013a2a..00a8b1e 100644
--- a/drivers/scsi/ncr53c8xx.c
+++ b/drivers/scsi/ncr53c8xx.c
@@ -8034,7 +8034,10 @@ static int ncr53c8xx_queue_command (struct scsi_cmnd *cmd, void (* done)(struct
      struct ncb *np = ((struct host_data *) cmd->device->host->hostdata)->ncb;
      unsigned long flags;
      int sts;
+     unsigned long irqflags;
 
+     spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+     scsi_cmd_get_serial(cmd->device->host, cmd);
 #ifdef DEBUG_NCR53C8XX
 printk("ncr53c8xx_queue_command\n");
 #endif
@@ -8065,6 +8068,7 @@ printk("ncr53c8xx : command successfully queued\n");
 	  sts = 0;
      }
 
+     spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
      return sts;
 }
 
diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c
index 4c1e545..42864e2 100644
--- a/drivers/scsi/nsp32.c
+++ b/drivers/scsi/nsp32.c
@@ -915,7 +915,10 @@ static int nsp32_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_
 	nsp32_target *target;
 	nsp32_lunt   *cur_lunt;
 	int ret;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(SCpnt->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(SCpnt->device->host, SCpnt);
 	nsp32_dbg(NSP32_DEBUG_QUEUECOMMAND,
 		  "enter. target: 0x%x LUN: 0x%x cmnd: 0x%x cmndlen: 0x%x "
 		  "use_sg: 0x%x reqbuf: 0x%lx reqlen: 0x%x",
@@ -927,6 +930,7 @@ static int nsp32_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_
 		data->CurrentSC = NULL;
 		SCpnt->result   = DID_NO_CONNECT << 16;
 		done(SCpnt);
+		spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 		return 0;
 	}
 
@@ -935,6 +939,7 @@ static int nsp32_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_
 		nsp32_dbg(NSP32_DEBUG_QUEUECOMMAND, "terget==host???");
 		SCpnt->result = DID_BAD_TARGET << 16;
 		done(SCpnt);
+		spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 		return 0;
 	}
 
@@ -943,6 +948,7 @@ static int nsp32_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_
 		nsp32_dbg(NSP32_DEBUG_QUEUECOMMAND, "no more lun");
 		SCpnt->result = DID_BAD_TARGET << 16;
 		done(SCpnt);
+		spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 		return 0;
 	}
 
@@ -975,6 +981,7 @@ static int nsp32_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_
 		nsp32_msg(KERN_ERR, "SGT fail");
 		SCpnt->result = DID_ERROR << 16;
 		nsp32_scsi_done(SCpnt);
+		spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 		return 0;
 	}
 
@@ -1047,6 +1054,7 @@ static int nsp32_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_
 		nsp32_scsi_done(SCpnt);
 	}
 
+	spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
index 9326c2c..6c4277d 100644
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -193,7 +193,10 @@ static int nsp_queuecommand(struct scsi_cmnd *SCpnt,
 	unsigned char target = scmd_id(SCpnt);
 #endif
 	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(SCpnt->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(SCpnt->device->host, SCpnt);
 	nsp_dbg(NSP_DEBUG_QUEUECOMMAND,
 		"SCpnt=0x%p target=%d lun=%d sglist=0x%p bufflen=%d sg_count=%d",
 		SCpnt, target, SCpnt->device->lun, scsi_sglist(SCpnt),
@@ -206,6 +209,7 @@ static int nsp_queuecommand(struct scsi_cmnd *SCpnt,
 		nsp_msg(KERN_DEBUG, "CurrentSC!=NULL this can't be happen");
 		SCpnt->result   = DID_BAD_TARGET << 16;
 		nsp_scsi_done(SCpnt);
+		spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 		return 0;
 	}
 
@@ -253,6 +257,7 @@ static int nsp_queuecommand(struct scsi_cmnd *SCpnt,
 		nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "selection fail");
 		SCpnt->result   = DID_BUS_BUSY << 16;
 		nsp_scsi_done(SCpnt);
+		spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 		return 0;
 	}
 
@@ -261,6 +266,7 @@ static int nsp_queuecommand(struct scsi_cmnd *SCpnt,
 #ifdef NSP_DEBUG
 	data->CmdId++;
 #endif
+	spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
index 0ae27cb..5f926bb 100644
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -553,7 +553,10 @@ SYM53C500_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 	int port_base = SCpnt->device->host->io_port;
 	struct sym53c500_data *data =
 	    (struct sym53c500_data *)SCpnt->device->host->hostdata;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(SCpnt->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(SCpnt->device->host, SCpnt);
 	VDEB(printk("SYM53C500_queue called\n"));
 
 	DEB(printk("cmd=%02x, cmd_len=%02x, target=%02x, lun=%02x, bufflen=%d\n", 
@@ -580,6 +583,7 @@ SYM53C500_queue(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 	}
 	outb(SELECT_NO_ATN, port_base + CMD_REG);
 
+	spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
index 4b87657..607a3cf 100644
--- a/drivers/scsi/pmcraid.c
+++ b/drivers/scsi/pmcraid.c
@@ -3482,7 +3482,10 @@ static int pmcraid_queuecommand(
 	struct pmcraid_cmd *cmd;
 	u32 fw_version;
 	int rc = 0;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(scsi_cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(scsi_cmd->device->host, scsi_cmd);
 	pinstance =
 		(struct pmcraid_instance *)scsi_cmd->device->host->hostdata;
 	fw_version = be16_to_cpu(pinstance->inq_data->fw_version);
@@ -3497,12 +3500,15 @@ static int pmcraid_queuecommand(
 		pmcraid_info("IOA is dead, but queuecommand is scheduled\n");
 		scsi_cmd->result = (DID_NO_CONNECT << 16);
 		scsi_cmd->scsi_done(scsi_cmd);
+		spin_unlock_irqrestore(scsi_cmd->device->host->host_lock, irqflags);
 		return 0;
 	}
 
 	/* If IOA reset is in progress, can't queue the commands */
-	if (pinstance->ioa_reset_in_progress)
+	if (pinstance->ioa_reset_in_progress) {
+		spin_unlock_irqrestore(scsi_cmd->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_HOST_BUSY;
+	}
 
 	/* Firmware doesn't support SYNCHRONIZE_CACHE command (0x35), complete
 	 * the command here itself with success return
@@ -3510,6 +3516,7 @@ static int pmcraid_queuecommand(
 	if (scsi_cmd->cmnd[0] == SYNCHRONIZE_CACHE) {
 		pmcraid_info("SYNC_CACHE(0x35), completing in driver itself\n");
 		scsi_cmd->scsi_done(scsi_cmd);
+		spin_unlock_irqrestore(scsi_cmd->device->host->host_lock, irqflags);
 		return 0;
 	}
 
@@ -3518,6 +3525,7 @@ static int pmcraid_queuecommand(
 
 	if (cmd == NULL) {
 		pmcraid_err("free command block is not available\n");
+		spin_unlock_irqrestore(scsi_cmd->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_HOST_BUSY;
 	}
 
@@ -3574,6 +3582,7 @@ static int pmcraid_queuecommand(
 		rc = SCSI_MLQUEUE_HOST_BUSY;
 	}
 
+	spin_unlock_irqrestore(scsi_cmd->device->host->host_lock, irqflags);
 	return rc;
 }
 
diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c
index 7bc2d79..6ffe805 100644
--- a/drivers/scsi/ppa.c
+++ b/drivers/scsi/ppa.c
@@ -802,7 +802,10 @@ static int ppa_queuecommand(struct scsi_cmnd *cmd,
 		void (*done) (struct scsi_cmnd *))
 {
 	ppa_struct *dev = ppa_dev(cmd->device->host);
+	unsigned long irqflags;
 
+	spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmd->device->host, cmd);
 	if (dev->cur_cmd) {
 		printk(KERN_ERR "PPA: bug in ppa_queuecommand\n");
 		return 0;
@@ -818,6 +821,7 @@ static int ppa_queuecommand(struct scsi_cmnd *cmd,
 
 	ppa_pb_claim(dev);
 
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/ps3rom.c b/drivers/scsi/ps3rom.c
index 92ffbb5..9cb6ad3 100644
--- a/drivers/scsi/ps3rom.c
+++ b/drivers/scsi/ps3rom.c
@@ -218,7 +218,10 @@ static int ps3rom_queuecommand(struct scsi_cmnd *cmd,
 	struct ps3_storage_device *dev = priv->dev;
 	unsigned char opcode;
 	int res;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmd->device->host, cmd);
 #ifdef DEBUG
 	scsi_print_command(cmd);
 #endif
@@ -257,6 +260,7 @@ static int ps3rom_queuecommand(struct scsi_cmnd *cmd,
 		cmd->scsi_done(cmd);
 	}
 
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index b8166ec..ca34ed1 100644
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -733,7 +733,10 @@ qla1280_queuecommand(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *))
 	struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata;
 	struct srb *sp = (struct srb *)CMD_SP(cmd);
 	int status;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmd->device->host, cmd);
 	cmd->scsi_done = fn;
 	sp->cmd = cmd;
 	sp->flags = 0;
@@ -753,6 +756,7 @@ qla1280_queuecommand(struct scsi_cmnd *cmd, void (*fn)(struct scsi_cmnd *))
 #else
 	status = qla1280_32bit_start_scsi(ha, sp);
 #endif
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return status;
 }
 
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 800ea92..2c2224e 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -538,7 +538,10 @@ qla2xxx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
 	srb_t *sp;
 	int rval;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmd->device->host, cmd);
 	if (ha->flags.eeh_busy) {
 		if (ha->flags.pci_channel_io_perm_failure)
 			cmd->result = DID_NO_CONNECT << 16;
@@ -586,6 +589,7 @@ qla2xxx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 
 	spin_lock_irq(vha->host->host_lock);
 
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return 0;
 
 qc24_host_busy_free_sp:
@@ -594,14 +598,17 @@ qc24_host_busy_free_sp:
 
 qc24_host_busy_lock:
 	spin_lock_irq(vha->host->host_lock);
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return SCSI_MLQUEUE_HOST_BUSY;
 
 qc24_target_busy:
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return SCSI_MLQUEUE_TARGET_BUSY;
 
 qc24_fail_command:
 	done(cmd);
 
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 370d40f..568e61f 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -474,7 +474,10 @@ static int qla4xxx_queuecommand(struct scsi_cmnd *cmd,
 	struct iscsi_cls_session *sess = ddb_entry->sess;
 	struct srb *srb;
 	int rval;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmd->device->host, cmd);
 	if (test_bit(AF_EEH_BUSY, &ha->flags)) {
 		if (test_bit(AF_PCI_CHANNEL_IO_PERM_FAILURE, &ha->flags))
 			cmd->result = DID_NO_CONNECT << 16;
@@ -499,6 +502,7 @@ static int qla4xxx_queuecommand(struct scsi_cmnd *cmd,
 			cmd->result = DID_NO_CONNECT << 16;
 			goto qc_fail_command;
 		}
+		spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_TARGET_BUSY;
 	}
 
@@ -522,6 +526,7 @@ static int qla4xxx_queuecommand(struct scsi_cmnd *cmd,
 		goto qc_host_busy_free_sp;
 
 	spin_lock_irq(ha->host->host_lock);
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return 0;
 
 qc_host_busy_free_sp:
@@ -532,11 +537,13 @@ qc_host_busy_lock:
 	spin_lock_irq(ha->host->host_lock);
 
 qc_host_busy:
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return SCSI_MLQUEUE_HOST_BUSY;
 
 qc_fail_command:
 	done(cmd);
 
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/qlogicfas408.c b/drivers/scsi/qlogicfas408.c
index 1ad5155..4146a5f 100644
--- a/drivers/scsi/qlogicfas408.c
+++ b/drivers/scsi/qlogicfas408.c
@@ -443,6 +443,9 @@ int qlogicfas408_queuecommand(struct scsi_cmnd *cmd,
 			      void (*done) (struct scsi_cmnd *))
 {
 	struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd);
+	unsigned long irqflags;
+	spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmd->device->host, cmd);
 	if (scmd_id(cmd) == priv->qinitid) {
 		cmd->result = DID_BAD_TARGET << 16;
 		done(cmd);
@@ -456,6 +459,7 @@ int qlogicfas408_queuecommand(struct scsi_cmnd *cmd,
 		cpu_relax();
 	}
 	ql_icmd(cmd);
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c
index f8c561c..e1491e5 100644
--- a/drivers/scsi/qlogicpti.c
+++ b/drivers/scsi/qlogicpti.c
@@ -1010,7 +1010,10 @@ static int qlogicpti_queuecommand(struct scsi_cmnd *Cmnd, void (*done)(struct sc
 	struct Command_Entry *cmd;
 	u_int out_ptr;
 	int in_ptr;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(Cmnd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(Cmnd->device->host, Cmnd);
 	Cmnd->scsi_done = done;
 
 	in_ptr = qpti->req_in_ptr;
@@ -1037,6 +1040,7 @@ static int qlogicpti_queuecommand(struct scsi_cmnd *Cmnd, void (*done)(struct sc
 
 	update_can_queue(host, in_ptr, out_ptr);
 
+	spin_unlock_irqrestore(Cmnd->device->host->host_lock, irqflags);
 	return 0;
 
 toss_command:
@@ -1049,6 +1053,7 @@ toss_command:
 	 */
 	Cmnd->result = DID_BUS_BUSY;
 	done(Cmnd);
+	spin_unlock_irqrestore(Cmnd->device->host->host_lock, irqflags);
 	return 1;
 }
 
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 348fba0..d6d3c50 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -634,13 +634,15 @@ void scsi_log_completion(struct scsi_cmnd *cmd, int disposition)
  * Description: a serial number identifies a request for error recovery
  * and debugging purposes.  Protected by the Host_Lock of host.
  */
-static inline void scsi_cmd_get_serial(struct Scsi_Host *host, struct scsi_cmnd *cmd)
+void scsi_cmd_get_serial(struct Scsi_Host *host, struct scsi_cmnd *cmd)
 {
 	cmd->serial_number = host->cmd_serial_number++;
 	if (cmd->serial_number == 0) 
 		cmd->serial_number = host->cmd_serial_number++;
 }
 
+EXPORT_SYMBOL(scsi_cmd_get_serial);
+
 /**
  * scsi_dispatch_command - Dispatch a command to the low-level driver.
  * @cmd: command block we are dispatching.
@@ -651,7 +653,6 @@ static inline void scsi_cmd_get_serial(struct Scsi_Host *host, struct scsi_cmnd
 int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
 {
 	struct Scsi_Host *host = cmd->device->host;
-	unsigned long flags = 0;
 	unsigned long timeout;
 	int rtn = 0;
 
@@ -737,15 +738,6 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
 		goto out;
 	}
 
-	spin_lock_irqsave(host->host_lock, flags);
-	/*
-	 * AK: unlikely race here: for some reason the timer could
-	 * expire before the serial number is set up below.
-	 *
-	 * TODO: kill serial or move to blk layer
-	 */
-	scsi_cmd_get_serial(host, cmd); 
-
 	if (unlikely(host->shost_state == SHOST_DEL)) {
 		cmd->result = (DID_NO_CONNECT << 16);
 		scsi_done(cmd);
@@ -753,7 +745,6 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
 		trace_scsi_dispatch_cmd_start(cmd);
 		rtn = host->hostt->queuecommand(cmd, scsi_done);
 	}
-	spin_unlock_irqrestore(host->host_lock, flags);
 	if (rtn) {
 		trace_scsi_dispatch_cmd_error(cmd, rtn);
 		if (rtn != SCSI_MLQUEUE_DEVICE_BUSY &&
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c
index 9c73dbd..351872e 100644
--- a/drivers/scsi/stex.c
+++ b/drivers/scsi/stex.c
@@ -579,14 +579,19 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
 	unsigned int id, lun;
 	struct req_msg *req;
 	u16 tag;
+	unsigned long irqflags;
 
 	host = cmd->device->host;
+	spin_lock_irqsave(host->host_lock, irqflags);
+	scsi_cmd_get_serial(host, cmd);
 	id = cmd->device->id;
 	lun = cmd->device->lun;
 	hba = (struct st_hba *) &host->hostdata[0];
 
-	if (unlikely(hba->mu_status == MU_STATE_RESETTING))
+	if (unlikely(hba->mu_status == MU_STATE_RESETTING)) {
+		spin_unlock_irqrestore(host->host_lock, irqflags);
 		return SCSI_MLQUEUE_HOST_BUSY;
+	}
 
 	switch (cmd->cmnd[0]) {
 	case MODE_SENSE_10:
@@ -603,6 +608,8 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
 			done(cmd);
 		} else
 			stex_invalid_field(cmd, done);
+
+		spin_unlock_irqrestore(host->host_lock, irqflags);
 		return 0;
 	}
 	case REPORT_LUNS:
@@ -613,6 +620,8 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
 		 */
 		if (hba->cardtype == st_shasta || id == host->max_id - 1) {
 			stex_invalid_field(cmd, done);
+
+			spin_unlock_irqrestore(host->host_lock, irqflags);
 			return 0;
 		}
 		break;
@@ -620,6 +629,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
 		if (id == host->max_id - 1) {
 			cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
 			done(cmd);
+			spin_unlock_irqrestore(host->host_lock, irqflags);
 			return 0;
 		}
 		break;
@@ -627,6 +637,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
 		if (lun >= host->max_lun) {
 			cmd->result = DID_NO_CONNECT << 16;
 			done(cmd);
+			spin_unlock_irqrestore(host->host_lock, irqflags);
 			return 0;
 		}
 		if (id != host->max_id - 1)
@@ -639,6 +650,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
 			done(cmd);
 		} else
 			stex_invalid_field(cmd, done);
+		spin_unlock_irqrestore(host->host_lock, irqflags);
 		return 0;
 	case PASSTHRU_CMD:
 		if (cmd->cmnd[1] == PASSTHRU_GET_DRVVER) {
@@ -657,6 +669,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
 				DID_OK << 16 | COMMAND_COMPLETE << 8 :
 				DID_ERROR << 16 | COMMAND_COMPLETE << 8;
 			done(cmd);
+			spin_unlock_irqrestore(host->host_lock, irqflags);
 			return 0;
 		}
 	default:
@@ -667,8 +680,10 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
 
 	tag = cmd->request->tag;
 
-	if (unlikely(tag >= host->can_queue))
+	if (unlikely(tag >= host->can_queue)) {
+		spin_unlock_irqrestore(host->host_lock, irqflags);
 		return SCSI_MLQUEUE_HOST_BUSY;
+	}
 
 	req = hba->alloc_rq(hba);
 
@@ -695,6 +710,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
 	}
 
 	hba->send(hba, req, tag);
+	spin_unlock_irqrestore(host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c
index 713620e..82eaa21 100644
--- a/drivers/scsi/sun3_NCR5380.c
+++ b/drivers/scsi/sun3_NCR5380.c
@@ -914,6 +914,10 @@ static int NCR5380_queue_command(struct scsi_cmnd *cmd,
     SETUP_HOSTDATA(cmd->device->host);
     struct scsi_cmnd *tmp;
     unsigned long flags;
+    unsigned long irqflags;
+
+    spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+    scsi_cmd_get_serial(cmd->device->host);
 
 #if (NDEBUG & NDEBUG_NO_WRITE)
     switch (cmd->cmnd[0]) {
@@ -923,6 +927,8 @@ static int NCR5380_queue_command(struct scsi_cmnd *cmd,
 	       H_NO(cmd));
 	cmd->result = (DID_ERROR << 16);
 	done(cmd);
+
+        spin_lock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return 0;
     }
 #endif /* (NDEBUG & NDEBUG_NO_WRITE) */
@@ -1016,6 +1022,8 @@ static int NCR5380_queue_command(struct scsi_cmnd *cmd,
 	queue_main();
     else
 	NCR5380_main(NULL);
+
+    spin_lock_irqrestore(cmd->device->host->host_lock, irqflags);
     return 0;
 }
 
diff --git a/drivers/scsi/sym53c416.c b/drivers/scsi/sym53c416.c
index e5c369b..28e24d2 100644
--- a/drivers/scsi/sym53c416.c
+++ b/drivers/scsi/sym53c416.c
@@ -739,7 +739,10 @@ int sym53c416_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
 	int base;
 	unsigned long flags = 0;
 	int i;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(SCpnt->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(SCpnt->device->host, SCpnt);
 	/* Store base register as we can have more than one controller in the system */
 	base = SCpnt->device->host->io_port;
 	current_command = SCpnt;                  /* set current command                */
@@ -758,6 +761,7 @@ int sym53c416_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
 	outb(SEL_WITHOUT_ATN_SEQ, base + COMMAND_REG);
 	/* Now an interrupt will be generated which we will catch in out interrupt routine */
 	spin_unlock_irqrestore(&sym53c416_lock, flags);
+	spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
index 8b955b5..eb0734a 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -511,7 +511,10 @@ static int sym53c8xx_queue_command(struct scsi_cmnd *cmd,
 	struct sym_hcb *np = SYM_SOFTC_PTR(cmd);
 	struct sym_ucmd *ucp = SYM_UCMD_PTR(cmd);
 	int sts = 0;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmd->device->host, cmd);
 	cmd->scsi_done = done;
 	memset(ucp, 0, sizeof(*ucp));
 
@@ -527,12 +530,17 @@ static int sym53c8xx_queue_command(struct scsi_cmnd *cmd,
 		}
 	}
 
-	if (np->s.settle_time_valid)
+	if (np->s.settle_time_valid) {
+		spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_HOST_BUSY;
+	}
 
 	sts = sym_queue_command(np, cmd);
-	if (sts)
+	if (sts) {
+		spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_HOST_BUSY;
+	}
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c
index 27866b0..fca1761 100644
--- a/drivers/scsi/tmscsim.c
+++ b/drivers/scsi/tmscsim.c
@@ -1890,7 +1890,10 @@ static int DC390_queuecommand(struct scsi_cmnd *cmd,
 	struct dc390_acb *acb = (struct dc390_acb *)sdev->host->hostdata;
 	struct dc390_dcb *dcb = sdev->hostdata;
 	struct dc390_srb *srb;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmd->device->host, cmd);
 	if (sdev->queue_depth <= dcb->GoingSRBCnt)
 		goto device_busy;
 	if (acb->pActiveDCB)
@@ -1935,9 +1938,11 @@ static int DC390_queuecommand(struct scsi_cmnd *cmd,
 
 	dc390_Going_append(dcb, srb);
 
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return 0;
 
  host_busy:
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return SCSI_MLQUEUE_HOST_BUSY;
 
  device_busy:
diff --git a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c
index 5d9fdee..2345891 100644
--- a/drivers/scsi/u14-34f.c
+++ b/drivers/scsi/u14-34f.c
@@ -1251,7 +1251,10 @@ static void scsi_to_dev_dir(unsigned int i, unsigned int j) {
 static int u14_34f_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) {
    unsigned int i, j, k;
    struct mscp *cpp;
+   unsigned long irqflags;
 
+   spin_lock_irqsave(SCpnt->device->host->host_lock, irqflags);
+   scsi_cmd_get_serial(SCpnt->device->host, SCpnt);
    /* j is the board number */
    j = ((struct hostdata *) SCpnt->device->host->hostdata)->board_number;
 
@@ -1275,6 +1278,7 @@ static int u14_34f_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scs
 
    if (k == sh[j]->can_queue) {
       printk("%s: qcomm, no free mailbox.\n", BN(j));
+      spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
       return 1;
       }
 
@@ -1308,6 +1312,7 @@ static int u14_34f_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scs
                                      && TLDEV(SCpnt->device->type)) {
       HD(j)->cp_stat[i] = READY;
       flush_dev(SCpnt->device, blk_rq_pos(SCpnt->request), j, FALSE);
+      spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
       return 0;
       }
 
@@ -1316,6 +1321,7 @@ static int u14_34f_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scs
       SCpnt->host_scribble = NULL;
       scmd_printk(KERN_INFO, SCpnt,
       		"qcomm, pid %ld, adapter busy.\n", SCpnt->serial_number);
+      spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
       return 1;
       }
 
@@ -1326,6 +1332,7 @@ static int u14_34f_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scs
    outb(CMD_OGM_INTR, sh[j]->io_port + REG_LCL_INTR);
 
    HD(j)->cp_stat[i] = IN_USE;
+   spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
    return 0;
 }
 
diff --git a/drivers/scsi/ultrastor.c b/drivers/scsi/ultrastor.c
index 27aa40f..d3b968f 100644
--- a/drivers/scsi/ultrastor.c
+++ b/drivers/scsi/ultrastor.c
@@ -708,6 +708,10 @@ static int ultrastor_queuecommand(struct scsi_cmnd *SCpnt,
     int mscp_index;
 #endif
     unsigned int status;
+    unsigned long irqflags;
+
+    spin_lock_irqsave(SCpnt->device->host->host_lock, irqflags);
+    scsi_cmd_get_serial(SCpnt->device->host, SCpnt);
 
     /* Next test is for debugging; "can't happen" */
     if ((config.mscp_free & ((1U << ULTRASTOR_MAX_CMDS) - 1)) == 0)
@@ -800,8 +804,10 @@ retry:
 #if ULTRASTOR_MAX_CMDS > 1
 	SCpnt->result = status;
 	done(SCpnt);
+        spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 	return 0;
 #else
+        spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 	return status;
 #endif
     }
@@ -822,6 +828,7 @@ retry:
     printk("USx4F: queuecommand: returning\n");
 #endif
 
+    spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
     return 0;
 }
 
diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c
index 2689445..36e3dfb 100644
--- a/drivers/scsi/vmw_pvscsi.c
+++ b/drivers/scsi/vmw_pvscsi.c
@@ -697,6 +697,9 @@ static int pvscsi_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 	struct pvscsi_ctx *ctx;
 	unsigned long flags;
 
+	unsigned long irqflags;
+	spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmd->device->host, cmd);
 	spin_lock_irqsave(&adapter->hw_lock, flags);
 
 	ctx = pvscsi_acquire_context(adapter, cmd);
@@ -704,6 +707,7 @@ static int pvscsi_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 		if (ctx)
 			pvscsi_release_context(adapter, ctx);
 		spin_unlock_irqrestore(&adapter->hw_lock, flags);
+		spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_HOST_BUSY;
 	}
 
@@ -716,6 +720,7 @@ static int pvscsi_queue(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
 
 	pvscsi_kick_io(adapter, cmd->cmnd[0]);
 
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c
index b701bf2..d552930 100644
--- a/drivers/scsi/wd33c93.c
+++ b/drivers/scsi/wd33c93.c
@@ -377,7 +377,10 @@ wd33c93_queuecommand(struct scsi_cmnd *cmd,
 {
 	struct WD33C93_hostdata *hostdata;
 	struct scsi_cmnd *tmp;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(cmd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmd->device->host, cmd);
 	hostdata = (struct WD33C93_hostdata *) cmd->device->host->hostdata;
 
 	DB(DB_QUEUE_COMMAND,
@@ -464,7 +467,8 @@ wd33c93_queuecommand(struct scsi_cmnd *cmd,
 
 	DB(DB_QUEUE_COMMAND, printk(")Q-%ld ", cmd->serial_number))
 
-	spin_unlock_irq(&hostdata->lock);
+	spin_unlock(&hostdata->lock);
+	spin_unlock_irqrestore(cmd->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c
index 333580b..70ff71b 100644
--- a/drivers/scsi/wd7000.c
+++ b/drivers/scsi/wd7000.c
@@ -1092,7 +1092,10 @@ static int wd7000_queuecommand(struct scsi_cmnd *SCpnt,
 	short cdblen;
 	int nseg;
 	Adapter *host = (Adapter *) SCpnt->device->host->hostdata;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(SCpnt->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(SCpnt->device->host, SCpnt);
 	cdblen = SCpnt->cmd_len;
 	idlun = ((SCpnt->device->id << 5) & 0xe0) | (SCpnt->device->lun & 7);
 	SCpnt->scsi_done = done;
@@ -1136,6 +1139,7 @@ static int wd7000_queuecommand(struct scsi_cmnd *SCpnt,
 	while (!mail_out(host, scb))
 		cpu_relax();	/* keep trying */
 
+	spin_unlock_irqrestore(SCpnt->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index 62882a4..7d19576 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -616,6 +616,10 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd,
 	int i;
 	struct scatterlist *sgl;
 	unsigned int sg_count = 0;
+	unsigned long irqflags;
+
+	spin_lock_irqsave(scmnd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(scmnd->device->host, scmnd);
 
 	DPRINT_DBG(STORVSC_DRV, "scmnd %p dir %d, use_sg %d buf %p len %d "
 		   "queue depth %d tagged %d", scmnd, scmnd->sc_data_direction,
@@ -648,6 +652,8 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd,
 		DPRINT_ERR(STORVSC_DRV, "scmnd (%p) - unable to allocate "
 			   "storvsc_cmd_request...marking queue busy", scmnd);
 		scmnd->scsi_done = NULL;
+
+		spin_unlock_irqrestore(scmnd->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_DEVICE_BUSY;
 	}
 
@@ -718,6 +724,7 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd,
 				kmem_cache_free(host_device_ctx->request_pool,
 						cmd_request);
 
+				spin_unlock_irqrestore(scmnd->device->host->host_lock, irqflags);
 				return SCSI_MLQUEUE_HOST_BUSY;
 			}
 
@@ -782,6 +789,7 @@ retry_request:
 		ret = SCSI_MLQUEUE_DEVICE_BUSY;
 	}
 
+	spin_unlock_irqrestore(scmnd->device->host->host_lock, irqflags);
 	return ret;
 }
 
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c
index 5a47805..7543420 100644
--- a/drivers/usb/image/microtek.c
+++ b/drivers/usb/image/microtek.c
@@ -578,7 +578,10 @@ mts_scsi_queuecommand(struct scsi_cmnd *srb, mts_scsi_cmnd_callback callback)
 	struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]);
 	int err = 0;
 	int res;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(srb->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(srb->device->host, srb);
 	MTS_DEBUG_GOT_HERE();
 	mts_show_command(srb);
 	mts_debug_dump(desc);
@@ -623,6 +626,7 @@ mts_scsi_queuecommand(struct scsi_cmnd *srb, mts_scsi_cmnd_callback callback)
 
 	}
 out:
+	spin_unlock_irqrestore(srb->device->host->host_lock, irqflags);
 	return err;
 }
 
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index a688b1e..f1b0aa9 100644
--- a/drivers/usb/storage/scsiglue.c
+++ b/drivers/usb/storage/scsiglue.c
@@ -289,13 +289,17 @@ static int queuecommand(struct scsi_cmnd *srb,
 			void (*done)(struct scsi_cmnd *))
 {
 	struct us_data *us = host_to_us(srb->device->host);
+	unsigned long irqflags;
 
+	spin_lock_irqsave(srb->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(srb->device->host, srb);
 	US_DEBUGP("%s called\n", __func__);
 
 	/* check for state-transition errors */
 	if (us->srb != NULL) {
 		printk(KERN_ERR USB_STORAGE "Error in %s: us->srb = %p\n",
 			__func__, us->srb);
+		spin_unlock_irqrestore(srb->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_HOST_BUSY;
 	}
 
@@ -304,6 +308,7 @@ static int queuecommand(struct scsi_cmnd *srb,
 		US_DEBUGP("Fail command during disconnect\n");
 		srb->result = DID_NO_CONNECT << 16;
 		done(srb);
+		spin_unlock_irqrestore(srb->device->host->host_lock, irqflags);
 		return 0;
 	}
 
@@ -312,6 +317,7 @@ static int queuecommand(struct scsi_cmnd *srb,
 	us->srb = srb;
 	complete(&us->cmnd_ready);
 
+	spin_unlock_irqrestore(srb->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
index 2054b1e..d00db31 100644
--- a/drivers/usb/storage/uas.c
+++ b/drivers/usb/storage/uas.c
@@ -440,11 +440,16 @@ static int uas_queuecommand(struct scsi_cmnd *cmnd,
 	struct uas_dev_info *devinfo = sdev->hostdata;
 	struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
 	int err;
+	unsigned long irqflags;
 
+	spin_lock_irqsave(cmnd->device->host->host_lock, irqflags);
+	scsi_cmd_get_serial(cmnd->device->host, cmnd);
 	BUILD_BUG_ON(sizeof(struct uas_cmd_info) > sizeof(struct scsi_pointer));
 
-	if (!cmdinfo->sense_urb && sdev->current_cmnd)
+	if (!cmdinfo->sense_urb && sdev->current_cmnd) {
+		spin_unlock_irqrestore(cmnd->device->host->host_lock, irqflags);
 		return SCSI_MLQUEUE_DEVICE_BUSY;
+	}
 
 	if (blk_rq_tagged(cmnd->request)) {
 		cmdinfo->stream = cmnd->request->tag + 1;
@@ -480,6 +485,7 @@ static int uas_queuecommand(struct scsi_cmnd *cmnd,
 		/* If we did nothing, give up now */
 		if (cmdinfo->state & SUBMIT_SENSE_URB) {
 			usb_free_urb(cmdinfo->sense_urb);
+			spin_unlock_irqrestore(cmnd->device->host->host_lock, irqflags);
 			return SCSI_MLQUEUE_DEVICE_BUSY;
 		}
 		spin_lock(&uas_work_lock);
@@ -488,6 +494,7 @@ static int uas_queuecommand(struct scsi_cmnd *cmnd,
 		schedule_work(&uas_work);
 	}
 
+	spin_unlock_irqrestore(cmnd->device->host->host_lock, irqflags);
 	return 0;
 }
 
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index d0a6a84..99a2da7 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -881,5 +881,6 @@ static inline unsigned char scsi_host_get_guard(struct Scsi_Host *shost)
 extern struct Scsi_Host *scsi_register(struct scsi_host_template *, int);
 extern void scsi_unregister(struct Scsi_Host *);
 extern int scsi_host_set_state(struct Scsi_Host *, enum scsi_host_state);
+extern void scsi_cmd_get_serial(struct Scsi_Host *host, struct scsi_cmnd *cmd);
 
 #endif /* _SCSI_SCSI_HOST_H */
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux