Skip to content

Commit

Permalink
[SCSI] qla2xxx: Extend base EEH support in qla2xxx.
Browse files Browse the repository at this point in the history
Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
  • Loading branch information
Andrew Vasquez authored and James Bottomley committed Dec 30, 2009
1 parent 5c66f5d commit 8588080
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 21 deletions.
32 changes: 27 additions & 5 deletions drivers/scsi/qla2xxx/qla_attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,9 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj,
if (off)
return 0;

if (unlikely(pci_channel_offline(ha->pdev)))
return 0;

if (sscanf(buf, "%d:%x:%x", &val, &start, &size) < 1)
return -EINVAL;
if (start > ha->optrom_size)
Expand Down Expand Up @@ -379,6 +382,9 @@ qla2x00_sysfs_read_vpd(struct kobject *kobj,
struct device, kobj)));
struct qla_hw_data *ha = vha->hw;

if (unlikely(pci_channel_offline(ha->pdev)))
return 0;

if (!capable(CAP_SYS_ADMIN))
return 0;

Expand All @@ -398,6 +404,9 @@ qla2x00_sysfs_write_vpd(struct kobject *kobj,
struct qla_hw_data *ha = vha->hw;
uint8_t *tmp_data;

if (unlikely(pci_channel_offline(ha->pdev)))
return 0;

if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size ||
!ha->isp_ops->write_nvram)
return 0;
Expand Down Expand Up @@ -1238,10 +1247,11 @@ qla2x00_fw_state_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
int rval;
int rval = QLA_FUNCTION_FAILED;
uint16_t state[5];

rval = qla2x00_get_firmware_state(vha, state);
if (!vha->hw->flags.eeh_busy)
rval = qla2x00_get_firmware_state(vha, state);
if (rval != QLA_SUCCESS)
memset(state, -1, sizeof(state));

Expand Down Expand Up @@ -1452,10 +1462,13 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport)
if (!fcport)
return;

if (unlikely(pci_channel_offline(fcport->vha->hw->pdev)))
if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags))
return;

if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) {
qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16);
else
qla2x00_abort_fcport_cmds(fcport);
return;
}

/*
* Transport has effectively 'deleted' the rport, clear
Expand All @@ -1475,6 +1488,9 @@ qla2x00_terminate_rport_io(struct fc_rport *rport)
if (!fcport)
return;

if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags))
return;

if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) {
qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16);
return;
Expand Down Expand Up @@ -1515,6 +1531,12 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
pfc_host_stat = &ha->fc_host_stat;
memset(pfc_host_stat, -1, sizeof(struct fc_host_statistics));

if (test_bit(UNLOADING, &vha->dpc_flags))
goto done;

if (unlikely(pci_channel_offline(ha->pdev)))
goto done;

stats = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &stats_dma);
if (stats == NULL) {
DEBUG2_3_11(printk("%s(%ld): Failed to allocate memory.\n",
Expand Down
9 changes: 8 additions & 1 deletion drivers/scsi/qla2xxx/qla_dbg.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
/* #define QL_DEBUG_LEVEL_14 */ /* Output RSCN trace msgs */
/* #define QL_DEBUG_LEVEL_15 */ /* Output NPIV trace msgs */
/* #define QL_DEBUG_LEVEL_16 */ /* Output ISP84XX trace msgs */
/* #define QL_DEBUG_LEVEL_17 */ /* Output MULTI-Q trace messages */
/* #define QL_DEBUG_LEVEL_17 */ /* Output EEH trace messages */

