#define QLA82XX_PCI_CAMQM_2M_BASE (0x000ff800UL)
#define CRB_INDIRECT_2M (0x1e0000UL)
-static inline void *qla82xx_pci_base_offsetfset(struct qla_hw_data *ha,
- unsigned long off)
-{
- if ((off < ha->first_page_group_end) &&
- (off >= ha->first_page_group_start))
- return (void *)(ha->nx_pcibase + off);
-
- return NULL;
-}
-
#define MAX_CRB_XFORM 60
static unsigned long crb_addr_xform[MAX_CRB_XFORM];
int qla82xx_crb_table_initialized;
0,
};
+/* Device states */
+char *qdev_state[] = {
+ "Unknown",
+ "Cold",
+ "Initializing",
+ "Ready",
+ "Need Reset",
+ "Need Quiescent",
+ "Failed",
+ "Quiescent",
+};
+
/*
* In: 'off' is offset from CRB space in 128M pci map
* Out: 'off' is 2M pci map addr
u64 off, void *data, int size)
{
unsigned long flags;
- void *addr;
+ void *addr = NULL;
int ret = 0;
u64 start;
uint8_t *mem_ptr = NULL;
return -1;
}
- addr = qla82xx_pci_base_offsetfset(ha, start);
- if (!addr) {
- write_unlock_irqrestore(&ha->hw_lock, flags);
- mem_base = pci_resource_start(ha->pdev, 0);
- mem_page = start & PAGE_MASK;
- /* Map two pages whenever user tries to access addresses in two
- * consecutive pages.
- */
- if (mem_page != ((start + size - 1) & PAGE_MASK))
- mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE * 2);
- else
- mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE);
- if (mem_ptr == 0UL) {
- *(u8 *)data = 0;
- return -1;
- }
- addr = mem_ptr;
- addr += start & (PAGE_SIZE - 1);
- write_lock_irqsave(&ha->hw_lock, flags);
+ write_unlock_irqrestore(&ha->hw_lock, flags);
+ mem_base = pci_resource_start(ha->pdev, 0);
+ mem_page = start & PAGE_MASK;
+ /* Map two pages whenever user tries to access addresses in two
+ * consecutive pages.
+ */
+ if (mem_page != ((start + size - 1) & PAGE_MASK))
+ mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE * 2);
+ else
+ mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE);
+ if (mem_ptr == 0UL) {
+ *(u8 *)data = 0;
+ return -1;
}
+ addr = mem_ptr;
+ addr += start & (PAGE_SIZE - 1);
+ write_lock_irqsave(&ha->hw_lock, flags);
switch (size) {
case 1:
u64 off, void *data, int size)
{
unsigned long flags;
- void *addr;
+ void *addr = NULL;
int ret = 0;
u64 start;
uint8_t *mem_ptr = NULL;
return -1;
}
- addr = qla82xx_pci_base_offsetfset(ha, start);
- if (!addr) {
- write_unlock_irqrestore(&ha->hw_lock, flags);
- mem_base = pci_resource_start(ha->pdev, 0);
- mem_page = start & PAGE_MASK;
- /* Map two pages whenever user tries to access addresses in two
- * consecutive pages.
- */
- if (mem_page != ((start + size - 1) & PAGE_MASK))
- mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE*2);
- else
- mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE);
- if (mem_ptr == 0UL)
- return -1;
+ write_unlock_irqrestore(&ha->hw_lock, flags);
+ mem_base = pci_resource_start(ha->pdev, 0);
+ mem_page = start & PAGE_MASK;
+ /* Map two pages whenever user tries to access addresses in two
+ * consecutive pages.
+ */
+ if (mem_page != ((start + size - 1) & PAGE_MASK))
+ mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE*2);
+ else
+ mem_ptr = ioremap(mem_base + mem_page, PAGE_SIZE);
+ if (mem_ptr == 0UL)
+ return -1;
- addr = mem_ptr;
- addr += start & (PAGE_SIZE - 1);
- write_lock_irqsave(&ha->hw_lock, flags);
- }
+ addr = mem_ptr;
+ addr += start & (PAGE_SIZE - 1);
+ write_lock_irqsave(&ha->hw_lock, flags);
switch (size) {
case 1:
WRT_REG_DWORD((unsigned long __iomem *)®->rsp_q_out[0], 0);
}
+void qla82xx_reset_adapter(struct scsi_qla_host *vha)
+{
+ struct qla_hw_data *ha = vha->hw;
+ vha->flags.online = 0;
+ qla2x00_try_to_stop_firmware(vha);
+ ha->isp_ops->disable_intrs(ha);
+}
+
int qla82xx_fw_load_from_blob(struct qla_hw_data *ha)
{
u64 *ptr64;
if (RD_REG_DWORD(®->host_int)) {
stat = RD_REG_DWORD(®->host_status);
- if (stat & HSRX_RISC_PAUSED) {
- if (pci_channel_offline(ha->pdev))
- break;
-
- qla_printk(KERN_INFO, ha, "RISC paused\n");
- set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
- qla2xxx_wake_dpc(vha);
- break;
- } else if ((stat & HSRX_RISC_INT) == 0)
+ if ((stat & HSRX_RISC_INT) == 0)
break;
switch (stat & 0xff) {
do {
if (RD_REG_DWORD(®->host_int)) {
stat = RD_REG_DWORD(®->host_status);
- if (stat & HSRX_RISC_PAUSED) {
- if (pci_channel_offline(ha->pdev))
- break;
-
- qla_printk(KERN_INFO, ha, "RISC paused\n");
- set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
- qla2xxx_wake_dpc(vha);
- break;
- } else if ((stat & HSRX_RISC_INT) == 0)
+ if ((stat & HSRX_RISC_INT) == 0)
break;
switch (stat & 0xff) {
}
dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
+ qla_printk(KERN_INFO, ha, "3:Device state is 0x%x = %s\n", dev_state,
+ dev_state < MAX_STATES ? qdev_state[dev_state] : "Unknown");
+
/* Force to DEV_COLD unless someone else is starting a reset */
if (dev_state != QLA82XX_DEV_INITIALIZING) {
qla_printk(KERN_INFO, ha, "HW State: COLD/RE-INIT\n");
qla82xx_device_state_handler(scsi_qla_host_t *vha)
{
uint32_t dev_state;
- uint32_t drv_active;
int rval = QLA_SUCCESS;
unsigned long dev_init_timeout;
struct qla_hw_data *ha = vha->hw;
if (!vha->flags.init_done)
qla82xx_set_drv_active(vha);
- /* Set cold state*/
- if (!PCI_FUNC(ha->pdev->devfn & 1)) {
-
- /* Check if other functions alive, else set dev state
- * to cold
- */
- drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
- drv_active &= ~(1 << (ha->portnum * 4));
- drv_active &= ~(1 << ((ha->portnum + 1) * 4));
-
- dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
- if (!drv_active) {
-
- switch (dev_state) {
- case QLA82XX_DEV_COLD:
- case QLA82XX_DEV_READY:
- case QLA82XX_DEV_INITIALIZING:
- case QLA82XX_DEV_NEED_RESET:
- case QLA82XX_DEV_NEED_QUIESCENT:
- case QLA82XX_DEV_QUIESCENT:
- case QLA82XX_DEV_FAILED:
- break;
- default:
- qla_printk(KERN_INFO, ha,
- "No other function exist,"
- " resetting dev state to COLD\n");
- qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
- QLA82XX_DEV_COLD);
- break;
- }
- }
- }
+ dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
+ qla_printk(KERN_INFO, ha, "1:Device state is 0x%x = %s\n", dev_state,
+ dev_state < MAX_STATES ? qdev_state[dev_state] : "Unknown");
/* wait for 30 seconds for device to go ready */
dev_init_timeout = jiffies + (ha->nx_dev_init_timeout * HZ);
break;
}
dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
+ qla_printk(KERN_INFO, ha,
+ "2:Device state is 0x%x = %s\n", dev_state,
+ dev_state < MAX_STATES ?
+ qdev_state[dev_state] : "Unknown");
+
switch (dev_state) {
case QLA82XX_DEV_READY:
goto exit;
qla82xx_idc_lock(ha);
dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
- if (dev_state != QLA82XX_DEV_INITIALIZING) {
+ if (dev_state == QLA82XX_DEV_READY) {
qla_printk(KERN_INFO, ha, "HW State: NEED RESET\n");
qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
QLA82XX_DEV_NEED_RESET);
} else
- qla_printk(KERN_INFO, ha, "HW State: DEVICE INITIALIZING\n");
+ qla_printk(KERN_INFO, ha, "HW State: %s\n",
+ dev_state < MAX_STATES ?
+ qdev_state[dev_state] : "Unknown");
qla82xx_idc_unlock(ha);
rval = qla82xx_device_state_handler(vha);
if (rval == QLA_SUCCESS)
qla82xx_restart_isp(vha);
+
+ if (rval) {
+ vha->flags.online = 1;
+ if (test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
+ if (ha->isp_abort_cnt == 0) {
+ qla_printk(KERN_WARNING, ha,
+ "ISP error recovery failed - "
+ "board disabled\n");
+ /*
+ * The next call disables the board
+ * completely.
+ */
+ ha->isp_ops->reset_adapter(vha);
+ vha->flags.online = 0;
+ clear_bit(ISP_ABORT_RETRY,
+ &vha->dpc_flags);
+ rval = QLA_SUCCESS;
+ } else { /* schedule another ISP abort */
+ ha->isp_abort_cnt--;
+ DEBUG(qla_printk(KERN_INFO, ha,
+ "qla%ld: ISP abort - retry remaining %d\n",
+ vha->host_no, ha->isp_abort_cnt));
+ rval = QLA_FUNCTION_FAILED;
+ }
+ } else {
+ ha->isp_abort_cnt = MAX_RETRIES_OF_ISP_ABORT;
+ DEBUG(qla_printk(KERN_INFO, ha,
+ "(%ld): ISP error recovery - retrying (%d) "
+ "more times\n", vha->host_no, ha->isp_abort_cnt));
+ set_bit(ISP_ABORT_RETRY, &vha->dpc_flags);
+ rval = QLA_FUNCTION_FAILED;
+ }
+ }
return rval;
}