void qla4xxx_dump_registers(struct scsi_qla_host *ha) { uint8_t i; if (is_qla8022(ha)) { for (i = 1; i < MBOX_REG_COUNT; i++) printk(KERN_INFO "mailbox[%d] = 0x%08X\n", i, readl(&ha->qla4_8xxx_reg->mailbox_in[i])); return; } for (i = 0; i < MBOX_REG_COUNT; i++) { printk(KERN_INFO "0x%02X mailbox[%d] = 0x%08X\n", (uint8_t) offsetof(struct isp_reg, mailbox[i]), i, readw(&ha->reg->mailbox[i])); } printk(KERN_INFO "0x%02X flash_address = 0x%08X\n", (uint8_t) offsetof(struct isp_reg, flash_address), readw(&ha->reg->flash_address)); printk(KERN_INFO "0x%02X flash_data = 0x%08X\n", (uint8_t) offsetof(struct isp_reg, flash_data), readw(&ha->reg->flash_data)); printk(KERN_INFO "0x%02X ctrl_status = 0x%08X\n", (uint8_t) offsetof(struct isp_reg, ctrl_status), readw(&ha->reg->ctrl_status)); if (is_qla4010(ha)) { printk(KERN_INFO "0x%02X nvram = 0x%08X\n", (uint8_t) offsetof(struct isp_reg, u1.isp4010.nvram), readw(&ha->reg->u1.isp4010.nvram)); } else if (is_qla4022(ha) | is_qla4032(ha)) {
static ssize_t qla4_8xxx_sysfs_write_fw_dump(struct file *filep, struct kobject *kobj, struct bin_attribute *ba, char *buf, loff_t off, size_t count) { struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, struct device, kobj))); uint32_t dev_state; int reading; if (is_qla40XX(ha)) return -EINVAL; if (off != 0) return 0; reading = simple_strtol(buf, NULL, 10); switch (reading) { case 0: /* clear dump collection flags */ if (test_and_clear_bit(AF_82XX_DUMP_READING, &ha->flags)) { clear_bit(AF_82XX_FW_DUMPED, &ha->flags); /* Reload minidump template */ qla4xxx_alloc_fw_dump(ha); DEBUG2(ql4_printk(KERN_INFO, ha, "Firmware template reloaded\n")); } break; case 1: /* Set flag to read dump */ if (test_bit(AF_82XX_FW_DUMPED, &ha->flags) && !test_bit(AF_82XX_DUMP_READING, &ha->flags)) { set_bit(AF_82XX_DUMP_READING, &ha->flags); DEBUG2(ql4_printk(KERN_INFO, ha, "Raw firmware dump ready for read on (%ld).\n", ha->host_no)); } break; case 2: /* Reset HBA and collect FW dump */ ha->isp_ops->idc_lock(ha); dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE); if (dev_state == QLA8XXX_DEV_READY) { ql4_printk(KERN_INFO, ha, "%s: Setting Need reset\n", __func__); qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE, QLA8XXX_DEV_NEED_RESET); if (is_qla8022(ha) || (is_qla8032(ha) && qla4_83xx_can_perform_reset(ha))) { set_bit(AF_8XXX_RST_OWNER, &ha->flags); set_bit(AF_FW_RECOVERY, &ha->flags); ql4_printk(KERN_INFO, ha, "%s: Reset owner is 0x%x\n", __func__, ha->func_num); } } else ql4_printk(KERN_INFO, ha, "%s: Reset not performed as device state is 0x%x\n", __func__, dev_state); ha->isp_ops->idc_unlock(ha); break; default: /* do nothing */ break; } return count; }
void qla4xxx_dump_registers(struct scsi_qla_host *ha) { uint8_t i; if (is_qla8022(ha)) { for (i = 1; i < MBOX_REG_COUNT; i++) // printk(KERN_INFO "mailbox[%d] = 0x%08X\n", ; return; } for (i = 0; i < MBOX_REG_COUNT; i++) { // printk(KERN_INFO "0x%02X mailbox[%d] = 0x%08X\n", // (uint8_t) offsetof(struct isp_reg, mailbox[i]), i, ; } // printk(KERN_INFO "0x%02X flash_address = 0x%08X\n", // (uint8_t) offsetof(struct isp_reg, flash_address), ; // printk(KERN_INFO "0x%02X flash_data = 0x%08X\n", // (uint8_t) offsetof(struct isp_reg, flash_data), ; // printk(KERN_INFO "0x%02X ctrl_status = 0x%08X\n", // (uint8_t) offsetof(struct isp_reg, ctrl_status), ; if (is_qla4010(ha)) { // printk(KERN_INFO "0x%02X nvram = 0x%08X\n", // (uint8_t) offsetof(struct isp_reg, u1.isp4010.nvram), ; } else if (is_qla4022(ha) | is_qla4032(ha)) { // printk(KERN_INFO "0x%02X intr_mask = 0x%08X\n", // (uint8_t) offsetof(struct isp_reg, u1.isp4022.intr_mask), ; // printk(KERN_INFO "0x%02X nvram = 0x%08X\n", // (uint8_t) offsetof(struct isp_reg, u1.isp4022.nvram), ; // printk(KERN_INFO "0x%02X semaphore = 0x%08X\n", // (uint8_t) offsetof(struct isp_reg, u1.isp4022.semaphore), ; } // printk(KERN_INFO "0x%02X req_q_in = 0x%08X\n", // (uint8_t) offsetof(struct isp_reg, req_q_in), ; // printk(KERN_INFO "0x%02X rsp_q_out = 0x%08X\n", // (uint8_t) offsetof(struct isp_reg, rsp_q_out), ; if (is_qla4010(ha)) { // printk(KERN_INFO "0x%02X ext_hw_conf = 0x%08X\n", // (uint8_t) offsetof(struct isp_reg, u2.isp4010.ext_hw_conf), ; // printk(KERN_INFO "0x%02X port_ctrl = 0x%08X\n", // (uint8_t) offsetof(struct isp_reg, u2.isp4010.port_ctrl), ; // printk(KERN_INFO "0x%02X port_status = 0x%08X\n", // (uint8_t) offsetof(struct isp_reg, u2.isp4010.port_status), ; // printk(KERN_INFO "0x%02X req_q_out = 0x%08X\n", // (uint8_t) offsetof(struct isp_reg, u2.isp4010.req_q_out), ; // printk(KERN_INFO "0x%02X gp_out = 0x%08X\n", // (uint8_t) offsetof(struct isp_reg, u2.isp4010.gp_out), ; // printk(KERN_INFO "0x%02X gp_in = 0x%08X\n", // (uint8_t) offsetof(struct isp_reg, u2.isp4010.gp_in), ; // printk(KERN_INFO "0x%02X port_err_status = 0x%08X\n", (uint8_t) // offsetof(struct isp_reg, u2.isp4010.port_err_status), ; } else if (is_qla4022(ha) | is_qla4032(ha)) { ; // printk(KERN_INFO "0x%02X ext_hw_conf = 0x%08X\n", (uint8_t) // offsetof(struct isp_reg, u2.isp4022.p0.ext_hw_conf), ; // printk(KERN_INFO "0x%02X port_ctrl = 0x%08X\n", (uint8_t) // offsetof(struct isp_reg, u2.isp4022.p0.port_ctrl), ; // printk(KERN_INFO "0x%02X port_status = 0x%08X\n", (uint8_t) // offsetof(struct isp_reg, u2.isp4022.p0.port_status), ; // printk(KERN_INFO "0x%02X gp_out = 0x%08X\n", // (uint8_t) offsetof(struct isp_reg, u2.isp4022.p0.gp_out), ; // printk(KERN_INFO "0x%02X gp_in = 0x%08X\n", // (uint8_t) offsetof(struct isp_reg, u2.isp4022.p0.gp_in), ; // printk(KERN_INFO "0x%02X port_err_status = 0x%08X\n", (uint8_t) // offsetof(struct isp_reg, u2.isp4022.p0.port_err_status), ; ; writel(HOST_MEM_CFG_PAGE & set_rmask(CSR_SCSI_PAGE_SELECT), &ha->reg->ctrl_status); // printk(KERN_INFO "0x%02X req_q_out = 0x%08X\n", // (uint8_t) offsetof(struct isp_reg, u2.isp4022.p1.req_q_out), ; writel(PORT_CTRL_STAT_PAGE & set_rmask(CSR_SCSI_PAGE_SELECT), &ha->reg->ctrl_status); } }
/** * qla4xxx_mailbox_command - issues mailbox commands * @ha: Pointer to host adapter structure. * @inCount: number of mailbox registers to load. * @outCount: number of mailbox registers to return. * @mbx_cmd: data pointer for mailbox in registers. * @mbx_sts: data pointer for mailbox out registers. * * This routine isssue mailbox commands and waits for completion. * If outCount is 0, this routine completes successfully WITHOUT waiting * for the mailbox command to complete. **/ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, uint8_t outCount, uint32_t *mbx_cmd, uint32_t *mbx_sts) { int status = QLA_ERROR; uint8_t i; u_long wait_count; uint32_t intr_status; unsigned long flags = 0; /* Make sure that pointers are valid */ if (!mbx_cmd || !mbx_sts) { DEBUG2(printk("scsi%ld: %s: Invalid mbx_cmd or mbx_sts " "pointer\n", ha->host_no, __func__)); return status; } if (is_qla8022(ha) && test_bit(AF_FW_RECOVERY, &ha->flags)) { DEBUG2(ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: prematurely " "completing mbx cmd as firmware recovery detected\n", ha->host_no, __func__)); return status; } if ((is_aer_supported(ha)) && (test_bit(AF_PCI_CHANNEL_IO_PERM_FAILURE, &ha->flags))) { DEBUG2(printk(KERN_WARNING "scsi%ld: %s: Perm failure on EEH, " "timeout MBX Exiting.\n", ha->host_no, __func__)); return status; } /* Mailbox code active */ wait_count = MBOX_TOV * 100; while (wait_count--) { mutex_lock(&ha->mbox_sem); if (!test_bit(AF_MBOX_COMMAND, &ha->flags)) { set_bit(AF_MBOX_COMMAND, &ha->flags); mutex_unlock(&ha->mbox_sem); break; } mutex_unlock(&ha->mbox_sem); if (!wait_count) { DEBUG2(printk("scsi%ld: %s: mbox_sem failed\n", ha->host_no, __func__)); return status; } msleep(10); } /* To prevent overwriting mailbox registers for a command that has * not yet been serviced, check to see if an active command * (AEN, IOCB, etc.) is interrupting, then service it. * ----------------------------------------------------------------- */ spin_lock_irqsave(&ha->hardware_lock, flags); if (is_qla8022(ha)) { intr_status = readl(&ha->qla4_8xxx_reg->host_int); if (intr_status & ISRX_82XX_RISC_INT) { /* Service existing interrupt */ DEBUG2(printk("scsi%ld: %s: " "servicing existing interrupt\n", ha->host_no, __func__)); intr_status = readl(&ha->qla4_8xxx_reg->host_status); ha->isp_ops->interrupt_service_routine(ha, intr_status); clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags); if (test_bit(AF_INTERRUPTS_ON, &ha->flags) && test_bit(AF_INTx_ENABLED, &ha->flags)) qla4_8xxx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff); } } else { intr_status = readl(&ha->reg->ctrl_status); if (intr_status & CSR_SCSI_PROCESSOR_INTR) { /* Service existing interrupt */ ha->isp_ops->interrupt_service_routine(ha, intr_status); clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags); } } ha->mbox_status_count = outCount; for (i = 0; i < outCount; i++) ha->mbox_status[i] = 0; if (is_qla8022(ha)) { /* Load all mailbox registers, except mailbox 0. */ 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_8xxx_reg->mailbox_in[i]); writel(mbx_cmd[0], &ha->qla4_8xxx_reg->mailbox_in[0]); readl(&ha->qla4_8xxx_reg->mailbox_in[0]); writel(HINT_MBX_INT_PENDING, &ha->qla4_8xxx_reg->hint); } else { /* Load all mailbox registers, except mailbox 0. */ for (i = 1; i < inCount; i++)
/** * qla4xxx_mailbox_command - issues mailbox commands * @ha: Pointer to host adapter structure. * @inCount: number of mailbox registers to load. * @outCount: number of mailbox registers to return. * @mbx_cmd: data pointer for mailbox in registers. * @mbx_sts: data pointer for mailbox out registers. * * This routine issue mailbox commands and waits for completion. * If outCount is 0, this routine completes successfully WITHOUT waiting * for the mailbox command to complete. **/ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, uint8_t outCount, uint32_t *mbx_cmd, uint32_t *mbx_sts) { int status = QLA_ERROR; uint8_t i; u_long wait_count; uint32_t intr_status; unsigned long flags = 0; uint32_t dev_state; /* Make sure that pointers are valid */ if (!mbx_cmd || !mbx_sts) { DEBUG2(printk("scsi%ld: %s: Invalid mbx_cmd or mbx_sts " "pointer\n", ha->host_no, __func__)); return status; } if (is_qla8022(ha)) { if (test_bit(AF_FW_RECOVERY, &ha->flags)) { DEBUG2(ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: " "prematurely completing mbx cmd as firmware " "recovery detected\n", ha->host_no, __func__)); return status; } /* Do not send any mbx cmd if h/w is in failed state*/ qla4_8xxx_idc_lock(ha); dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE); qla4_8xxx_idc_unlock(ha); if (dev_state == QLA82XX_DEV_FAILED) { ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: H/W is in " "failed state, do not send any mailbox commands\n", ha->host_no, __func__); return status; } } if ((is_aer_supported(ha)) && (test_bit(AF_PCI_CHANNEL_IO_PERM_FAILURE, &ha->flags))) { DEBUG2(printk(KERN_WARNING "scsi%ld: %s: Perm failure on EEH, " "timeout MBX Exiting.\n", ha->host_no, __func__)); return status; } /* Mailbox code active */ wait_count = MBOX_TOV * 100; while (wait_count--) { mutex_lock(&ha->mbox_sem); if (!test_bit(AF_MBOX_COMMAND, &ha->flags)) { set_bit(AF_MBOX_COMMAND, &ha->flags); mutex_unlock(&ha->mbox_sem); break; } mutex_unlock(&ha->mbox_sem); if (!wait_count) { DEBUG2(printk("scsi%ld: %s: mbox_sem failed\n", ha->host_no, __func__)); return status; } msleep(10); } spin_lock_irqsave(&ha->hardware_lock, flags); ha->mbox_status_count = outCount; for (i = 0; i < outCount; i++) ha->mbox_status[i] = 0; if (is_qla8022(ha)) { /* Load all mailbox registers, except mailbox 0. */ 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_8xxx_reg->mailbox_in[i]); writel(mbx_cmd[0], &ha->qla4_8xxx_reg->mailbox_in[0]); readl(&ha->qla4_8xxx_reg->mailbox_in[0]); writel(HINT_MBX_INT_PENDING, &ha->qla4_8xxx_reg->hint); } else { /* Load all mailbox registers, except mailbox 0. */ for (i = 1; i < inCount; i++)