summaryrefslogtreecommitdiff
path: root/drivers/scsi/qla4xxx/ql4_mbx.c
diff options
context:
space:
mode:
authorVikas Chaudhary <vikas.chaudhary@qlogic.com>2012-11-23 06:58:38 -0500
committerJames Bottomley <JBottomley@Parallels.com>2013-01-29 13:55:06 +1100
commit5c19b92ae82a2b39add78b2d2bc1c4e4d7c4d2ec (patch)
tree6c90d253925988191a522e0f718a871110fe646a /drivers/scsi/qla4xxx/ql4_mbx.c
parent8108de9739abeec72f4811532109695e245df42a (diff)
[SCSI] qla4xxx: Fix MBOX intr switching from polling to intr mode for ISP83XX
Issue: Mailbox command timed out after switching from polling mode to interrupt mode. Events:- 1. Mailbox interrupts are disabled 2. FW generates AEN and at same time driver enables Mailbox Interrupt 3. Driver issues new mailbox to Firmware In above case driver will not get AEN interrupts generated by FW in step #2 as FW generated this AEN when interrupts are disabled. During the same time driver enabled the mailbox interrupt, so driver will not poll for interrupt. Driver will never process AENs generated in step #2 and issues new mailbox to FW, but now FW is not able to post mailbox completion as AENs generated before are not processed by driver. Fix: Enable Mailbox / AEN interrupts before initializing FW in case of ISP83XX. This will make sure we process all Mailbox and AENs in interrupt mode. Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/qla4xxx/ql4_mbx.c')
-rw-r--r--drivers/scsi/qla4xxx/ql4_mbx.c41
1 files changed, 30 insertions, 11 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c
index 3d41034191f0..1c57c227c808 100644
--- a/drivers/scsi/qla4xxx/ql4_mbx.c
+++ b/drivers/scsi/qla4xxx/ql4_mbx.c
@@ -44,6 +44,30 @@ void qla4xxx_process_mbox_intr(struct scsi_qla_host *ha, int out_count)
}
/**
+ * qla4xxx_is_intr_poll_mode – Are we allowed to poll for interrupts?
+ * @ha: Pointer to host adapter structure.
+ * @ret: 1=polling mode, 0=non-polling mode
+ **/
+static int qla4xxx_is_intr_poll_mode(struct scsi_qla_host *ha)
+{
+ int rval = 1;
+
+ if (is_qla8032(ha)) {
+ if (test_bit(AF_IRQ_ATTACHED, &ha->flags) &&
+ test_bit(AF_83XX_MBOX_INTR_ON, &ha->flags))
+ rval = 0;
+ } else {
+ if (test_bit(AF_IRQ_ATTACHED, &ha->flags) &&
+ test_bit(AF_INTERRUPTS_ON, &ha->flags) &&
+ test_bit(AF_ONLINE, &ha->flags) &&
+ !test_bit(AF_HA_REMOVAL, &ha->flags))
+ rval = 0;
+ }
+
+ return rval;
+}
+
+/**
* qla4xxx_mailbox_command - issues mailbox commands
* @ha: Pointer to host adapter structure.
* @inCount: number of mailbox registers to load.
@@ -153,33 +177,28 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
/*
* Wait for completion: Poll or completion queue
*/
- if (test_bit(AF_IRQ_ATTACHED, &ha->flags) &&
- test_bit(AF_INTERRUPTS_ON, &ha->flags) &&
- test_bit(AF_ONLINE, &ha->flags) &&
- !test_bit(AF_HA_REMOVAL, &ha->flags)) {
- /* Do not poll for completion. Use completion queue */
- set_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags);
- wait_for_completion_timeout(&ha->mbx_intr_comp, MBOX_TOV * HZ);
- clear_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags);
- } else {
+ if (qla4xxx_is_intr_poll_mode(ha)) {
/* Poll for command to complete */
wait_count = jiffies + MBOX_TOV * HZ;
while (test_bit(AF_MBOX_COMMAND_DONE, &ha->flags) == 0) {
if (time_after_eq(jiffies, wait_count))
break;
-
/*
* Service the interrupt.
* The ISR will save the mailbox status registers
* to a temporary storage location in the adapter
* structure.
*/
-
spin_lock_irqsave(&ha->hardware_lock, flags);
ha->isp_ops->process_mailbox_interrupt(ha, outCount);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
msleep(10);
}
+ } else {
+ /* Do not poll for completion. Use completion queue */
+ set_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags);
+ wait_for_completion_timeout(&ha->mbx_intr_comp, MBOX_TOV * HZ);
+ clear_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags);
}
/* Check for mailbox timeout. */