aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi.c')
-rw-r--r--drivers/scsi/scsi.c18
1 files changed, 5 insertions, 13 deletions
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 348fba0a8976..2aeb2e9c4d3b 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -634,12 +634,13 @@ void scsi_log_completion(struct scsi_cmnd *cmd, int disposition)
634 * Description: a serial number identifies a request for error recovery 634 * Description: a serial number identifies a request for error recovery
635 * and debugging purposes. Protected by the Host_Lock of host. 635 * and debugging purposes. Protected by the Host_Lock of host.
636 */ 636 */
637static inline void scsi_cmd_get_serial(struct Scsi_Host *host, struct scsi_cmnd *cmd) 637void scsi_cmd_get_serial(struct Scsi_Host *host, struct scsi_cmnd *cmd)
638{ 638{
639 cmd->serial_number = host->cmd_serial_number++; 639 cmd->serial_number = host->cmd_serial_number++;
640 if (cmd->serial_number == 0) 640 if (cmd->serial_number == 0)
641 cmd->serial_number = host->cmd_serial_number++; 641 cmd->serial_number = host->cmd_serial_number++;
642} 642}
643EXPORT_SYMBOL(scsi_cmd_get_serial);
643 644
644/** 645/**
645 * scsi_dispatch_command - Dispatch a command to the low-level driver. 646 * scsi_dispatch_command - Dispatch a command to the low-level driver.
@@ -651,7 +652,6 @@ static inline void scsi_cmd_get_serial(struct Scsi_Host *host, struct scsi_cmnd
651int scsi_dispatch_cmd(struct scsi_cmnd *cmd) 652int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
652{ 653{
653 struct Scsi_Host *host = cmd->device->host; 654 struct Scsi_Host *host = cmd->device->host;
654 unsigned long flags = 0;
655 unsigned long timeout; 655 unsigned long timeout;
656 int rtn = 0; 656 int rtn = 0;
657 657
@@ -737,23 +737,15 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
737 goto out; 737 goto out;
738 } 738 }
739 739
740 spin_lock_irqsave(host->host_lock, flags);
741 /*
742 * AK: unlikely race here: for some reason the timer could
743 * expire before the serial number is set up below.
744 *
745 * TODO: kill serial or move to blk layer
746 */
747 scsi_cmd_get_serial(host, cmd);
748
749 if (unlikely(host->shost_state == SHOST_DEL)) { 740 if (unlikely(host->shost_state == SHOST_DEL)) {
750 cmd->result = (DID_NO_CONNECT << 16); 741 cmd->result = (DID_NO_CONNECT << 16);
751 scsi_done(cmd); 742 scsi_done(cmd);
752 } else { 743 } else {
753 trace_scsi_dispatch_cmd_start(cmd); 744 trace_scsi_dispatch_cmd_start(cmd);
754 rtn = host->hostt->queuecommand(cmd, scsi_done); 745 cmd->scsi_done = scsi_done;
746 rtn = host->hostt->queuecommand(host, cmd);
755 } 747 }
756 spin_unlock_irqrestore(host->host_lock, flags); 748
757 if (rtn) { 749 if (rtn) {
758 trace_scsi_dispatch_cmd_error(cmd, rtn); 750 trace_scsi_dispatch_cmd_error(cmd, rtn);
759 if (rtn != SCSI_MLQUEUE_DEVICE_BUSY && 751 if (rtn != SCSI_MLQUEUE_DEVICE_BUSY &&