diff options
author | Giridhar Malavali <giridhar.malavali@qlogic.com> | 2012-02-09 11:15:34 -0800 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-02-19 08:11:11 -0600 |
commit | 6246b8a1d26c7cdb77fd2f3f3578d4db025d5c9e (patch) | |
tree | ae6059dbe0d5e59dea54135841c0001643188d07 /drivers | |
parent | 050c9bb1361439e63dafb5f192f87b81d8ffbf4a (diff) |
[SCSI] qla2xxx: Enhancements to support ISP83xx.
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: Harish Zunjarrao <harish.zunjarrao@qlogic.com>
Signed-off-by: Nigel Kirkland <nigel.kirkland@qlogic.com>
Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 23 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_bsg.c | 10 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_dbg.c | 521 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_dbg.h | 49 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 37 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_dfs.c | 2 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_fw.h | 13 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 10 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gs.c | 6 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 66 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_iocb.c | 9 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 44 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 262 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_nx.c | 8 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_nx.h | 3 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 192 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_sup.c | 148 |
17 files changed, 1233 insertions, 170 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 9f41b3b4358..7f895cdcaeb 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -356,7 +356,8 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj, else if (start == (ha->flt_region_boot * 4) || start == (ha->flt_region_fw * 4)) valid = 1; - else if (IS_QLA25XX(ha) || IS_QLA8XXX_TYPE(ha)) + else if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) + || IS_CNA_CAPABLE(ha) || IS_QLA2031(ha)) valid = 1; if (!valid) { ql_log(ql_log_warn, vha, 0x7065, @@ -898,7 +899,7 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t *vha) continue; if (iter->is4GBp_only == 2 && !IS_QLA25XX(vha->hw)) continue; - if (iter->is4GBp_only == 3 && !(IS_QLA8XXX_TYPE(vha->hw))) + if (iter->is4GBp_only == 3 && !(IS_CNA_CAPABLE(vha->hw))) continue; ret = sysfs_create_bin_file(&host->shost_gendev.kobj, @@ -926,7 +927,7 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *vha) continue; if (iter->is4GBp_only == 2 && !IS_QLA25XX(ha)) continue; - if (iter->is4GBp_only == 3 && !!(IS_QLA8XXX_TYPE(vha->hw))) + if (iter->is4GBp_only == 3 && !(IS_CNA_CAPABLE(vha->hw))) continue; sysfs_remove_bin_file(&host->shost_gendev.kobj, @@ -1231,7 +1232,7 @@ qla2x00_optrom_gold_fw_version_show(struct device *dev, scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); struct qla_hw_data *ha = vha->hw; - if (!IS_QLA81XX(ha)) + if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha)) return snprintf(buf, PAGE_SIZE, "\n"); return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%d)\n", @@ -1278,7 +1279,7 @@ qla2x00_mpi_version_show(struct device *dev, struct device_attribute *attr, scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); struct qla_hw_data *ha = vha->hw; - if (!IS_QLA81XX(ha)) + if (!IS_QLA81XX(ha) && !IS_QLA8031(ha)) return snprintf(buf, PAGE_SIZE, "\n"); return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%x)\n", @@ -1293,7 +1294,7 @@ qla2x00_phy_version_show(struct device *dev, struct device_attribute *attr, scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); struct qla_hw_data *ha = vha->hw; - if (!IS_QLA81XX(ha)) + if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha)) return snprintf(buf, PAGE_SIZE, "\n"); return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d\n", @@ -1316,7 +1317,7 @@ qla2x00_vlan_id_show(struct device *dev, struct device_attribute *attr, { scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); - if (!IS_QLA8XXX_TYPE(vha->hw)) + if (!IS_CNA_CAPABLE(vha->hw)) return snprintf(buf, PAGE_SIZE, "\n"); return snprintf(buf, PAGE_SIZE, "%d\n", vha->fcoe_vlan_id); @@ -1328,7 +1329,7 @@ qla2x00_vn_port_mac_address_show(struct device *dev, { scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); - if (!IS_QLA8XXX_TYPE(vha->hw)) + if (!IS_CNA_CAPABLE(vha->hw)) return snprintf(buf, PAGE_SIZE, "\n"); return snprintf(buf, PAGE_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x\n", @@ -1493,6 +1494,9 @@ qla2x00_get_host_speed(struct Scsi_Host *shost) case PORT_SPEED_10GB: speed = FC_PORTSPEED_10GBIT; break; + case PORT_SPEED_16GB: + speed = FC_PORTSPEED_16GBIT; + break; } fc_host_speed(shost) = speed; } @@ -1889,6 +1893,7 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable) break; } } + if (qos) { ret = qla25xx_create_req_que(ha, options, vha->vp_idx, 0, 0, qos); @@ -2086,7 +2091,7 @@ qla2x00_init_host_attr(scsi_qla_host_t *vha) fc_host_max_npiv_vports(vha->host) = ha->max_npiv_vports; fc_host_npiv_vports_inuse(vha->host) = ha->cur_vport_count; - if (IS_QLA8XXX_TYPE(ha)) + if (IS_CNA_CAPABLE(ha)) speed = FC_PORTSPEED_10GBIT; else if (IS_QLA25XX(ha)) speed = FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index 1682e2e4201..6887538d173 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -540,7 +540,7 @@ qla81xx_set_internal_loopback(scsi_qla_host_t *vha, uint16_t *config, int rval = 0; struct qla_hw_data *ha = vha->hw; - if (!IS_QLA81XX(ha)) + if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha)) goto done_set_internal; new_config[0] = config[0] | (ENABLE_INTERNAL_LOOPBACK << 1); @@ -582,7 +582,7 @@ qla81xx_reset_internal_loopback(scsi_qla_host_t *vha, uint16_t *config, uint16_t new_config[4]; struct qla_hw_data *ha = vha->hw; - if (!IS_QLA81XX(ha)) + if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha)) goto done_reset_internal; memset(new_config, 0 , sizeof(new_config)); @@ -707,7 +707,7 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job) if ((ha->current_topology == ISP_CFG_F || (atomic_read(&vha->loop_state) == LOOP_DOWN) || - (IS_QLA81XX(ha) && + ((IS_QLA81XX(ha) || IS_QLA83XX(ha)) && le32_to_cpu(*(uint32_t *)req_data) == ELS_OPCODE_BYTE && req_data_len == MAX_ELS_FRAME_PAYLOAD)) && elreq.options == EXTERNAL_LOOPBACK) { @@ -717,7 +717,7 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job) command_sent = INT_DEF_LB_ECHO_CMD; rval = qla2x00_echo_test(vha, &elreq, response); } else { - if (IS_QLA81XX(ha)) { + if (IS_QLA81XX(ha) || IS_QLA8031(ha)) { memset(config, 0, sizeof(config)); memset(new_config, 0, sizeof(new_config)); if (qla81xx_get_port_config(vha, config)) { @@ -1331,7 +1331,7 @@ qla2x00_optrom_setup(struct fc_bsg_job *bsg_job, scsi_qla_host_t *vha, start == (ha->flt_region_fw * 4)) valid = 1; else if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) || - IS_QLA8XXX_TYPE(ha)) + IS_CNA_CAPABLE(ha) || IS_QLA2031(ha)) valid = 1; if (!valid) { ql_log(ql_log_warn, vha, 0x7058, diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index cdf06176354..e4c6b940993 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c @@ -11,23 +11,23 @@ * ---------------------------------------------------------------------- * | Level | Last Value Used | Holes | * ---------------------------------------------------------------------- - * | Module Init and Probe | 0x0116 | 0xfa | - * | Mailbox commands | 0x112b | | - * | Device Discovery | 0x2084 | | - * | Queue Command and IO tracing | 0x302f | 0x3008,0x302d, | - * | | | 0x302e | + * | Module Init and Probe | 0x011f | 0x4b,0xfa | + * | Mailbox commands | 0x1139 | 0x112c-0x112e | + * | Device Discovery | 0x2084 | | + * | Queue Command and IO tracing | 0x302f | 0x3008 | + * | | | 0x302d-0x302e | * | DPC Thread | 0x401c | | * | Async Events | 0x5057 | 0x5052 | - * | Timer Routines | 0x6011 | 0x600e,0x600f | + * | Timer Routines | 0x6011 | 0x600e-0x600f | * | User Space Interactions | 0x709e | 0x7018,0x702e | * | | | 0x7039,0x7045 | * | Task Management | 0x803c | 0x8025-0x8026 | * | | | 0x800b,0x8039 | * | AER/EEH | 0x900f | | * | Virtual Port | 0xa007 | | - * | ISP82XX Specific | 0xb052 | | - * | MultiQ | 0xc00b | | - * | Misc | 0xd00b | | + * | ISP82XX Specific | 0xb052 | | + * | MultiQ | 0xc00c | | + * | Misc | 0xd010 | | * ---------------------------------------------------------------------- */ @@ -453,7 +453,7 @@ qla25xx_copy_mq(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain) struct qla2xxx_mq_chain *mq = ptr; struct device_reg_25xxmq __iomem *reg; - if (!ha->mqenable) + if (!ha->mqenable || IS_QLA83XX(ha)) return ptr; mq = ptr; @@ -1729,6 +1729,507 @@ qla81xx_fw_dump_failed: spin_unlock_irqrestore(&ha->hardware_lock, flags); } +void +qla83xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) +{ + int rval; + uint32_t cnt, reg_data; + uint32_t risc_address; + struct qla_hw_data *ha = vha->hw; + struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; + uint32_t __iomem *dmp_reg; + uint32_t *iter_reg; + uint16_t __iomem *mbx_reg; + unsigned long flags; + struct qla83xx_fw_dump *fw; + uint32_t ext_mem_cnt; + void *nxt, *nxt_chain; + uint32_t *last_chain = NULL; + struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); + + risc_address = ext_mem_cnt = 0; + flags = 0; + + if (!hardware_locked) + spin_lock_irqsave(&ha->hardware_lock, flags); + + if (!ha->fw_dump) { + ql_log(ql_log_warn, vha, 0xd00c, + "No buffer available for dump!!!\n"); + goto qla83xx_fw_dump_failed; + } + + if (ha->fw_dumped) { + ql_log(ql_log_warn, vha, 0xd00d, + "Firmware has been previously dumped (%p) -- ignoring " + "request...\n", ha->fw_dump); + goto qla83xx_fw_dump_failed; + } + fw = &ha->fw_dump->isp.isp83; + qla2xxx_prep_dump(ha, ha->fw_dump); + + fw->host_status = htonl(RD_REG_DWORD(®->host_status)); + + /* Pause RISC. */ + rval = qla24xx_pause_risc(reg); + if (rval != QLA_SUCCESS) + goto qla83xx_fw_dump_failed_0; + + WRT_REG_DWORD(®->iobase_addr, 0x6000); + dmp_reg = ®->iobase_window; + reg_data = RD_REG_DWORD(dmp_reg); + WRT_REG_DWORD(dmp_reg, 0); + + dmp_reg = ®->unused_4_1[0]; + reg_data = RD_REG_DWORD(dmp_reg); + WRT_REG_DWORD(dmp_reg, 0); + + WRT_REG_DWORD(®->iobase_addr, 0x6010); + dmp_reg = ®->unused_4_1[2]; + reg_data = RD_REG_DWORD(dmp_reg); + WRT_REG_DWORD(dmp_reg, 0); + + /* select PCR and disable ecc checking and correction */ + WRT_REG_DWORD(®->iobase_addr, 0x0F70); + RD_REG_DWORD(®->iobase_addr); + WRT_REG_DWORD(®->iobase_select, 0x60000000); /* write to F0h = PCR */ + + /* Host/Risc registers. */ + iter_reg = fw->host_risc_reg; + iter_reg = qla24xx_read_window(reg, 0x7000, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x7010, 16, iter_reg); + qla24xx_read_window(reg, 0x7040, 16, iter_reg); + + /* PCIe registers. */ + WRT_REG_DWORD(®->iobase_addr, 0x7C00); + RD_REG_DWORD(®->iobase_addr); + WRT_REG_DWORD(®->iobase_window, 0x01); + dmp_reg = ®->iobase_c4; + fw->pcie_regs[0] = htonl(RD_REG_DWORD(dmp_reg++)); + fw->pcie_regs[1] = htonl(RD_REG_DWORD(dmp_reg++)); + fw->pcie_regs[2] = htonl(RD_REG_DWORD(dmp_reg)); + fw->pcie_regs[3] = htonl(RD_REG_DWORD(®->iobase_window)); + + WRT_REG_DWORD(®->iobase_window, 0x00); + RD_REG_DWORD(®->iobase_window); + + /* Host interface registers. */ + dmp_reg = ®->flash_addr; + for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++) + fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); + + /* Disable interrupts. */ + WRT_REG_DWORD(®->ictrl, 0); + RD_REG_DWORD(®->ictrl); + + /* Shadow registers. */ + WRT_REG_DWORD(®->iobase_addr, 0x0F70); + RD_REG_DWORD(®->iobase_addr); + WRT_REG_DWORD(®->iobase_select, 0xB0000000); + fw->shadow_reg[0] = htonl(RD_REG_DWORD(®->iobase_sdata)); + + WRT_REG_DWORD(®->iobase_select, 0xB0100000); + fw->shadow_reg[1] = htonl(RD_REG_DWORD(®->iobase_sdata)); + + WRT_REG_DWORD(®->iobase_select, 0xB0200000); + fw->shadow_reg[2] = htonl(RD_REG_DWORD(®->iobase_sdata)); + + WRT_REG_DWORD(®->iobase_select, 0xB0300000); + fw->shadow_reg[3] = htonl(RD_REG_DWORD(®->iobase_sdata)); + + WRT_REG_DWORD(®->iobase_select, 0xB0400000); + fw->shadow_reg[4] = htonl(RD_REG_DWORD(®->iobase_sdata)); + + WRT_REG_DWORD(®->iobase_select, 0xB0500000); + fw->shadow_reg[5] = htonl(RD_REG_DWORD(®->iobase_sdata)); + + WRT_REG_DWORD(®->iobase_select, 0xB0600000); + fw->shadow_reg[6] = htonl(RD_REG_DWORD(®->iobase_sdata)); + + WRT_REG_DWORD(®->iobase_select, 0xB0700000); + fw->shadow_reg[7] = htonl(RD_REG_DWORD(®->iobase_sdata)); + + WRT_REG_DWORD(®->iobase_select, 0xB0800000); + fw->shadow_reg[8] = htonl(RD_REG_DWORD(®->iobase_sdata)); + + WRT_REG_DWORD(®->iobase_select, 0xB0900000); + fw->shadow_reg[9] = htonl(RD_REG_DWORD(®->iobase_sdata)); + + WRT_REG_DWORD(®->iobase_select, 0xB0A00000); + fw->shadow_reg[10] = htonl(RD_REG_DWORD(®->iobase_sdata)); + + /* RISC I/O register. */ + WRT_REG_DWORD(®->iobase_addr, 0x0010); + fw->risc_io_reg = htonl(RD_REG_DWORD(®->iobase_window)); + + /* Mailbox registers. */ + mbx_reg = ®->mailbox0; + for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) + fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++)); + + /* Transfer sequence registers. */ + iter_reg = fw->xseq_gp_reg; + iter_reg = qla24xx_read_window(reg, 0xBE00, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xBE10, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xBE20, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xBE30, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xBE40, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xBE50, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xBE60, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xBE70, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg); + qla24xx_read_window(reg, 0xBF70, 16, iter_reg); + + iter_reg = fw->xseq_0_reg; + iter_reg = qla24xx_read_window(reg, 0xBFC0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xBFD0, 16, iter_reg); + qla24xx_read_window(reg, 0xBFE0, 16, iter_reg); + + qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg); + + qla24xx_read_window(reg, 0xBEF0, 16, fw->xseq_2_reg); + + /* Receive sequence registers. */ + iter_reg = fw->rseq_gp_reg; + iter_reg = qla24xx_read_window(reg, 0xFE00, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xFE10, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xFE20, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xFE30, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xFE40, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xFE50, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xFE60, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xFE70, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg); + qla24xx_read_window(reg, 0xFF70, 16, iter_reg); + + iter_reg = fw->rseq_0_reg; + iter_reg = qla24xx_read_window(reg, 0xFFC0, 16, iter_reg); + qla24xx_read_window(reg, 0xFFD0, 16, iter_reg); + + qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg); + qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg); + qla24xx_read_window(reg, 0xFEF0, 16, fw->rseq_3_reg); + + /* Auxiliary sequence registers. */ + iter_reg = fw->aseq_gp_reg; + iter_reg = qla24xx_read_window(reg, 0xB000, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xB010, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xB020, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xB030, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xB040, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xB050, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xB060, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xB070, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xB100, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xB110, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xB120, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xB130, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xB140, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xB150, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0xB160, 16, iter_reg); + qla24xx_read_window(reg, 0xB170, 16, iter_reg); + + iter_reg = fw->aseq_0_reg; + iter_reg = qla24xx_read_window(reg, 0xB0C0, 16, iter_reg); + qla24xx_read_window(reg, 0xB0D0, 16, iter_reg); + + qla24xx_read_window(reg, 0xB0E0, 16, fw->aseq_1_reg); + qla24xx_read_window(reg, 0xB0F0, 16, fw->aseq_2_reg); + qla24xx_read_window(reg, 0xB1F0, 16, fw->aseq_3_reg); + + /* Command DMA registers. */ + iter_reg = fw->cmd_dma_reg; + iter_reg = qla24xx_read_window(reg, 0x7100, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x7120, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x7130, 16, iter_reg); + qla24xx_read_window(reg, 0x71F0, 16, iter_reg); + + /* Queues. */ + iter_reg = fw->req0_dma_reg; + iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg); + dmp_reg = ®->iobase_q; + for (cnt = 0; cnt < 7; cnt++) + *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); + + iter_reg = fw->resp0_dma_reg; + iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg); + dmp_reg = ®->iobase_q; + for (cnt = 0; cnt < 7; cnt++) + *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); + + iter_reg = fw->req1_dma_reg; + iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg); + dmp_reg = ®->iobase_q; + for (cnt = 0; cnt < 7; cnt++) + *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); + + /* Transmit DMA registers. */ + iter_reg = fw->xmt0_dma_reg; + iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg); + qla24xx_read_window(reg, 0x7610, 16, iter_reg); + + iter_reg = fw->xmt1_dma_reg; + iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg); + qla24xx_read_window(reg, 0x7630, 16, iter_reg); + + iter_reg = fw->xmt2_dma_reg; + iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg); + qla24xx_read_window(reg, 0x7650, 16, iter_reg); + + iter_reg = fw->xmt3_dma_reg; + iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg); + qla24xx_read_window(reg, 0x7670, 16, iter_reg); + + iter_reg = fw->xmt4_dma_reg; + iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg); + qla24xx_read_window(reg, 0x7690, 16, iter_reg); + + qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg); + + /* Receive DMA registers. */ + iter_reg = fw->rcvt0_data_dma_reg; + iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg); + qla24xx_read_window(reg, 0x7710, 16, iter_reg); + + iter_reg = fw->rcvt1_data_dma_reg; + iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg); + qla24xx_read_window(reg, 0x7730, 16, iter_reg); + + /* RISC registers. */ + iter_reg = fw->risc_gp_reg; + iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg); + qla24xx_read_window(reg, 0x0F70, 16, iter_reg); + + /* Local memory controller registers. */ + iter_reg = fw->lmc_reg; + iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x3060, 16, iter_reg); + qla24xx_read_window(reg, 0x3070, 16, iter_reg); + + /* Fibre Protocol Module registers. */ + iter_reg = fw->fpm_hdw_reg; + iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x40B0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x40C0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x40D0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x40E0, 16, iter_reg); + qla24xx_read_window(reg, 0x40F0, 16, iter_reg); + + /* RQ0 Array registers. */ + iter_reg = fw->rq0_array_reg; + iter_reg = qla24xx_read_window(reg, 0x5C00, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5C10, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5C20, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5C30, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5C40, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5C50, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5C60, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5C70, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5C80, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5C90, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5CA0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5CB0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5CC0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5CD0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5CE0, 16, iter_reg); + qla24xx_read_window(reg, 0x5CF0, 16, iter_reg); + + /* RQ1 Array registers. */ + iter_reg = fw->rq1_array_reg; + iter_reg = qla24xx_read_window(reg, 0x5D00, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5D10, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5D20, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5D30, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5D40, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5D50, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5D60, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5D70, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5D80, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5D90, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5DA0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5DB0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5DC0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5DD0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5DE0, 16, iter_reg); + qla24xx_read_window(reg, 0x5DF0, 16, iter_reg); + + /* RP0 Array registers. */ + iter_reg = fw->rp0_array_reg; + iter_reg = qla24xx_read_window(reg, 0x5E00, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5E10, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5E20, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5E30, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5E40, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5E50, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5E60, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5E70, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5E80, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5E90, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5EA0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5EB0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5EC0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5ED0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5EE0, 16, iter_reg); + qla24xx_read_window(reg, 0x5EF0, 16, iter_reg); + + /* RP1 Array registers. */ + iter_reg = fw->rp1_array_reg; + iter_reg = qla24xx_read_window(reg, 0x5F00, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5F10, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5F20, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5F30, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5F40, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5F50, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5F60, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5F70, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5F80, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5F90, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5FA0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5FB0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5FC0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5FD0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x5FE0, 16, iter_reg); + qla24xx_read_window(reg, 0x5FF0, 16, iter_reg); + + iter_reg = fw->at0_array_reg; + iter_reg = qla24xx_read_window(reg, 0x7080, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x7090, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x70A0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x70B0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x70C0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x70D0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x70E0, 16, iter_reg); + qla24xx_read_window(reg, 0x70F0, 16, iter_reg); + + /* I/O Queue Control registers. */ + qla24xx_read_window(reg, 0x7800, 16, fw->queue_control_reg); + + /* Frame Buffer registers. */ + iter_reg = fw->fb_hdw_reg; + iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6060, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6070, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x61C0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6530, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6540, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6550, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6560, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6570, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6580, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x6590, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x65A0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x65B0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x65C0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x65D0, 16, iter_reg); + iter_reg = qla24xx_read_window(reg, 0x65E0, 16, iter_reg); + qla24xx_read_window(reg, 0x6F00, 16, iter_reg); + + /* Multi queue registers */ + nxt_chain = qla25xx_copy_mq(ha, (void *)ha->fw_dump + ha->chain_offset, + &last_chain); + + rval = qla24xx_soft_reset(ha); + if (rval != QLA_SUCCESS) { + ql_log(ql_log_warn, vha, 0xd00e, + "SOFT RESET FAILED, forcing continuation of dump!!!\n"); + rval = QLA_SUCCESS; + + ql_log(ql_log_warn, vha, 0xd00f, "try a bigger hammer!!!\n"); + + WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_RESET); + RD_REG_DWORD(®->hccr); + + WRT_REG_DWORD(®->hccr, HCCRX_REL_RISC_PAUSE); + RD_REG_DWORD(®->hccr); + + WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_RESET); + RD_REG_DWORD(®->hccr); + + for (cnt = 30000; cnt && (RD_REG_WORD(®->mailbox0)); cnt--) + udelay(5); + + if (!cnt) { + nxt = fw->code_ram; + nxt += sizeof(fw->code_ram), + nxt += (ha->fw_memory_size - 0x100000 + 1); + goto copy_queue; + } else + ql_log(ql_log_warn, vha, 0xd010, + "bigger hammer success?\n"); + } + + rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram), + &nxt); + if (rval != QLA_SUCCESS) + goto qla83xx_fw_dump_failed_0; + +copy_queue: + nxt = qla2xxx_copy_queues(ha, nxt); + + nxt = qla24xx_copy_eft(ha, nxt); + + /* Chain entries -- started with MQ. */ + nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain); + nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain); + if (last_chain) { + ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT); + *last_chain |= __constant_htonl(DUMP_CHAIN_LAST); + } + + /* Adjust valid length. */ + ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump); + +qla83xx_fw_dump_failed_0: + qla2xxx_dump_post_process(base_vha, rval); + +qla83xx_fw_dump_failed: + if (!hardware_locked) + spin_unlock_irqrestore(&ha->hardware_lock, flags); +} + /****************************************************************************/ /* Driver Debug Functions. */ /****************************************************************************/ diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index 6b05cb1d187..2157bdf1569 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h @@ -165,6 +165,54 @@ struct qla81xx_fw_dump { uint32_t ext_mem[1]; }; +struct qla83xx_fw_dump { + uint32_t host_status; + uint32_t host_risc_reg[48]; + uint32_t pcie_regs[4]; + uint32_t host_reg[32]; + uint32_t shadow_reg[11]; + uint32_t risc_io_reg; + uint16_t mailbox_reg[32]; + uint32_t xseq_gp_reg[256]; + uint32_t xseq_0_reg[48]; + uint32_t xseq_1_reg[16]; + uint32_t xseq_2_reg[16]; + uint32_t rseq_gp_reg[256]; + uint32_t rseq_0_reg[32]; + uint32_t rseq_1_reg[16]; + uint32_t rseq_2_reg[16]; + uint32_t rseq_3_reg[16]; + uint32_t aseq_gp_reg[256]; + uint32_t aseq_0_reg[32]; + uint32_t aseq_1_reg[16]; + uint32_t aseq_2_reg[16]; + uint32_t aseq_3_reg[16]; + uint32_t cmd_dma_reg[64]; + uint32_t req0_dma_reg[15]; + uint32_t resp0_dma_reg[15]; + uint32_t req1_dma_reg[15]; + uint32_t xmt0_dma_reg[32]; + uint32_t xmt1_dma_reg[32]; + uint32_t xmt2_dma_reg[32]; + uint32_t xmt3_dma_reg[32]; + uint32_t xmt4_dma_reg[32]; + uint32_t xmt_data_dma_reg[16]; + uint32_t rcvt0_data_dma_reg[32]; + uint32_t rcvt1_data_dma_reg[32]; + uint32_t risc_gp_reg[128]; + uint32_t lmc_reg[128]; + uint32_t fpm_hdw_reg[256]; + uint32_t rq0_array_reg[256]; + uint32_t rq1_array_reg[256]; + uint32_t rp0_array_reg[256]; + uint32_t rp1_array_reg[256]; + uint32_t queue_control_reg[16]; + uint32_t fb_hdw_reg[432]; + uint32_t at0_array_reg[128]; + uint32_t code_ram[0x2400]; + uint32_t ext_mem[1]; +}; + #define EFT_NUM_BUFFERS 4 #define EFT_BYTES_PER_BUFFER 0x4000 #define EFT_SIZE ((EFT_BYTES_PER_BUFFER) * (EFT_NUM_BUFFERS)) @@ -242,6 +290,7 @@ struct qla2xxx_fw_dump { struct qla24xx_fw_dump isp24; struct qla25xx_fw_dump isp25; struct qla81xx_fw_dump isp81; + struct qla83xx_fw_dump isp83; } isp; }; diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index af1003f9de1..7b7d829bef8 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -653,6 +653,7 @@ typedef struct { #define MBC_DIAGNOSTIC_LOOP_BACK 0x45 /* Diagnostic loop back. */ #define MBC_ONLINE_SELF_TEST 0x46 /* Online self-test. */ #define MBC_ENHANCED_GET_PORT_DATABASE 0x47 /* Get port database + login */ +#define MBC_CONFIGURE_VF 0x4b /* Configure VFs */ #define MBC_RESET_LINK_STATUS 0x52 /* Reset Link Error Status */ #define MBC_IOCB_COMMAND_A64 0x54 /* Execute IOCB command (64) */ #define MBC_SEND_RNID_ELS 0x57 /* Send RNID ELS request */ @@ -2261,6 +2262,7 @@ struct isp_operations { #define QLA_MIDX_DEFAULT 0 #define QLA_MIDX_RSP_Q 1 #define QLA_PCI_MSIX_CONTROL 0xa2 +#define QLA_83XX_PCI_MSIX_CONTROL 0x92 struct scsi_qla_host; @@ -2341,7 +2343,7 @@ struct qla_statistics { #define QLA_MQ_SIZE 32 #define QLA_MAX_QUEUES 256 #define ISP_QUE_REG(ha, id) \ - ((ha->mqenable) ? \ + ((ha->mqenable || IS_QLA83XX(ha)) ? \ ((void *)(ha->mqiobas |