[SCSI] qla4xxx: Added new functions in isp_ops
Signed-off-by: Poornima Vonti <poornima.vonti@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>
This commit is contained in:
parent
c38fa3abea
commit
33693c7aab
|
@ -75,21 +75,21 @@ qla4_8xxx_sysfs_write_fw_dump(struct file *filep, struct kobject *kobj,
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
/* Reset HBA */
|
/* Reset HBA */
|
||||||
qla4_82xx_idc_lock(ha);
|
ha->isp_ops->idc_lock(ha);
|
||||||
dev_state = qla4_82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
|
dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE);
|
||||||
if (dev_state == QLA8XXX_DEV_READY) {
|
if (dev_state == QLA8XXX_DEV_READY) {
|
||||||
ql4_printk(KERN_INFO, ha,
|
ql4_printk(KERN_INFO, ha,
|
||||||
"%s: Setting Need reset, reset_owner is 0x%x.\n",
|
"%s: Setting Need reset, reset_owner is 0x%x.\n",
|
||||||
__func__, ha->func_num);
|
__func__, ha->func_num);
|
||||||
qla4_82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
|
qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
|
||||||
QLA8XXX_DEV_NEED_RESET);
|
QLA8XXX_DEV_NEED_RESET);
|
||||||
set_bit(AF_8XXX_RST_OWNER, &ha->flags);
|
set_bit(AF_8XXX_RST_OWNER, &ha->flags);
|
||||||
} else
|
} else
|
||||||
ql4_printk(KERN_INFO, ha,
|
ql4_printk(KERN_INFO, ha,
|
||||||
"%s: Reset not performed as device state is 0x%x\n",
|
"%s: Reset not performed as device state is 0x%x\n",
|
||||||
__func__, dev_state);
|
__func__, dev_state);
|
||||||
|
|
||||||
qla4_82xx_idc_unlock(ha);
|
ha->isp_ops->idc_unlock(ha);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* do nothing */
|
/* do nothing */
|
||||||
|
|
|
@ -388,8 +388,10 @@ struct isp_operations {
|
||||||
void (*disable_intrs) (struct scsi_qla_host *);
|
void (*disable_intrs) (struct scsi_qla_host *);
|
||||||
void (*enable_intrs) (struct scsi_qla_host *);
|
void (*enable_intrs) (struct scsi_qla_host *);
|
||||||
int (*start_firmware) (struct scsi_qla_host *);
|
int (*start_firmware) (struct scsi_qla_host *);
|
||||||
|
int (*restart_firmware) (struct scsi_qla_host *);
|
||||||
irqreturn_t (*intr_handler) (int , void *);
|
irqreturn_t (*intr_handler) (int , void *);
|
||||||
void (*interrupt_service_routine) (struct scsi_qla_host *, uint32_t);
|
void (*interrupt_service_routine) (struct scsi_qla_host *, uint32_t);
|
||||||
|
int (*need_reset) (struct scsi_qla_host *);
|
||||||
int (*reset_chip) (struct scsi_qla_host *);
|
int (*reset_chip) (struct scsi_qla_host *);
|
||||||
int (*reset_firmware) (struct scsi_qla_host *);
|
int (*reset_firmware) (struct scsi_qla_host *);
|
||||||
void (*queue_iocb) (struct scsi_qla_host *);
|
void (*queue_iocb) (struct scsi_qla_host *);
|
||||||
|
@ -397,6 +399,15 @@ struct isp_operations {
|
||||||
uint16_t (*rd_shdw_req_q_out) (struct scsi_qla_host *);
|
uint16_t (*rd_shdw_req_q_out) (struct scsi_qla_host *);
|
||||||
uint16_t (*rd_shdw_rsp_q_in) (struct scsi_qla_host *);
|
uint16_t (*rd_shdw_rsp_q_in) (struct scsi_qla_host *);
|
||||||
int (*get_sys_info) (struct scsi_qla_host *);
|
int (*get_sys_info) (struct scsi_qla_host *);
|
||||||
|
uint32_t (*rd_reg_direct) (struct scsi_qla_host *, ulong);
|
||||||
|
void (*wr_reg_direct) (struct scsi_qla_host *, ulong, uint32_t);
|
||||||
|
int (*rd_reg_indirect) (struct scsi_qla_host *, uint32_t, uint32_t *);
|
||||||
|
int (*wr_reg_indirect) (struct scsi_qla_host *, uint32_t, uint32_t);
|
||||||
|
int (*idc_lock) (struct scsi_qla_host *);
|
||||||
|
void (*idc_unlock) (struct scsi_qla_host *);
|
||||||
|
void (*rom_lock_recovery) (struct scsi_qla_host *);
|
||||||
|
void (*queue_mailbox_command) (struct scsi_qla_host *, uint32_t *, int);
|
||||||
|
void (*process_mailbox_interrupt) (struct scsi_qla_host *, int);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ql4_mdump_size_table {
|
struct ql4_mdump_size_table {
|
||||||
|
@ -733,6 +744,8 @@ struct scsi_qla_host {
|
||||||
#define MAX_MRB 128
|
#define MAX_MRB 128
|
||||||
struct mrb *active_mrb_array[MAX_MRB];
|
struct mrb *active_mrb_array[MAX_MRB];
|
||||||
uint32_t mrb_index;
|
uint32_t mrb_index;
|
||||||
|
|
||||||
|
uint32_t *reg_tbl;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ql4_task_data {
|
struct ql4_task_data {
|
||||||
|
@ -942,6 +955,20 @@ static inline int ql4xxx_reset_active(struct scsi_qla_host *ha)
|
||||||
test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags);
|
test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int qla4_8xxx_rd_direct(struct scsi_qla_host *ha,
|
||||||
|
const uint32_t crb_reg)
|
||||||
|
{
|
||||||
|
return ha->isp_ops->rd_reg_direct(ha, ha->reg_tbl[crb_reg]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void qla4_8xxx_wr_direct(struct scsi_qla_host *ha,
|
||||||
|
const uint32_t crb_reg,
|
||||||
|
const uint32_t value)
|
||||||
|
{
|
||||||
|
ha->isp_ops->wr_reg_direct(ha, ha->reg_tbl[crb_reg], value);
|
||||||
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/* Defines for qla4xxx_initialize_adapter() and qla4xxx_recover_adapter() */
|
/* Defines for qla4xxx_initialize_adapter() and qla4xxx_recover_adapter() */
|
||||||
|
|
|
@ -117,7 +117,7 @@ int qla4_82xx_crb_win_lock(struct scsi_qla_host *);
|
||||||
void qla4_82xx_crb_win_unlock(struct scsi_qla_host *);
|
void qla4_82xx_crb_win_unlock(struct scsi_qla_host *);
|
||||||
int qla4_82xx_pci_get_crb_addr_2M(struct scsi_qla_host *, ulong *);
|
int qla4_82xx_pci_get_crb_addr_2M(struct scsi_qla_host *, ulong *);
|
||||||
void qla4_82xx_wr_32(struct scsi_qla_host *, ulong, u32);
|
void qla4_82xx_wr_32(struct scsi_qla_host *, ulong, u32);
|
||||||
int qla4_82xx_rd_32(struct scsi_qla_host *, ulong);
|
uint32_t qla4_82xx_rd_32(struct scsi_qla_host *, ulong);
|
||||||
int qla4_82xx_pci_mem_read_2M(struct scsi_qla_host *, u64, void *, int);
|
int qla4_82xx_pci_mem_read_2M(struct scsi_qla_host *, u64, void *, int);
|
||||||
int qla4_82xx_pci_mem_write_2M(struct scsi_qla_host *ha, u64, void *, int);
|
int qla4_82xx_pci_mem_write_2M(struct scsi_qla_host *ha, u64, void *, int);
|
||||||
int qla4_82xx_isp_reset(struct scsi_qla_host *ha);
|
int qla4_82xx_isp_reset(struct scsi_qla_host *ha);
|
||||||
|
@ -203,6 +203,17 @@ int qla4xxx_req_template_size(struct scsi_qla_host *ha);
|
||||||
void qla4_8xxx_alloc_sysfs_attr(struct scsi_qla_host *ha);
|
void qla4_8xxx_alloc_sysfs_attr(struct scsi_qla_host *ha);
|
||||||
void qla4_8xxx_free_sysfs_attr(struct scsi_qla_host *ha);
|
void qla4_8xxx_free_sysfs_attr(struct scsi_qla_host *ha);
|
||||||
void qla4xxx_alloc_fw_dump(struct scsi_qla_host *ha);
|
void qla4xxx_alloc_fw_dump(struct scsi_qla_host *ha);
|
||||||
|
int qla4_82xx_try_start_fw(struct scsi_qla_host *ha);
|
||||||
|
int qla4_8xxx_need_reset(struct scsi_qla_host *ha);
|
||||||
|
int qla4_82xx_md_rd_32(struct scsi_qla_host *ha, uint32_t off, uint32_t *data);
|
||||||
|
int qla4_82xx_md_wr_32(struct scsi_qla_host *ha, uint32_t off, uint32_t data);
|
||||||
|
void qla4_82xx_rom_lock_recovery(struct scsi_qla_host *ha);
|
||||||
|
void qla4_82xx_queue_mbox_cmd(struct scsi_qla_host *ha, uint32_t *mbx_cmd,
|
||||||
|
int incount);
|
||||||
|
void qla4_82xx_process_mbox_intr(struct scsi_qla_host *ha, int outcount);
|
||||||
|
void qla4xxx_queue_mbox_cmd(struct scsi_qla_host *ha, uint32_t *mbx_cmd,
|
||||||
|
int incount);
|
||||||
|
void qla4xxx_process_mbox_intr(struct scsi_qla_host *ha, int outcount);
|
||||||
|
|
||||||
extern int ql4xextended_error_logging;
|
extern int ql4xextended_error_logging;
|
||||||
extern int ql4xdontresethba;
|
extern int ql4xdontresethba;
|
||||||
|
|
|
@ -10,6 +10,37 @@
|
||||||
#include "ql4_dbg.h"
|
#include "ql4_dbg.h"
|
||||||
#include "ql4_inline.h"
|
#include "ql4_inline.h"
|
||||||
|
|
||||||
|
void qla4xxx_queue_mbox_cmd(struct scsi_qla_host *ha, uint32_t *mbx_cmd,
|
||||||
|
int in_count)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Load all mailbox registers, except mailbox 0. */
|
||||||
|
for (i = 1; i < in_count; i++)
|
||||||
|
writel(mbx_cmd[i], &ha->reg->mailbox[i]);
|
||||||
|
|
||||||
|
/* Wakeup firmware */
|
||||||
|
writel(mbx_cmd[0], &ha->reg->mailbox[0]);
|
||||||
|
readl(&ha->reg->mailbox[0]);
|
||||||
|
writel(set_rmask(CSR_INTR_RISC), &ha->reg->ctrl_status);
|
||||||
|
readl(&ha->reg->ctrl_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
void qla4xxx_process_mbox_intr(struct scsi_qla_host *ha, int out_count)
|
||||||
|
{
|
||||||
|
int intr_status;
|
||||||
|
|
||||||
|
intr_status = readl(&ha->reg->ctrl_status);
|
||||||
|
if (intr_status & INTR_PENDING) {
|
||||||
|
/*
|
||||||
|
* Service the interrupt.
|
||||||
|
* The ISR will save the mailbox status registers
|
||||||
|
* to a temporary storage location in the adapter structure.
|
||||||
|
*/
|
||||||
|
ha->mbox_status_count = out_count;
|
||||||
|
ha->isp_ops->interrupt_service_routine(ha, intr_status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* qla4xxx_mailbox_command - issues mailbox commands
|
* qla4xxx_mailbox_command - issues mailbox commands
|
||||||
|
@ -30,7 +61,6 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
|
||||||
int status = QLA_ERROR;
|
int status = QLA_ERROR;
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
u_long wait_count;
|
u_long wait_count;
|
||||||
uint32_t intr_status;
|
|
||||||
unsigned long flags = 0;
|
unsigned long flags = 0;
|
||||||
uint32_t dev_state;
|
uint32_t dev_state;
|
||||||
|
|
||||||
|
@ -85,9 +115,9 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
|
||||||
goto mbox_exit;
|
goto mbox_exit;
|
||||||
}
|
}
|
||||||
/* Do not send any mbx cmd if h/w is in failed state*/
|
/* Do not send any mbx cmd if h/w is in failed state*/
|
||||||
qla4_82xx_idc_lock(ha);
|
ha->isp_ops->idc_lock(ha);
|
||||||
dev_state = qla4_82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
|
dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE);
|
||||||
qla4_82xx_idc_unlock(ha);
|
ha->isp_ops->idc_unlock(ha);
|
||||||
if (dev_state == QLA8XXX_DEV_FAILED) {
|
if (dev_state == QLA8XXX_DEV_FAILED) {
|
||||||
ql4_printk(KERN_WARNING, ha,
|
ql4_printk(KERN_WARNING, ha,
|
||||||
"scsi%ld: %s: H/W is in failed state, do not send any mailbox commands\n",
|
"scsi%ld: %s: H/W is in failed state, do not send any mailbox commands\n",
|
||||||
|
@ -102,30 +132,8 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
|
||||||
for (i = 0; i < outCount; i++)
|
for (i = 0; i < outCount; i++)
|
||||||
ha->mbox_status[i] = 0;
|
ha->mbox_status[i] = 0;
|
||||||
|
|
||||||
if (is_qla8022(ha)) {
|
/* Queue the mailbox command to the firmware */
|
||||||
/* Load all mailbox registers, except mailbox 0. */
|
ha->isp_ops->queue_mailbox_command(ha, mbx_cmd, inCount);
|
||||||
DEBUG5(
|
|
||||||
printk("scsi%ld: %s: Cmd ", ha->host_no, __func__);
|
|
||||||
for (i = 0; i < inCount; i++)
|
|
||||||
printk("mb%d=%04x ", i, mbx_cmd[i]);
|
|
||||||
printk("\n"));
|
|
||||||
|
|
||||||
for (i = 1; i < inCount; i++)
|
|
||||||
writel(mbx_cmd[i], &ha->qla4_82xx_reg->mailbox_in[i]);
|
|
||||||
writel(mbx_cmd[0], &ha->qla4_82xx_reg->mailbox_in[0]);
|
|
||||||
readl(&ha->qla4_82xx_reg->mailbox_in[0]);
|
|
||||||
writel(HINT_MBX_INT_PENDING, &ha->qla4_82xx_reg->hint);
|
|
||||||
} else {
|
|
||||||
/* Load all mailbox registers, except mailbox 0. */
|
|
||||||
for (i = 1; i < inCount; i++)
|
|
||||||
writel(mbx_cmd[i], &ha->reg->mailbox[i]);
|
|
||||||
|
|
||||||
/* Wakeup firmware */
|
|
||||||
writel(mbx_cmd[0], &ha->reg->mailbox[0]);
|
|
||||||
readl(&ha->reg->mailbox[0]);
|
|
||||||
writel(set_rmask(CSR_INTR_RISC), &ha->reg->ctrl_status);
|
|
||||||
readl(&ha->reg->ctrl_status);
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||||
|
|
||||||
|
@ -167,37 +175,7 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||||
if (is_qla8022(ha)) {
|
ha->isp_ops->process_mailbox_interrupt(ha, outCount);
|
||||||
intr_status =
|
|
||||||
readl(&ha->qla4_82xx_reg->host_int);
|
|
||||||
if (intr_status & ISRX_82XX_RISC_INT) {
|
|
||||||
ha->mbox_status_count = outCount;
|
|
||||||
intr_status =
|
|
||||||
readl(&ha->qla4_82xx_reg->host_status);
|
|
||||||
ha->isp_ops->interrupt_service_routine(
|
|
||||||
ha, intr_status);
|
|
||||||
if (test_bit(AF_INTERRUPTS_ON,
|
|
||||||
&ha->flags) &&
|
|
||||||
test_bit(AF_INTx_ENABLED,
|
|
||||||
&ha->flags))
|
|
||||||
qla4_82xx_wr_32(ha,
|
|
||||||
ha->nx_legacy_intr.tgt_mask_reg,
|
|
||||||
0xfbff);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
intr_status = readl(&ha->reg->ctrl_status);
|
|
||||||
if (intr_status & INTR_PENDING) {
|
|
||||||
/*
|
|
||||||
* Service the interrupt.
|
|
||||||
* The ISR will save the mailbox status
|
|
||||||
* registers to a temporary storage
|
|
||||||
* location in the adapter structure.
|
|
||||||
*/
|
|
||||||
ha->mbox_status_count = outCount;
|
|
||||||
ha->isp_ops->interrupt_service_routine(
|
|
||||||
ha, intr_status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||||
msleep(10);
|
msleep(10);
|
||||||
}
|
}
|
||||||
|
|
|
@ -396,8 +396,7 @@ qla4_82xx_wr_32(struct scsi_qla_host *ha, ulong off, u32 data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
uint32_t qla4_82xx_rd_32(struct scsi_qla_host *ha, ulong off)
|
||||||
qla4_82xx_rd_32(struct scsi_qla_host *ha, ulong off)
|
|
||||||
{
|
{
|
||||||
unsigned long flags = 0;
|
unsigned long flags = 0;
|
||||||
int rv;
|
int rv;
|
||||||
|
@ -422,10 +421,36 @@ qla4_82xx_rd_32(struct scsi_qla_host *ha, ulong off)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Minidump related functions */
|
/* Minidump related functions */
|
||||||
static int qla4_8xxx_md_rw_32(struct scsi_qla_host *ha, uint32_t off,
|
int qla4_82xx_md_rd_32(struct scsi_qla_host *ha, uint32_t off, uint32_t *data)
|
||||||
u32 data, uint8_t flag)
|
|
||||||
{
|
{
|
||||||
uint32_t win_read, off_value, rval = QLA_SUCCESS;
|
uint32_t win_read, off_value;
|
||||||
|
int rval = QLA_SUCCESS;
|
||||||
|
|
||||||
|
off_value = off & 0xFFFF0000;
|
||||||
|
writel(off_value, (void __iomem *)(CRB_WINDOW_2M + ha->nx_pcibase));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read back value to make sure write has gone through before trying
|
||||||
|
* to use it.
|
||||||
|
*/
|
||||||
|
win_read = readl((void __iomem *)(CRB_WINDOW_2M + ha->nx_pcibase));
|
||||||
|
if (win_read != off_value) {
|
||||||
|
DEBUG2(ql4_printk(KERN_INFO, ha,
|
||||||
|
"%s: Written (0x%x) != Read (0x%x), off=0x%x\n",
|
||||||
|
__func__, off_value, win_read, off));
|
||||||
|
rval = QLA_ERROR;
|
||||||
|
} else {
|
||||||
|
off_value = off & 0x0000FFFF;
|
||||||
|
*data = readl((void __iomem *)(off_value + CRB_INDIRECT_2M +
|
||||||
|
ha->nx_pcibase));
|
||||||
|
}
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
int qla4_82xx_md_wr_32(struct scsi_qla_host *ha, uint32_t off, uint32_t data)
|
||||||
|
{
|
||||||
|
uint32_t win_read, off_value;
|
||||||
|
int rval = QLA_SUCCESS;
|
||||||
|
|
||||||
off_value = off & 0xFFFF0000;
|
off_value = off & 0xFFFF0000;
|
||||||
writel(off_value, (void __iomem *)(CRB_WINDOW_2M + ha->nx_pcibase));
|
writel(off_value, (void __iomem *)(CRB_WINDOW_2M + ha->nx_pcibase));
|
||||||
|
@ -437,19 +462,13 @@ static int qla4_8xxx_md_rw_32(struct scsi_qla_host *ha, uint32_t off,
|
||||||
if (win_read != off_value) {
|
if (win_read != off_value) {
|
||||||
DEBUG2(ql4_printk(KERN_INFO, ha,
|
DEBUG2(ql4_printk(KERN_INFO, ha,
|
||||||
"%s: Written (0x%x) != Read (0x%x), off=0x%x\n",
|
"%s: Written (0x%x) != Read (0x%x), off=0x%x\n",
|
||||||
__func__, off_value, win_read, off));
|
__func__, off_value, win_read, off));
|
||||||
return QLA_ERROR;
|
rval = QLA_ERROR;
|
||||||
}
|
} else {
|
||||||
|
off_value = off & 0x0000FFFF;
|
||||||
off_value = off & 0x0000FFFF;
|
|
||||||
|
|
||||||
if (flag)
|
|
||||||
writel(data, (void __iomem *)(off_value + CRB_INDIRECT_2M +
|
writel(data, (void __iomem *)(off_value + CRB_INDIRECT_2M +
|
||||||
ha->nx_pcibase));
|
ha->nx_pcibase));
|
||||||
else
|
}
|
||||||
rval = readl((void __iomem *)(off_value + CRB_INDIRECT_2M +
|
|
||||||
ha->nx_pcibase));
|
|
||||||
|
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1491,11 +1510,11 @@ qla4_8xxx_set_drv_active(struct scsi_qla_host *ha)
|
||||||
{
|
{
|
||||||
uint32_t drv_active;
|
uint32_t drv_active;
|
||||||
|
|
||||||
drv_active = qla4_82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
|
drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE);
|
||||||
drv_active |= (1 << (ha->func_num * 4));
|
drv_active |= (1 << (ha->func_num * 4));
|
||||||
ql4_printk(KERN_INFO, ha, "%s(%ld): drv_active: 0x%08x\n",
|
ql4_printk(KERN_INFO, ha, "%s(%ld): drv_active: 0x%08x\n",
|
||||||
__func__, ha->host_no, drv_active);
|
__func__, ha->host_no, drv_active);
|
||||||
qla4_82xx_wr_32(ha, QLA82XX_CRB_DRV_ACTIVE, drv_active);
|
qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_ACTIVE, drv_active);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1503,21 +1522,20 @@ qla4_8xxx_clear_drv_active(struct scsi_qla_host *ha)
|
||||||
{
|
{
|
||||||
uint32_t drv_active;
|
uint32_t drv_active;
|
||||||
|
|
||||||
drv_active = qla4_82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
|
drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE);
|
||||||
drv_active &= ~(1 << (ha->func_num * 4));
|
drv_active &= ~(1 << (ha->func_num * 4));
|
||||||
ql4_printk(KERN_INFO, ha, "%s(%ld): drv_active: 0x%08x\n",
|
ql4_printk(KERN_INFO, ha, "%s(%ld): drv_active: 0x%08x\n",
|
||||||
__func__, ha->host_no, drv_active);
|
__func__, ha->host_no, drv_active);
|
||||||
qla4_82xx_wr_32(ha, QLA82XX_CRB_DRV_ACTIVE, drv_active);
|
qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_ACTIVE, drv_active);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
inline int qla4_8xxx_need_reset(struct scsi_qla_host *ha)
|
||||||
qla4_8xxx_need_reset(struct scsi_qla_host *ha)
|
|
||||||
{
|
{
|
||||||
uint32_t drv_state, drv_active;
|
uint32_t drv_state, drv_active;
|
||||||
int rval;
|
int rval;
|
||||||
|
|
||||||
drv_active = qla4_82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
|
drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE);
|
||||||
drv_state = qla4_82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
|
drv_state = qla4_8xxx_rd_direct(ha, QLA8XXX_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)
|
if ((test_bit(AF_EEH_BUSY, &ha->flags)) && drv_active)
|
||||||
rval = 1;
|
rval = 1;
|
||||||
|
@ -1530,11 +1548,11 @@ qla4_8xxx_set_rst_ready(struct scsi_qla_host *ha)
|
||||||
{
|
{
|
||||||
uint32_t drv_state;
|
uint32_t drv_state;
|
||||||
|
|
||||||
drv_state = qla4_82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
|
drv_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_STATE);
|
||||||
drv_state |= (1 << (ha->func_num * 4));
|
drv_state |= (1 << (ha->func_num * 4));
|
||||||
ql4_printk(KERN_INFO, ha, "%s(%ld): drv_state: 0x%08x\n",
|
ql4_printk(KERN_INFO, ha, "%s(%ld): drv_state: 0x%08x\n",
|
||||||
__func__, ha->host_no, drv_state);
|
__func__, ha->host_no, drv_state);
|
||||||
qla4_82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, drv_state);
|
qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_STATE, drv_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
@ -1542,11 +1560,11 @@ qla4_8xxx_clear_rst_ready(struct scsi_qla_host *ha)
|
||||||
{
|
{
|
||||||
uint32_t drv_state;
|
uint32_t drv_state;
|
||||||
|
|
||||||
drv_state = qla4_82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
|
drv_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_STATE);
|
||||||
drv_state &= ~(1 << (ha->func_num * 4));
|
drv_state &= ~(1 << (ha->func_num * 4));
|
||||||
ql4_printk(KERN_INFO, ha, "%s(%ld): drv_state: 0x%08x\n",
|
ql4_printk(KERN_INFO, ha, "%s(%ld): drv_state: 0x%08x\n",
|
||||||
__func__, ha->host_no, drv_state);
|
__func__, ha->host_no, drv_state);
|
||||||
qla4_82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, drv_state);
|
qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_STATE, drv_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
@ -1554,9 +1572,9 @@ qla4_8xxx_set_qsnt_ready(struct scsi_qla_host *ha)
|
||||||
{
|
{
|
||||||
uint32_t qsnt_state;
|
uint32_t qsnt_state;
|
||||||
|
|
||||||
qsnt_state = qla4_82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
|
qsnt_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_STATE);
|
||||||
qsnt_state |= (2 << (ha->func_num * 4));
|
qsnt_state |= (2 << (ha->func_num * 4));
|
||||||
qla4_82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, qsnt_state);
|
qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_STATE, qsnt_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1595,8 +1613,7 @@ qla4_82xx_start_firmware(struct scsi_qla_host *ha, uint32_t image_start)
|
||||||
return qla4_82xx_rcvpeg_ready(ha);
|
return qla4_82xx_rcvpeg_ready(ha);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
int qla4_82xx_try_start_fw(struct scsi_qla_host *ha)
|
||||||
qla4_82xx_try_start_fw(struct scsi_qla_host *ha)
|
|
||||||
{
|
{
|
||||||
int rval = QLA_ERROR;
|
int rval = QLA_ERROR;
|
||||||
|
|
||||||
|
@ -1625,7 +1642,7 @@ qla4_82xx_try_start_fw(struct scsi_qla_host *ha)
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qla4_82xx_rom_lock_recovery(struct scsi_qla_host *ha)
|
void qla4_82xx_rom_lock_recovery(struct scsi_qla_host *ha)
|
||||||
{
|
{
|
||||||
if (qla4_82xx_rom_lock(ha)) {
|
if (qla4_82xx_rom_lock(ha)) {
|
||||||
/* Someone else is holding the lock. */
|
/* Someone else is holding the lock. */
|
||||||
|
@ -1655,7 +1672,7 @@ static void qla4_8xxx_minidump_process_rdcrb(struct scsi_qla_host *ha,
|
||||||
loop_cnt = crb_hdr->op_count;
|
loop_cnt = crb_hdr->op_count;
|
||||||
|
|
||||||
for (i = 0; i < loop_cnt; i++) {
|
for (i = 0; i < loop_cnt; i++) {
|
||||||
r_value = qla4_8xxx_md_rw_32(ha, r_addr, 0, 0);
|
ha->isp_ops->rd_reg_indirect(ha, r_addr, &r_value);
|
||||||
*data_ptr++ = cpu_to_le32(r_addr);
|
*data_ptr++ = cpu_to_le32(r_addr);
|
||||||
*data_ptr++ = cpu_to_le32(r_value);
|
*data_ptr++ = cpu_to_le32(r_value);
|
||||||
r_addr += r_stride;
|
r_addr += r_stride;
|
||||||
|
@ -1690,16 +1707,16 @@ static int qla4_8xxx_minidump_process_l2tag(struct scsi_qla_host *ha,
|
||||||
p_mask = cache_hdr->cache_ctrl.poll_mask;
|
p_mask = cache_hdr->cache_ctrl.poll_mask;
|
||||||
|
|
||||||
for (i = 0; i < loop_count; i++) {
|
for (i = 0; i < loop_count; i++) {
|
||||||
qla4_8xxx_md_rw_32(ha, t_r_addr, t_value, 1);
|
ha->isp_ops->wr_reg_indirect(ha, t_r_addr, t_value);
|
||||||
|
|
||||||
if (c_value_w)
|
if (c_value_w)
|
||||||
qla4_8xxx_md_rw_32(ha, c_addr, c_value_w, 1);
|
ha->isp_ops->wr_reg_indirect(ha, c_addr, c_value_w);
|
||||||
|
|
||||||
if (p_mask) {
|
if (p_mask) {
|
||||||
w_time = jiffies + p_wait;
|
w_time = jiffies + p_wait;
|
||||||
do {
|
do {
|
||||||
c_value_r = qla4_8xxx_md_rw_32(ha, c_addr,
|
ha->isp_ops->rd_reg_indirect(ha, c_addr,
|
||||||
0, 0);
|
&c_value_r);
|
||||||
if ((c_value_r & p_mask) == 0) {
|
if ((c_value_r & p_mask) == 0) {
|
||||||
break;
|
break;
|
||||||
} else if (time_after_eq(jiffies, w_time)) {
|
} else if (time_after_eq(jiffies, w_time)) {
|
||||||
|
@ -1711,7 +1728,7 @@ static int qla4_8xxx_minidump_process_l2tag(struct scsi_qla_host *ha,
|
||||||
|
|
||||||
addr = r_addr;
|
addr = r_addr;
|
||||||
for (k = 0; k < r_cnt; k++) {
|
for (k = 0; k < r_cnt; k++) {
|
||||||
r_value = qla4_8xxx_md_rw_32(ha, addr, 0, 0);
|
ha->isp_ops->rd_reg_indirect(ha, addr, &r_value);
|
||||||
*data_ptr++ = cpu_to_le32(r_value);
|
*data_ptr++ = cpu_to_le32(r_value);
|
||||||
addr += cache_hdr->read_ctrl.read_addr_stride;
|
addr += cache_hdr->read_ctrl.read_addr_stride;
|
||||||
}
|
}
|
||||||
|
@ -1741,47 +1758,48 @@ static int qla4_8xxx_minidump_process_control(struct scsi_qla_host *ha,
|
||||||
for (i = 0; i < crb_entry->op_count; i++) {
|
for (i = 0; i < crb_entry->op_count; i++) {
|
||||||
opcode = crb_entry->crb_ctrl.opcode;
|
opcode = crb_entry->crb_ctrl.opcode;
|
||||||
if (opcode & QLA8XXX_DBG_OPCODE_WR) {
|
if (opcode & QLA8XXX_DBG_OPCODE_WR) {
|
||||||
qla4_8xxx_md_rw_32(ha, crb_addr,
|
ha->isp_ops->wr_reg_indirect(ha, crb_addr,
|
||||||
crb_entry->value_1, 1);
|
crb_entry->value_1);
|
||||||
opcode &= ~QLA8XXX_DBG_OPCODE_WR;
|
opcode &= ~QLA8XXX_DBG_OPCODE_WR;
|
||||||
}
|
}
|
||||||
if (opcode & QLA8XXX_DBG_OPCODE_RW) {
|
if (opcode & QLA8XXX_DBG_OPCODE_RW) {
|
||||||
read_value = qla4_8xxx_md_rw_32(ha, crb_addr, 0, 0);
|
ha->isp_ops->rd_reg_indirect(ha, crb_addr, &read_value);
|
||||||
qla4_8xxx_md_rw_32(ha, crb_addr, read_value, 1);
|
ha->isp_ops->wr_reg_indirect(ha, crb_addr, read_value);
|
||||||
opcode &= ~QLA8XXX_DBG_OPCODE_RW;
|
opcode &= ~QLA8XXX_DBG_OPCODE_RW;
|
||||||
}
|
}
|
||||||
if (opcode & QLA8XXX_DBG_OPCODE_AND) {
|
if (opcode & QLA8XXX_DBG_OPCODE_AND) {
|
||||||
read_value = qla4_8xxx_md_rw_32(ha, crb_addr, 0, 0);
|
ha->isp_ops->rd_reg_indirect(ha, crb_addr, &read_value);
|
||||||
read_value &= crb_entry->value_2;
|
read_value &= crb_entry->value_2;
|
||||||
opcode &= ~QLA8XXX_DBG_OPCODE_AND;
|
opcode &= ~QLA8XXX_DBG_OPCODE_AND;
|
||||||
if (opcode & QLA8XXX_DBG_OPCODE_OR) {
|
if (opcode & QLA8XXX_DBG_OPCODE_OR) {
|
||||||
read_value |= crb_entry->value_3;
|
read_value |= crb_entry->value_3;
|
||||||
opcode &= ~QLA8XXX_DBG_OPCODE_OR;
|
opcode &= ~QLA8XXX_DBG_OPCODE_OR;
|
||||||
}
|
}
|
||||||
qla4_8xxx_md_rw_32(ha, crb_addr, read_value, 1);
|
ha->isp_ops->wr_reg_indirect(ha, crb_addr, read_value);
|
||||||
}
|
}
|
||||||
if (opcode & QLA8XXX_DBG_OPCODE_OR) {
|
if (opcode & QLA8XXX_DBG_OPCODE_OR) {
|
||||||
read_value = qla4_8xxx_md_rw_32(ha, crb_addr, 0, 0);
|
ha->isp_ops->rd_reg_indirect(ha, crb_addr, &read_value);
|
||||||
read_value |= crb_entry->value_3;
|
read_value |= crb_entry->value_3;
|
||||||
qla4_8xxx_md_rw_32(ha, crb_addr, read_value, 1);
|
ha->isp_ops->wr_reg_indirect(ha, crb_addr, read_value);
|
||||||
opcode &= ~QLA8XXX_DBG_OPCODE_OR;
|
opcode &= ~QLA8XXX_DBG_OPCODE_OR;
|
||||||
}
|
}
|
||||||
if (opcode & QLA8XXX_DBG_OPCODE_POLL) {
|
if (opcode & QLA8XXX_DBG_OPCODE_POLL) {
|
||||||
poll_time = crb_entry->crb_strd.poll_timeout;
|
poll_time = crb_entry->crb_strd.poll_timeout;
|
||||||
wtime = jiffies + poll_time;
|
wtime = jiffies + poll_time;
|
||||||
read_value = qla4_8xxx_md_rw_32(ha, crb_addr, 0, 0);
|
ha->isp_ops->rd_reg_indirect(ha, crb_addr, &read_value);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if ((read_value & crb_entry->value_2) ==
|
if ((read_value & crb_entry->value_2) ==
|
||||||
crb_entry->value_1)
|
crb_entry->value_1) {
|
||||||
break;
|
break;
|
||||||
else if (time_after_eq(jiffies, wtime)) {
|
} else if (time_after_eq(jiffies, wtime)) {
|
||||||
/* capturing dump failed */
|
/* capturing dump failed */
|
||||||
rval = QLA_ERROR;
|
rval = QLA_ERROR;
|
||||||
break;
|
break;
|
||||||
} else
|
} else {
|
||||||
read_value = qla4_8xxx_md_rw_32(ha,
|
ha->isp_ops->rd_reg_indirect(ha,
|
||||||
crb_addr, 0, 0);
|
crb_addr, &read_value);
|
||||||
|
}
|
||||||
} while (1);
|
} while (1);
|
||||||
opcode &= ~QLA8XXX_DBG_OPCODE_POLL;
|
opcode &= ~QLA8XXX_DBG_OPCODE_POLL;
|
||||||
}
|
}
|
||||||
|
@ -1794,7 +1812,7 @@ static int qla4_8xxx_minidump_process_control(struct scsi_qla_host *ha,
|
||||||
addr = crb_addr;
|
addr = crb_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
read_value = qla4_8xxx_md_rw_32(ha, addr, 0, 0);
|
ha->isp_ops->rd_reg_indirect(ha, addr, &read_value);
|
||||||
index = crb_entry->crb_ctrl.state_index_v;
|
index = crb_entry->crb_ctrl.state_index_v;
|
||||||
tmplt_hdr->saved_state_array[index] = read_value;
|
tmplt_hdr->saved_state_array[index] = read_value;
|
||||||
opcode &= ~QLA8XXX_DBG_OPCODE_RDSTATE;
|
opcode &= ~QLA8XXX_DBG_OPCODE_RDSTATE;
|
||||||
|
@ -1816,7 +1834,7 @@ static int qla4_8xxx_minidump_process_control(struct scsi_qla_host *ha,
|
||||||
read_value = crb_entry->value_1;
|
read_value = crb_entry->value_1;
|
||||||
}
|
}
|
||||||
|
|
||||||
qla4_8xxx_md_rw_32(ha, addr, read_value, 1);
|
ha->isp_ops->wr_reg_indirect(ha, addr, read_value);
|
||||||
opcode &= ~QLA8XXX_DBG_OPCODE_WRSTATE;
|
opcode &= ~QLA8XXX_DBG_OPCODE_WRSTATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1883,8 +1901,8 @@ static void qla4_8xxx_minidump_process_rdmux(struct scsi_qla_host *ha,
|
||||||
loop_cnt = mux_hdr->op_count;
|
loop_cnt = mux_hdr->op_count;
|
||||||
|
|
||||||
for (i = 0; i < loop_cnt; i++) {
|
for (i = 0; i < loop_cnt; i++) {
|
||||||
qla4_8xxx_md_rw_32(ha, s_addr, s_value, 1);
|
ha->isp_ops->wr_reg_indirect(ha, s_addr, s_value);
|
||||||
r_value = qla4_8xxx_md_rw_32(ha, r_addr, 0, 0);
|
ha->isp_ops->rd_reg_indirect(ha, r_addr, &r_value);
|
||||||
*data_ptr++ = cpu_to_le32(s_value);
|
*data_ptr++ = cpu_to_le32(s_value);
|
||||||
*data_ptr++ = cpu_to_le32(r_value);
|
*data_ptr++ = cpu_to_le32(r_value);
|
||||||
s_value += s_stride;
|
s_value += s_stride;
|
||||||
|
@ -1913,11 +1931,11 @@ static void qla4_8xxx_minidump_process_l1cache(struct scsi_qla_host *ha,
|
||||||
r_cnt = cache_hdr->read_ctrl.read_addr_cnt;
|
r_cnt = cache_hdr->read_ctrl.read_addr_cnt;
|
||||||
|
|
||||||
for (i = 0; i < loop_count; i++) {
|
for (i = 0; i < loop_count; i++) {
|
||||||
qla4_8xxx_md_rw_32(ha, t_r_addr, t_value, 1);
|
ha->isp_ops->wr_reg_indirect(ha, t_r_addr, t_value);
|
||||||
qla4_8xxx_md_rw_32(ha, c_addr, c_value_w, 1);
|
ha->isp_ops->wr_reg_indirect(ha, c_addr, c_value_w);
|
||||||
addr = r_addr;
|
addr = r_addr;
|
||||||
for (k = 0; k < r_cnt; k++) {
|
for (k = 0; k < r_cnt; k++) {
|
||||||
r_value = qla4_8xxx_md_rw_32(ha, addr, 0, 0);
|
ha->isp_ops->rd_reg_indirect(ha, addr, &r_value);
|
||||||
*data_ptr++ = cpu_to_le32(r_value);
|
*data_ptr++ = cpu_to_le32(r_value);
|
||||||
addr += cache_hdr->read_ctrl.read_addr_stride;
|
addr += cache_hdr->read_ctrl.read_addr_stride;
|
||||||
}
|
}
|
||||||
|
@ -1944,10 +1962,10 @@ static void qla4_8xxx_minidump_process_queue(struct scsi_qla_host *ha,
|
||||||
loop_cnt = q_hdr->op_count;
|
loop_cnt = q_hdr->op_count;
|
||||||
|
|
||||||
for (i = 0; i < loop_cnt; i++) {
|
for (i = 0; i < loop_cnt; i++) {
|
||||||
qla4_8xxx_md_rw_32(ha, s_addr, qid, 1);
|
ha->isp_ops->wr_reg_indirect(ha, s_addr, qid);
|
||||||
r_addr = q_hdr->read_addr;
|
r_addr = q_hdr->read_addr;
|
||||||
for (k = 0; k < r_cnt; k++) {
|
for (k = 0; k < r_cnt; k++) {
|
||||||
r_value = qla4_8xxx_md_rw_32(ha, r_addr, 0, 0);
|
ha->isp_ops->rd_reg_indirect(ha, r_addr, &r_value);
|
||||||
*data_ptr++ = cpu_to_le32(r_value);
|
*data_ptr++ = cpu_to_le32(r_value);
|
||||||
r_addr += r_stride;
|
r_addr += r_stride;
|
||||||
}
|
}
|
||||||
|
@ -1978,11 +1996,11 @@ static void qla4_82xx_minidump_process_rdrom(struct scsi_qla_host *ha,
|
||||||
__func__, r_addr, loop_cnt));
|
__func__, r_addr, loop_cnt));
|
||||||
|
|
||||||
for (i = 0; i < loop_cnt; i++) {
|
for (i = 0; i < loop_cnt; i++) {
|
||||||
qla4_8xxx_md_rw_32(ha, MD_DIRECT_ROM_WINDOW,
|
ha->isp_ops->wr_reg_indirect(ha, MD_DIRECT_ROM_WINDOW,
|
||||||
(r_addr & 0xFFFF0000), 1);
|
(r_addr & 0xFFFF0000));
|
||||||
r_value = qla4_8xxx_md_rw_32(ha,
|
ha->isp_ops->rd_reg_indirect(ha,
|
||||||
MD_DIRECT_ROM_READ_BASE +
|
MD_DIRECT_ROM_READ_BASE + (r_addr & 0x0000FFFF),
|
||||||
(r_addr & 0x0000FFFF), 0, 0);
|
&r_value);
|
||||||
*data_ptr++ = cpu_to_le32(r_value);
|
*data_ptr++ = cpu_to_le32(r_value);
|
||||||
r_addr += sizeof(uint32_t);
|
r_addr += sizeof(uint32_t);
|
||||||
}
|
}
|
||||||
|
@ -2032,17 +2050,19 @@ static int qla4_8xxx_minidump_process_rdmem(struct scsi_qla_host *ha,
|
||||||
|
|
||||||
write_lock_irqsave(&ha->hw_lock, flags);
|
write_lock_irqsave(&ha->hw_lock, flags);
|
||||||
for (i = 0; i < loop_cnt; i++) {
|
for (i = 0; i < loop_cnt; i++) {
|
||||||
qla4_8xxx_md_rw_32(ha, MD_MIU_TEST_AGT_ADDR_LO, r_addr, 1);
|
ha->isp_ops->wr_reg_indirect(ha, MD_MIU_TEST_AGT_ADDR_LO,
|
||||||
|
r_addr);
|
||||||
r_value = 0;
|
r_value = 0;
|
||||||
qla4_8xxx_md_rw_32(ha, MD_MIU_TEST_AGT_ADDR_HI, r_value, 1);
|
ha->isp_ops->wr_reg_indirect(ha, MD_MIU_TEST_AGT_ADDR_HI,
|
||||||
|
r_value);
|
||||||
r_value = MIU_TA_CTL_ENABLE;
|
r_value = MIU_TA_CTL_ENABLE;
|
||||||
qla4_8xxx_md_rw_32(ha, MD_MIU_TEST_AGT_CTRL, r_value, 1);
|
ha->isp_ops->wr_reg_indirect(ha, MD_MIU_TEST_AGT_CTRL, r_value);
|
||||||
r_value = MIU_TA_CTL_START_ENABLE;
|
r_value = MIU_TA_CTL_START_ENABLE;
|
||||||
qla4_8xxx_md_rw_32(ha, MD_MIU_TEST_AGT_CTRL, r_value, 1);
|
ha->isp_ops->wr_reg_indirect(ha, MD_MIU_TEST_AGT_CTRL, r_value);
|
||||||
|
|
||||||
for (j = 0; j < MAX_CTL_CHECK; j++) {
|
for (j = 0; j < MAX_CTL_CHECK; j++) {
|
||||||
r_value = qla4_8xxx_md_rw_32(ha, MD_MIU_TEST_AGT_CTRL,
|
ha->isp_ops->rd_reg_indirect(ha, MD_MIU_TEST_AGT_CTRL,
|
||||||
0, 0);
|
&r_value);
|
||||||
if ((r_value & MIU_TA_CTL_BUSY) == 0)
|
if ((r_value & MIU_TA_CTL_BUSY) == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2056,9 +2076,9 @@ static int qla4_8xxx_minidump_process_rdmem(struct scsi_qla_host *ha,
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j = 0; j < 4; j++) {
|
for (j = 0; j < 4; j++) {
|
||||||
r_data = qla4_8xxx_md_rw_32(ha,
|
ha->isp_ops->rd_reg_indirect(ha,
|
||||||
MD_MIU_TEST_AGT_RDDATA[j],
|
MD_MIU_TEST_AGT_RDDATA[j],
|
||||||
0, 0);
|
&r_data);
|
||||||
*data_ptr++ = cpu_to_le32(r_data);
|
*data_ptr++ = cpu_to_le32(r_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2277,19 +2297,18 @@ qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha)
|
||||||
uint32_t old_count, count;
|
uint32_t old_count, count;
|
||||||
int need_reset = 0, peg_stuck = 1;
|
int need_reset = 0, peg_stuck = 1;
|
||||||
|
|
||||||
need_reset = qla4_8xxx_need_reset(ha);
|
need_reset = ha->isp_ops->need_reset(ha);
|
||||||
|
old_count = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_ALIVE_COUNTER);
|
||||||
old_count = qla4_82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER);
|
|
||||||
|
|
||||||
for (i = 0; i < 10; i++) {
|
for (i = 0; i < 10; i++) {
|
||||||
timeout = msleep_interruptible(200);
|
timeout = msleep_interruptible(200);
|
||||||
if (timeout) {
|
if (timeout) {
|
||||||
qla4_82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
|
qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
|
||||||
QLA8XXX_DEV_FAILED);
|
QLA8XXX_DEV_FAILED);
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
count = qla4_82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER);
|
count = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_ALIVE_COUNTER);
|
||||||
if (count != old_count)
|
if (count != old_count)
|
||||||
peg_stuck = 0;
|
peg_stuck = 0;
|
||||||
}
|
}
|
||||||
|
@ -2297,13 +2316,13 @@ qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha)
|
||||||
if (need_reset) {
|
if (need_reset) {
|
||||||
/* We are trying to perform a recovery here. */
|
/* We are trying to perform a recovery here. */
|
||||||
if (peg_stuck)
|
if (peg_stuck)
|
||||||
qla4_82xx_rom_lock_recovery(ha);
|
ha->isp_ops->rom_lock_recovery(ha);
|
||||||
goto dev_initialize;
|
goto dev_initialize;
|
||||||
} else {
|
} else {
|
||||||
/* Start of day for this ha context. */
|
/* Start of day for this ha context. */
|
||||||
if (peg_stuck) {
|
if (peg_stuck) {
|
||||||
/* Either we are the first or recovery in progress. */
|
/* Either we are the first or recovery in progress. */
|
||||||
qla4_82xx_rom_lock_recovery(ha);
|
ha->isp_ops->rom_lock_recovery(ha);
|
||||||
goto dev_initialize;
|
goto dev_initialize;
|
||||||
} else {
|
} else {
|
||||||
/* Firmware already running. */
|
/* Firmware already running. */
|
||||||
|
@ -2315,12 +2334,14 @@ qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha)
|
||||||
dev_initialize:
|
dev_initialize:
|
||||||
/* set to DEV_INITIALIZING */
|
/* set to DEV_INITIALIZING */
|
||||||
ql4_printk(KERN_INFO, ha, "HW State: INITIALIZING\n");
|
ql4_printk(KERN_INFO, ha, "HW State: INITIALIZING\n");
|
||||||
qla4_82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA8XXX_DEV_INITIALIZING);
|
qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
|
||||||
|
QLA8XXX_DEV_INITIALIZING);
|
||||||
|
|
||||||
/* Driver that sets device state to initializating sets IDC version */
|
/* Driver that sets device state to initializating sets IDC version */
|
||||||
qla4_82xx_wr_32(ha, QLA82XX_CRB_DRV_IDC_VERSION, QLA82XX_IDC_VERSION);
|
qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_IDC_VERSION,
|
||||||
|
QLA82XX_IDC_VERSION);
|
||||||
|
|
||||||
qla4_82xx_idc_unlock(ha);
|
ha->isp_ops->idc_unlock(ha);
|
||||||
if (ql4xenablemd && test_bit(AF_FW_RECOVERY, &ha->flags) &&
|
if (ql4xenablemd && test_bit(AF_FW_RECOVERY, &ha->flags) &&
|
||||||
!test_and_set_bit(AF_82XX_FW_DUMPED, &ha->flags)) {
|
!test_and_set_bit(AF_82XX_FW_DUMPED, &ha->flags)) {
|
||||||
if (!qla4_8xxx_collect_md_data(ha)) {
|
if (!qla4_8xxx_collect_md_data(ha)) {
|
||||||
|
@ -2330,19 +2351,20 @@ dev_initialize:
|
||||||
clear_bit(AF_82XX_FW_DUMPED, &ha->flags);
|
clear_bit(AF_82XX_FW_DUMPED, &ha->flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rval = qla4_82xx_try_start_fw(ha);
|
rval = ha->isp_ops->restart_firmware(ha);
|
||||||
qla4_82xx_idc_lock(ha);
|
ha->isp_ops->idc_lock(ha);
|
||||||
|
|
||||||
if (rval != QLA_SUCCESS) {
|
if (rval != QLA_SUCCESS) {
|
||||||
ql4_printk(KERN_INFO, ha, "HW State: FAILED\n");
|
ql4_printk(KERN_INFO, ha, "HW State: FAILED\n");
|
||||||
qla4_8xxx_clear_drv_active(ha);
|
qla4_8xxx_clear_drv_active(ha);
|
||||||
qla4_82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA8XXX_DEV_FAILED);
|
qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
|
||||||
|
QLA8XXX_DEV_FAILED);
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_ready:
|
dev_ready:
|
||||||
ql4_printk(KERN_INFO, ha, "HW State: READY\n");
|
ql4_printk(KERN_INFO, ha, "HW State: READY\n");
|
||||||
qla4_82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA8XXX_DEV_READY);
|
qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE, QLA8XXX_DEV_READY);
|
||||||
|
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
@ -2436,9 +2458,9 @@ qla4_82xx_need_reset_handler(struct scsi_qla_host *ha)
|
||||||
void
|
void
|
||||||
qla4_8xxx_need_qsnt_handler(struct scsi_qla_host *ha)
|
qla4_8xxx_need_qsnt_handler(struct scsi_qla_host *ha)
|
||||||
{
|
{
|
||||||
qla4_82xx_idc_lock(ha);
|
ha->isp_ops->idc_lock(ha);
|
||||||
qla4_8xxx_set_qsnt_ready(ha);
|
qla4_8xxx_set_qsnt_ready(ha);
|
||||||
qla4_82xx_idc_unlock(ha);
|
ha->isp_ops->idc_unlock(ha);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2454,12 +2476,12 @@ int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha)
|
||||||
unsigned long dev_init_timeout;
|
unsigned long dev_init_timeout;
|
||||||
|
|
||||||
if (!test_bit(AF_INIT_DONE, &ha->flags)) {
|
if (!test_bit(AF_INIT_DONE, &ha->flags)) {
|
||||||
qla4_82xx_idc_lock(ha);
|
ha->isp_ops->idc_lock(ha);
|
||||||
qla4_8xxx_set_drv_active(ha);
|
qla4_8xxx_set_drv_active(ha);
|
||||||
qla4_82xx_idc_unlock(ha);
|
ha->isp_ops->idc_unlock(ha);
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_state = qla4_82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
|
dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE);
|
||||||
DEBUG2(ql4_printk(KERN_INFO, ha, "Device state is 0x%x = %s\n",
|
DEBUG2(ql4_printk(KERN_INFO, ha, "Device state is 0x%x = %s\n",
|
||||||
dev_state, dev_state < MAX_STATES ?
|
dev_state, dev_state < MAX_STATES ?
|
||||||
qdev_state[dev_state] : "Unknown"));
|
qdev_state[dev_state] : "Unknown"));
|
||||||
|
@ -2467,7 +2489,7 @@ int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha)
|
||||||
/* wait for 30 seconds for device to go ready */
|
/* wait for 30 seconds for device to go ready */
|
||||||
dev_init_timeout = jiffies + (ha->nx_dev_init_timeout * HZ);
|
dev_init_timeout = jiffies + (ha->nx_dev_init_timeout * HZ);
|
||||||
|
|
||||||
qla4_82xx_idc_lock(ha);
|
ha->isp_ops->idc_lock(ha);
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
if (time_after_eq(jiffies, dev_init_timeout)) {
|
if (time_after_eq(jiffies, dev_init_timeout)) {
|
||||||
|
@ -2476,11 +2498,11 @@ int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha)
|
||||||
DRIVER_NAME,
|
DRIVER_NAME,
|
||||||
dev_state, dev_state < MAX_STATES ?
|
dev_state, dev_state < MAX_STATES ?
|
||||||
qdev_state[dev_state] : "Unknown");
|
qdev_state[dev_state] : "Unknown");
|
||||||
qla4_82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
|
qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
|
||||||
QLA8XXX_DEV_FAILED);
|
QLA8XXX_DEV_FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_state = qla4_82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
|
dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE);
|
||||||
ql4_printk(KERN_INFO, ha, "Device state is 0x%x = %s\n",
|
ql4_printk(KERN_INFO, ha, "Device state is 0x%x = %s\n",
|
||||||
dev_state, dev_state < MAX_STATES ?
|
dev_state, dev_state < MAX_STATES ?
|
||||||
qdev_state[dev_state] : "Unknown");
|
qdev_state[dev_state] : "Unknown");
|
||||||
|
@ -2493,9 +2515,9 @@ int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha)
|
||||||
rval = qla4_8xxx_device_bootstrap(ha);
|
rval = qla4_8xxx_device_bootstrap(ha);
|
||||||
goto exit;
|
goto exit;
|
||||||
case QLA8XXX_DEV_INITIALIZING:
|
case QLA8XXX_DEV_INITIALIZING:
|
||||||
qla4_82xx_idc_unlock(ha);
|
ha->isp_ops->idc_unlock(ha);
|
||||||
msleep(1000);
|
msleep(1000);
|
||||||
qla4_82xx_idc_lock(ha);
|
ha->isp_ops->idc_lock(ha);
|
||||||
break;
|
break;
|
||||||
case QLA8XXX_DEV_NEED_RESET:
|
case QLA8XXX_DEV_NEED_RESET:
|
||||||
if (!ql4xdontresethba) {
|
if (!ql4xdontresethba) {
|
||||||
|
@ -2505,9 +2527,9 @@ int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha)
|
||||||
dev_init_timeout = jiffies +
|
dev_init_timeout = jiffies +
|
||||||
(ha->nx_dev_init_timeout * HZ);
|
(ha->nx_dev_init_timeout * HZ);
|
||||||
} else {
|
} else {
|
||||||
qla4_82xx_idc_unlock(ha);
|
ha->isp_ops->idc_unlock(ha);
|
||||||
msleep(1000);
|
msleep(1000);
|
||||||
qla4_82xx_idc_lock(ha);
|
ha->isp_ops->idc_lock(ha);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case QLA8XXX_DEV_NEED_QUIESCENT:
|
case QLA8XXX_DEV_NEED_QUIESCENT:
|
||||||
|
@ -2515,26 +2537,26 @@ int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha)
|
||||||
qla4_8xxx_need_qsnt_handler(ha);
|
qla4_8xxx_need_qsnt_handler(ha);
|
||||||
break;
|
break;
|
||||||
case QLA8XXX_DEV_QUIESCENT:
|
case QLA8XXX_DEV_QUIESCENT:
|
||||||
qla4_82xx_idc_unlock(ha);
|
ha->isp_ops->idc_unlock(ha);
|
||||||
msleep(1000);
|
msleep(1000);
|
||||||
qla4_82xx_idc_lock(ha);
|
ha->isp_ops->idc_lock(ha);
|
||||||
break;
|
break;
|
||||||
case QLA8XXX_DEV_FAILED:
|
case QLA8XXX_DEV_FAILED:
|
||||||
qla4_82xx_idc_unlock(ha);
|
ha->isp_ops->idc_unlock(ha);
|
||||||
qla4xxx_dead_adapter_cleanup(ha);
|
qla4xxx_dead_adapter_cleanup(ha);
|
||||||
rval = QLA_ERROR;
|
rval = QLA_ERROR;
|
||||||
qla4_82xx_idc_lock(ha);
|
ha->isp_ops->idc_lock(ha);
|
||||||
goto exit;
|
goto exit;
|
||||||
default:
|
default:
|
||||||
qla4_82xx_idc_unlock(ha);
|
ha->isp_ops->idc_unlock(ha);
|
||||||
qla4xxx_dead_adapter_cleanup(ha);
|
qla4xxx_dead_adapter_cleanup(ha);
|
||||||
rval = QLA_ERROR;
|
rval = QLA_ERROR;
|
||||||
qla4_82xx_idc_lock(ha);
|
ha->isp_ops->idc_lock(ha);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exit:
|
exit:
|
||||||
qla4_82xx_idc_unlock(ha);
|
ha->isp_ops->idc_unlock(ha);
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2822,6 +2844,39 @@ qla4_82xx_get_idc_param(struct scsi_qla_host *ha)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void qla4_82xx_queue_mbox_cmd(struct scsi_qla_host *ha, uint32_t *mbx_cmd,
|
||||||
|
int in_count)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Load all mailbox registers, except mailbox 0. */
|
||||||
|
for (i = 1; i < in_count; i++)
|
||||||
|
writel(mbx_cmd[i], &ha->qla4_82xx_reg->mailbox_in[i]);
|
||||||
|
|
||||||
|
/* Wakeup firmware */
|
||||||
|
writel(mbx_cmd[0], &ha->qla4_82xx_reg->mailbox_in[0]);
|
||||||
|
readl(&ha->qla4_82xx_reg->mailbox_in[0]);
|
||||||
|
writel(HINT_MBX_INT_PENDING, &ha->qla4_82xx_reg->hint);
|
||||||
|
readl(&ha->qla4_82xx_reg->hint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void qla4_82xx_process_mbox_intr(struct scsi_qla_host *ha, int out_count)
|
||||||
|
{
|
||||||
|
int intr_status;
|
||||||
|
|
||||||
|
intr_status = readl(&ha->qla4_82xx_reg->host_int);
|
||||||
|
if (intr_status & ISRX_82XX_RISC_INT) {
|
||||||
|
ha->mbox_status_count = out_count;
|
||||||
|
intr_status = readl(&ha->qla4_82xx_reg->host_status);
|
||||||
|
ha->isp_ops->interrupt_service_routine(ha, intr_status);
|
||||||
|
|
||||||
|
if (test_bit(AF_INTERRUPTS_ON, &ha->flags) &&
|
||||||
|
test_bit(AF_INTx_ENABLED, &ha->flags))
|
||||||
|
qla4_82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg,
|
||||||
|
0xfbff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
qla4_8xxx_get_flash_info(struct scsi_qla_host *ha)
|
qla4_8xxx_get_flash_info(struct scsi_qla_host *ha)
|
||||||
{
|
{
|
||||||
|
|
|
@ -579,6 +579,40 @@ enum {
|
||||||
#define QLA82XX_CRB_DEV_PART_INFO (QLA82XX_CAM_RAM(0x14c))
|
#define QLA82XX_CRB_DEV_PART_INFO (QLA82XX_CAM_RAM(0x14c))
|
||||||
#define QLA82XX_CRB_DRV_IDC_VERSION (QLA82XX_CAM_RAM(0x174))
|
#define QLA82XX_CRB_DRV_IDC_VERSION (QLA82XX_CAM_RAM(0x174))
|
||||||
|
|
||||||
|
enum qla_regs {
|
||||||
|
QLA8XXX_PEG_HALT_STATUS1 = 0,
|
||||||
|
QLA8XXX_PEG_HALT_STATUS2,
|
||||||
|
QLA8XXX_PEG_ALIVE_COUNTER,
|
||||||
|
QLA8XXX_CRB_DRV_ACTIVE,
|
||||||
|
QLA8XXX_CRB_DEV_STATE,
|
||||||
|
QLA8XXX_CRB_DRV_STATE,
|
||||||
|
QLA8XXX_CRB_DRV_SCRATCH,
|
||||||
|
QLA8XXX_CRB_DEV_PART_INFO,
|
||||||
|
QLA8XXX_CRB_DRV_IDC_VERSION,
|
||||||
|
QLA8XXX_FW_VERSION_MAJOR,
|
||||||
|
QLA8XXX_FW_VERSION_MINOR,
|
||||||
|
QLA8XXX_FW_VERSION_SUB,
|
||||||
|
QLA8XXX_CRB_CMDPEG_STATE,
|
||||||
|
QLA8XXX_CRB_TEMP_STATE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint32_t qla4_82xx_reg_tbl[] = {
|
||||||
|
QLA82XX_PEG_HALT_STATUS1,
|
||||||
|
QLA82XX_PEG_HALT_STATUS2,
|
||||||
|
QLA82XX_PEG_ALIVE_COUNTER,
|
||||||
|
QLA82XX_CRB_DRV_ACTIVE,
|
||||||
|
QLA82XX_CRB_DEV_STATE,
|
||||||
|
QLA82XX_CRB_DRV_STATE,
|
||||||
|
QLA82XX_CRB_DRV_SCRATCH,
|
||||||
|
QLA82XX_CRB_DEV_PART_INFO,
|
||||||
|
QLA82XX_CRB_DRV_IDC_VERSION,
|
||||||
|
QLA82XX_FW_VERSION_MAJOR,
|
||||||
|
QLA82XX_FW_VERSION_MINOR,
|
||||||
|
QLA82XX_FW_VERSION_SUB,
|
||||||
|
CRB_CMDPEG_STATE,
|
||||||
|
CRB_TEMP_STATE,
|
||||||
|
};
|
||||||
|
|
||||||
/* Every driver should use these Device State */
|
/* Every driver should use these Device State */
|
||||||
#define QLA8XXX_DEV_COLD 1
|
#define QLA8XXX_DEV_COLD 1
|
||||||
#define QLA8XXX_DEV_INITIALIZING 2
|
#define QLA8XXX_DEV_INITIALIZING 2
|
||||||
|
|
|
@ -2420,7 +2420,7 @@ static int qla4_8xxx_check_temp(struct scsi_qla_host *ha)
|
||||||
uint32_t temp, temp_state, temp_val;
|
uint32_t temp, temp_state, temp_val;
|
||||||
int status = QLA_SUCCESS;
|
int status = QLA_SUCCESS;
|
||||||
|
|
||||||
temp = qla4_82xx_rd_32(ha, CRB_TEMP_STATE);
|
temp = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_TEMP_STATE);
|
||||||
|
|
||||||
temp_state = qla82xx_get_temp_state(temp);
|
temp_state = qla82xx_get_temp_state(temp);
|
||||||
temp_val = qla82xx_get_temp_val(temp);
|
temp_val = qla82xx_get_temp_val(temp);
|
||||||
|
@ -2454,9 +2454,11 @@ static int qla4_8xxx_check_temp(struct scsi_qla_host *ha)
|
||||||
static int qla4_8xxx_check_fw_alive(struct scsi_qla_host *ha)
|
static int qla4_8xxx_check_fw_alive(struct scsi_qla_host *ha)
|
||||||
{
|
{
|
||||||
uint32_t fw_heartbeat_counter;
|
uint32_t fw_heartbeat_counter;
|
||||||
|
uint32_t halt_status1, halt_status2;
|
||||||
int status = QLA_SUCCESS;
|
int status = QLA_SUCCESS;
|
||||||
|
|
||||||
fw_heartbeat_counter = qla4_82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER);
|
fw_heartbeat_counter = qla4_8xxx_rd_direct(ha,
|
||||||
|
QLA8XXX_PEG_ALIVE_COUNTER);
|
||||||
/* If PEG_ALIVE_COUNTER is 0xffffffff, AER/EEH is in progress, ignore */
|
/* If PEG_ALIVE_COUNTER is 0xffffffff, AER/EEH is in progress, ignore */
|
||||||
if (fw_heartbeat_counter == 0xffffffff) {
|
if (fw_heartbeat_counter == 0xffffffff) {
|
||||||
DEBUG2(printk(KERN_WARNING "scsi%ld: %s: Device in frozen "
|
DEBUG2(printk(KERN_WARNING "scsi%ld: %s: Device in frozen "
|
||||||
|
@ -2470,18 +2472,18 @@ static int qla4_8xxx_check_fw_alive(struct scsi_qla_host *ha)
|
||||||
/* FW not alive after 2 seconds */
|
/* FW not alive after 2 seconds */
|
||||||
if (ha->seconds_since_last_heartbeat == 2) {
|
if (ha->seconds_since_last_heartbeat == 2) {
|
||||||
ha->seconds_since_last_heartbeat = 0;
|
ha->seconds_since_last_heartbeat = 0;
|
||||||
|
halt_status1 = qla4_8xxx_rd_direct(ha,
|
||||||
|
QLA8XXX_PEG_HALT_STATUS1);
|
||||||
|
halt_status2 = qla4_8xxx_rd_direct(ha,
|
||||||
|
QLA8XXX_PEG_HALT_STATUS2);
|
||||||
|
|
||||||
ql4_printk(KERN_INFO, ha,
|
ql4_printk(KERN_INFO, ha,
|
||||||
"scsi(%ld): %s, Dumping hw/fw registers:\n "
|
"scsi(%ld): %s, Dumping hw/fw registers:\n "
|
||||||
" PEG_HALT_STATUS1: 0x%x, PEG_HALT_STATUS2:"
|
" PEG_HALT_STATUS1: 0x%x, PEG_HALT_STATUS2:"
|
||||||
" 0x%x,\n PEG_NET_0_PC: 0x%x, PEG_NET_1_PC:"
|
" 0x%x,\n PEG_NET_0_PC: 0x%x, PEG_NET_1_PC:"
|
||||||
" 0x%x,\n PEG_NET_2_PC: 0x%x, PEG_NET_3_PC:"
|
" 0x%x,\n PEG_NET_2_PC: 0x%x, PEG_NET_3_PC:"
|
||||||
" 0x%x,\n PEG_NET_4_PC: 0x%x\n",
|
" 0x%x,\n PEG_NET_4_PC: 0x%x\n", ha->host_no,
|
||||||
ha->host_no, __func__,
|
__func__, halt_status1, halt_status2,
|
||||||
qla4_82xx_rd_32(ha,
|
|
||||||
QLA82XX_PEG_HALT_STATUS1),
|
|
||||||
qla4_82xx_rd_32(ha,
|
|
||||||
QLA82XX_PEG_HALT_STATUS2),
|
|
||||||
qla4_82xx_rd_32(ha, QLA82XX_CRB_PEG_NET_0 +
|
qla4_82xx_rd_32(ha, QLA82XX_CRB_PEG_NET_0 +
|
||||||
0x3c),
|
0x3c),
|
||||||
qla4_82xx_rd_32(ha, QLA82XX_CRB_PEG_NET_1 +
|
qla4_82xx_rd_32(ha, QLA82XX_CRB_PEG_NET_1 +
|
||||||
|
@ -2515,7 +2517,7 @@ void qla4_8xxx_watchdog(struct scsi_qla_host *ha)
|
||||||
if (!(test_bit(DPC_RESET_ACTIVE, &ha->dpc_flags) ||
|
if (!(test_bit(DPC_RESET_ACTIVE, &ha->dpc_flags) ||
|
||||||
test_bit(DPC_RESET_HA, &ha->dpc_flags) ||
|
test_bit(DPC_RESET_HA, &ha->dpc_flags) ||
|
||||||
test_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags))) {
|
test_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags))) {
|
||||||
dev_state = qla4_82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
|
dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE);
|
||||||
|
|
||||||
if (qla4_8xxx_check_temp(ha)) {
|
if (qla4_8xxx_check_temp(ha)) {
|
||||||
ql4_printk(KERN_INFO, ha, "disabling pause"
|
ql4_printk(KERN_INFO, ha, "disabling pause"
|
||||||
|
@ -2547,8 +2549,8 @@ void qla4_8xxx_watchdog(struct scsi_qla_host *ha)
|
||||||
qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x98,
|
qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x98,
|
||||||
CRB_NIU_XG_PAUSE_CTL_P0 |
|
CRB_NIU_XG_PAUSE_CTL_P0 |
|
||||||
CRB_NIU_XG_PAUSE_CTL_P1);
|
CRB_NIU_XG_PAUSE_CTL_P1);
|
||||||
halt_status = qla4_82xx_rd_32(ha,
|
halt_status = qla4_8xxx_rd_direct(ha,
|
||||||
QLA82XX_PEG_HALT_STATUS1);
|
QLA8XXX_PEG_HALT_STATUS1);
|
||||||
|
|
||||||
if (QLA82XX_FWERROR_CODE(halt_status) == 0x67)
|
if (QLA82XX_FWERROR_CODE(halt_status) == 0x67)
|
||||||
ql4_printk(KERN_ERR, ha, "%s:"
|
ql4_printk(KERN_ERR, ha, "%s:"
|
||||||
|
@ -3040,9 +3042,10 @@ recover_ha_init_adapter:
|
||||||
* with multiple resets in the same thread,
|
* with multiple resets in the same thread,
|
||||||
* utilize DPC to retry */
|
* utilize DPC to retry */
|
||||||
if (is_qla8022(ha)) {
|
if (is_qla8022(ha)) {
|
||||||
qla4_82xx_idc_lock(ha);
|
ha->isp_ops->idc_lock(ha);
|
||||||
dev_state = qla4_82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
|
dev_state = qla4_8xxx_rd_direct(ha,
|
||||||
qla4_82xx_idc_unlock(ha);
|
QLA8XXX_CRB_DEV_STATE);
|
||||||
|
ha->isp_ops->idc_unlock(ha);
|
||||||
if (dev_state == QLA8XXX_DEV_FAILED) {
|
if (dev_state == QLA8XXX_DEV_FAILED) {
|
||||||
ql4_printk(KERN_INFO, ha, "%s: don't retry "
|
ql4_printk(KERN_INFO, ha, "%s: don't retry "
|
||||||
"recover adapter. H/W is in Failed "
|
"recover adapter. H/W is in Failed "
|
||||||
|
@ -3385,10 +3388,10 @@ static void qla4xxx_do_dpc(struct work_struct *work)
|
||||||
|
|
||||||
if (is_qla8022(ha)) {
|
if (is_qla8022(ha)) {
|
||||||
if (test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags)) {
|
if (test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags)) {
|
||||||
qla4_82xx_idc_lock(ha);
|
ha->isp_ops->idc_lock(ha);
|
||||||
qla4_82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
|
qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
|
||||||
QLA8XXX_DEV_FAILED);
|
QLA8XXX_DEV_FAILED);
|
||||||
qla4_82xx_idc_unlock(ha);
|
ha->isp_ops->idc_unlock(ha);
|
||||||
ql4_printk(KERN_INFO, ha, "HW State: FAILED\n");
|
ql4_printk(KERN_INFO, ha, "HW State: FAILED\n");
|
||||||
qla4_8xxx_device_state_handler(ha);
|
qla4_8xxx_device_state_handler(ha);
|
||||||
}
|
}
|
||||||
|
@ -3512,9 +3515,9 @@ static void qla4xxx_free_adapter(struct scsi_qla_host *ha)
|
||||||
ha->isp_ops->reset_firmware(ha);
|
ha->isp_ops->reset_firmware(ha);
|
||||||
|
|
||||||
if (is_qla8022(ha)) {
|
if (is_qla8022(ha)) {
|
||||||
qla4_82xx_idc_lock(ha);
|
ha->isp_ops->idc_lock(ha);
|
||||||
qla4_8xxx_clear_drv_active(ha);
|
qla4_8xxx_clear_drv_active(ha);
|
||||||
qla4_82xx_idc_unlock(ha);
|
ha->isp_ops->idc_unlock(ha);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Detach interrupts */
|
/* Detach interrupts */
|
||||||
|
@ -3658,6 +3661,8 @@ static struct isp_operations qla4xxx_isp_ops = {
|
||||||
.rd_shdw_req_q_out = qla4xxx_rd_shdw_req_q_out,
|
.rd_shdw_req_q_out = qla4xxx_rd_shdw_req_q_out,
|
||||||
.rd_shdw_rsp_q_in = qla4xxx_rd_shdw_rsp_q_in,
|
.rd_shdw_rsp_q_in = qla4xxx_rd_shdw_rsp_q_in,
|
||||||
.get_sys_info = qla4xxx_get_sys_info,
|
.get_sys_info = qla4xxx_get_sys_info,
|
||||||
|
.queue_mailbox_command = qla4xxx_queue_mbox_cmd,
|
||||||
|
.process_mailbox_interrupt = qla4xxx_process_mbox_intr,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct isp_operations qla4_82xx_isp_ops = {
|
static struct isp_operations qla4_82xx_isp_ops = {
|
||||||
|
@ -3666,8 +3671,10 @@ static struct isp_operations qla4_82xx_isp_ops = {
|
||||||
.disable_intrs = qla4_82xx_disable_intrs,
|
.disable_intrs = qla4_82xx_disable_intrs,
|
||||||
.enable_intrs = qla4_82xx_enable_intrs,
|
.enable_intrs = qla4_82xx_enable_intrs,
|
||||||
.start_firmware = qla4_8xxx_load_risc,
|
.start_firmware = qla4_8xxx_load_risc,
|
||||||
|
.restart_firmware = qla4_82xx_try_start_fw,
|
||||||
.intr_handler = qla4_82xx_intr_handler,
|
.intr_handler = qla4_82xx_intr_handler,
|
||||||
.interrupt_service_routine = qla4_82xx_interrupt_service_routine,
|
.interrupt_service_routine = qla4_82xx_interrupt_service_routine,
|
||||||
|
.need_reset = qla4_8xxx_need_reset,
|
||||||
.reset_chip = qla4_82xx_isp_reset,
|
.reset_chip = qla4_82xx_isp_reset,
|
||||||
.reset_firmware = qla4_8xxx_stop_firmware,
|
.reset_firmware = qla4_8xxx_stop_firmware,
|
||||||
.queue_iocb = qla4_82xx_queue_iocb,
|
.queue_iocb = qla4_82xx_queue_iocb,
|
||||||
|
@ -3675,6 +3682,15 @@ static struct isp_operations qla4_82xx_isp_ops = {
|
||||||
.rd_shdw_req_q_out = qla4_82xx_rd_shdw_req_q_out,
|
.rd_shdw_req_q_out = qla4_82xx_rd_shdw_req_q_out,
|
||||||
.rd_shdw_rsp_q_in = qla4_82xx_rd_shdw_rsp_q_in,
|
.rd_shdw_rsp_q_in = qla4_82xx_rd_shdw_rsp_q_in,
|
||||||
.get_sys_info = qla4_8xxx_get_sys_info,
|
.get_sys_info = qla4_8xxx_get_sys_info,
|
||||||
|
.rd_reg_direct = qla4_82xx_rd_32,
|
||||||
|
.wr_reg_direct = qla4_82xx_wr_32,
|
||||||
|
.rd_reg_indirect = qla4_82xx_md_rd_32,
|
||||||
|
.wr_reg_indirect = qla4_82xx_md_wr_32,
|
||||||
|
.idc_lock = qla4_82xx_idc_lock,
|
||||||
|
.idc_unlock = qla4_82xx_idc_unlock,
|
||||||
|
.rom_lock_recovery = qla4_82xx_rom_lock_recovery,
|
||||||
|
.queue_mailbox_command = qla4_82xx_queue_mbox_cmd,
|
||||||
|
.process_mailbox_interrupt = qla4_82xx_process_mbox_intr,
|
||||||
};
|
};
|
||||||
|
|
||||||
uint16_t qla4xxx_rd_shdw_req_q_out(struct scsi_qla_host *ha)
|
uint16_t qla4xxx_rd_shdw_req_q_out(struct scsi_qla_host *ha)
|
||||||
|
@ -5075,6 +5091,7 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
|
||||||
/* Setup Runtime configurable options */
|
/* Setup Runtime configurable options */
|
||||||
if (is_qla8022(ha)) {
|
if (is_qla8022(ha)) {
|
||||||
ha->isp_ops = &qla4_82xx_isp_ops;
|
ha->isp_ops = &qla4_82xx_isp_ops;
|
||||||
|
ha->reg_tbl = (uint32_t *) qla4_82xx_reg_tbl;
|
||||||
rwlock_init(&ha->hw_lock);
|
rwlock_init(&ha->hw_lock);
|
||||||
ha->qdr_sn_window = -1;
|
ha->qdr_sn_window = -1;
|
||||||
ha->ddr_mn_window = -1;
|
ha->ddr_mn_window = -1;
|
||||||
|
@ -5161,9 +5178,10 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
|
||||||
init_retry_count++ < MAX_INIT_RETRIES) {
|
init_retry_count++ < MAX_INIT_RETRIES) {
|
||||||
|
|
||||||
if (is_qla8022(ha)) {
|
if (is_qla8022(ha)) {
|
||||||
qla4_82xx_idc_lock(ha);
|
ha->isp_ops->idc_lock(ha);
|
||||||
dev_state = qla4_82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
|
dev_state = qla4_8xxx_rd_direct(ha,
|
||||||
qla4_82xx_idc_unlock(ha);
|
QLA82XX_CRB_DEV_STATE);
|
||||||
|
ha->isp_ops->idc_unlock(ha);
|
||||||
if (dev_state == QLA8XXX_DEV_FAILED) {
|
if (dev_state == QLA8XXX_DEV_FAILED) {
|
||||||
ql4_printk(KERN_WARNING, ha, "%s: don't retry "
|
ql4_printk(KERN_WARNING, ha, "%s: don't retry "
|
||||||
"initialize adapter. H/W is in failed state\n",
|
"initialize adapter. H/W is in failed state\n",
|
||||||
|
@ -5186,10 +5204,10 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
|
||||||
if (is_qla8022(ha) && ql4xdontresethba) {
|
if (is_qla8022(ha) && ql4xdontresethba) {
|
||||||
/* Put the device in failed state. */
|
/* Put the device in failed state. */
|
||||||
DEBUG2(printk(KERN_ERR "HW STATE: FAILED\n"));
|
DEBUG2(printk(KERN_ERR "HW STATE: FAILED\n"));
|
||||||
qla4_82xx_idc_lock(ha);
|
ha->isp_ops->idc_lock(ha);
|
||||||
qla4_82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
|
qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
|
||||||
QLA8XXX_DEV_FAILED);
|
QLA8XXX_DEV_FAILED);
|
||||||
qla4_82xx_idc_unlock(ha);
|
ha->isp_ops->idc_unlock(ha);
|
||||||
}
|
}
|
||||||
ret = -ENODEV;
|
ret = -ENODEV;
|
||||||
goto remove_host;
|
goto remove_host;
|
||||||
|
@ -6033,31 +6051,29 @@ static uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha)
|
||||||
"0x%x is the owner\n", ha->host_no, __func__,
|
"0x%x is the owner\n", ha->host_no, __func__,
|
||||||
ha->pdev->devfn);
|
ha->pdev->devfn);
|
||||||
|
|
||||||
qla4_82xx_idc_lock(ha);
|
ha->isp_ops->idc_lock(ha);
|
||||||
qla4_82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
|
qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
|
||||||
QLA8XXX_DEV_COLD);
|
QLA8XXX_DEV_COLD);
|
||||||
|
qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_IDC_VERSION,
|
||||||
qla4_82xx_wr_32(ha, QLA82XX_CRB_DRV_IDC_VERSION,
|
QLA82XX_IDC_VERSION);
|
||||||
QLA82XX_IDC_VERSION);
|
ha->isp_ops->idc_unlock(ha);
|
||||||
|
|
||||||
qla4_82xx_idc_unlock(ha);
|
|
||||||
clear_bit(AF_FW_RECOVERY, &ha->flags);
|
clear_bit(AF_FW_RECOVERY, &ha->flags);
|
||||||
rval = qla4xxx_initialize_adapter(ha, RESET_ADAPTER);
|
rval = qla4xxx_initialize_adapter(ha, RESET_ADAPTER);
|
||||||
qla4_82xx_idc_lock(ha);
|
ha->isp_ops->idc_lock(ha);
|
||||||
|
|
||||||
if (rval != QLA_SUCCESS) {
|
if (rval != QLA_SUCCESS) {
|
||||||
ql4_printk(KERN_INFO, ha, "scsi%ld: %s: HW State: "
|
ql4_printk(KERN_INFO, ha, "scsi%ld: %s: HW State: "
|
||||||
"FAILED\n", ha->host_no, __func__);
|
"FAILED\n", ha->host_no, __func__);
|
||||||
qla4_8xxx_clear_drv_active(ha);
|
qla4_8xxx_clear_drv_active(ha);
|
||||||
qla4_82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
|
qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
|
||||||
QLA8XXX_DEV_FAILED);
|
QLA8XXX_DEV_FAILED);
|
||||||
} else {
|
} else {
|
||||||
ql4_printk(KERN_INFO, ha, "scsi%ld: %s: HW State: "
|
ql4_printk(KERN_INFO, ha, "scsi%ld: %s: HW State: "
|
||||||
"READY\n", ha->host_no, __func__);
|
"READY\n", ha->host_no, __func__);
|
||||||
qla4_82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
|
qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
|
||||||
QLA8XXX_DEV_READY);
|
QLA8XXX_DEV_READY);
|
||||||
/* Clear driver state register */
|
/* Clear driver state register */
|
||||||
qla4_82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, 0);
|
qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_STATE, 0);
|
||||||
qla4_8xxx_set_drv_active(ha);
|
qla4_8xxx_set_drv_active(ha);
|
||||||
ret = qla4xxx_request_irqs(ha);
|
ret = qla4xxx_request_irqs(ha);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -6070,13 +6086,13 @@ static uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha)
|
||||||
rval = QLA_SUCCESS;
|
rval = QLA_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
qla4_82xx_idc_unlock(ha);
|
ha->isp_ops->idc_unlock(ha);
|
||||||
} else {
|
} else {
|
||||||
ql4_printk(KERN_INFO, ha, "scsi%ld: %s: devfn 0x%x is not "
|
ql4_printk(KERN_INFO, ha, "scsi%ld: %s: devfn 0x%x is not "
|
||||||
"the reset owner\n", ha->host_no, __func__,
|
"the reset owner\n", ha->host_no, __func__,
|
||||||
ha->pdev->devfn);
|
ha->pdev->devfn);
|
||||||
if ((qla4_82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE) ==
|
if ((qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE) ==
|
||||||
QLA8XXX_DEV_READY)) {
|
QLA8XXX_DEV_READY)) {
|
||||||
clear_bit(AF_FW_RECOVERY, &ha->flags);
|
clear_bit(AF_FW_RECOVERY, &ha->flags);
|
||||||
rval = qla4xxx_initialize_adapter(ha, RESET_ADAPTER);
|
rval = qla4xxx_initialize_adapter(ha, RESET_ADAPTER);
|
||||||
if (rval == QLA_SUCCESS) {
|
if (rval == QLA_SUCCESS) {
|
||||||
|
@ -6091,9 +6107,9 @@ static uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha)
|
||||||
rval = QLA_SUCCESS;
|
rval = QLA_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
qla4_82xx_idc_lock(ha);
|
ha->isp_ops->idc_lock(ha);
|
||||||
qla4_8xxx_set_drv_active(ha);
|
qla4_8xxx_set_drv_active(ha);
|
||||||
qla4_82xx_idc_unlock(ha);
|
ha->isp_ops->idc_unlock(ha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
clear_bit(DPC_RESET_ACTIVE, &ha->dpc_flags);
|
clear_bit(DPC_RESET_ACTIVE, &ha->dpc_flags);
|
||||||
|
|
Loading…
Reference in New Issue