[SCSI] qla4xxx: Disable generating pause frames in case of FW hung
authorGiridhar Malavali <giridhar.malavali@qlogic.com>
Wed, 11 Jan 2012 10:44:16 +0000 (02:44 -0800)
committerJames Bottomley <JBottomley@Parallels.com>
Mon, 16 Jan 2012 08:32:08 +0000 (12:32 +0400)
In case of FW hung  ISP82xx generates continuous pause frames
which causes switch to disable port.
Added fix to disable generating pause frames in case of
FW hung

Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
Reviewed-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
drivers/scsi/qla4xxx/ql4_mbx.c
drivers/scsi/qla4xxx/ql4_nx.h
drivers/scsi/qla4xxx/ql4_os.c

index c259378..e1e66a4 100644 (file)
@@ -219,6 +219,13 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
                ha->mailbox_timeout_count++;
                mbx_sts[0] = (-1);
                set_bit(DPC_RESET_HA, &ha->dpc_flags);
+               if (is_qla8022(ha)) {
+                       ql4_printk(KERN_INFO, ha,
+                                  "disabling pause transmit on port 0 & 1.\n");
+                       qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0x98,
+                                       CRB_NIU_XG_PAUSE_CTL_P0 |
+                                       CRB_NIU_XG_PAUSE_CTL_P1);
+               }
                goto mbox_exit;
        }
 
index cfb2f2e..dc45ac9 100644 (file)
@@ -39,6 +39,9 @@ enum {
        QLA82XX_TEMP_PANIC      /* Fatal error, hardware has shut down. */
 };
 
+#define CRB_NIU_XG_PAUSE_CTL_P0                0x1
+#define CRB_NIU_XG_PAUSE_CTL_P1                0x8
+
 #define QLA82XX_HW_H0_CH_HUB_ADR       0x05
 #define QLA82XX_HW_H1_CH_HUB_ADR       0x0E
 #define QLA82XX_HW_H2_CH_HUB_ADR       0x03
index 9d3eab5..e2ef776 100644 (file)
@@ -2080,6 +2080,11 @@ void qla4_8xxx_watchdog(struct scsi_qla_host *ha)
                dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
 
                if (qla4_8xxx_check_temp(ha)) {
+                       ql4_printk(KERN_INFO, ha, "disabling pause"
+                                  " transmit on port 0 & 1.\n");
+                       qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0x98,
+                                       CRB_NIU_XG_PAUSE_CTL_P0 |
+                                       CRB_NIU_XG_PAUSE_CTL_P1);
                        set_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags);
                        qla4xxx_wake_dpc(ha);
                } else if (dev_state == QLA82XX_DEV_NEED_RESET &&
@@ -2099,6 +2104,11 @@ void qla4_8xxx_watchdog(struct scsi_qla_host *ha)
                } else  {
                        /* Check firmware health */
                        if (qla4_8xxx_check_fw_alive(ha)) {
+                               ql4_printk(KERN_INFO, ha, "disabling pause"
+                                          " transmit on port 0 & 1.\n");
+                               qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0x98,
+                                               CRB_NIU_XG_PAUSE_CTL_P0 |
+                                               CRB_NIU_XG_PAUSE_CTL_P1);
                                halt_status = qla4_8xxx_rd_32(ha,
                                                QLA82XX_PEG_HALT_STATUS1);