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