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 /drivers/scsi/qla2xxx | |
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>
Diffstat (limited to 'drivers/scsi/qla2xxx')
-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); |