diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_init.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index f2da5c5..c2d7bb8 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -944,6 +944,19 @@ qla2x00_reset_chip(scsi_qla_host_t *vha) } /** + * qla81xx_reset_mpi() - Reset's MPI FW via Write MPI Register MBC. + * + * Returns 0 on success. + */ +int +qla81xx_reset_mpi(scsi_qla_host_t *vha) +{ + uint16_t mb[4] = {0x1010, 0, 1, 0}; + + return qla81xx_write_mpi_register(vha, mb); +} + +/** * qla24xx_reset_risc() - Perform full reset of ISP24xx RISC. * @ha: HA context * @@ -957,6 +970,7 @@ qla24xx_reset_risc(scsi_qla_host_t *vha) struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; uint32_t cnt, d2; uint16_t wd; + static int abts_cnt; /* ISP abort retry counts */ spin_lock_irqsave(&ha->hardware_lock, flags); @@ -990,6 +1004,23 @@ qla24xx_reset_risc(scsi_qla_host_t *vha) barrier(); } + /* If required, do an MPI FW reset now */ + if (test_and_clear_bit(MPI_RESET_NEEDED, &vha->dpc_flags)) { + if (qla81xx_reset_mpi(vha) != QLA_SUCCESS) { + if (++abts_cnt < 5) { + set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); + set_bit(MPI_RESET_NEEDED, &vha->dpc_flags); + } else { + /* + * We exhausted the ISP abort retries. We have to + * set the board offline. + */ + abts_cnt = 0; + vha->flags.online = 0; + } + } + } + WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_RESET); RD_REG_DWORD(®->hccr); |