diff options
Diffstat (limited to 'drivers/scsi/scsi.c')
-rw-r--r-- | drivers/scsi/scsi.c | 18 |
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 | */ |
637 | static inline void scsi_cmd_get_serial(struct Scsi_Host *host, struct scsi_cmnd *cmd) | 637 | void 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 | } |
643 | EXPORT_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 | |||
651 | int scsi_dispatch_cmd(struct scsi_cmnd *cmd) | 652 | int 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 && |