diff options
| author | Mike Christie <michaelc@cs.wisc.edu> | 2010-10-15 14:27:47 -0400 |
|---|---|---|
| committer | James Bottomley <James.Bottomley@suse.de> | 2010-10-25 17:03:39 -0400 |
| commit | 170babc3721997b7808193221f94926df44f3d1e (patch) | |
| tree | cc7da8745df750c69047cc0529959a4d682cefb4 | |
| parent | e30d1756480dc5d139458b140b69873cdb10119f (diff) | |
[SCSI] qla2xxx: Drop srb reference before waiting for completion.
This patch fixes a regression introduced by commit
083a469db4ecf3b286a96b5b722c37fc1affe0be
qla2xxx_eh_wait_on_command() is waiting for an srb to
complete, which will never happen as the routine took
a reference to the srb previously and will only drop it
after this function. So every command abort will fail.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: Madhuranath Iyengar <Madhu.Iyengar@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
| -rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 61 |
1 files changed, 20 insertions, 41 deletions
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 05977e736f76..02232deaf82d 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
| @@ -830,62 +830,44 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
| 830 | { | 830 | { |
| 831 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); | 831 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); |
| 832 | srb_t *sp; | 832 | srb_t *sp; |
| 833 | int ret, i; | 833 | int ret; |
| 834 | unsigned int id, lun; | 834 | unsigned int id, lun; |
| 835 | unsigned long flags; | 835 | unsigned long flags; |
| 836 | int wait = 0; | 836 | int wait = 0; |
| 837 | struct qla_hw_data *ha = vha->hw; | 837 | struct qla_hw_data *ha = vha->hw; |
| 838 | struct req_que *req = vha->req; | ||
| 839 | srb_t *spt; | ||
| 840 | int got_ref = 0; | ||
| 841 | 838 | ||
| 842 | fc_block_scsi_eh(cmd); | 839 | fc_block_scsi_eh(cmd); |
| 843 | 840 | ||
| 844 | if (!CMD_SP(cmd)) | 841 | if (!CMD_SP(cmd)) |
| 845 | return SUCCESS; | 842 | return SUCCESS; |
| 846 | 843 | ||
| 847 | ret = SUCCESS; | ||
| 848 | |||
| 849 | id = cmd->device->id; | 844 | id = cmd->device->id; |
| 850 | lun = cmd->device->lun; | 845 | lun = cmd->device->lun; |
| 851 | spt = (srb_t *) CMD_SP(cmd); | ||
| 852 | if (!spt) | ||
| 853 | return SUCCESS; | ||
| 854 | 846 | ||
| 855 | /* Check active list for command command. */ | ||
| 856 | spin_lock_irqsave(&ha->hardware_lock, flags); | 847 | spin_lock_irqsave(&ha->hardware_lock, flags); |
| 857 | for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) { | 848 | sp = (srb_t *) CMD_SP(cmd); |
| 858 | sp = req->outstanding_cmds[i]; | 849 | if (!sp) { |
| 859 | 850 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | |
| 860 | if (sp == NULL) | 851 | return SUCCESS; |
| 861 | continue; | 852 | } |
| 862 | if ((sp->ctx) && !(sp->flags & SRB_FCP_CMND_DMA_VALID) && | ||
| 863 | !IS_PROT_IO(sp)) | ||
| 864 | continue; | ||
| 865 | if (sp->cmd != cmd) | ||
| 866 | continue; | ||
| 867 | 853 | ||
| 868 | DEBUG2(printk("%s(%ld): aborting sp %p from RISC.", | 854 | DEBUG2(printk("%s(%ld): aborting sp %p from RISC.", |
| 869 | __func__, vha->host_no, sp)); | 855 | __func__, vha->host_no, sp)); |
| 870 | 856 | ||
| 871 | /* Get a reference to the sp and drop the lock.*/ | 857 | /* Get a reference to the sp and drop the lock.*/ |
| 872 | sp_get(sp); | 858 | sp_get(sp); |
| 873 | got_ref++; | ||
| 874 | 859 | ||
| 875 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
| 876 | if (ha->isp_ops->abort_command(sp)) { | ||
| 877 | DEBUG2(printk("%s(%ld): abort_command " | ||
| 878 | "mbx failed.\n", __func__, vha->host_no)); | ||
| 879 | ret = FAILED; | ||
| 880 | } else { | ||
| 881 | DEBUG3(printk("%s(%ld): abort_command " | ||
| 882 | "mbx success.\n", __func__, vha->host_no)); | ||
| 883 | wait = 1; | ||
| 884 | } | ||
| 885 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
| 886 | break; | ||
| 887 | } | ||
| 888 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 860 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
| 861 | if (ha->isp_ops->abort_command(sp)) { | ||
| 862 | DEBUG2(printk("%s(%ld): abort_command " | ||
| 863 | "mbx failed.\n", __func__, vha->host_no)); | ||
| 864 | ret = FAILED; | ||
| 865 | } else { | ||
| 866 | DEBUG3(printk("%s(%ld): abort_command " | ||
| 867 | "mbx success.\n", __func__, vha->host_no)); | ||
| 868 | wait = 1; | ||
| 869 | } | ||
| 870 | qla2x00_sp_compl(ha, sp); | ||
| 889 | 871 | ||
| 890 | /* Wait for the command to be returned. */ | 872 | /* Wait for the command to be returned. */ |
| 891 | if (wait) { | 873 | if (wait) { |
| @@ -897,9 +879,6 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
| 897 | } | 879 | } |
| 898 | } | 880 | } |
| 899 | 881 | ||
| 900 | if (got_ref) | ||
| 901 | qla2x00_sp_compl(ha, sp); | ||
| 902 | |||
| 903 | qla_printk(KERN_INFO, ha, | 882 | qla_printk(KERN_INFO, ha, |
| 904 | "scsi(%ld:%d:%d): Abort command issued -- %d %x.\n", | 883 | "scsi(%ld:%d:%d): Abort command issued -- %d %x.\n", |
| 905 | vha->host_no, id, lun, wait, ret); | 884 | vha->host_no, id, lun, wait, ret); |