/*
* Macros use for debugging the driver.
Expand Down Expand Up @@ -132,6 +132,13 @@
#else
#define DEBUG16(x) do {} while (0)
#endif

#if defined(QL_DEBUG_LEVEL_17)
#define DEBUG17(x) do {x;} while (0)
#else
#define DEBUG17(x) do {} while (0)
#endif

/*
* Firmware Dump structure definition
*/
Expand Down
2 changes: 2 additions & 0 deletions drivers/scsi/qla2xxx/qla_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -2256,11 +2256,13 @@ struct qla_hw_data {
uint32_t disable_serdes :1;
uint32_t gpsc_supported :1;
uint32_t npiv_supported :1;
uint32_t pci_channel_io_perm_failure :1;
uint32_t fce_enabled :1;
uint32_t fac_supported :1;
uint32_t chip_reset_done :1;
uint32_t port0 :1;
uint32_t running_gold_fw :1;
uint32_t eeh_busy :1;
uint32_t cpu_affinity_enabled :1;
uint32_t disable_msix_handshake :1;
} flags;
Expand Down
20 changes: 20 additions & 0 deletions drivers/scsi/qla2xxx/qla_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,8 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
vha->flags.online = 0;
ha->flags.chip_reset_done = 0;
vha->flags.reset_active = 0;
ha->flags.pci_channel_io_perm_failure = 0;
ha->flags.eeh_busy = 0;
atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
atomic_set(&vha->loop_state, LOOP_DOWN);
vha->device_flags = DFLG_NO_CABLE;
Expand Down Expand Up @@ -581,6 +583,9 @@ qla2x00_reset_chip(scsi_qla_host_t *vha)
uint32_t cnt;
uint16_t cmd;

if (unlikely(pci_channel_offline(ha->pdev)))
return;

ha->isp_ops->disable_intrs(ha);

spin_lock_irqsave(&ha->hardware_lock, flags);
Expand Down Expand Up @@ -786,6 +791,12 @@ void
qla24xx_reset_chip(scsi_qla_host_t *vha)
{
struct qla_hw_data *ha = vha->hw;

if (pci_channel_offline(ha->pdev) &&
ha->flags.pci_channel_io_perm_failure) {
return;
}

ha->isp_ops->disable_intrs(ha);

/* Perform RISC reset. */
Expand Down Expand Up @@ -3562,6 +3573,13 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
/* Requeue all commands in outstanding command list. */
qla2x00_abort_all_cmds(vha, DID_RESET << 16);

if (unlikely(pci_channel_offline(ha->pdev) &&
ha->flags.pci_channel_io_perm_failure)) {
clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags);
status = 0;
return status;
}

ha->isp_ops->get_flash_version(vha, req->ring);

ha->isp_ops->nvram_config(vha);
Expand Down Expand Up @@ -4460,6 +4478,8 @@ qla2x00_try_to_stop_firmware(scsi_qla_host_t *vha)
int ret, retries;
struct qla_hw_data *ha = vha->hw;

