[SCSI] qla2xxx: Add acquiring of risc semaphore before doing ISP reset.
Try to acquire the semaphore; if semaphore is hung then acquire it by force. The ISP reset clears the semaphore, thereby implicitly releasing it. Signed-off-by: Joe Carnuccio <joe.carnuccio@qlogic.com> Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
Родитель
807fb6d8af
Коммит
4ea2c9c7b3
|
@ -1092,6 +1092,27 @@ struct device_reg_24xx {
|
|||
uint32_t unused_6[2]; /* Gap. */
|
||||
uint32_t iobase_sdata;
|
||||
};
|
||||
/* RISC-RISC semaphore register PCI offet */
|
||||
#define RISC_REGISTER_BASE_OFFSET 0x7010
|
||||
#define RISC_REGISTER_WINDOW_OFFET 0x6
|
||||
|
||||
/* RISC-RISC semaphore/flag register (risc address 0x7016) */
|
||||
|
||||
#define RISC_SEMAPHORE 0x1UL
|
||||
#define RISC_SEMAPHORE_WE (RISC_SEMAPHORE << 16)
|
||||
#define RISC_SEMAPHORE_CLR (RISC_SEMAPHORE_WE | 0x0UL)
|
||||
#define RISC_SEMAPHORE_SET (RISC_SEMAPHORE_WE | RISC_SEMAPHORE)
|
||||
|
||||
#define RISC_SEMAPHORE_FORCE 0x8000UL
|
||||
#define RISC_SEMAPHORE_FORCE_WE (RISC_SEMAPHORE_FORCE << 16)
|
||||
#define RISC_SEMAPHORE_FORCE_CLR (RISC_SEMAPHORE_FORCE_WE | 0x0UL)
|
||||
#define RISC_SEMAPHORE_FORCE_SET \
|
||||
(RISC_SEMAPHORE_FORCE_WE | RISC_SEMAPHORE_FORCE)
|
||||
|
||||
/* RISC semaphore timeouts (ms) */
|
||||
#define TIMEOUT_SEMAPHORE 2500
|
||||
#define TIMEOUT_SEMAPHORE_FORCE 2000
|
||||
#define TIMEOUT_TOTAL_ELAPSED 4500
|
||||
|
||||
/* Trace Control *************************************************************/
|
||||
|
||||
|
|
|
@ -1095,6 +1095,83 @@ qla24xx_reset_risc(scsi_qla_host_t *vha)
|
|||
ha->isp_ops->enable_intrs(ha);
|
||||
}
|
||||
|
||||
static void
|
||||
qla25xx_read_risc_sema_reg(scsi_qla_host_t *vha, uint32_t *data)
|
||||
{
|
||||
struct device_reg_24xx __iomem *reg = &vha->hw->iobase->isp24;
|
||||
|
||||
WRT_REG_DWORD(®->iobase_addr, RISC_REGISTER_BASE_OFFSET);
|
||||
*data = RD_REG_DWORD(®->iobase_window + RISC_REGISTER_WINDOW_OFFET);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
qla25xx_write_risc_sema_reg(scsi_qla_host_t *vha, uint32_t data)
|
||||
{
|
||||
struct device_reg_24xx __iomem *reg = &vha->hw->iobase->isp24;
|
||||
|
||||
WRT_REG_DWORD(®->iobase_addr, RISC_REGISTER_BASE_OFFSET);
|
||||
WRT_REG_DWORD(®->iobase_window + RISC_REGISTER_WINDOW_OFFET, data);
|
||||
}
|
||||
|
||||
static void
|
||||
qla25xx_manipulate_risc_semaphore(scsi_qla_host_t *vha)
|
||||
{
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
uint32_t wd32 = 0;
|
||||
uint delta_msec = 100;
|
||||
uint elapsed_msec = 0;
|
||||
uint timeout_msec;
|
||||
ulong n;
|
||||
|
||||
if (!IS_QLA25XX(ha) && !IS_QLA2031(ha))
|
||||
return;
|
||||
|
||||
attempt:
|
||||
timeout_msec = TIMEOUT_SEMAPHORE;
|
||||
n = timeout_msec / delta_msec;
|
||||
while (n--) {
|
||||
qla25xx_write_risc_sema_reg(vha, RISC_SEMAPHORE_SET);
|
||||
qla25xx_read_risc_sema_reg(vha, &wd32);
|
||||
if (wd32 & RISC_SEMAPHORE)
|
||||
break;
|
||||
msleep(delta_msec);
|
||||
elapsed_msec += delta_msec;
|
||||
if (elapsed_msec > TIMEOUT_TOTAL_ELAPSED)
|
||||
goto force;
|
||||
}
|
||||
|
||||
if (!(wd32 & RISC_SEMAPHORE))
|
||||
goto force;
|
||||
|
||||
if (!(wd32 & RISC_SEMAPHORE_FORCE))
|
||||
goto acquired;
|
||||
|
||||
qla25xx_write_risc_sema_reg(vha, RISC_SEMAPHORE_CLR);
|
||||
timeout_msec = TIMEOUT_SEMAPHORE_FORCE;
|
||||
n = timeout_msec / delta_msec;
|
||||
while (n--) {
|
||||
qla25xx_read_risc_sema_reg(vha, &wd32);
|
||||
if (!(wd32 & RISC_SEMAPHORE_FORCE))
|
||||
break;
|
||||
msleep(delta_msec);
|
||||
elapsed_msec += delta_msec;
|
||||
if (elapsed_msec > TIMEOUT_TOTAL_ELAPSED)
|
||||
goto force;
|
||||
}
|
||||
|
||||
if (wd32 & RISC_SEMAPHORE_FORCE)
|
||||
qla25xx_write_risc_sema_reg(vha, RISC_SEMAPHORE_FORCE_CLR);
|
||||
|
||||
goto attempt;
|
||||
|
||||
force:
|
||||
qla25xx_write_risc_sema_reg(vha, RISC_SEMAPHORE_FORCE_SET);
|
||||
|
||||
acquired:
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* qla24xx_reset_chip() - Reset ISP24xx chip.
|
||||
* @ha: HA context
|
||||
|
@ -1113,6 +1190,8 @@ qla24xx_reset_chip(scsi_qla_host_t *vha)
|
|||
|
||||
ha->isp_ops->disable_intrs(ha);
|
||||
|
||||
qla25xx_manipulate_risc_semaphore(vha);
|
||||
|
||||
/* Perform RISC reset. */
|
||||
qla24xx_reset_risc(vha);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче