aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_nx.c
diff options
context:
space:
mode:
authorgurinder.shergill@hp.com <gurinder.shergill@hp.com>2013-04-23 13:13:17 -0400
committerJames Bottomley <JBottomley@Parallels.com>2013-05-12 15:51:15 -0400
commit364398324c901bc834f762eb5443d2e5a1d2a0db (patch)
tree9041d31c3d28f2a77cc9e65e131134a5c9a904f5 /drivers/scsi/qla2xxx/qla_nx.c
parentf722406faae2d073cc1d01063d1123c35425939e (diff)
[SCSI] qla2xxx: Fix for locking issue between driver ISR and mailbox routines
The driver uses ha->mbx_cmd_flags variable to pass information between its ISR and mailbox routines, however, it does so without the protection of any locks. Under certain conditions, this can lead to multiple mailbox command completions being signaled, which, in turn, leads to a false mailbox timeout error for the subsequently issued mailbox command. The issue occurs frequently but intermittenly with the Qlogic 8GFC mezz card during card initialization, resulting in card initialization failure. Signed-off-by: Gurinder (Sunny) Shergill <gurinder.shergill@hp.com> Acked-by: Saurav Kashyap <saurav.kashyap@qlogic.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_nx.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_nx.c26
1 files changed, 10 insertions, 16 deletions
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c
index 10754f518303..cce0cd0d7ec4 100644
--- a/drivers/scsi/qla2xxx/qla_nx.c
+++ b/drivers/scsi/qla2xxx/qla_nx.c
@@ -2074,9 +2074,6 @@ qla82xx_intr_handler(int irq, void *dev_id)
2074 } 2074 }
2075 WRT_REG_DWORD(&reg->host_int, 0); 2075 WRT_REG_DWORD(&reg->host_int, 0);
2076 } 2076 }
2077 spin_unlock_irqrestore(&ha->hardware_lock, flags);
2078 if (!ha->flags.msi_enabled)
2079 qla82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff);
2080 2077
2081#ifdef QL_DEBUG_LEVEL_17 2078#ifdef QL_DEBUG_LEVEL_17
2082 if (!irq && ha->flags.eeh_busy) 2079 if (!irq && ha->flags.eeh_busy)
@@ -2085,11 +2082,12 @@ qla82xx_intr_handler(int irq, void *dev_id)
2085 status, ha->mbx_cmd_flags, ha->flags.mbox_int, stat); 2082 status, ha->mbx_cmd_flags, ha->flags.mbox_int, stat);
2086#endif 2083#endif
2087 2084
2088 if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && 2085 qla2x00_handle_mbx_completion(ha, status);
2089 (status & MBX_INTERRUPT) && ha->flags.mbox_int) { 2086 spin_unlock_irqrestore(&ha->hardware_lock, flags);
2090 set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); 2087
2091 complete(&ha->mbx_intr_comp); 2088 if (!ha->flags.msi_enabled)
2092 } 2089 qla82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff);
2090
2093 return IRQ_HANDLED; 2091 return IRQ_HANDLED;
2094} 2092}
2095 2093
@@ -2149,8 +2147,6 @@ qla82xx_msix_default(int irq, void *dev_id)
2149 WRT_REG_DWORD(&reg->host_int, 0); 2147 WRT_REG_DWORD(&reg->host_int, 0);
2150 } while (0); 2148 } while (0);
2151 2149
2152 spin_unlock_irqrestore(&ha->hardware_lock, flags);
2153
2154#ifdef QL_DEBUG_LEVEL_17 2150#ifdef QL_DEBUG_LEVEL_17
2155 if (!irq && ha->flags.eeh_busy) 2151 if (!irq && ha->flags.eeh_busy)
2156 ql_log(ql_log_warn, vha, 0x5044, 2152 ql_log(ql_log_warn, vha, 0x5044,
@@ -2158,11 +2154,9 @@ qla82xx_msix_default(int irq, void *dev_id)
2158 status, ha->mbx_cmd_flags, ha->flags.mbox_int, stat); 2154 status, ha->mbx_cmd_flags, ha->flags.mbox_int, stat);
2159#endif 2155#endif
2160 2156
2161 if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && 2157 qla2x00_handle_mbx_completion(ha, status);
2162 (status & MBX_INTERRUPT) && ha->flags.mbox_int) { 2158 spin_unlock_irqrestore(&ha->hardware_lock, flags);
2163 set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); 2159
2164 complete(&ha->mbx_intr_comp);
2165 }
2166 return IRQ_HANDLED; 2160 return IRQ_HANDLED;
2167} 2161}
2168 2162
@@ -3345,7 +3339,7 @@ void qla82xx_clear_pending_mbx(scsi_qla_host_t *vha)
3345 ha->flags.mbox_busy = 0; 3339 ha->flags.mbox_busy = 0;
3346 ql_log(ql_log_warn, vha, 0x6010, 3340 ql_log(ql_log_warn, vha, 0x6010,
3347 "Doing premature completion of mbx command.\n"); 3341 "Doing premature completion of mbx command.\n");
3348 if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags)) 3342 if (test_and_clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags))
3349 complete(&ha->mbx_intr_comp); 3343 complete(&ha->mbx_intr_comp);
3350 } 3344 }
3351} 3345}