if (ha->flags.pci_channel_io_perm_failure)
return;
if (!IS_FWI2_CAPABLE(ha))
return;
if (!ha->fw_major_version)
Expand Down
9 changes: 6 additions & 3 deletions drivers/scsi/qla2xxx/qla_isr.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ qla2300_intr_handler(int irq, void *dev_id)
for (iter = 50; iter--; ) {
stat = RD_REG_DWORD(&reg->u.isp2300.host_status);
if (stat & HSR_RISC_PAUSED) {
if (pci_channel_offline(ha->pdev))
if (unlikely(pci_channel_offline(ha->pdev)))
break;

hccr = RD_REG_WORD(&reg->hccr);
Expand Down Expand Up @@ -1846,12 +1846,15 @@ qla24xx_intr_handler(int irq, void *dev_id)
reg = &ha->iobase->isp24;
status = 0;

if (unlikely(pci_channel_offline(ha->pdev)))
return IRQ_HANDLED;

spin_lock_irqsave(&ha->hardware_lock, flags);
vha = pci_get_drvdata(ha->pdev);
for (iter = 50; iter--; ) {
stat = RD_REG_DWORD(&reg->host_status);
if (stat & HSRX_RISC_PAUSED) {
if (pci_channel_offline(ha->pdev))
if (unlikely(pci_channel_offline(ha->pdev)))
break;

hccr = RD_REG_DWORD(&reg->hccr);
Expand Down Expand Up @@ -1992,7 +1995,7 @@ qla24xx_msix_default(int irq, void *dev_id)
do {
stat = RD_REG_DWORD(&reg->host_status);
if (stat & HSRX_RISC_PAUSED) {
if (pci_channel_offline(ha->pdev))
if (unlikely(pci_channel_offline(ha->pdev)))
break;

hccr = RD_REG_DWORD(&reg->hccr);
Expand Down
31 changes: 27 additions & 4 deletions drivers/scsi/qla2xxx/qla_mbx.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)

DEBUG11(printk("%s(%ld): entered.\n", __func__, base_vha->host_no));

if (ha->flags.pci_channel_io_perm_failure) {
DEBUG(printk("%s(%ld): Perm failure on EEH, timeout MBX "
"Exiting.\n", __func__, vha->host_no));
return QLA_FUNCTION_TIMEOUT;
}

/*
* Wait for active mailbox commands to finish by waiting at most tov
* seconds. This is to serialize actual issuing of mailbox cmds during
Expand Down Expand Up @@ -154,10 +160,14 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
/* Check for pending interrupts. */
qla2x00_poll(ha->rsp_q_map[0]);

if (command != MBC_LOAD_RISC_RAM_EXTENDED &&
!ha->flags.mbox_int)
if (!ha->flags.mbox_int &&
!(IS_QLA2200(ha) &&
command == MBC_LOAD_RISC_RAM_EXTENDED))
msleep(10);
} /* while */
DEBUG17(qla_printk(KERN_WARNING, ha,
"Waited %d sec\n",
(uint)((jiffies - (wait_time - (mcp->tov * HZ)))/HZ)));
}

/* Check whether we timed out */
Expand Down Expand Up @@ -227,7 +237,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)

if (rval == QLA_FUNCTION_TIMEOUT &&
mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) {
if (!io_lock_on || (mcp->flags & IOCTL_CMD)) {
if (!io_lock_on || (mcp->flags & IOCTL_CMD) ||
ha->flags.eeh_busy) {
/* not in dpc. schedule it for dpc to take over. */
DEBUG(printk("%s(%ld): timeout schedule "
"isp_abort_needed.\n", __func__,
Expand All @@ -237,7 +248,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
base_vha->host_no));
qla_printk(KERN_WARNING, ha,
"Mailbox command timeout occurred. Scheduling ISP "
"abort.\n");
"abort. eeh_busy: 0x%x\n", ha->flags.eeh_busy);
set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags);
qla2xxx_wake_dpc(vha);
} else if (!abort_active) {
Expand Down Expand Up @@ -2530,6 +2541,9 @@ qla2x00_enable_eft_trace(scsi_qla_host_t *vha, dma_addr_t eft_dma,
if (!IS_FWI2_CAPABLE(vha->hw))
return QLA_FUNCTION_FAILED;

if (unlikely(pci_channel_offline(vha->hw->pdev)))
return QLA_FUNCTION_FAILED;

DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));

mcp->mb[0] = MBC_TRACE_CONTROL;
Expand Down Expand Up @@ -2565,6 +2579,9 @@ qla2x00_disable_eft_trace(scsi_qla_host_t *vha)
if (!IS_FWI2_CAPABLE(vha->hw))
return QLA_FUNCTION_FAILED;

if (unlikely(pci_channel_offline(vha->hw->pdev)))
return QLA_FUNCTION_FAILED;

DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));

mcp->mb[0] = MBC_TRACE_CONTROL;
Expand Down Expand Up @@ -2595,6 +2612,9 @@ qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma,
if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw))
return QLA_FUNCTION_FAILED;

if (unlikely(pci_channel_offline(vha->hw->pdev)))
return QLA_FUNCTION_FAILED;

DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));

mcp->mb[0] = MBC_TRACE_CONTROL;
Expand Down Expand Up @@ -2639,6 +2659,9 @@ qla2x00_disable_fce_trace(scsi_qla_host_t *vha, uint64_t *wr, uint64_t *rd)
if (!IS_FWI2_CAPABLE(vha->hw))
return QLA_FUNCTION_FAILED;

if (unlikely(pci_channel_offline(vha->hw->pdev)))
return QLA_FUNCTION_FAILED;

DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));

mcp->mb[0] = MBC_TRACE_CONTROL;
Expand Down
Loading

0 comments on commit 8588080

Please sign in to comment.