diff options
Diffstat (limited to 'drivers/scsi/scsi.c')
| -rw-r--r-- | drivers/scsi/scsi.c | 22 |
1 files changed, 7 insertions, 15 deletions
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index ad0ed212db4a..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 && |
| @@ -1046,13 +1038,13 @@ int scsi_get_vpd_page(struct scsi_device *sdev, u8 page, unsigned char *buf, | |||
| 1046 | 1038 | ||
| 1047 | /* If the user actually wanted this page, we can skip the rest */ | 1039 | /* If the user actually wanted this page, we can skip the rest */ |
| 1048 | if (page == 0) | 1040 | if (page == 0) |
| 1049 | return -EINVAL; | 1041 | return 0; |
| 1050 | 1042 | ||
| 1051 | for (i = 0; i < min((int)buf[3], buf_len - 4); i++) | 1043 | for (i = 0; i < min((int)buf[3], buf_len - 4); i++) |
| 1052 | if (buf[i + 4] == page) | 1044 | if (buf[i + 4] == page) |
| 1053 | goto found; | 1045 | goto found; |
| 1054 | 1046 | ||
| 1055 | if (i < buf[3] && i > buf_len) | 1047 | if (i < buf[3] && i >= buf_len - 4) |
| 1056 | /* ran off the end of the buffer, give us benefit of doubt */ | 1048 | /* ran off the end of the buffer, give us benefit of doubt */ |
| 1057 | goto found; | 1049 | goto found; |
| 1058 | /* The device claims it doesn't support the requested page */ | 1050 | /* The device claims it doesn't support the requested page */ |
