Commit 2232be0d authored by Lalit Chandivade's avatar Lalit Chandivade Committed by James Bottomley

[SCSI] qla4xxx: Added AER support for ISP82xx

Added support for PCI error handling
Signed-off-by: default avatarLalit Chandivade <lalit.chandivade@qlogic.com>
Signed-off-by: default avatarVikas Chaudhary <vikas.chaudhary@qlogic.com>
Signed-off-by: default avatarPoornima Vonti <poornima.vonti@qlogic.com>
Signed-off-by: default avatarRavi Anand <ravi.anand@qlogic.com>
Reviewed-by: default avatarMike Christie <michaelc@cs.wisc.edu>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 21033639
...@@ -36,6 +36,24 @@ ...@@ -36,6 +36,24 @@
#include "ql4_dbg.h" #include "ql4_dbg.h"
#include "ql4_nx.h" #include "ql4_nx.h"
#if defined(CONFIG_PCIEAER)
#include <linux/aer.h>
#else
/* AER releated */
static inline int pci_enable_pcie_error_reporting(struct pci_dev *dev)
{
return -EINVAL;
}
static inline int pci_disable_pcie_error_reporting(struct pci_dev *dev)
{
return -EINVAL;
}
static inline int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev)
{
return -EINVAL;
}
#endif
#ifndef PCI_DEVICE_ID_QLOGIC_ISP4010 #ifndef PCI_DEVICE_ID_QLOGIC_ISP4010
#define PCI_DEVICE_ID_QLOGIC_ISP4010 0x4010 #define PCI_DEVICE_ID_QLOGIC_ISP4010 0x4010
#endif #endif
...@@ -381,7 +399,8 @@ struct scsi_qla_host { ...@@ -381,7 +399,8 @@ struct scsi_qla_host {
#define AF_MSIX_ENABLED 17 /* 0x00020000 */ #define AF_MSIX_ENABLED 17 /* 0x00020000 */
#define AF_MBOX_COMMAND_NOPOLL 18 /* 0x00040000 */ #define AF_MBOX_COMMAND_NOPOLL 18 /* 0x00040000 */
#define AF_FW_RECOVERY 19 /* 0x00080000 */ #define AF_FW_RECOVERY 19 /* 0x00080000 */
#define AF_EEH_BUSY 20 /* 0x00100000 */
#define AF_PCI_CHANNEL_IO_PERM_FAILURE 21 /* 0x00200000 */
unsigned long dpc_flags; unsigned long dpc_flags;
...@@ -617,6 +636,15 @@ static inline int is_qla8022(struct scsi_qla_host *ha) ...@@ -617,6 +636,15 @@ static inline int is_qla8022(struct scsi_qla_host *ha)
return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8022; return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8022;
} }
/* Note: Currently AER/EEH is now supported only for 8022 cards
* This function needs to be updated when AER/EEH is enabled
* for other cards.
*/
static inline int is_aer_supported(struct scsi_qla_host *ha)
{
return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8022;
}
static inline int adapter_up(struct scsi_qla_host *ha) static inline int adapter_up(struct scsi_qla_host *ha)
{ {
return (test_bit(AF_ONLINE, &ha->flags) != 0) && return (test_bit(AF_ONLINE, &ha->flags) != 0) &&
......
...@@ -132,6 +132,7 @@ void qla4_8xxx_idc_unlock(struct scsi_qla_host *ha); ...@@ -132,6 +132,7 @@ void qla4_8xxx_idc_unlock(struct scsi_qla_host *ha);
int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha); int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha);
void qla4_8xxx_need_qsnt_handler(struct scsi_qla_host *ha); void qla4_8xxx_need_qsnt_handler(struct scsi_qla_host *ha);
void qla4_8xxx_clear_drv_active(struct scsi_qla_host *ha); void qla4_8xxx_clear_drv_active(struct scsi_qla_host *ha);
inline void qla4_8xxx_set_drv_active(struct scsi_qla_host *ha);
extern int ql4xextended_error_logging; extern int ql4xextended_error_logging;
extern int ql4xdiscoverywait; extern int ql4xdiscoverywait;
......
...@@ -308,7 +308,6 @@ static int qla4xxx_fw_ready(struct scsi_qla_host *ha) ...@@ -308,7 +308,6 @@ static int qla4xxx_fw_ready(struct scsi_qla_host *ha)
DEBUG2(printk("scsi%ld: %s: unable to get firmware " DEBUG2(printk("scsi%ld: %s: unable to get firmware "
"state\n", ha->host_no, __func__)); "state\n", ha->host_no, __func__));
break; break;
} }
if (ha->firmware_state & FW_STATE_ERROR) { if (ha->firmware_state & FW_STATE_ERROR) {
...@@ -445,6 +444,10 @@ static int qla4xxx_init_firmware(struct scsi_qla_host *ha) ...@@ -445,6 +444,10 @@ static int qla4xxx_init_firmware(struct scsi_qla_host *ha)
{ {
int status = QLA_ERROR; int status = QLA_ERROR;
if (is_aer_supported(ha) &&
test_bit(AF_PCI_CHANNEL_IO_PERM_FAILURE, &ha->flags))
return status;
/* For 82xx, stop firmware before initializing because if BIOS /* For 82xx, stop firmware before initializing because if BIOS
* has previously initialized firmware, then driver's initialize * has previously initialized firmware, then driver's initialize
* firmware will fail. */ * firmware will fail. */
......
...@@ -816,6 +816,9 @@ irqreturn_t qla4_8xxx_intr_handler(int irq, void *dev_id) ...@@ -816,6 +816,9 @@ irqreturn_t qla4_8xxx_intr_handler(int irq, void *dev_id)
unsigned long flags = 0; unsigned long flags = 0;
uint8_t reqs_count = 0; uint8_t reqs_count = 0;
if (unlikely(pci_channel_offline(ha->pdev)))
return IRQ_HANDLED;
ha->isr_count++; ha->isr_count++;
status = qla4_8xxx_rd_32(ha, ISR_INT_VECTOR); status = qla4_8xxx_rd_32(ha, ISR_INT_VECTOR);
if (!(status & ha->nx_legacy_intr.int_vec_bit)) if (!(status & ha->nx_legacy_intr.int_vec_bit))
......
...@@ -48,6 +48,13 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, ...@@ -48,6 +48,13 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
return status; return status;
} }
if ((is_aer_supported(ha)) &&
(test_bit(AF_PCI_CHANNEL_IO_PERM_FAILURE, &ha->flags))) {
DEBUG2(printk(KERN_WARNING "scsi%ld: %s: Perm failure on EEH, "
"timeout MBX Exiting.\n", ha->host_no, __func__));
return status;
}
/* Mailbox code active */ /* Mailbox code active */
wait_count = MBOX_TOV * 100; wait_count = MBOX_TOV * 100;
...@@ -159,6 +166,7 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, ...@@ -159,6 +166,7 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
while (test_bit(AF_MBOX_COMMAND_DONE, &ha->flags) == 0) { while (test_bit(AF_MBOX_COMMAND_DONE, &ha->flags) == 0) {
if (time_after_eq(jiffies, wait_count)) if (time_after_eq(jiffies, wait_count))
break; break;
/* /*
* Service the interrupt. * Service the interrupt.
* The ISR will save the mailbox status registers * The ISR will save the mailbox status registers
......
...@@ -1418,7 +1418,7 @@ static int qla4_8xxx_rcvpeg_ready(struct scsi_qla_host *ha) ...@@ -1418,7 +1418,7 @@ static int qla4_8xxx_rcvpeg_ready(struct scsi_qla_host *ha)
return QLA_SUCCESS; return QLA_SUCCESS;
} }
static inline void inline void
qla4_8xxx_set_drv_active(struct scsi_qla_host *ha) qla4_8xxx_set_drv_active(struct scsi_qla_host *ha)
{ {
uint32_t drv_active; uint32_t drv_active;
...@@ -1441,11 +1441,15 @@ qla4_8xxx_clear_drv_active(struct scsi_qla_host *ha) ...@@ -1441,11 +1441,15 @@ qla4_8xxx_clear_drv_active(struct scsi_qla_host *ha)
static inline int static inline int
qla4_8xxx_need_reset(struct scsi_qla_host *ha) qla4_8xxx_need_reset(struct scsi_qla_host *ha)
{ {
uint32_t drv_state; uint32_t drv_state, drv_active;
int rval; int rval;
drv_active = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
drv_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DRV_STATE); drv_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
rval = drv_state & (1 << (ha->func_num * 4)); rval = drv_state & (1 << (ha->func_num * 4));
if ((test_bit(AF_EEH_BUSY, &ha->flags)) && drv_active)
rval = 1;
return rval; return rval;
} }
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment