162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * QLogic Fibre Channel HBA Driver 462306a36Sopenharmony_ci * Copyright (c) 2003-2014 QLogic Corporation 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci/* 862306a36Sopenharmony_ci * Table for showing the current message id in use for particular level 962306a36Sopenharmony_ci * Change this table for addition of log/debug messages. 1062306a36Sopenharmony_ci * ---------------------------------------------------------------------- 1162306a36Sopenharmony_ci * | Level | Last Value Used | Holes | 1262306a36Sopenharmony_ci * ---------------------------------------------------------------------- 1362306a36Sopenharmony_ci * | Module Init and Probe | 0x0199 | | 1462306a36Sopenharmony_ci * | Mailbox commands | 0x1206 | 0x11a5-0x11ff | 1562306a36Sopenharmony_ci * | Device Discovery | 0x2134 | 0x2112-0x2115 | 1662306a36Sopenharmony_ci * | | | 0x2127-0x2128 | 1762306a36Sopenharmony_ci * | Queue Command and IO tracing | 0x3074 | 0x300b | 1862306a36Sopenharmony_ci * | | | 0x3027-0x3028 | 1962306a36Sopenharmony_ci * | | | 0x303d-0x3041 | 2062306a36Sopenharmony_ci * | | | 0x302e,0x3033 | 2162306a36Sopenharmony_ci * | | | 0x3036,0x3038 | 2262306a36Sopenharmony_ci * | | | 0x303a | 2362306a36Sopenharmony_ci * | DPC Thread | 0x4023 | 0x4002,0x4013 | 2462306a36Sopenharmony_ci * | Async Events | 0x509c | | 2562306a36Sopenharmony_ci * | Timer Routines | 0x6012 | | 2662306a36Sopenharmony_ci * | User Space Interactions | 0x70e3 | 0x7018,0x702e | 2762306a36Sopenharmony_ci * | | | 0x7020,0x7024 | 2862306a36Sopenharmony_ci * | | | 0x7039,0x7045 | 2962306a36Sopenharmony_ci * | | | 0x7073-0x7075 | 3062306a36Sopenharmony_ci * | | | 0x70a5-0x70a6 | 3162306a36Sopenharmony_ci * | | | 0x70a8,0x70ab | 3262306a36Sopenharmony_ci * | | | 0x70ad-0x70ae | 3362306a36Sopenharmony_ci * | | | 0x70d0-0x70d6 | 3462306a36Sopenharmony_ci * | | | 0x70d7-0x70db | 3562306a36Sopenharmony_ci * | Task Management | 0x8042 | 0x8000 | 3662306a36Sopenharmony_ci * | | | 0x8019 | 3762306a36Sopenharmony_ci * | | | 0x8025,0x8026 | 3862306a36Sopenharmony_ci * | | | 0x8031,0x8032 | 3962306a36Sopenharmony_ci * | | | 0x8039,0x803c | 4062306a36Sopenharmony_ci * | AER/EEH | 0x9011 | | 4162306a36Sopenharmony_ci * | Virtual Port | 0xa007 | | 4262306a36Sopenharmony_ci * | ISP82XX Specific | 0xb157 | 0xb002,0xb024 | 4362306a36Sopenharmony_ci * | | | 0xb09e,0xb0ae | 4462306a36Sopenharmony_ci * | | | 0xb0c3,0xb0c6 | 4562306a36Sopenharmony_ci * | | | 0xb0e0-0xb0ef | 4662306a36Sopenharmony_ci * | | | 0xb085,0xb0dc | 4762306a36Sopenharmony_ci * | | | 0xb107,0xb108 | 4862306a36Sopenharmony_ci * | | | 0xb111,0xb11e | 4962306a36Sopenharmony_ci * | | | 0xb12c,0xb12d | 5062306a36Sopenharmony_ci * | | | 0xb13a,0xb142 | 5162306a36Sopenharmony_ci * | | | 0xb13c-0xb140 | 5262306a36Sopenharmony_ci * | | | 0xb149 | 5362306a36Sopenharmony_ci * | MultiQ | 0xc010 | | 5462306a36Sopenharmony_ci * | Misc | 0xd303 | 0xd031-0xd0ff | 5562306a36Sopenharmony_ci * | | | 0xd101-0xd1fe | 5662306a36Sopenharmony_ci * | | | 0xd214-0xd2fe | 5762306a36Sopenharmony_ci * | Target Mode | 0xe081 | | 5862306a36Sopenharmony_ci * | Target Mode Management | 0xf09b | 0xf002 | 5962306a36Sopenharmony_ci * | | | 0xf046-0xf049 | 6062306a36Sopenharmony_ci * | Target Mode Task Management | 0x1000d | | 6162306a36Sopenharmony_ci * ---------------------------------------------------------------------- 6262306a36Sopenharmony_ci */ 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci#include "qla_def.h" 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci#include <linux/delay.h> 6762306a36Sopenharmony_ci#define CREATE_TRACE_POINTS 6862306a36Sopenharmony_ci#include <trace/events/qla.h> 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_cistatic uint32_t ql_dbg_offset = 0x800; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_cistatic inline void 7362306a36Sopenharmony_ciqla2xxx_prep_dump(struct qla_hw_data *ha, struct qla2xxx_fw_dump *fw_dump) 7462306a36Sopenharmony_ci{ 7562306a36Sopenharmony_ci fw_dump->fw_major_version = htonl(ha->fw_major_version); 7662306a36Sopenharmony_ci fw_dump->fw_minor_version = htonl(ha->fw_minor_version); 7762306a36Sopenharmony_ci fw_dump->fw_subminor_version = htonl(ha->fw_subminor_version); 7862306a36Sopenharmony_ci fw_dump->fw_attributes = htonl(ha->fw_attributes); 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci fw_dump->vendor = htonl(ha->pdev->vendor); 8162306a36Sopenharmony_ci fw_dump->device = htonl(ha->pdev->device); 8262306a36Sopenharmony_ci fw_dump->subsystem_vendor = htonl(ha->pdev->subsystem_vendor); 8362306a36Sopenharmony_ci fw_dump->subsystem_device = htonl(ha->pdev->subsystem_device); 8462306a36Sopenharmony_ci} 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_cistatic inline void * 8762306a36Sopenharmony_ciqla2xxx_copy_queues(struct qla_hw_data *ha, void *ptr) 8862306a36Sopenharmony_ci{ 8962306a36Sopenharmony_ci struct req_que *req = ha->req_q_map[0]; 9062306a36Sopenharmony_ci struct rsp_que *rsp = ha->rsp_q_map[0]; 9162306a36Sopenharmony_ci /* Request queue. */ 9262306a36Sopenharmony_ci memcpy(ptr, req->ring, req->length * 9362306a36Sopenharmony_ci sizeof(request_t)); 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci /* Response queue. */ 9662306a36Sopenharmony_ci ptr += req->length * sizeof(request_t); 9762306a36Sopenharmony_ci memcpy(ptr, rsp->ring, rsp->length * 9862306a36Sopenharmony_ci sizeof(response_t)); 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci return ptr + (rsp->length * sizeof(response_t)); 10162306a36Sopenharmony_ci} 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ciint 10462306a36Sopenharmony_ciqla27xx_dump_mpi_ram(struct qla_hw_data *ha, uint32_t addr, uint32_t *ram, 10562306a36Sopenharmony_ci uint32_t ram_dwords, void **nxt) 10662306a36Sopenharmony_ci{ 10762306a36Sopenharmony_ci struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; 10862306a36Sopenharmony_ci dma_addr_t dump_dma = ha->gid_list_dma; 10962306a36Sopenharmony_ci uint32_t *chunk = (uint32_t *)ha->gid_list; 11062306a36Sopenharmony_ci uint32_t dwords = qla2x00_gid_list_size(ha) / 4; 11162306a36Sopenharmony_ci uint32_t stat; 11262306a36Sopenharmony_ci ulong i, j, timer = 6000000; 11362306a36Sopenharmony_ci int rval = QLA_FUNCTION_FAILED; 11462306a36Sopenharmony_ci scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci if (qla_pci_disconnected(vha, reg)) 11962306a36Sopenharmony_ci return rval; 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci for (i = 0; i < ram_dwords; i += dwords, addr += dwords) { 12262306a36Sopenharmony_ci if (i + dwords > ram_dwords) 12362306a36Sopenharmony_ci dwords = ram_dwords - i; 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci wrt_reg_word(®->mailbox0, MBC_LOAD_DUMP_MPI_RAM); 12662306a36Sopenharmony_ci wrt_reg_word(®->mailbox1, LSW(addr)); 12762306a36Sopenharmony_ci wrt_reg_word(®->mailbox8, MSW(addr)); 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci wrt_reg_word(®->mailbox2, MSW(LSD(dump_dma))); 13062306a36Sopenharmony_ci wrt_reg_word(®->mailbox3, LSW(LSD(dump_dma))); 13162306a36Sopenharmony_ci wrt_reg_word(®->mailbox6, MSW(MSD(dump_dma))); 13262306a36Sopenharmony_ci wrt_reg_word(®->mailbox7, LSW(MSD(dump_dma))); 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci wrt_reg_word(®->mailbox4, MSW(dwords)); 13562306a36Sopenharmony_ci wrt_reg_word(®->mailbox5, LSW(dwords)); 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci wrt_reg_word(®->mailbox9, 0); 13862306a36Sopenharmony_ci wrt_reg_dword(®->hccr, HCCRX_SET_HOST_INT); 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci ha->flags.mbox_int = 0; 14162306a36Sopenharmony_ci while (timer--) { 14262306a36Sopenharmony_ci udelay(5); 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci if (qla_pci_disconnected(vha, reg)) 14562306a36Sopenharmony_ci return rval; 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci stat = rd_reg_dword(®->host_status); 14862306a36Sopenharmony_ci /* Check for pending interrupts. */ 14962306a36Sopenharmony_ci if (!(stat & HSRX_RISC_INT)) 15062306a36Sopenharmony_ci continue; 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci stat &= 0xff; 15362306a36Sopenharmony_ci if (stat != 0x1 && stat != 0x2 && 15462306a36Sopenharmony_ci stat != 0x10 && stat != 0x11) { 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci /* Clear this intr; it wasn't a mailbox intr */ 15762306a36Sopenharmony_ci wrt_reg_dword(®->hccr, HCCRX_CLR_RISC_INT); 15862306a36Sopenharmony_ci rd_reg_dword(®->hccr); 15962306a36Sopenharmony_ci continue; 16062306a36Sopenharmony_ci } 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); 16362306a36Sopenharmony_ci rval = rd_reg_word(®->mailbox0) & MBS_MASK; 16462306a36Sopenharmony_ci wrt_reg_dword(®->hccr, HCCRX_CLR_RISC_INT); 16562306a36Sopenharmony_ci rd_reg_dword(®->hccr); 16662306a36Sopenharmony_ci break; 16762306a36Sopenharmony_ci } 16862306a36Sopenharmony_ci ha->flags.mbox_int = 1; 16962306a36Sopenharmony_ci *nxt = ram + i; 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci if (!test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { 17262306a36Sopenharmony_ci /* no interrupt, timed out*/ 17362306a36Sopenharmony_ci return rval; 17462306a36Sopenharmony_ci } 17562306a36Sopenharmony_ci if (rval) { 17662306a36Sopenharmony_ci /* error completion status */ 17762306a36Sopenharmony_ci return rval; 17862306a36Sopenharmony_ci } 17962306a36Sopenharmony_ci for (j = 0; j < dwords; j++) { 18062306a36Sopenharmony_ci ram[i + j] = 18162306a36Sopenharmony_ci (IS_QLA27XX(ha) || IS_QLA28XX(ha)) ? 18262306a36Sopenharmony_ci chunk[j] : swab32(chunk[j]); 18362306a36Sopenharmony_ci } 18462306a36Sopenharmony_ci } 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci *nxt = ram + i; 18762306a36Sopenharmony_ci return QLA_SUCCESS; 18862306a36Sopenharmony_ci} 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ciint 19162306a36Sopenharmony_ciqla24xx_dump_ram(struct qla_hw_data *ha, uint32_t addr, __be32 *ram, 19262306a36Sopenharmony_ci uint32_t ram_dwords, void **nxt) 19362306a36Sopenharmony_ci{ 19462306a36Sopenharmony_ci int rval = QLA_FUNCTION_FAILED; 19562306a36Sopenharmony_ci struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; 19662306a36Sopenharmony_ci dma_addr_t dump_dma = ha->gid_list_dma; 19762306a36Sopenharmony_ci uint32_t *chunk = (uint32_t *)ha->gid_list; 19862306a36Sopenharmony_ci uint32_t dwords = qla2x00_gid_list_size(ha) / 4; 19962306a36Sopenharmony_ci uint32_t stat; 20062306a36Sopenharmony_ci ulong i, j, timer = 6000000; 20162306a36Sopenharmony_ci scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci if (qla_pci_disconnected(vha, reg)) 20662306a36Sopenharmony_ci return rval; 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci for (i = 0; i < ram_dwords; i += dwords, addr += dwords) { 20962306a36Sopenharmony_ci if (i + dwords > ram_dwords) 21062306a36Sopenharmony_ci dwords = ram_dwords - i; 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci wrt_reg_word(®->mailbox0, MBC_DUMP_RISC_RAM_EXTENDED); 21362306a36Sopenharmony_ci wrt_reg_word(®->mailbox1, LSW(addr)); 21462306a36Sopenharmony_ci wrt_reg_word(®->mailbox8, MSW(addr)); 21562306a36Sopenharmony_ci wrt_reg_word(®->mailbox10, 0); 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci wrt_reg_word(®->mailbox2, MSW(LSD(dump_dma))); 21862306a36Sopenharmony_ci wrt_reg_word(®->mailbox3, LSW(LSD(dump_dma))); 21962306a36Sopenharmony_ci wrt_reg_word(®->mailbox6, MSW(MSD(dump_dma))); 22062306a36Sopenharmony_ci wrt_reg_word(®->mailbox7, LSW(MSD(dump_dma))); 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci wrt_reg_word(®->mailbox4, MSW(dwords)); 22362306a36Sopenharmony_ci wrt_reg_word(®->mailbox5, LSW(dwords)); 22462306a36Sopenharmony_ci wrt_reg_dword(®->hccr, HCCRX_SET_HOST_INT); 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci ha->flags.mbox_int = 0; 22762306a36Sopenharmony_ci while (timer--) { 22862306a36Sopenharmony_ci udelay(5); 22962306a36Sopenharmony_ci if (qla_pci_disconnected(vha, reg)) 23062306a36Sopenharmony_ci return rval; 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci stat = rd_reg_dword(®->host_status); 23362306a36Sopenharmony_ci /* Check for pending interrupts. */ 23462306a36Sopenharmony_ci if (!(stat & HSRX_RISC_INT)) 23562306a36Sopenharmony_ci continue; 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci stat &= 0xff; 23862306a36Sopenharmony_ci if (stat != 0x1 && stat != 0x2 && 23962306a36Sopenharmony_ci stat != 0x10 && stat != 0x11) { 24062306a36Sopenharmony_ci wrt_reg_dword(®->hccr, HCCRX_CLR_RISC_INT); 24162306a36Sopenharmony_ci rd_reg_dword(®->hccr); 24262306a36Sopenharmony_ci continue; 24362306a36Sopenharmony_ci } 24462306a36Sopenharmony_ci 24562306a36Sopenharmony_ci set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); 24662306a36Sopenharmony_ci rval = rd_reg_word(®->mailbox0) & MBS_MASK; 24762306a36Sopenharmony_ci wrt_reg_dword(®->hccr, HCCRX_CLR_RISC_INT); 24862306a36Sopenharmony_ci rd_reg_dword(®->hccr); 24962306a36Sopenharmony_ci break; 25062306a36Sopenharmony_ci } 25162306a36Sopenharmony_ci ha->flags.mbox_int = 1; 25262306a36Sopenharmony_ci *nxt = ram + i; 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ci if (!test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { 25562306a36Sopenharmony_ci /* no interrupt, timed out*/ 25662306a36Sopenharmony_ci return rval; 25762306a36Sopenharmony_ci } 25862306a36Sopenharmony_ci if (rval) { 25962306a36Sopenharmony_ci /* error completion status */ 26062306a36Sopenharmony_ci return rval; 26162306a36Sopenharmony_ci } 26262306a36Sopenharmony_ci for (j = 0; j < dwords; j++) { 26362306a36Sopenharmony_ci ram[i + j] = (__force __be32) 26462306a36Sopenharmony_ci ((IS_QLA27XX(ha) || IS_QLA28XX(ha)) ? 26562306a36Sopenharmony_ci chunk[j] : swab32(chunk[j])); 26662306a36Sopenharmony_ci } 26762306a36Sopenharmony_ci } 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci *nxt = ram + i; 27062306a36Sopenharmony_ci return QLA_SUCCESS; 27162306a36Sopenharmony_ci} 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_cistatic int 27462306a36Sopenharmony_ciqla24xx_dump_memory(struct qla_hw_data *ha, __be32 *code_ram, 27562306a36Sopenharmony_ci uint32_t cram_size, void **nxt) 27662306a36Sopenharmony_ci{ 27762306a36Sopenharmony_ci int rval; 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci /* Code RAM. */ 28062306a36Sopenharmony_ci rval = qla24xx_dump_ram(ha, 0x20000, code_ram, cram_size / 4, nxt); 28162306a36Sopenharmony_ci if (rval != QLA_SUCCESS) 28262306a36Sopenharmony_ci return rval; 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_ci set_bit(RISC_SRAM_DUMP_CMPL, &ha->fw_dump_cap_flags); 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci /* External Memory. */ 28762306a36Sopenharmony_ci rval = qla24xx_dump_ram(ha, 0x100000, *nxt, 28862306a36Sopenharmony_ci ha->fw_memory_size - 0x100000 + 1, nxt); 28962306a36Sopenharmony_ci if (rval == QLA_SUCCESS) 29062306a36Sopenharmony_ci set_bit(RISC_EXT_MEM_DUMP_CMPL, &ha->fw_dump_cap_flags); 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci return rval; 29362306a36Sopenharmony_ci} 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_cistatic __be32 * 29662306a36Sopenharmony_ciqla24xx_read_window(struct device_reg_24xx __iomem *reg, uint32_t iobase, 29762306a36Sopenharmony_ci uint32_t count, __be32 *buf) 29862306a36Sopenharmony_ci{ 29962306a36Sopenharmony_ci __le32 __iomem *dmp_reg; 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci wrt_reg_dword(®->iobase_addr, iobase); 30262306a36Sopenharmony_ci dmp_reg = ®->iobase_window; 30362306a36Sopenharmony_ci for ( ; count--; dmp_reg++) 30462306a36Sopenharmony_ci *buf++ = htonl(rd_reg_dword(dmp_reg)); 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ci return buf; 30762306a36Sopenharmony_ci} 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_civoid 31062306a36Sopenharmony_ciqla24xx_pause_risc(struct device_reg_24xx __iomem *reg, struct qla_hw_data *ha) 31162306a36Sopenharmony_ci{ 31262306a36Sopenharmony_ci wrt_reg_dword(®->hccr, HCCRX_SET_RISC_PAUSE); 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci /* 100 usec delay is sufficient enough for hardware to pause RISC */ 31562306a36Sopenharmony_ci udelay(100); 31662306a36Sopenharmony_ci if (rd_reg_dword(®->host_status) & HSRX_RISC_PAUSED) 31762306a36Sopenharmony_ci set_bit(RISC_PAUSE_CMPL, &ha->fw_dump_cap_flags); 31862306a36Sopenharmony_ci} 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ciint 32162306a36Sopenharmony_ciqla24xx_soft_reset(struct qla_hw_data *ha) 32262306a36Sopenharmony_ci{ 32362306a36Sopenharmony_ci int rval = QLA_SUCCESS; 32462306a36Sopenharmony_ci uint32_t cnt; 32562306a36Sopenharmony_ci uint16_t wd; 32662306a36Sopenharmony_ci struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci /* 32962306a36Sopenharmony_ci * Reset RISC. The delay is dependent on system architecture. 33062306a36Sopenharmony_ci * Driver can proceed with the reset sequence after waiting 33162306a36Sopenharmony_ci * for a timeout period. 33262306a36Sopenharmony_ci */ 33362306a36Sopenharmony_ci wrt_reg_dword(®->ctrl_status, CSRX_DMA_SHUTDOWN|MWB_4096_BYTES); 33462306a36Sopenharmony_ci for (cnt = 0; cnt < 30000; cnt++) { 33562306a36Sopenharmony_ci if ((rd_reg_dword(®->ctrl_status) & CSRX_DMA_ACTIVE) == 0) 33662306a36Sopenharmony_ci break; 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_ci udelay(10); 33962306a36Sopenharmony_ci } 34062306a36Sopenharmony_ci if (!(rd_reg_dword(®->ctrl_status) & CSRX_DMA_ACTIVE)) 34162306a36Sopenharmony_ci set_bit(DMA_SHUTDOWN_CMPL, &ha->fw_dump_cap_flags); 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_ci wrt_reg_dword(®->ctrl_status, 34462306a36Sopenharmony_ci CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES); 34562306a36Sopenharmony_ci pci_read_config_word(ha->pdev, PCI_COMMAND, &wd); 34662306a36Sopenharmony_ci 34762306a36Sopenharmony_ci udelay(100); 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ci /* Wait for soft-reset to complete. */ 35062306a36Sopenharmony_ci for (cnt = 0; cnt < 30000; cnt++) { 35162306a36Sopenharmony_ci if ((rd_reg_dword(®->ctrl_status) & 35262306a36Sopenharmony_ci CSRX_ISP_SOFT_RESET) == 0) 35362306a36Sopenharmony_ci break; 35462306a36Sopenharmony_ci 35562306a36Sopenharmony_ci udelay(10); 35662306a36Sopenharmony_ci } 35762306a36Sopenharmony_ci if (!(rd_reg_dword(®->ctrl_status) & CSRX_ISP_SOFT_RESET)) 35862306a36Sopenharmony_ci set_bit(ISP_RESET_CMPL, &ha->fw_dump_cap_flags); 35962306a36Sopenharmony_ci 36062306a36Sopenharmony_ci wrt_reg_dword(®->hccr, HCCRX_CLR_RISC_RESET); 36162306a36Sopenharmony_ci rd_reg_dword(®->hccr); /* PCI Posting. */ 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ci for (cnt = 10000; rd_reg_word(®->mailbox0) != 0 && 36462306a36Sopenharmony_ci rval == QLA_SUCCESS; cnt--) { 36562306a36Sopenharmony_ci if (cnt) 36662306a36Sopenharmony_ci udelay(10); 36762306a36Sopenharmony_ci else 36862306a36Sopenharmony_ci rval = QLA_FUNCTION_TIMEOUT; 36962306a36Sopenharmony_ci } 37062306a36Sopenharmony_ci if (rval == QLA_SUCCESS) 37162306a36Sopenharmony_ci set_bit(RISC_RDY_AFT_RESET, &ha->fw_dump_cap_flags); 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_ci return rval; 37462306a36Sopenharmony_ci} 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_cistatic int 37762306a36Sopenharmony_ciqla2xxx_dump_ram(struct qla_hw_data *ha, uint32_t addr, __be16 *ram, 37862306a36Sopenharmony_ci uint32_t ram_words, void **nxt) 37962306a36Sopenharmony_ci{ 38062306a36Sopenharmony_ci int rval; 38162306a36Sopenharmony_ci uint32_t cnt, stat, timer, words, idx; 38262306a36Sopenharmony_ci uint16_t mb0; 38362306a36Sopenharmony_ci struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; 38462306a36Sopenharmony_ci dma_addr_t dump_dma = ha->gid_list_dma; 38562306a36Sopenharmony_ci __le16 *dump = (__force __le16 *)ha->gid_list; 38662306a36Sopenharmony_ci 38762306a36Sopenharmony_ci rval = QLA_SUCCESS; 38862306a36Sopenharmony_ci mb0 = 0; 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ci WRT_MAILBOX_REG(ha, reg, 0, MBC_DUMP_RISC_RAM_EXTENDED); 39162306a36Sopenharmony_ci clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_ci words = qla2x00_gid_list_size(ha) / 2; 39462306a36Sopenharmony_ci for (cnt = 0; cnt < ram_words && rval == QLA_SUCCESS; 39562306a36Sopenharmony_ci cnt += words, addr += words) { 39662306a36Sopenharmony_ci if (cnt + words > ram_words) 39762306a36Sopenharmony_ci words = ram_words - cnt; 39862306a36Sopenharmony_ci 39962306a36Sopenharmony_ci WRT_MAILBOX_REG(ha, reg, 1, LSW(addr)); 40062306a36Sopenharmony_ci WRT_MAILBOX_REG(ha, reg, 8, MSW(addr)); 40162306a36Sopenharmony_ci 40262306a36Sopenharmony_ci WRT_MAILBOX_REG(ha, reg, 2, MSW(dump_dma)); 40362306a36Sopenharmony_ci WRT_MAILBOX_REG(ha, reg, 3, LSW(dump_dma)); 40462306a36Sopenharmony_ci WRT_MAILBOX_REG(ha, reg, 6, MSW(MSD(dump_dma))); 40562306a36Sopenharmony_ci WRT_MAILBOX_REG(ha, reg, 7, LSW(MSD(dump_dma))); 40662306a36Sopenharmony_ci 40762306a36Sopenharmony_ci WRT_MAILBOX_REG(ha, reg, 4, words); 40862306a36Sopenharmony_ci wrt_reg_word(®->hccr, HCCR_SET_HOST_INT); 40962306a36Sopenharmony_ci 41062306a36Sopenharmony_ci for (timer = 6000000; timer; timer--) { 41162306a36Sopenharmony_ci /* Check for pending interrupts. */ 41262306a36Sopenharmony_ci stat = rd_reg_dword(®->u.isp2300.host_status); 41362306a36Sopenharmony_ci if (stat & HSR_RISC_INT) { 41462306a36Sopenharmony_ci stat &= 0xff; 41562306a36Sopenharmony_ci 41662306a36Sopenharmony_ci if (stat == 0x1 || stat == 0x2) { 41762306a36Sopenharmony_ci set_bit(MBX_INTERRUPT, 41862306a36Sopenharmony_ci &ha->mbx_cmd_flags); 41962306a36Sopenharmony_ci 42062306a36Sopenharmony_ci mb0 = RD_MAILBOX_REG(ha, reg, 0); 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_ci /* Release mailbox registers. */ 42362306a36Sopenharmony_ci wrt_reg_word(®->semaphore, 0); 42462306a36Sopenharmony_ci wrt_reg_word(®->hccr, 42562306a36Sopenharmony_ci HCCR_CLR_RISC_INT); 42662306a36Sopenharmony_ci rd_reg_word(®->hccr); 42762306a36Sopenharmony_ci break; 42862306a36Sopenharmony_ci } else if (stat == 0x10 || stat == 0x11) { 42962306a36Sopenharmony_ci set_bit(MBX_INTERRUPT, 43062306a36Sopenharmony_ci &ha->mbx_cmd_flags); 43162306a36Sopenharmony_ci 43262306a36Sopenharmony_ci mb0 = RD_MAILBOX_REG(ha, reg, 0); 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_ci wrt_reg_word(®->hccr, 43562306a36Sopenharmony_ci HCCR_CLR_RISC_INT); 43662306a36Sopenharmony_ci rd_reg_word(®->hccr); 43762306a36Sopenharmony_ci break; 43862306a36Sopenharmony_ci } 43962306a36Sopenharmony_ci 44062306a36Sopenharmony_ci /* clear this intr; it wasn't a mailbox intr */ 44162306a36Sopenharmony_ci wrt_reg_word(®->hccr, HCCR_CLR_RISC_INT); 44262306a36Sopenharmony_ci rd_reg_word(®->hccr); 44362306a36Sopenharmony_ci } 44462306a36Sopenharmony_ci udelay(5); 44562306a36Sopenharmony_ci } 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_ci if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { 44862306a36Sopenharmony_ci rval = mb0 & MBS_MASK; 44962306a36Sopenharmony_ci for (idx = 0; idx < words; idx++) 45062306a36Sopenharmony_ci ram[cnt + idx] = 45162306a36Sopenharmony_ci cpu_to_be16(le16_to_cpu(dump[idx])); 45262306a36Sopenharmony_ci } else { 45362306a36Sopenharmony_ci rval = QLA_FUNCTION_FAILED; 45462306a36Sopenharmony_ci } 45562306a36Sopenharmony_ci } 45662306a36Sopenharmony_ci 45762306a36Sopenharmony_ci *nxt = rval == QLA_SUCCESS ? &ram[cnt] : NULL; 45862306a36Sopenharmony_ci return rval; 45962306a36Sopenharmony_ci} 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_cistatic inline void 46262306a36Sopenharmony_ciqla2xxx_read_window(struct device_reg_2xxx __iomem *reg, uint32_t count, 46362306a36Sopenharmony_ci __be16 *buf) 46462306a36Sopenharmony_ci{ 46562306a36Sopenharmony_ci __le16 __iomem *dmp_reg = ®->u.isp2300.fb_cmd; 46662306a36Sopenharmony_ci 46762306a36Sopenharmony_ci for ( ; count--; dmp_reg++) 46862306a36Sopenharmony_ci *buf++ = htons(rd_reg_word(dmp_reg)); 46962306a36Sopenharmony_ci} 47062306a36Sopenharmony_ci 47162306a36Sopenharmony_cistatic inline void * 47262306a36Sopenharmony_ciqla24xx_copy_eft(struct qla_hw_data *ha, void *ptr) 47362306a36Sopenharmony_ci{ 47462306a36Sopenharmony_ci if (!ha->eft) 47562306a36Sopenharmony_ci return ptr; 47662306a36Sopenharmony_ci 47762306a36Sopenharmony_ci memcpy(ptr, ha->eft, ntohl(ha->fw_dump->eft_size)); 47862306a36Sopenharmony_ci return ptr + ntohl(ha->fw_dump->eft_size); 47962306a36Sopenharmony_ci} 48062306a36Sopenharmony_ci 48162306a36Sopenharmony_cistatic inline void * 48262306a36Sopenharmony_ciqla25xx_copy_fce(struct qla_hw_data *ha, void *ptr, __be32 **last_chain) 48362306a36Sopenharmony_ci{ 48462306a36Sopenharmony_ci uint32_t cnt; 48562306a36Sopenharmony_ci __be32 *iter_reg; 48662306a36Sopenharmony_ci struct qla2xxx_fce_chain *fcec = ptr; 48762306a36Sopenharmony_ci 48862306a36Sopenharmony_ci if (!ha->fce) 48962306a36Sopenharmony_ci return ptr; 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_ci *last_chain = &fcec->type; 49262306a36Sopenharmony_ci fcec->type = htonl(DUMP_CHAIN_FCE); 49362306a36Sopenharmony_ci fcec->chain_size = htonl(sizeof(struct qla2xxx_fce_chain) + 49462306a36Sopenharmony_ci fce_calc_size(ha->fce_bufs)); 49562306a36Sopenharmony_ci fcec->size = htonl(fce_calc_size(ha->fce_bufs)); 49662306a36Sopenharmony_ci fcec->addr_l = htonl(LSD(ha->fce_dma)); 49762306a36Sopenharmony_ci fcec->addr_h = htonl(MSD(ha->fce_dma)); 49862306a36Sopenharmony_ci 49962306a36Sopenharmony_ci iter_reg = fcec->eregs; 50062306a36Sopenharmony_ci for (cnt = 0; cnt < 8; cnt++) 50162306a36Sopenharmony_ci *iter_reg++ = htonl(ha->fce_mb[cnt]); 50262306a36Sopenharmony_ci 50362306a36Sopenharmony_ci memcpy(iter_reg, ha->fce, ntohl(fcec->size)); 50462306a36Sopenharmony_ci 50562306a36Sopenharmony_ci return (char *)iter_reg + ntohl(fcec->size); 50662306a36Sopenharmony_ci} 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_cistatic inline void * 50962306a36Sopenharmony_ciqla25xx_copy_exlogin(struct qla_hw_data *ha, void *ptr, __be32 **last_chain) 51062306a36Sopenharmony_ci{ 51162306a36Sopenharmony_ci struct qla2xxx_offld_chain *c = ptr; 51262306a36Sopenharmony_ci 51362306a36Sopenharmony_ci if (!ha->exlogin_buf) 51462306a36Sopenharmony_ci return ptr; 51562306a36Sopenharmony_ci 51662306a36Sopenharmony_ci *last_chain = &c->type; 51762306a36Sopenharmony_ci 51862306a36Sopenharmony_ci c->type = cpu_to_be32(DUMP_CHAIN_EXLOGIN); 51962306a36Sopenharmony_ci c->chain_size = cpu_to_be32(sizeof(struct qla2xxx_offld_chain) + 52062306a36Sopenharmony_ci ha->exlogin_size); 52162306a36Sopenharmony_ci c->size = cpu_to_be32(ha->exlogin_size); 52262306a36Sopenharmony_ci c->addr = cpu_to_be64(ha->exlogin_buf_dma); 52362306a36Sopenharmony_ci 52462306a36Sopenharmony_ci ptr += sizeof(struct qla2xxx_offld_chain); 52562306a36Sopenharmony_ci memcpy(ptr, ha->exlogin_buf, ha->exlogin_size); 52662306a36Sopenharmony_ci 52762306a36Sopenharmony_ci return (char *)ptr + be32_to_cpu(c->size); 52862306a36Sopenharmony_ci} 52962306a36Sopenharmony_ci 53062306a36Sopenharmony_cistatic inline void * 53162306a36Sopenharmony_ciqla81xx_copy_exchoffld(struct qla_hw_data *ha, void *ptr, __be32 **last_chain) 53262306a36Sopenharmony_ci{ 53362306a36Sopenharmony_ci struct qla2xxx_offld_chain *c = ptr; 53462306a36Sopenharmony_ci 53562306a36Sopenharmony_ci if (!ha->exchoffld_buf) 53662306a36Sopenharmony_ci return ptr; 53762306a36Sopenharmony_ci 53862306a36Sopenharmony_ci *last_chain = &c->type; 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_ci c->type = cpu_to_be32(DUMP_CHAIN_EXCHG); 54162306a36Sopenharmony_ci c->chain_size = cpu_to_be32(sizeof(struct qla2xxx_offld_chain) + 54262306a36Sopenharmony_ci ha->exchoffld_size); 54362306a36Sopenharmony_ci c->size = cpu_to_be32(ha->exchoffld_size); 54462306a36Sopenharmony_ci c->addr = cpu_to_be64(ha->exchoffld_buf_dma); 54562306a36Sopenharmony_ci 54662306a36Sopenharmony_ci ptr += sizeof(struct qla2xxx_offld_chain); 54762306a36Sopenharmony_ci memcpy(ptr, ha->exchoffld_buf, ha->exchoffld_size); 54862306a36Sopenharmony_ci 54962306a36Sopenharmony_ci return (char *)ptr + be32_to_cpu(c->size); 55062306a36Sopenharmony_ci} 55162306a36Sopenharmony_ci 55262306a36Sopenharmony_cistatic inline void * 55362306a36Sopenharmony_ciqla2xxx_copy_atioqueues(struct qla_hw_data *ha, void *ptr, 55462306a36Sopenharmony_ci __be32 **last_chain) 55562306a36Sopenharmony_ci{ 55662306a36Sopenharmony_ci struct qla2xxx_mqueue_chain *q; 55762306a36Sopenharmony_ci struct qla2xxx_mqueue_header *qh; 55862306a36Sopenharmony_ci uint32_t num_queues; 55962306a36Sopenharmony_ci int que; 56062306a36Sopenharmony_ci struct { 56162306a36Sopenharmony_ci int length; 56262306a36Sopenharmony_ci void *ring; 56362306a36Sopenharmony_ci } aq, *aqp; 56462306a36Sopenharmony_ci 56562306a36Sopenharmony_ci if (!ha->tgt.atio_ring) 56662306a36Sopenharmony_ci return ptr; 56762306a36Sopenharmony_ci 56862306a36Sopenharmony_ci num_queues = 1; 56962306a36Sopenharmony_ci aqp = &aq; 57062306a36Sopenharmony_ci aqp->length = ha->tgt.atio_q_length; 57162306a36Sopenharmony_ci aqp->ring = ha->tgt.atio_ring; 57262306a36Sopenharmony_ci 57362306a36Sopenharmony_ci for (que = 0; que < num_queues; que++) { 57462306a36Sopenharmony_ci /* aqp = ha->atio_q_map[que]; */ 57562306a36Sopenharmony_ci q = ptr; 57662306a36Sopenharmony_ci *last_chain = &q->type; 57762306a36Sopenharmony_ci q->type = htonl(DUMP_CHAIN_QUEUE); 57862306a36Sopenharmony_ci q->chain_size = htonl( 57962306a36Sopenharmony_ci sizeof(struct qla2xxx_mqueue_chain) + 58062306a36Sopenharmony_ci sizeof(struct qla2xxx_mqueue_header) + 58162306a36Sopenharmony_ci (aqp->length * sizeof(request_t))); 58262306a36Sopenharmony_ci ptr += sizeof(struct qla2xxx_mqueue_chain); 58362306a36Sopenharmony_ci 58462306a36Sopenharmony_ci /* Add header. */ 58562306a36Sopenharmony_ci qh = ptr; 58662306a36Sopenharmony_ci qh->queue = htonl(TYPE_ATIO_QUEUE); 58762306a36Sopenharmony_ci qh->number = htonl(que); 58862306a36Sopenharmony_ci qh->size = htonl(aqp->length * sizeof(request_t)); 58962306a36Sopenharmony_ci ptr += sizeof(struct qla2xxx_mqueue_header); 59062306a36Sopenharmony_ci 59162306a36Sopenharmony_ci /* Add data. */ 59262306a36Sopenharmony_ci memcpy(ptr, aqp->ring, aqp->length * sizeof(request_t)); 59362306a36Sopenharmony_ci 59462306a36Sopenharmony_ci ptr += aqp->length * sizeof(request_t); 59562306a36Sopenharmony_ci } 59662306a36Sopenharmony_ci 59762306a36Sopenharmony_ci return ptr; 59862306a36Sopenharmony_ci} 59962306a36Sopenharmony_ci 60062306a36Sopenharmony_cistatic inline void * 60162306a36Sopenharmony_ciqla25xx_copy_mqueues(struct qla_hw_data *ha, void *ptr, __be32 **last_chain) 60262306a36Sopenharmony_ci{ 60362306a36Sopenharmony_ci struct qla2xxx_mqueue_chain *q; 60462306a36Sopenharmony_ci struct qla2xxx_mqueue_header *qh; 60562306a36Sopenharmony_ci struct req_que *req; 60662306a36Sopenharmony_ci struct rsp_que *rsp; 60762306a36Sopenharmony_ci int que; 60862306a36Sopenharmony_ci 60962306a36Sopenharmony_ci if (!ha->mqenable) 61062306a36Sopenharmony_ci return ptr; 61162306a36Sopenharmony_ci 61262306a36Sopenharmony_ci /* Request queues */ 61362306a36Sopenharmony_ci for (que = 1; que < ha->max_req_queues; que++) { 61462306a36Sopenharmony_ci req = ha->req_q_map[que]; 61562306a36Sopenharmony_ci if (!req) 61662306a36Sopenharmony_ci break; 61762306a36Sopenharmony_ci 61862306a36Sopenharmony_ci /* Add chain. */ 61962306a36Sopenharmony_ci q = ptr; 62062306a36Sopenharmony_ci *last_chain = &q->type; 62162306a36Sopenharmony_ci q->type = htonl(DUMP_CHAIN_QUEUE); 62262306a36Sopenharmony_ci q->chain_size = htonl( 62362306a36Sopenharmony_ci sizeof(struct qla2xxx_mqueue_chain) + 62462306a36Sopenharmony_ci sizeof(struct qla2xxx_mqueue_header) + 62562306a36Sopenharmony_ci (req->length * sizeof(request_t))); 62662306a36Sopenharmony_ci ptr += sizeof(struct qla2xxx_mqueue_chain); 62762306a36Sopenharmony_ci 62862306a36Sopenharmony_ci /* Add header. */ 62962306a36Sopenharmony_ci qh = ptr; 63062306a36Sopenharmony_ci qh->queue = htonl(TYPE_REQUEST_QUEUE); 63162306a36Sopenharmony_ci qh->number = htonl(que); 63262306a36Sopenharmony_ci qh->size = htonl(req->length * sizeof(request_t)); 63362306a36Sopenharmony_ci ptr += sizeof(struct qla2xxx_mqueue_header); 63462306a36Sopenharmony_ci 63562306a36Sopenharmony_ci /* Add data. */ 63662306a36Sopenharmony_ci memcpy(ptr, req->ring, req->length * sizeof(request_t)); 63762306a36Sopenharmony_ci ptr += req->length * sizeof(request_t); 63862306a36Sopenharmony_ci } 63962306a36Sopenharmony_ci 64062306a36Sopenharmony_ci /* Response queues */ 64162306a36Sopenharmony_ci for (que = 1; que < ha->max_rsp_queues; que++) { 64262306a36Sopenharmony_ci rsp = ha->rsp_q_map[que]; 64362306a36Sopenharmony_ci if (!rsp) 64462306a36Sopenharmony_ci break; 64562306a36Sopenharmony_ci 64662306a36Sopenharmony_ci /* Add chain. */ 64762306a36Sopenharmony_ci q = ptr; 64862306a36Sopenharmony_ci *last_chain = &q->type; 64962306a36Sopenharmony_ci q->type = htonl(DUMP_CHAIN_QUEUE); 65062306a36Sopenharmony_ci q->chain_size = htonl( 65162306a36Sopenharmony_ci sizeof(struct qla2xxx_mqueue_chain) + 65262306a36Sopenharmony_ci sizeof(struct qla2xxx_mqueue_header) + 65362306a36Sopenharmony_ci (rsp->length * sizeof(response_t))); 65462306a36Sopenharmony_ci ptr += sizeof(struct qla2xxx_mqueue_chain); 65562306a36Sopenharmony_ci 65662306a36Sopenharmony_ci /* Add header. */ 65762306a36Sopenharmony_ci qh = ptr; 65862306a36Sopenharmony_ci qh->queue = htonl(TYPE_RESPONSE_QUEUE); 65962306a36Sopenharmony_ci qh->number = htonl(que); 66062306a36Sopenharmony_ci qh->size = htonl(rsp->length * sizeof(response_t)); 66162306a36Sopenharmony_ci ptr += sizeof(struct qla2xxx_mqueue_header); 66262306a36Sopenharmony_ci 66362306a36Sopenharmony_ci /* Add data. */ 66462306a36Sopenharmony_ci memcpy(ptr, rsp->ring, rsp->length * sizeof(response_t)); 66562306a36Sopenharmony_ci ptr += rsp->length * sizeof(response_t); 66662306a36Sopenharmony_ci } 66762306a36Sopenharmony_ci 66862306a36Sopenharmony_ci return ptr; 66962306a36Sopenharmony_ci} 67062306a36Sopenharmony_ci 67162306a36Sopenharmony_cistatic inline void * 67262306a36Sopenharmony_ciqla25xx_copy_mq(struct qla_hw_data *ha, void *ptr, __be32 **last_chain) 67362306a36Sopenharmony_ci{ 67462306a36Sopenharmony_ci uint32_t cnt, que_idx; 67562306a36Sopenharmony_ci uint8_t que_cnt; 67662306a36Sopenharmony_ci struct qla2xxx_mq_chain *mq = ptr; 67762306a36Sopenharmony_ci device_reg_t *reg; 67862306a36Sopenharmony_ci 67962306a36Sopenharmony_ci if (!ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha) || 68062306a36Sopenharmony_ci IS_QLA28XX(ha)) 68162306a36Sopenharmony_ci return ptr; 68262306a36Sopenharmony_ci 68362306a36Sopenharmony_ci mq = ptr; 68462306a36Sopenharmony_ci *last_chain = &mq->type; 68562306a36Sopenharmony_ci mq->type = htonl(DUMP_CHAIN_MQ); 68662306a36Sopenharmony_ci mq->chain_size = htonl(sizeof(struct qla2xxx_mq_chain)); 68762306a36Sopenharmony_ci 68862306a36Sopenharmony_ci que_cnt = ha->max_req_queues > ha->max_rsp_queues ? 68962306a36Sopenharmony_ci ha->max_req_queues : ha->max_rsp_queues; 69062306a36Sopenharmony_ci mq->count = htonl(que_cnt); 69162306a36Sopenharmony_ci for (cnt = 0; cnt < que_cnt; cnt++) { 69262306a36Sopenharmony_ci reg = ISP_QUE_REG(ha, cnt); 69362306a36Sopenharmony_ci que_idx = cnt * 4; 69462306a36Sopenharmony_ci mq->qregs[que_idx] = 69562306a36Sopenharmony_ci htonl(rd_reg_dword(®->isp25mq.req_q_in)); 69662306a36Sopenharmony_ci mq->qregs[que_idx+1] = 69762306a36Sopenharmony_ci htonl(rd_reg_dword(®->isp25mq.req_q_out)); 69862306a36Sopenharmony_ci mq->qregs[que_idx+2] = 69962306a36Sopenharmony_ci htonl(rd_reg_dword(®->isp25mq.rsp_q_in)); 70062306a36Sopenharmony_ci mq->qregs[que_idx+3] = 70162306a36Sopenharmony_ci htonl(rd_reg_dword(®->isp25mq.rsp_q_out)); 70262306a36Sopenharmony_ci } 70362306a36Sopenharmony_ci 70462306a36Sopenharmony_ci return ptr + sizeof(struct qla2xxx_mq_chain); 70562306a36Sopenharmony_ci} 70662306a36Sopenharmony_ci 70762306a36Sopenharmony_civoid 70862306a36Sopenharmony_ciqla2xxx_dump_post_process(scsi_qla_host_t *vha, int rval) 70962306a36Sopenharmony_ci{ 71062306a36Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 71162306a36Sopenharmony_ci 71262306a36Sopenharmony_ci if (rval != QLA_SUCCESS) { 71362306a36Sopenharmony_ci ql_log(ql_log_warn, vha, 0xd000, 71462306a36Sopenharmony_ci "Failed to dump firmware (%x), dump status flags (0x%lx).\n", 71562306a36Sopenharmony_ci rval, ha->fw_dump_cap_flags); 71662306a36Sopenharmony_ci ha->fw_dumped = false; 71762306a36Sopenharmony_ci } else { 71862306a36Sopenharmony_ci ql_log(ql_log_info, vha, 0xd001, 71962306a36Sopenharmony_ci "Firmware dump saved to temp buffer (%ld/%p), dump status flags (0x%lx).\n", 72062306a36Sopenharmony_ci vha->host_no, ha->fw_dump, ha->fw_dump_cap_flags); 72162306a36Sopenharmony_ci ha->fw_dumped = true; 72262306a36Sopenharmony_ci qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP); 72362306a36Sopenharmony_ci } 72462306a36Sopenharmony_ci} 72562306a36Sopenharmony_ci 72662306a36Sopenharmony_civoid qla2xxx_dump_fw(scsi_qla_host_t *vha) 72762306a36Sopenharmony_ci{ 72862306a36Sopenharmony_ci unsigned long flags; 72962306a36Sopenharmony_ci 73062306a36Sopenharmony_ci spin_lock_irqsave(&vha->hw->hardware_lock, flags); 73162306a36Sopenharmony_ci vha->hw->isp_ops->fw_dump(vha); 73262306a36Sopenharmony_ci spin_unlock_irqrestore(&vha->hw->hardware_lock, flags); 73362306a36Sopenharmony_ci} 73462306a36Sopenharmony_ci 73562306a36Sopenharmony_ci/** 73662306a36Sopenharmony_ci * qla2300_fw_dump() - Dumps binary data from the 2300 firmware. 73762306a36Sopenharmony_ci * @vha: HA context 73862306a36Sopenharmony_ci */ 73962306a36Sopenharmony_civoid 74062306a36Sopenharmony_ciqla2300_fw_dump(scsi_qla_host_t *vha) 74162306a36Sopenharmony_ci{ 74262306a36Sopenharmony_ci int rval; 74362306a36Sopenharmony_ci uint32_t cnt; 74462306a36Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 74562306a36Sopenharmony_ci struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; 74662306a36Sopenharmony_ci __le16 __iomem *dmp_reg; 74762306a36Sopenharmony_ci struct qla2300_fw_dump *fw; 74862306a36Sopenharmony_ci void *nxt; 74962306a36Sopenharmony_ci struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); 75062306a36Sopenharmony_ci 75162306a36Sopenharmony_ci lockdep_assert_held(&ha->hardware_lock); 75262306a36Sopenharmony_ci 75362306a36Sopenharmony_ci if (!ha->fw_dump) { 75462306a36Sopenharmony_ci ql_log(ql_log_warn, vha, 0xd002, 75562306a36Sopenharmony_ci "No buffer available for dump.\n"); 75662306a36Sopenharmony_ci return; 75762306a36Sopenharmony_ci } 75862306a36Sopenharmony_ci 75962306a36Sopenharmony_ci if (ha->fw_dumped) { 76062306a36Sopenharmony_ci ql_log(ql_log_warn, vha, 0xd003, 76162306a36Sopenharmony_ci "Firmware has been previously dumped (%p) " 76262306a36Sopenharmony_ci "-- ignoring request.\n", 76362306a36Sopenharmony_ci ha->fw_dump); 76462306a36Sopenharmony_ci return; 76562306a36Sopenharmony_ci } 76662306a36Sopenharmony_ci fw = &ha->fw_dump->isp.isp23; 76762306a36Sopenharmony_ci qla2xxx_prep_dump(ha, ha->fw_dump); 76862306a36Sopenharmony_ci 76962306a36Sopenharmony_ci rval = QLA_SUCCESS; 77062306a36Sopenharmony_ci fw->hccr = htons(rd_reg_word(®->hccr)); 77162306a36Sopenharmony_ci 77262306a36Sopenharmony_ci /* Pause RISC. */ 77362306a36Sopenharmony_ci wrt_reg_word(®->hccr, HCCR_PAUSE_RISC); 77462306a36Sopenharmony_ci if (IS_QLA2300(ha)) { 77562306a36Sopenharmony_ci for (cnt = 30000; 77662306a36Sopenharmony_ci (rd_reg_word(®->hccr) & HCCR_RISC_PAUSE) == 0 && 77762306a36Sopenharmony_ci rval == QLA_SUCCESS; cnt--) { 77862306a36Sopenharmony_ci if (cnt) 77962306a36Sopenharmony_ci udelay(100); 78062306a36Sopenharmony_ci else 78162306a36Sopenharmony_ci rval = QLA_FUNCTION_TIMEOUT; 78262306a36Sopenharmony_ci } 78362306a36Sopenharmony_ci } else { 78462306a36Sopenharmony_ci rd_reg_word(®->hccr); /* PCI Posting. */ 78562306a36Sopenharmony_ci udelay(10); 78662306a36Sopenharmony_ci } 78762306a36Sopenharmony_ci 78862306a36Sopenharmony_ci if (rval == QLA_SUCCESS) { 78962306a36Sopenharmony_ci dmp_reg = ®->flash_address; 79062306a36Sopenharmony_ci for (cnt = 0; cnt < ARRAY_SIZE(fw->pbiu_reg); cnt++, dmp_reg++) 79162306a36Sopenharmony_ci fw->pbiu_reg[cnt] = htons(rd_reg_word(dmp_reg)); 79262306a36Sopenharmony_ci 79362306a36Sopenharmony_ci dmp_reg = ®->u.isp2300.req_q_in; 79462306a36Sopenharmony_ci for (cnt = 0; cnt < ARRAY_SIZE(fw->risc_host_reg); 79562306a36Sopenharmony_ci cnt++, dmp_reg++) 79662306a36Sopenharmony_ci fw->risc_host_reg[cnt] = htons(rd_reg_word(dmp_reg)); 79762306a36Sopenharmony_ci 79862306a36Sopenharmony_ci dmp_reg = ®->u.isp2300.mailbox0; 79962306a36Sopenharmony_ci for (cnt = 0; cnt < ARRAY_SIZE(fw->mailbox_reg); 80062306a36Sopenharmony_ci cnt++, dmp_reg++) 80162306a36Sopenharmony_ci fw->mailbox_reg[cnt] = htons(rd_reg_word(dmp_reg)); 80262306a36Sopenharmony_ci 80362306a36Sopenharmony_ci wrt_reg_word(®->ctrl_status, 0x40); 80462306a36Sopenharmony_ci qla2xxx_read_window(reg, 32, fw->resp_dma_reg); 80562306a36Sopenharmony_ci 80662306a36Sopenharmony_ci wrt_reg_word(®->ctrl_status, 0x50); 80762306a36Sopenharmony_ci qla2xxx_read_window(reg, 48, fw->dma_reg); 80862306a36Sopenharmony_ci 80962306a36Sopenharmony_ci wrt_reg_word(®->ctrl_status, 0x00); 81062306a36Sopenharmony_ci dmp_reg = ®->risc_hw; 81162306a36Sopenharmony_ci for (cnt = 0; cnt < ARRAY_SIZE(fw->risc_hdw_reg); 81262306a36Sopenharmony_ci cnt++, dmp_reg++) 81362306a36Sopenharmony_ci fw->risc_hdw_reg[cnt] = htons(rd_reg_word(dmp_reg)); 81462306a36Sopenharmony_ci 81562306a36Sopenharmony_ci wrt_reg_word(®->pcr, 0x2000); 81662306a36Sopenharmony_ci qla2xxx_read_window(reg, 16, fw->risc_gp0_reg); 81762306a36Sopenharmony_ci 81862306a36Sopenharmony_ci wrt_reg_word(®->pcr, 0x2200); 81962306a36Sopenharmony_ci qla2xxx_read_window(reg, 16, fw->risc_gp1_reg); 82062306a36Sopenharmony_ci 82162306a36Sopenharmony_ci wrt_reg_word(®->pcr, 0x2400); 82262306a36Sopenharmony_ci qla2xxx_read_window(reg, 16, fw->risc_gp2_reg); 82362306a36Sopenharmony_ci 82462306a36Sopenharmony_ci wrt_reg_word(®->pcr, 0x2600); 82562306a36Sopenharmony_ci qla2xxx_read_window(reg, 16, fw->risc_gp3_reg); 82662306a36Sopenharmony_ci 82762306a36Sopenharmony_ci wrt_reg_word(®->pcr, 0x2800); 82862306a36Sopenharmony_ci qla2xxx_read_window(reg, 16, fw->risc_gp4_reg); 82962306a36Sopenharmony_ci 83062306a36Sopenharmony_ci wrt_reg_word(®->pcr, 0x2A00); 83162306a36Sopenharmony_ci qla2xxx_read_window(reg, 16, fw->risc_gp5_reg); 83262306a36Sopenharmony_ci 83362306a36Sopenharmony_ci wrt_reg_word(®->pcr, 0x2C00); 83462306a36Sopenharmony_ci qla2xxx_read_window(reg, 16, fw->risc_gp6_reg); 83562306a36Sopenharmony_ci 83662306a36Sopenharmony_ci wrt_reg_word(®->pcr, 0x2E00); 83762306a36Sopenharmony_ci qla2xxx_read_window(reg, 16, fw->risc_gp7_reg); 83862306a36Sopenharmony_ci 83962306a36Sopenharmony_ci wrt_reg_word(®->ctrl_status, 0x10); 84062306a36Sopenharmony_ci qla2xxx_read_window(reg, 64, fw->frame_buf_hdw_reg); 84162306a36Sopenharmony_ci 84262306a36Sopenharmony_ci wrt_reg_word(®->ctrl_status, 0x20); 84362306a36Sopenharmony_ci qla2xxx_read_window(reg, 64, fw->fpm_b0_reg); 84462306a36Sopenharmony_ci 84562306a36Sopenharmony_ci wrt_reg_word(®->ctrl_status, 0x30); 84662306a36Sopenharmony_ci qla2xxx_read_window(reg, 64, fw->fpm_b1_reg); 84762306a36Sopenharmony_ci 84862306a36Sopenharmony_ci /* Reset RISC. */ 84962306a36Sopenharmony_ci wrt_reg_word(®->ctrl_status, CSR_ISP_SOFT_RESET); 85062306a36Sopenharmony_ci for (cnt = 0; cnt < 30000; cnt++) { 85162306a36Sopenharmony_ci if ((rd_reg_word(®->ctrl_status) & 85262306a36Sopenharmony_ci CSR_ISP_SOFT_RESET) == 0) 85362306a36Sopenharmony_ci break; 85462306a36Sopenharmony_ci 85562306a36Sopenharmony_ci udelay(10); 85662306a36Sopenharmony_ci } 85762306a36Sopenharmony_ci } 85862306a36Sopenharmony_ci 85962306a36Sopenharmony_ci if (!IS_QLA2300(ha)) { 86062306a36Sopenharmony_ci for (cnt = 30000; RD_MAILBOX_REG(ha, reg, 0) != 0 && 86162306a36Sopenharmony_ci rval == QLA_SUCCESS; cnt--) { 86262306a36Sopenharmony_ci if (cnt) 86362306a36Sopenharmony_ci udelay(100); 86462306a36Sopenharmony_ci else 86562306a36Sopenharmony_ci rval = QLA_FUNCTION_TIMEOUT; 86662306a36Sopenharmony_ci } 86762306a36Sopenharmony_ci } 86862306a36Sopenharmony_ci 86962306a36Sopenharmony_ci /* Get RISC SRAM. */ 87062306a36Sopenharmony_ci if (rval == QLA_SUCCESS) 87162306a36Sopenharmony_ci rval = qla2xxx_dump_ram(ha, 0x800, fw->risc_ram, 87262306a36Sopenharmony_ci ARRAY_SIZE(fw->risc_ram), &nxt); 87362306a36Sopenharmony_ci 87462306a36Sopenharmony_ci /* Get stack SRAM. */ 87562306a36Sopenharmony_ci if (rval == QLA_SUCCESS) 87662306a36Sopenharmony_ci rval = qla2xxx_dump_ram(ha, 0x10000, fw->stack_ram, 87762306a36Sopenharmony_ci ARRAY_SIZE(fw->stack_ram), &nxt); 87862306a36Sopenharmony_ci 87962306a36Sopenharmony_ci /* Get data SRAM. */ 88062306a36Sopenharmony_ci if (rval == QLA_SUCCESS) 88162306a36Sopenharmony_ci rval = qla2xxx_dump_ram(ha, 0x11000, fw->data_ram, 88262306a36Sopenharmony_ci ha->fw_memory_size - 0x11000 + 1, &nxt); 88362306a36Sopenharmony_ci 88462306a36Sopenharmony_ci if (rval == QLA_SUCCESS) 88562306a36Sopenharmony_ci qla2xxx_copy_queues(ha, nxt); 88662306a36Sopenharmony_ci 88762306a36Sopenharmony_ci qla2xxx_dump_post_process(base_vha, rval); 88862306a36Sopenharmony_ci} 88962306a36Sopenharmony_ci 89062306a36Sopenharmony_ci/** 89162306a36Sopenharmony_ci * qla2100_fw_dump() - Dumps binary data from the 2100/2200 firmware. 89262306a36Sopenharmony_ci * @vha: HA context 89362306a36Sopenharmony_ci */ 89462306a36Sopenharmony_civoid 89562306a36Sopenharmony_ciqla2100_fw_dump(scsi_qla_host_t *vha) 89662306a36Sopenharmony_ci{ 89762306a36Sopenharmony_ci int rval; 89862306a36Sopenharmony_ci uint32_t cnt, timer; 89962306a36Sopenharmony_ci uint16_t risc_address = 0; 90062306a36Sopenharmony_ci uint16_t mb0 = 0, mb2 = 0; 90162306a36Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 90262306a36Sopenharmony_ci struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; 90362306a36Sopenharmony_ci __le16 __iomem *dmp_reg; 90462306a36Sopenharmony_ci struct qla2100_fw_dump *fw; 90562306a36Sopenharmony_ci struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); 90662306a36Sopenharmony_ci 90762306a36Sopenharmony_ci lockdep_assert_held(&ha->hardware_lock); 90862306a36Sopenharmony_ci 90962306a36Sopenharmony_ci if (!ha->fw_dump) { 91062306a36Sopenharmony_ci ql_log(ql_log_warn, vha, 0xd004, 91162306a36Sopenharmony_ci "No buffer available for dump.\n"); 91262306a36Sopenharmony_ci return; 91362306a36Sopenharmony_ci } 91462306a36Sopenharmony_ci 91562306a36Sopenharmony_ci if (ha->fw_dumped) { 91662306a36Sopenharmony_ci ql_log(ql_log_warn, vha, 0xd005, 91762306a36Sopenharmony_ci "Firmware has been previously dumped (%p) " 91862306a36Sopenharmony_ci "-- ignoring request.\n", 91962306a36Sopenharmony_ci ha->fw_dump); 92062306a36Sopenharmony_ci return; 92162306a36Sopenharmony_ci } 92262306a36Sopenharmony_ci fw = &ha->fw_dump->isp.isp21; 92362306a36Sopenharmony_ci qla2xxx_prep_dump(ha, ha->fw_dump); 92462306a36Sopenharmony_ci 92562306a36Sopenharmony_ci rval = QLA_SUCCESS; 92662306a36Sopenharmony_ci fw->hccr = htons(rd_reg_word(®->hccr)); 92762306a36Sopenharmony_ci 92862306a36Sopenharmony_ci /* Pause RISC. */ 92962306a36Sopenharmony_ci wrt_reg_word(®->hccr, HCCR_PAUSE_RISC); 93062306a36Sopenharmony_ci for (cnt = 30000; (rd_reg_word(®->hccr) & HCCR_RISC_PAUSE) == 0 && 93162306a36Sopenharmony_ci rval == QLA_SUCCESS; cnt--) { 93262306a36Sopenharmony_ci if (cnt) 93362306a36Sopenharmony_ci udelay(100); 93462306a36Sopenharmony_ci else 93562306a36Sopenharmony_ci rval = QLA_FUNCTION_TIMEOUT; 93662306a36Sopenharmony_ci } 93762306a36Sopenharmony_ci if (rval == QLA_SUCCESS) { 93862306a36Sopenharmony_ci dmp_reg = ®->flash_address; 93962306a36Sopenharmony_ci for (cnt = 0; cnt < ARRAY_SIZE(fw->pbiu_reg); cnt++, dmp_reg++) 94062306a36Sopenharmony_ci fw->pbiu_reg[cnt] = htons(rd_reg_word(dmp_reg)); 94162306a36Sopenharmony_ci 94262306a36Sopenharmony_ci dmp_reg = ®->u.isp2100.mailbox0; 94362306a36Sopenharmony_ci for (cnt = 0; cnt < ha->mbx_count; cnt++, dmp_reg++) { 94462306a36Sopenharmony_ci if (cnt == 8) 94562306a36Sopenharmony_ci dmp_reg = ®->u_end.isp2200.mailbox8; 94662306a36Sopenharmony_ci 94762306a36Sopenharmony_ci fw->mailbox_reg[cnt] = htons(rd_reg_word(dmp_reg)); 94862306a36Sopenharmony_ci } 94962306a36Sopenharmony_ci 95062306a36Sopenharmony_ci dmp_reg = ®->u.isp2100.unused_2[0]; 95162306a36Sopenharmony_ci for (cnt = 0; cnt < ARRAY_SIZE(fw->dma_reg); cnt++, dmp_reg++) 95262306a36Sopenharmony_ci fw->dma_reg[cnt] = htons(rd_reg_word(dmp_reg)); 95362306a36Sopenharmony_ci 95462306a36Sopenharmony_ci wrt_reg_word(®->ctrl_status, 0x00); 95562306a36Sopenharmony_ci dmp_reg = ®->risc_hw; 95662306a36Sopenharmony_ci for (cnt = 0; cnt < ARRAY_SIZE(fw->risc_hdw_reg); cnt++, dmp_reg++) 95762306a36Sopenharmony_ci fw->risc_hdw_reg[cnt] = htons(rd_reg_word(dmp_reg)); 95862306a36Sopenharmony_ci 95962306a36Sopenharmony_ci wrt_reg_word(®->pcr, 0x2000); 96062306a36Sopenharmony_ci qla2xxx_read_window(reg, 16, fw->risc_gp0_reg); 96162306a36Sopenharmony_ci 96262306a36Sopenharmony_ci wrt_reg_word(®->pcr, 0x2100); 96362306a36Sopenharmony_ci qla2xxx_read_window(reg, 16, fw->risc_gp1_reg); 96462306a36Sopenharmony_ci 96562306a36Sopenharmony_ci wrt_reg_word(®->pcr, 0x2200); 96662306a36Sopenharmony_ci qla2xxx_read_window(reg, 16, fw->risc_gp2_reg); 96762306a36Sopenharmony_ci 96862306a36Sopenharmony_ci wrt_reg_word(®->pcr, 0x2300); 96962306a36Sopenharmony_ci qla2xxx_read_window(reg, 16, fw->risc_gp3_reg); 97062306a36Sopenharmony_ci 97162306a36Sopenharmony_ci wrt_reg_word(®->pcr, 0x2400); 97262306a36Sopenharmony_ci qla2xxx_read_window(reg, 16, fw->risc_gp4_reg); 97362306a36Sopenharmony_ci 97462306a36Sopenharmony_ci wrt_reg_word(®->pcr, 0x2500); 97562306a36Sopenharmony_ci qla2xxx_read_window(reg, 16, fw->risc_gp5_reg); 97662306a36Sopenharmony_ci 97762306a36Sopenharmony_ci wrt_reg_word(®->pcr, 0x2600); 97862306a36Sopenharmony_ci qla2xxx_read_window(reg, 16, fw->risc_gp6_reg); 97962306a36Sopenharmony_ci 98062306a36Sopenharmony_ci wrt_reg_word(®->pcr, 0x2700); 98162306a36Sopenharmony_ci qla2xxx_read_window(reg, 16, fw->risc_gp7_reg); 98262306a36Sopenharmony_ci 98362306a36Sopenharmony_ci wrt_reg_word(®->ctrl_status, 0x10); 98462306a36Sopenharmony_ci qla2xxx_read_window(reg, 16, fw->frame_buf_hdw_reg); 98562306a36Sopenharmony_ci 98662306a36Sopenharmony_ci wrt_reg_word(®->ctrl_status, 0x20); 98762306a36Sopenharmony_ci qla2xxx_read_window(reg, 64, fw->fpm_b0_reg); 98862306a36Sopenharmony_ci 98962306a36Sopenharmony_ci wrt_reg_word(®->ctrl_status, 0x30); 99062306a36Sopenharmony_ci qla2xxx_read_window(reg, 64, fw->fpm_b1_reg); 99162306a36Sopenharmony_ci 99262306a36Sopenharmony_ci /* Reset the ISP. */ 99362306a36Sopenharmony_ci wrt_reg_word(®->ctrl_status, CSR_ISP_SOFT_RESET); 99462306a36Sopenharmony_ci } 99562306a36Sopenharmony_ci 99662306a36Sopenharmony_ci for (cnt = 30000; RD_MAILBOX_REG(ha, reg, 0) != 0 && 99762306a36Sopenharmony_ci rval == QLA_SUCCESS; cnt--) { 99862306a36Sopenharmony_ci if (cnt) 99962306a36Sopenharmony_ci udelay(100); 100062306a36Sopenharmony_ci else 100162306a36Sopenharmony_ci rval = QLA_FUNCTION_TIMEOUT; 100262306a36Sopenharmony_ci } 100362306a36Sopenharmony_ci 100462306a36Sopenharmony_ci /* Pause RISC. */ 100562306a36Sopenharmony_ci if (rval == QLA_SUCCESS && (IS_QLA2200(ha) || (IS_QLA2100(ha) && 100662306a36Sopenharmony_ci (rd_reg_word(®->mctr) & (BIT_1 | BIT_0)) != 0))) { 100762306a36Sopenharmony_ci 100862306a36Sopenharmony_ci wrt_reg_word(®->hccr, HCCR_PAUSE_RISC); 100962306a36Sopenharmony_ci for (cnt = 30000; 101062306a36Sopenharmony_ci (rd_reg_word(®->hccr) & HCCR_RISC_PAUSE) == 0 && 101162306a36Sopenharmony_ci rval == QLA_SUCCESS; cnt--) { 101262306a36Sopenharmony_ci if (cnt) 101362306a36Sopenharmony_ci udelay(100); 101462306a36Sopenharmony_ci else 101562306a36Sopenharmony_ci rval = QLA_FUNCTION_TIMEOUT; 101662306a36Sopenharmony_ci } 101762306a36Sopenharmony_ci if (rval == QLA_SUCCESS) { 101862306a36Sopenharmony_ci /* Set memory configuration and timing. */ 101962306a36Sopenharmony_ci if (IS_QLA2100(ha)) 102062306a36Sopenharmony_ci wrt_reg_word(®->mctr, 0xf1); 102162306a36Sopenharmony_ci else 102262306a36Sopenharmony_ci wrt_reg_word(®->mctr, 0xf2); 102362306a36Sopenharmony_ci rd_reg_word(®->mctr); /* PCI Posting. */ 102462306a36Sopenharmony_ci 102562306a36Sopenharmony_ci /* Release RISC. */ 102662306a36Sopenharmony_ci wrt_reg_word(®->hccr, HCCR_RELEASE_RISC); 102762306a36Sopenharmony_ci } 102862306a36Sopenharmony_ci } 102962306a36Sopenharmony_ci 103062306a36Sopenharmony_ci if (rval == QLA_SUCCESS) { 103162306a36Sopenharmony_ci /* Get RISC SRAM. */ 103262306a36Sopenharmony_ci risc_address = 0x1000; 103362306a36Sopenharmony_ci WRT_MAILBOX_REG(ha, reg, 0, MBC_READ_RAM_WORD); 103462306a36Sopenharmony_ci clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); 103562306a36Sopenharmony_ci } 103662306a36Sopenharmony_ci for (cnt = 0; cnt < ARRAY_SIZE(fw->risc_ram) && rval == QLA_SUCCESS; 103762306a36Sopenharmony_ci cnt++, risc_address++) { 103862306a36Sopenharmony_ci WRT_MAILBOX_REG(ha, reg, 1, risc_address); 103962306a36Sopenharmony_ci wrt_reg_word(®->hccr, HCCR_SET_HOST_INT); 104062306a36Sopenharmony_ci 104162306a36Sopenharmony_ci for (timer = 6000000; timer != 0; timer--) { 104262306a36Sopenharmony_ci /* Check for pending interrupts. */ 104362306a36Sopenharmony_ci if (rd_reg_word(®->istatus) & ISR_RISC_INT) { 104462306a36Sopenharmony_ci if (rd_reg_word(®->semaphore) & BIT_0) { 104562306a36Sopenharmony_ci set_bit(MBX_INTERRUPT, 104662306a36Sopenharmony_ci &ha->mbx_cmd_flags); 104762306a36Sopenharmony_ci 104862306a36Sopenharmony_ci mb0 = RD_MAILBOX_REG(ha, reg, 0); 104962306a36Sopenharmony_ci mb2 = RD_MAILBOX_REG(ha, reg, 2); 105062306a36Sopenharmony_ci 105162306a36Sopenharmony_ci wrt_reg_word(®->semaphore, 0); 105262306a36Sopenharmony_ci wrt_reg_word(®->hccr, 105362306a36Sopenharmony_ci HCCR_CLR_RISC_INT); 105462306a36Sopenharmony_ci rd_reg_word(®->hccr); 105562306a36Sopenharmony_ci break; 105662306a36Sopenharmony_ci } 105762306a36Sopenharmony_ci wrt_reg_word(®->hccr, HCCR_CLR_RISC_INT); 105862306a36Sopenharmony_ci rd_reg_word(®->hccr); 105962306a36Sopenharmony_ci } 106062306a36Sopenharmony_ci udelay(5); 106162306a36Sopenharmony_ci } 106262306a36Sopenharmony_ci 106362306a36Sopenharmony_ci if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { 106462306a36Sopenharmony_ci rval = mb0 & MBS_MASK; 106562306a36Sopenharmony_ci fw->risc_ram[cnt] = htons(mb2); 106662306a36Sopenharmony_ci } else { 106762306a36Sopenharmony_ci rval = QLA_FUNCTION_FAILED; 106862306a36Sopenharmony_ci } 106962306a36Sopenharmony_ci } 107062306a36Sopenharmony_ci 107162306a36Sopenharmony_ci if (rval == QLA_SUCCESS) 107262306a36Sopenharmony_ci qla2xxx_copy_queues(ha, &fw->queue_dump[0]); 107362306a36Sopenharmony_ci 107462306a36Sopenharmony_ci qla2xxx_dump_post_process(base_vha, rval); 107562306a36Sopenharmony_ci} 107662306a36Sopenharmony_ci 107762306a36Sopenharmony_civoid 107862306a36Sopenharmony_ciqla24xx_fw_dump(scsi_qla_host_t *vha) 107962306a36Sopenharmony_ci{ 108062306a36Sopenharmony_ci int rval; 108162306a36Sopenharmony_ci uint32_t cnt; 108262306a36Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 108362306a36Sopenharmony_ci struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; 108462306a36Sopenharmony_ci __le32 __iomem *dmp_reg; 108562306a36Sopenharmony_ci __be32 *iter_reg; 108662306a36Sopenharmony_ci __le16 __iomem *mbx_reg; 108762306a36Sopenharmony_ci struct qla24xx_fw_dump *fw; 108862306a36Sopenharmony_ci void *nxt; 108962306a36Sopenharmony_ci void *nxt_chain; 109062306a36Sopenharmony_ci __be32 *last_chain = NULL; 109162306a36Sopenharmony_ci struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); 109262306a36Sopenharmony_ci 109362306a36Sopenharmony_ci lockdep_assert_held(&ha->hardware_lock); 109462306a36Sopenharmony_ci 109562306a36Sopenharmony_ci if (IS_P3P_TYPE(ha)) 109662306a36Sopenharmony_ci return; 109762306a36Sopenharmony_ci 109862306a36Sopenharmony_ci ha->fw_dump_cap_flags = 0; 109962306a36Sopenharmony_ci 110062306a36Sopenharmony_ci if (!ha->fw_dump) { 110162306a36Sopenharmony_ci ql_log(ql_log_warn, vha, 0xd006, 110262306a36Sopenharmony_ci "No buffer available for dump.\n"); 110362306a36Sopenharmony_ci return; 110462306a36Sopenharmony_ci } 110562306a36Sopenharmony_ci 110662306a36Sopenharmony_ci if (ha->fw_dumped) { 110762306a36Sopenharmony_ci ql_log(ql_log_warn, vha, 0xd007, 110862306a36Sopenharmony_ci "Firmware has been previously dumped (%p) " 110962306a36Sopenharmony_ci "-- ignoring request.\n", 111062306a36Sopenharmony_ci ha->fw_dump); 111162306a36Sopenharmony_ci return; 111262306a36Sopenharmony_ci } 111362306a36Sopenharmony_ci QLA_FW_STOPPED(ha); 111462306a36Sopenharmony_ci fw = &ha->fw_dump->isp.isp24; 111562306a36Sopenharmony_ci qla2xxx_prep_dump(ha, ha->fw_dump); 111662306a36Sopenharmony_ci 111762306a36Sopenharmony_ci fw->host_status = htonl(rd_reg_dword(®->host_status)); 111862306a36Sopenharmony_ci 111962306a36Sopenharmony_ci /* 112062306a36Sopenharmony_ci * Pause RISC. No need to track timeout, as resetting the chip 112162306a36Sopenharmony_ci * is the right approach incase of pause timeout 112262306a36Sopenharmony_ci */ 112362306a36Sopenharmony_ci qla24xx_pause_risc(reg, ha); 112462306a36Sopenharmony_ci 112562306a36Sopenharmony_ci /* Host interface registers. */ 112662306a36Sopenharmony_ci dmp_reg = ®->flash_addr; 112762306a36Sopenharmony_ci for (cnt = 0; cnt < ARRAY_SIZE(fw->host_reg); cnt++, dmp_reg++) 112862306a36Sopenharmony_ci fw->host_reg[cnt] = htonl(rd_reg_dword(dmp_reg)); 112962306a36Sopenharmony_ci 113062306a36Sopenharmony_ci /* Disable interrupts. */ 113162306a36Sopenharmony_ci wrt_reg_dword(®->ictrl, 0); 113262306a36Sopenharmony_ci rd_reg_dword(®->ictrl); 113362306a36Sopenharmony_ci 113462306a36Sopenharmony_ci /* Shadow registers. */ 113562306a36Sopenharmony_ci wrt_reg_dword(®->iobase_addr, 0x0F70); 113662306a36Sopenharmony_ci rd_reg_dword(®->iobase_addr); 113762306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0000000); 113862306a36Sopenharmony_ci fw->shadow_reg[0] = htonl(rd_reg_dword(®->iobase_sdata)); 113962306a36Sopenharmony_ci 114062306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0100000); 114162306a36Sopenharmony_ci fw->shadow_reg[1] = htonl(rd_reg_dword(®->iobase_sdata)); 114262306a36Sopenharmony_ci 114362306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0200000); 114462306a36Sopenharmony_ci fw->shadow_reg[2] = htonl(rd_reg_dword(®->iobase_sdata)); 114562306a36Sopenharmony_ci 114662306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0300000); 114762306a36Sopenharmony_ci fw->shadow_reg[3] = htonl(rd_reg_dword(®->iobase_sdata)); 114862306a36Sopenharmony_ci 114962306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0400000); 115062306a36Sopenharmony_ci fw->shadow_reg[4] = htonl(rd_reg_dword(®->iobase_sdata)); 115162306a36Sopenharmony_ci 115262306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0500000); 115362306a36Sopenharmony_ci fw->shadow_reg[5] = htonl(rd_reg_dword(®->iobase_sdata)); 115462306a36Sopenharmony_ci 115562306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0600000); 115662306a36Sopenharmony_ci fw->shadow_reg[6] = htonl(rd_reg_dword(®->iobase_sdata)); 115762306a36Sopenharmony_ci 115862306a36Sopenharmony_ci /* Mailbox registers. */ 115962306a36Sopenharmony_ci mbx_reg = ®->mailbox0; 116062306a36Sopenharmony_ci for (cnt = 0; cnt < ARRAY_SIZE(fw->mailbox_reg); cnt++, mbx_reg++) 116162306a36Sopenharmony_ci fw->mailbox_reg[cnt] = htons(rd_reg_word(mbx_reg)); 116262306a36Sopenharmony_ci 116362306a36Sopenharmony_ci /* Transfer sequence registers. */ 116462306a36Sopenharmony_ci iter_reg = fw->xseq_gp_reg; 116562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg); 116662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg); 116762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg); 116862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg); 116962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg); 117062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg); 117162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg); 117262306a36Sopenharmony_ci qla24xx_read_window(reg, 0xBF70, 16, iter_reg); 117362306a36Sopenharmony_ci 117462306a36Sopenharmony_ci qla24xx_read_window(reg, 0xBFE0, 16, fw->xseq_0_reg); 117562306a36Sopenharmony_ci qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg); 117662306a36Sopenharmony_ci 117762306a36Sopenharmony_ci /* Receive sequence registers. */ 117862306a36Sopenharmony_ci iter_reg = fw->rseq_gp_reg; 117962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg); 118062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg); 118162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg); 118262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg); 118362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg); 118462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg); 118562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg); 118662306a36Sopenharmony_ci qla24xx_read_window(reg, 0xFF70, 16, iter_reg); 118762306a36Sopenharmony_ci 118862306a36Sopenharmony_ci qla24xx_read_window(reg, 0xFFD0, 16, fw->rseq_0_reg); 118962306a36Sopenharmony_ci qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg); 119062306a36Sopenharmony_ci qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg); 119162306a36Sopenharmony_ci 119262306a36Sopenharmony_ci /* Command DMA registers. */ 119362306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7100, 16, fw->cmd_dma_reg); 119462306a36Sopenharmony_ci 119562306a36Sopenharmony_ci /* Queues. */ 119662306a36Sopenharmony_ci iter_reg = fw->req0_dma_reg; 119762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg); 119862306a36Sopenharmony_ci dmp_reg = ®->iobase_q; 119962306a36Sopenharmony_ci for (cnt = 0; cnt < 7; cnt++, dmp_reg++) 120062306a36Sopenharmony_ci *iter_reg++ = htonl(rd_reg_dword(dmp_reg)); 120162306a36Sopenharmony_ci 120262306a36Sopenharmony_ci iter_reg = fw->resp0_dma_reg; 120362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg); 120462306a36Sopenharmony_ci dmp_reg = ®->iobase_q; 120562306a36Sopenharmony_ci for (cnt = 0; cnt < 7; cnt++, dmp_reg++) 120662306a36Sopenharmony_ci *iter_reg++ = htonl(rd_reg_dword(dmp_reg)); 120762306a36Sopenharmony_ci 120862306a36Sopenharmony_ci iter_reg = fw->req1_dma_reg; 120962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg); 121062306a36Sopenharmony_ci dmp_reg = ®->iobase_q; 121162306a36Sopenharmony_ci for (cnt = 0; cnt < 7; cnt++, dmp_reg++) 121262306a36Sopenharmony_ci *iter_reg++ = htonl(rd_reg_dword(dmp_reg)); 121362306a36Sopenharmony_ci 121462306a36Sopenharmony_ci /* Transmit DMA registers. */ 121562306a36Sopenharmony_ci iter_reg = fw->xmt0_dma_reg; 121662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg); 121762306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7610, 16, iter_reg); 121862306a36Sopenharmony_ci 121962306a36Sopenharmony_ci iter_reg = fw->xmt1_dma_reg; 122062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg); 122162306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7630, 16, iter_reg); 122262306a36Sopenharmony_ci 122362306a36Sopenharmony_ci iter_reg = fw->xmt2_dma_reg; 122462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg); 122562306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7650, 16, iter_reg); 122662306a36Sopenharmony_ci 122762306a36Sopenharmony_ci iter_reg = fw->xmt3_dma_reg; 122862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg); 122962306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7670, 16, iter_reg); 123062306a36Sopenharmony_ci 123162306a36Sopenharmony_ci iter_reg = fw->xmt4_dma_reg; 123262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg); 123362306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7690, 16, iter_reg); 123462306a36Sopenharmony_ci 123562306a36Sopenharmony_ci qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg); 123662306a36Sopenharmony_ci 123762306a36Sopenharmony_ci /* Receive DMA registers. */ 123862306a36Sopenharmony_ci iter_reg = fw->rcvt0_data_dma_reg; 123962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg); 124062306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7710, 16, iter_reg); 124162306a36Sopenharmony_ci 124262306a36Sopenharmony_ci iter_reg = fw->rcvt1_data_dma_reg; 124362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg); 124462306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7730, 16, iter_reg); 124562306a36Sopenharmony_ci 124662306a36Sopenharmony_ci /* RISC registers. */ 124762306a36Sopenharmony_ci iter_reg = fw->risc_gp_reg; 124862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg); 124962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg); 125062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg); 125162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg); 125262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg); 125362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg); 125462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg); 125562306a36Sopenharmony_ci qla24xx_read_window(reg, 0x0F70, 16, iter_reg); 125662306a36Sopenharmony_ci 125762306a36Sopenharmony_ci /* Local memory controller registers. */ 125862306a36Sopenharmony_ci iter_reg = fw->lmc_reg; 125962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg); 126062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg); 126162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg); 126262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg); 126362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg); 126462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg); 126562306a36Sopenharmony_ci qla24xx_read_window(reg, 0x3060, 16, iter_reg); 126662306a36Sopenharmony_ci 126762306a36Sopenharmony_ci /* Fibre Protocol Module registers. */ 126862306a36Sopenharmony_ci iter_reg = fw->fpm_hdw_reg; 126962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg); 127062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg); 127162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg); 127262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg); 127362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg); 127462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg); 127562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg); 127662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg); 127762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg); 127862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg); 127962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg); 128062306a36Sopenharmony_ci qla24xx_read_window(reg, 0x40B0, 16, iter_reg); 128162306a36Sopenharmony_ci 128262306a36Sopenharmony_ci /* Frame Buffer registers. */ 128362306a36Sopenharmony_ci iter_reg = fw->fb_hdw_reg; 128462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg); 128562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg); 128662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg); 128762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg); 128862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg); 128962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg); 129062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg); 129162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg); 129262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg); 129362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg); 129462306a36Sopenharmony_ci qla24xx_read_window(reg, 0x61B0, 16, iter_reg); 129562306a36Sopenharmony_ci 129662306a36Sopenharmony_ci rval = qla24xx_soft_reset(ha); 129762306a36Sopenharmony_ci if (rval != QLA_SUCCESS) 129862306a36Sopenharmony_ci goto qla24xx_fw_dump_failed_0; 129962306a36Sopenharmony_ci 130062306a36Sopenharmony_ci rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram), 130162306a36Sopenharmony_ci &nxt); 130262306a36Sopenharmony_ci if (rval != QLA_SUCCESS) 130362306a36Sopenharmony_ci goto qla24xx_fw_dump_failed_0; 130462306a36Sopenharmony_ci 130562306a36Sopenharmony_ci nxt = qla2xxx_copy_queues(ha, nxt); 130662306a36Sopenharmony_ci 130762306a36Sopenharmony_ci qla24xx_copy_eft(ha, nxt); 130862306a36Sopenharmony_ci 130962306a36Sopenharmony_ci nxt_chain = (void *)ha->fw_dump + ha->chain_offset; 131062306a36Sopenharmony_ci nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain); 131162306a36Sopenharmony_ci if (last_chain) { 131262306a36Sopenharmony_ci ha->fw_dump->version |= htonl(DUMP_CHAIN_VARIANT); 131362306a36Sopenharmony_ci *last_chain |= htonl(DUMP_CHAIN_LAST); 131462306a36Sopenharmony_ci } 131562306a36Sopenharmony_ci 131662306a36Sopenharmony_ci /* Adjust valid length. */ 131762306a36Sopenharmony_ci ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump); 131862306a36Sopenharmony_ci 131962306a36Sopenharmony_ciqla24xx_fw_dump_failed_0: 132062306a36Sopenharmony_ci qla2xxx_dump_post_process(base_vha, rval); 132162306a36Sopenharmony_ci} 132262306a36Sopenharmony_ci 132362306a36Sopenharmony_civoid 132462306a36Sopenharmony_ciqla25xx_fw_dump(scsi_qla_host_t *vha) 132562306a36Sopenharmony_ci{ 132662306a36Sopenharmony_ci int rval; 132762306a36Sopenharmony_ci uint32_t cnt; 132862306a36Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 132962306a36Sopenharmony_ci struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; 133062306a36Sopenharmony_ci __le32 __iomem *dmp_reg; 133162306a36Sopenharmony_ci __be32 *iter_reg; 133262306a36Sopenharmony_ci __le16 __iomem *mbx_reg; 133362306a36Sopenharmony_ci struct qla25xx_fw_dump *fw; 133462306a36Sopenharmony_ci void *nxt, *nxt_chain; 133562306a36Sopenharmony_ci __be32 *last_chain = NULL; 133662306a36Sopenharmony_ci struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); 133762306a36Sopenharmony_ci 133862306a36Sopenharmony_ci lockdep_assert_held(&ha->hardware_lock); 133962306a36Sopenharmony_ci 134062306a36Sopenharmony_ci ha->fw_dump_cap_flags = 0; 134162306a36Sopenharmony_ci 134262306a36Sopenharmony_ci if (!ha->fw_dump) { 134362306a36Sopenharmony_ci ql_log(ql_log_warn, vha, 0xd008, 134462306a36Sopenharmony_ci "No buffer available for dump.\n"); 134562306a36Sopenharmony_ci return; 134662306a36Sopenharmony_ci } 134762306a36Sopenharmony_ci 134862306a36Sopenharmony_ci if (ha->fw_dumped) { 134962306a36Sopenharmony_ci ql_log(ql_log_warn, vha, 0xd009, 135062306a36Sopenharmony_ci "Firmware has been previously dumped (%p) " 135162306a36Sopenharmony_ci "-- ignoring request.\n", 135262306a36Sopenharmony_ci ha->fw_dump); 135362306a36Sopenharmony_ci return; 135462306a36Sopenharmony_ci } 135562306a36Sopenharmony_ci QLA_FW_STOPPED(ha); 135662306a36Sopenharmony_ci fw = &ha->fw_dump->isp.isp25; 135762306a36Sopenharmony_ci qla2xxx_prep_dump(ha, ha->fw_dump); 135862306a36Sopenharmony_ci ha->fw_dump->version = htonl(2); 135962306a36Sopenharmony_ci 136062306a36Sopenharmony_ci fw->host_status = htonl(rd_reg_dword(®->host_status)); 136162306a36Sopenharmony_ci 136262306a36Sopenharmony_ci /* 136362306a36Sopenharmony_ci * Pause RISC. No need to track timeout, as resetting the chip 136462306a36Sopenharmony_ci * is the right approach incase of pause timeout 136562306a36Sopenharmony_ci */ 136662306a36Sopenharmony_ci qla24xx_pause_risc(reg, ha); 136762306a36Sopenharmony_ci 136862306a36Sopenharmony_ci /* Host/Risc registers. */ 136962306a36Sopenharmony_ci iter_reg = fw->host_risc_reg; 137062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7000, 16, iter_reg); 137162306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7010, 16, iter_reg); 137262306a36Sopenharmony_ci 137362306a36Sopenharmony_ci /* PCIe registers. */ 137462306a36Sopenharmony_ci wrt_reg_dword(®->iobase_addr, 0x7C00); 137562306a36Sopenharmony_ci rd_reg_dword(®->iobase_addr); 137662306a36Sopenharmony_ci wrt_reg_dword(®->iobase_window, 0x01); 137762306a36Sopenharmony_ci dmp_reg = ®->iobase_c4; 137862306a36Sopenharmony_ci fw->pcie_regs[0] = htonl(rd_reg_dword(dmp_reg)); 137962306a36Sopenharmony_ci dmp_reg++; 138062306a36Sopenharmony_ci fw->pcie_regs[1] = htonl(rd_reg_dword(dmp_reg)); 138162306a36Sopenharmony_ci dmp_reg++; 138262306a36Sopenharmony_ci fw->pcie_regs[2] = htonl(rd_reg_dword(dmp_reg)); 138362306a36Sopenharmony_ci fw->pcie_regs[3] = htonl(rd_reg_dword(®->iobase_window)); 138462306a36Sopenharmony_ci 138562306a36Sopenharmony_ci wrt_reg_dword(®->iobase_window, 0x00); 138662306a36Sopenharmony_ci rd_reg_dword(®->iobase_window); 138762306a36Sopenharmony_ci 138862306a36Sopenharmony_ci /* Host interface registers. */ 138962306a36Sopenharmony_ci dmp_reg = ®->flash_addr; 139062306a36Sopenharmony_ci for (cnt = 0; cnt < ARRAY_SIZE(fw->host_reg); cnt++, dmp_reg++) 139162306a36Sopenharmony_ci fw->host_reg[cnt] = htonl(rd_reg_dword(dmp_reg)); 139262306a36Sopenharmony_ci 139362306a36Sopenharmony_ci /* Disable interrupts. */ 139462306a36Sopenharmony_ci wrt_reg_dword(®->ictrl, 0); 139562306a36Sopenharmony_ci rd_reg_dword(®->ictrl); 139662306a36Sopenharmony_ci 139762306a36Sopenharmony_ci /* Shadow registers. */ 139862306a36Sopenharmony_ci wrt_reg_dword(®->iobase_addr, 0x0F70); 139962306a36Sopenharmony_ci rd_reg_dword(®->iobase_addr); 140062306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0000000); 140162306a36Sopenharmony_ci fw->shadow_reg[0] = htonl(rd_reg_dword(®->iobase_sdata)); 140262306a36Sopenharmony_ci 140362306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0100000); 140462306a36Sopenharmony_ci fw->shadow_reg[1] = htonl(rd_reg_dword(®->iobase_sdata)); 140562306a36Sopenharmony_ci 140662306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0200000); 140762306a36Sopenharmony_ci fw->shadow_reg[2] = htonl(rd_reg_dword(®->iobase_sdata)); 140862306a36Sopenharmony_ci 140962306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0300000); 141062306a36Sopenharmony_ci fw->shadow_reg[3] = htonl(rd_reg_dword(®->iobase_sdata)); 141162306a36Sopenharmony_ci 141262306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0400000); 141362306a36Sopenharmony_ci fw->shadow_reg[4] = htonl(rd_reg_dword(®->iobase_sdata)); 141462306a36Sopenharmony_ci 141562306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0500000); 141662306a36Sopenharmony_ci fw->shadow_reg[5] = htonl(rd_reg_dword(®->iobase_sdata)); 141762306a36Sopenharmony_ci 141862306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0600000); 141962306a36Sopenharmony_ci fw->shadow_reg[6] = htonl(rd_reg_dword(®->iobase_sdata)); 142062306a36Sopenharmony_ci 142162306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0700000); 142262306a36Sopenharmony_ci fw->shadow_reg[7] = htonl(rd_reg_dword(®->iobase_sdata)); 142362306a36Sopenharmony_ci 142462306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0800000); 142562306a36Sopenharmony_ci fw->shadow_reg[8] = htonl(rd_reg_dword(®->iobase_sdata)); 142662306a36Sopenharmony_ci 142762306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0900000); 142862306a36Sopenharmony_ci fw->shadow_reg[9] = htonl(rd_reg_dword(®->iobase_sdata)); 142962306a36Sopenharmony_ci 143062306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0A00000); 143162306a36Sopenharmony_ci fw->shadow_reg[10] = htonl(rd_reg_dword(®->iobase_sdata)); 143262306a36Sopenharmony_ci 143362306a36Sopenharmony_ci /* RISC I/O register. */ 143462306a36Sopenharmony_ci wrt_reg_dword(®->iobase_addr, 0x0010); 143562306a36Sopenharmony_ci fw->risc_io_reg = htonl(rd_reg_dword(®->iobase_window)); 143662306a36Sopenharmony_ci 143762306a36Sopenharmony_ci /* Mailbox registers. */ 143862306a36Sopenharmony_ci mbx_reg = ®->mailbox0; 143962306a36Sopenharmony_ci for (cnt = 0; cnt < ARRAY_SIZE(fw->mailbox_reg); cnt++, mbx_reg++) 144062306a36Sopenharmony_ci fw->mailbox_reg[cnt] = htons(rd_reg_word(mbx_reg)); 144162306a36Sopenharmony_ci 144262306a36Sopenharmony_ci /* Transfer sequence registers. */ 144362306a36Sopenharmony_ci iter_reg = fw->xseq_gp_reg; 144462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg); 144562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg); 144662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg); 144762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg); 144862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg); 144962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg); 145062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg); 145162306a36Sopenharmony_ci qla24xx_read_window(reg, 0xBF70, 16, iter_reg); 145262306a36Sopenharmony_ci 145362306a36Sopenharmony_ci iter_reg = fw->xseq_0_reg; 145462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBFC0, 16, iter_reg); 145562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBFD0, 16, iter_reg); 145662306a36Sopenharmony_ci qla24xx_read_window(reg, 0xBFE0, 16, iter_reg); 145762306a36Sopenharmony_ci 145862306a36Sopenharmony_ci qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg); 145962306a36Sopenharmony_ci 146062306a36Sopenharmony_ci /* Receive sequence registers. */ 146162306a36Sopenharmony_ci iter_reg = fw->rseq_gp_reg; 146262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg); 146362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg); 146462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg); 146562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg); 146662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg); 146762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg); 146862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg); 146962306a36Sopenharmony_ci qla24xx_read_window(reg, 0xFF70, 16, iter_reg); 147062306a36Sopenharmony_ci 147162306a36Sopenharmony_ci iter_reg = fw->rseq_0_reg; 147262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFFC0, 16, iter_reg); 147362306a36Sopenharmony_ci qla24xx_read_window(reg, 0xFFD0, 16, iter_reg); 147462306a36Sopenharmony_ci 147562306a36Sopenharmony_ci qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg); 147662306a36Sopenharmony_ci qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg); 147762306a36Sopenharmony_ci 147862306a36Sopenharmony_ci /* Auxiliary sequence registers. */ 147962306a36Sopenharmony_ci iter_reg = fw->aseq_gp_reg; 148062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB000, 16, iter_reg); 148162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB010, 16, iter_reg); 148262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB020, 16, iter_reg); 148362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB030, 16, iter_reg); 148462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB040, 16, iter_reg); 148562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB050, 16, iter_reg); 148662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB060, 16, iter_reg); 148762306a36Sopenharmony_ci qla24xx_read_window(reg, 0xB070, 16, iter_reg); 148862306a36Sopenharmony_ci 148962306a36Sopenharmony_ci iter_reg = fw->aseq_0_reg; 149062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB0C0, 16, iter_reg); 149162306a36Sopenharmony_ci qla24xx_read_window(reg, 0xB0D0, 16, iter_reg); 149262306a36Sopenharmony_ci 149362306a36Sopenharmony_ci qla24xx_read_window(reg, 0xB0E0, 16, fw->aseq_1_reg); 149462306a36Sopenharmony_ci qla24xx_read_window(reg, 0xB0F0, 16, fw->aseq_2_reg); 149562306a36Sopenharmony_ci 149662306a36Sopenharmony_ci /* Command DMA registers. */ 149762306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7100, 16, fw->cmd_dma_reg); 149862306a36Sopenharmony_ci 149962306a36Sopenharmony_ci /* Queues. */ 150062306a36Sopenharmony_ci iter_reg = fw->req0_dma_reg; 150162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg); 150262306a36Sopenharmony_ci dmp_reg = ®->iobase_q; 150362306a36Sopenharmony_ci for (cnt = 0; cnt < 7; cnt++, dmp_reg++) 150462306a36Sopenharmony_ci *iter_reg++ = htonl(rd_reg_dword(dmp_reg)); 150562306a36Sopenharmony_ci 150662306a36Sopenharmony_ci iter_reg = fw->resp0_dma_reg; 150762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg); 150862306a36Sopenharmony_ci dmp_reg = ®->iobase_q; 150962306a36Sopenharmony_ci for (cnt = 0; cnt < 7; cnt++, dmp_reg++) 151062306a36Sopenharmony_ci *iter_reg++ = htonl(rd_reg_dword(dmp_reg)); 151162306a36Sopenharmony_ci 151262306a36Sopenharmony_ci iter_reg = fw->req1_dma_reg; 151362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg); 151462306a36Sopenharmony_ci dmp_reg = ®->iobase_q; 151562306a36Sopenharmony_ci for (cnt = 0; cnt < 7; cnt++, dmp_reg++) 151662306a36Sopenharmony_ci *iter_reg++ = htonl(rd_reg_dword(dmp_reg)); 151762306a36Sopenharmony_ci 151862306a36Sopenharmony_ci /* Transmit DMA registers. */ 151962306a36Sopenharmony_ci iter_reg = fw->xmt0_dma_reg; 152062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg); 152162306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7610, 16, iter_reg); 152262306a36Sopenharmony_ci 152362306a36Sopenharmony_ci iter_reg = fw->xmt1_dma_reg; 152462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg); 152562306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7630, 16, iter_reg); 152662306a36Sopenharmony_ci 152762306a36Sopenharmony_ci iter_reg = fw->xmt2_dma_reg; 152862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg); 152962306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7650, 16, iter_reg); 153062306a36Sopenharmony_ci 153162306a36Sopenharmony_ci iter_reg = fw->xmt3_dma_reg; 153262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg); 153362306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7670, 16, iter_reg); 153462306a36Sopenharmony_ci 153562306a36Sopenharmony_ci iter_reg = fw->xmt4_dma_reg; 153662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg); 153762306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7690, 16, iter_reg); 153862306a36Sopenharmony_ci 153962306a36Sopenharmony_ci qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg); 154062306a36Sopenharmony_ci 154162306a36Sopenharmony_ci /* Receive DMA registers. */ 154262306a36Sopenharmony_ci iter_reg = fw->rcvt0_data_dma_reg; 154362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg); 154462306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7710, 16, iter_reg); 154562306a36Sopenharmony_ci 154662306a36Sopenharmony_ci iter_reg = fw->rcvt1_data_dma_reg; 154762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg); 154862306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7730, 16, iter_reg); 154962306a36Sopenharmony_ci 155062306a36Sopenharmony_ci /* RISC registers. */ 155162306a36Sopenharmony_ci iter_reg = fw->risc_gp_reg; 155262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg); 155362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg); 155462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg); 155562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg); 155662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg); 155762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg); 155862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg); 155962306a36Sopenharmony_ci qla24xx_read_window(reg, 0x0F70, 16, iter_reg); 156062306a36Sopenharmony_ci 156162306a36Sopenharmony_ci /* Local memory controller registers. */ 156262306a36Sopenharmony_ci iter_reg = fw->lmc_reg; 156362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg); 156462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg); 156562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg); 156662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg); 156762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg); 156862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg); 156962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x3060, 16, iter_reg); 157062306a36Sopenharmony_ci qla24xx_read_window(reg, 0x3070, 16, iter_reg); 157162306a36Sopenharmony_ci 157262306a36Sopenharmony_ci /* Fibre Protocol Module registers. */ 157362306a36Sopenharmony_ci iter_reg = fw->fpm_hdw_reg; 157462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg); 157562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg); 157662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg); 157762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg); 157862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg); 157962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg); 158062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg); 158162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg); 158262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg); 158362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg); 158462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg); 158562306a36Sopenharmony_ci qla24xx_read_window(reg, 0x40B0, 16, iter_reg); 158662306a36Sopenharmony_ci 158762306a36Sopenharmony_ci /* Frame Buffer registers. */ 158862306a36Sopenharmony_ci iter_reg = fw->fb_hdw_reg; 158962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg); 159062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg); 159162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg); 159262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg); 159362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg); 159462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg); 159562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg); 159662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg); 159762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg); 159862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg); 159962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg); 160062306a36Sopenharmony_ci qla24xx_read_window(reg, 0x6F00, 16, iter_reg); 160162306a36Sopenharmony_ci 160262306a36Sopenharmony_ci /* Multi queue registers */ 160362306a36Sopenharmony_ci nxt_chain = qla25xx_copy_mq(ha, (void *)ha->fw_dump + ha->chain_offset, 160462306a36Sopenharmony_ci &last_chain); 160562306a36Sopenharmony_ci 160662306a36Sopenharmony_ci rval = qla24xx_soft_reset(ha); 160762306a36Sopenharmony_ci if (rval != QLA_SUCCESS) 160862306a36Sopenharmony_ci goto qla25xx_fw_dump_failed_0; 160962306a36Sopenharmony_ci 161062306a36Sopenharmony_ci rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram), 161162306a36Sopenharmony_ci &nxt); 161262306a36Sopenharmony_ci if (rval != QLA_SUCCESS) 161362306a36Sopenharmony_ci goto qla25xx_fw_dump_failed_0; 161462306a36Sopenharmony_ci 161562306a36Sopenharmony_ci nxt = qla2xxx_copy_queues(ha, nxt); 161662306a36Sopenharmony_ci 161762306a36Sopenharmony_ci qla24xx_copy_eft(ha, nxt); 161862306a36Sopenharmony_ci 161962306a36Sopenharmony_ci /* Chain entries -- started with MQ. */ 162062306a36Sopenharmony_ci nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain); 162162306a36Sopenharmony_ci nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain); 162262306a36Sopenharmony_ci nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain); 162362306a36Sopenharmony_ci nxt_chain = qla25xx_copy_exlogin(ha, nxt_chain, &last_chain); 162462306a36Sopenharmony_ci if (last_chain) { 162562306a36Sopenharmony_ci ha->fw_dump->version |= htonl(DUMP_CHAIN_VARIANT); 162662306a36Sopenharmony_ci *last_chain |= htonl(DUMP_CHAIN_LAST); 162762306a36Sopenharmony_ci } 162862306a36Sopenharmony_ci 162962306a36Sopenharmony_ci /* Adjust valid length. */ 163062306a36Sopenharmony_ci ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump); 163162306a36Sopenharmony_ci 163262306a36Sopenharmony_ciqla25xx_fw_dump_failed_0: 163362306a36Sopenharmony_ci qla2xxx_dump_post_process(base_vha, rval); 163462306a36Sopenharmony_ci} 163562306a36Sopenharmony_ci 163662306a36Sopenharmony_civoid 163762306a36Sopenharmony_ciqla81xx_fw_dump(scsi_qla_host_t *vha) 163862306a36Sopenharmony_ci{ 163962306a36Sopenharmony_ci int rval; 164062306a36Sopenharmony_ci uint32_t cnt; 164162306a36Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 164262306a36Sopenharmony_ci struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; 164362306a36Sopenharmony_ci __le32 __iomem *dmp_reg; 164462306a36Sopenharmony_ci __be32 *iter_reg; 164562306a36Sopenharmony_ci __le16 __iomem *mbx_reg; 164662306a36Sopenharmony_ci struct qla81xx_fw_dump *fw; 164762306a36Sopenharmony_ci void *nxt, *nxt_chain; 164862306a36Sopenharmony_ci __be32 *last_chain = NULL; 164962306a36Sopenharmony_ci struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); 165062306a36Sopenharmony_ci 165162306a36Sopenharmony_ci lockdep_assert_held(&ha->hardware_lock); 165262306a36Sopenharmony_ci 165362306a36Sopenharmony_ci ha->fw_dump_cap_flags = 0; 165462306a36Sopenharmony_ci 165562306a36Sopenharmony_ci if (!ha->fw_dump) { 165662306a36Sopenharmony_ci ql_log(ql_log_warn, vha, 0xd00a, 165762306a36Sopenharmony_ci "No buffer available for dump.\n"); 165862306a36Sopenharmony_ci return; 165962306a36Sopenharmony_ci } 166062306a36Sopenharmony_ci 166162306a36Sopenharmony_ci if (ha->fw_dumped) { 166262306a36Sopenharmony_ci ql_log(ql_log_warn, vha, 0xd00b, 166362306a36Sopenharmony_ci "Firmware has been previously dumped (%p) " 166462306a36Sopenharmony_ci "-- ignoring request.\n", 166562306a36Sopenharmony_ci ha->fw_dump); 166662306a36Sopenharmony_ci return; 166762306a36Sopenharmony_ci } 166862306a36Sopenharmony_ci fw = &ha->fw_dump->isp.isp81; 166962306a36Sopenharmony_ci qla2xxx_prep_dump(ha, ha->fw_dump); 167062306a36Sopenharmony_ci 167162306a36Sopenharmony_ci fw->host_status = htonl(rd_reg_dword(®->host_status)); 167262306a36Sopenharmony_ci 167362306a36Sopenharmony_ci /* 167462306a36Sopenharmony_ci * Pause RISC. No need to track timeout, as resetting the chip 167562306a36Sopenharmony_ci * is the right approach incase of pause timeout 167662306a36Sopenharmony_ci */ 167762306a36Sopenharmony_ci qla24xx_pause_risc(reg, ha); 167862306a36Sopenharmony_ci 167962306a36Sopenharmony_ci /* Host/Risc registers. */ 168062306a36Sopenharmony_ci iter_reg = fw->host_risc_reg; 168162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7000, 16, iter_reg); 168262306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7010, 16, iter_reg); 168362306a36Sopenharmony_ci 168462306a36Sopenharmony_ci /* PCIe registers. */ 168562306a36Sopenharmony_ci wrt_reg_dword(®->iobase_addr, 0x7C00); 168662306a36Sopenharmony_ci rd_reg_dword(®->iobase_addr); 168762306a36Sopenharmony_ci wrt_reg_dword(®->iobase_window, 0x01); 168862306a36Sopenharmony_ci dmp_reg = ®->iobase_c4; 168962306a36Sopenharmony_ci fw->pcie_regs[0] = htonl(rd_reg_dword(dmp_reg)); 169062306a36Sopenharmony_ci dmp_reg++; 169162306a36Sopenharmony_ci fw->pcie_regs[1] = htonl(rd_reg_dword(dmp_reg)); 169262306a36Sopenharmony_ci dmp_reg++; 169362306a36Sopenharmony_ci fw->pcie_regs[2] = htonl(rd_reg_dword(dmp_reg)); 169462306a36Sopenharmony_ci fw->pcie_regs[3] = htonl(rd_reg_dword(®->iobase_window)); 169562306a36Sopenharmony_ci 169662306a36Sopenharmony_ci wrt_reg_dword(®->iobase_window, 0x00); 169762306a36Sopenharmony_ci rd_reg_dword(®->iobase_window); 169862306a36Sopenharmony_ci 169962306a36Sopenharmony_ci /* Host interface registers. */ 170062306a36Sopenharmony_ci dmp_reg = ®->flash_addr; 170162306a36Sopenharmony_ci for (cnt = 0; cnt < ARRAY_SIZE(fw->host_reg); cnt++, dmp_reg++) 170262306a36Sopenharmony_ci fw->host_reg[cnt] = htonl(rd_reg_dword(dmp_reg)); 170362306a36Sopenharmony_ci 170462306a36Sopenharmony_ci /* Disable interrupts. */ 170562306a36Sopenharmony_ci wrt_reg_dword(®->ictrl, 0); 170662306a36Sopenharmony_ci rd_reg_dword(®->ictrl); 170762306a36Sopenharmony_ci 170862306a36Sopenharmony_ci /* Shadow registers. */ 170962306a36Sopenharmony_ci wrt_reg_dword(®->iobase_addr, 0x0F70); 171062306a36Sopenharmony_ci rd_reg_dword(®->iobase_addr); 171162306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0000000); 171262306a36Sopenharmony_ci fw->shadow_reg[0] = htonl(rd_reg_dword(®->iobase_sdata)); 171362306a36Sopenharmony_ci 171462306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0100000); 171562306a36Sopenharmony_ci fw->shadow_reg[1] = htonl(rd_reg_dword(®->iobase_sdata)); 171662306a36Sopenharmony_ci 171762306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0200000); 171862306a36Sopenharmony_ci fw->shadow_reg[2] = htonl(rd_reg_dword(®->iobase_sdata)); 171962306a36Sopenharmony_ci 172062306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0300000); 172162306a36Sopenharmony_ci fw->shadow_reg[3] = htonl(rd_reg_dword(®->iobase_sdata)); 172262306a36Sopenharmony_ci 172362306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0400000); 172462306a36Sopenharmony_ci fw->shadow_reg[4] = htonl(rd_reg_dword(®->iobase_sdata)); 172562306a36Sopenharmony_ci 172662306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0500000); 172762306a36Sopenharmony_ci fw->shadow_reg[5] = htonl(rd_reg_dword(®->iobase_sdata)); 172862306a36Sopenharmony_ci 172962306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0600000); 173062306a36Sopenharmony_ci fw->shadow_reg[6] = htonl(rd_reg_dword(®->iobase_sdata)); 173162306a36Sopenharmony_ci 173262306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0700000); 173362306a36Sopenharmony_ci fw->shadow_reg[7] = htonl(rd_reg_dword(®->iobase_sdata)); 173462306a36Sopenharmony_ci 173562306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0800000); 173662306a36Sopenharmony_ci fw->shadow_reg[8] = htonl(rd_reg_dword(®->iobase_sdata)); 173762306a36Sopenharmony_ci 173862306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0900000); 173962306a36Sopenharmony_ci fw->shadow_reg[9] = htonl(rd_reg_dword(®->iobase_sdata)); 174062306a36Sopenharmony_ci 174162306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0A00000); 174262306a36Sopenharmony_ci fw->shadow_reg[10] = htonl(rd_reg_dword(®->iobase_sdata)); 174362306a36Sopenharmony_ci 174462306a36Sopenharmony_ci /* RISC I/O register. */ 174562306a36Sopenharmony_ci wrt_reg_dword(®->iobase_addr, 0x0010); 174662306a36Sopenharmony_ci fw->risc_io_reg = htonl(rd_reg_dword(®->iobase_window)); 174762306a36Sopenharmony_ci 174862306a36Sopenharmony_ci /* Mailbox registers. */ 174962306a36Sopenharmony_ci mbx_reg = ®->mailbox0; 175062306a36Sopenharmony_ci for (cnt = 0; cnt < ARRAY_SIZE(fw->mailbox_reg); cnt++, mbx_reg++) 175162306a36Sopenharmony_ci fw->mailbox_reg[cnt] = htons(rd_reg_word(mbx_reg)); 175262306a36Sopenharmony_ci 175362306a36Sopenharmony_ci /* Transfer sequence registers. */ 175462306a36Sopenharmony_ci iter_reg = fw->xseq_gp_reg; 175562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg); 175662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg); 175762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg); 175862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg); 175962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg); 176062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg); 176162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg); 176262306a36Sopenharmony_ci qla24xx_read_window(reg, 0xBF70, 16, iter_reg); 176362306a36Sopenharmony_ci 176462306a36Sopenharmony_ci iter_reg = fw->xseq_0_reg; 176562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBFC0, 16, iter_reg); 176662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBFD0, 16, iter_reg); 176762306a36Sopenharmony_ci qla24xx_read_window(reg, 0xBFE0, 16, iter_reg); 176862306a36Sopenharmony_ci 176962306a36Sopenharmony_ci qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg); 177062306a36Sopenharmony_ci 177162306a36Sopenharmony_ci /* Receive sequence registers. */ 177262306a36Sopenharmony_ci iter_reg = fw->rseq_gp_reg; 177362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg); 177462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg); 177562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg); 177662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg); 177762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg); 177862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg); 177962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg); 178062306a36Sopenharmony_ci qla24xx_read_window(reg, 0xFF70, 16, iter_reg); 178162306a36Sopenharmony_ci 178262306a36Sopenharmony_ci iter_reg = fw->rseq_0_reg; 178362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFFC0, 16, iter_reg); 178462306a36Sopenharmony_ci qla24xx_read_window(reg, 0xFFD0, 16, iter_reg); 178562306a36Sopenharmony_ci 178662306a36Sopenharmony_ci qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg); 178762306a36Sopenharmony_ci qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg); 178862306a36Sopenharmony_ci 178962306a36Sopenharmony_ci /* Auxiliary sequence registers. */ 179062306a36Sopenharmony_ci iter_reg = fw->aseq_gp_reg; 179162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB000, 16, iter_reg); 179262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB010, 16, iter_reg); 179362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB020, 16, iter_reg); 179462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB030, 16, iter_reg); 179562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB040, 16, iter_reg); 179662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB050, 16, iter_reg); 179762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB060, 16, iter_reg); 179862306a36Sopenharmony_ci qla24xx_read_window(reg, 0xB070, 16, iter_reg); 179962306a36Sopenharmony_ci 180062306a36Sopenharmony_ci iter_reg = fw->aseq_0_reg; 180162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB0C0, 16, iter_reg); 180262306a36Sopenharmony_ci qla24xx_read_window(reg, 0xB0D0, 16, iter_reg); 180362306a36Sopenharmony_ci 180462306a36Sopenharmony_ci qla24xx_read_window(reg, 0xB0E0, 16, fw->aseq_1_reg); 180562306a36Sopenharmony_ci qla24xx_read_window(reg, 0xB0F0, 16, fw->aseq_2_reg); 180662306a36Sopenharmony_ci 180762306a36Sopenharmony_ci /* Command DMA registers. */ 180862306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7100, 16, fw->cmd_dma_reg); 180962306a36Sopenharmony_ci 181062306a36Sopenharmony_ci /* Queues. */ 181162306a36Sopenharmony_ci iter_reg = fw->req0_dma_reg; 181262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg); 181362306a36Sopenharmony_ci dmp_reg = ®->iobase_q; 181462306a36Sopenharmony_ci for (cnt = 0; cnt < 7; cnt++, dmp_reg++) 181562306a36Sopenharmony_ci *iter_reg++ = htonl(rd_reg_dword(dmp_reg)); 181662306a36Sopenharmony_ci 181762306a36Sopenharmony_ci iter_reg = fw->resp0_dma_reg; 181862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg); 181962306a36Sopenharmony_ci dmp_reg = ®->iobase_q; 182062306a36Sopenharmony_ci for (cnt = 0; cnt < 7; cnt++, dmp_reg++) 182162306a36Sopenharmony_ci *iter_reg++ = htonl(rd_reg_dword(dmp_reg)); 182262306a36Sopenharmony_ci 182362306a36Sopenharmony_ci iter_reg = fw->req1_dma_reg; 182462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg); 182562306a36Sopenharmony_ci dmp_reg = ®->iobase_q; 182662306a36Sopenharmony_ci for (cnt = 0; cnt < 7; cnt++, dmp_reg++) 182762306a36Sopenharmony_ci *iter_reg++ = htonl(rd_reg_dword(dmp_reg)); 182862306a36Sopenharmony_ci 182962306a36Sopenharmony_ci /* Transmit DMA registers. */ 183062306a36Sopenharmony_ci iter_reg = fw->xmt0_dma_reg; 183162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg); 183262306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7610, 16, iter_reg); 183362306a36Sopenharmony_ci 183462306a36Sopenharmony_ci iter_reg = fw->xmt1_dma_reg; 183562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg); 183662306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7630, 16, iter_reg); 183762306a36Sopenharmony_ci 183862306a36Sopenharmony_ci iter_reg = fw->xmt2_dma_reg; 183962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg); 184062306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7650, 16, iter_reg); 184162306a36Sopenharmony_ci 184262306a36Sopenharmony_ci iter_reg = fw->xmt3_dma_reg; 184362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg); 184462306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7670, 16, iter_reg); 184562306a36Sopenharmony_ci 184662306a36Sopenharmony_ci iter_reg = fw->xmt4_dma_reg; 184762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg); 184862306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7690, 16, iter_reg); 184962306a36Sopenharmony_ci 185062306a36Sopenharmony_ci qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg); 185162306a36Sopenharmony_ci 185262306a36Sopenharmony_ci /* Receive DMA registers. */ 185362306a36Sopenharmony_ci iter_reg = fw->rcvt0_data_dma_reg; 185462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg); 185562306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7710, 16, iter_reg); 185662306a36Sopenharmony_ci 185762306a36Sopenharmony_ci iter_reg = fw->rcvt1_data_dma_reg; 185862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg); 185962306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7730, 16, iter_reg); 186062306a36Sopenharmony_ci 186162306a36Sopenharmony_ci /* RISC registers. */ 186262306a36Sopenharmony_ci iter_reg = fw->risc_gp_reg; 186362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg); 186462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg); 186562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg); 186662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg); 186762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg); 186862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg); 186962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg); 187062306a36Sopenharmony_ci qla24xx_read_window(reg, 0x0F70, 16, iter_reg); 187162306a36Sopenharmony_ci 187262306a36Sopenharmony_ci /* Local memory controller registers. */ 187362306a36Sopenharmony_ci iter_reg = fw->lmc_reg; 187462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg); 187562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg); 187662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg); 187762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg); 187862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg); 187962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg); 188062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x3060, 16, iter_reg); 188162306a36Sopenharmony_ci qla24xx_read_window(reg, 0x3070, 16, iter_reg); 188262306a36Sopenharmony_ci 188362306a36Sopenharmony_ci /* Fibre Protocol Module registers. */ 188462306a36Sopenharmony_ci iter_reg = fw->fpm_hdw_reg; 188562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg); 188662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg); 188762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg); 188862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg); 188962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg); 189062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg); 189162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg); 189262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg); 189362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg); 189462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg); 189562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg); 189662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x40B0, 16, iter_reg); 189762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x40C0, 16, iter_reg); 189862306a36Sopenharmony_ci qla24xx_read_window(reg, 0x40D0, 16, iter_reg); 189962306a36Sopenharmony_ci 190062306a36Sopenharmony_ci /* Frame Buffer registers. */ 190162306a36Sopenharmony_ci iter_reg = fw->fb_hdw_reg; 190262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg); 190362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg); 190462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg); 190562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg); 190662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg); 190762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg); 190862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg); 190962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg); 191062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg); 191162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg); 191262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg); 191362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x61C0, 16, iter_reg); 191462306a36Sopenharmony_ci qla24xx_read_window(reg, 0x6F00, 16, iter_reg); 191562306a36Sopenharmony_ci 191662306a36Sopenharmony_ci /* Multi queue registers */ 191762306a36Sopenharmony_ci nxt_chain = qla25xx_copy_mq(ha, (void *)ha->fw_dump + ha->chain_offset, 191862306a36Sopenharmony_ci &last_chain); 191962306a36Sopenharmony_ci 192062306a36Sopenharmony_ci rval = qla24xx_soft_reset(ha); 192162306a36Sopenharmony_ci if (rval != QLA_SUCCESS) 192262306a36Sopenharmony_ci goto qla81xx_fw_dump_failed_0; 192362306a36Sopenharmony_ci 192462306a36Sopenharmony_ci rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram), 192562306a36Sopenharmony_ci &nxt); 192662306a36Sopenharmony_ci if (rval != QLA_SUCCESS) 192762306a36Sopenharmony_ci goto qla81xx_fw_dump_failed_0; 192862306a36Sopenharmony_ci 192962306a36Sopenharmony_ci nxt = qla2xxx_copy_queues(ha, nxt); 193062306a36Sopenharmony_ci 193162306a36Sopenharmony_ci qla24xx_copy_eft(ha, nxt); 193262306a36Sopenharmony_ci 193362306a36Sopenharmony_ci /* Chain entries -- started with MQ. */ 193462306a36Sopenharmony_ci nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain); 193562306a36Sopenharmony_ci nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain); 193662306a36Sopenharmony_ci nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain); 193762306a36Sopenharmony_ci nxt_chain = qla25xx_copy_exlogin(ha, nxt_chain, &last_chain); 193862306a36Sopenharmony_ci nxt_chain = qla81xx_copy_exchoffld(ha, nxt_chain, &last_chain); 193962306a36Sopenharmony_ci if (last_chain) { 194062306a36Sopenharmony_ci ha->fw_dump->version |= htonl(DUMP_CHAIN_VARIANT); 194162306a36Sopenharmony_ci *last_chain |= htonl(DUMP_CHAIN_LAST); 194262306a36Sopenharmony_ci } 194362306a36Sopenharmony_ci 194462306a36Sopenharmony_ci /* Adjust valid length. */ 194562306a36Sopenharmony_ci ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump); 194662306a36Sopenharmony_ci 194762306a36Sopenharmony_ciqla81xx_fw_dump_failed_0: 194862306a36Sopenharmony_ci qla2xxx_dump_post_process(base_vha, rval); 194962306a36Sopenharmony_ci} 195062306a36Sopenharmony_ci 195162306a36Sopenharmony_civoid 195262306a36Sopenharmony_ciqla83xx_fw_dump(scsi_qla_host_t *vha) 195362306a36Sopenharmony_ci{ 195462306a36Sopenharmony_ci int rval; 195562306a36Sopenharmony_ci uint32_t cnt; 195662306a36Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 195762306a36Sopenharmony_ci struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; 195862306a36Sopenharmony_ci __le32 __iomem *dmp_reg; 195962306a36Sopenharmony_ci __be32 *iter_reg; 196062306a36Sopenharmony_ci __le16 __iomem *mbx_reg; 196162306a36Sopenharmony_ci struct qla83xx_fw_dump *fw; 196262306a36Sopenharmony_ci void *nxt, *nxt_chain; 196362306a36Sopenharmony_ci __be32 *last_chain = NULL; 196462306a36Sopenharmony_ci struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); 196562306a36Sopenharmony_ci 196662306a36Sopenharmony_ci lockdep_assert_held(&ha->hardware_lock); 196762306a36Sopenharmony_ci 196862306a36Sopenharmony_ci ha->fw_dump_cap_flags = 0; 196962306a36Sopenharmony_ci 197062306a36Sopenharmony_ci if (!ha->fw_dump) { 197162306a36Sopenharmony_ci ql_log(ql_log_warn, vha, 0xd00c, 197262306a36Sopenharmony_ci "No buffer available for dump!!!\n"); 197362306a36Sopenharmony_ci return; 197462306a36Sopenharmony_ci } 197562306a36Sopenharmony_ci 197662306a36Sopenharmony_ci if (ha->fw_dumped) { 197762306a36Sopenharmony_ci ql_log(ql_log_warn, vha, 0xd00d, 197862306a36Sopenharmony_ci "Firmware has been previously dumped (%p) -- ignoring " 197962306a36Sopenharmony_ci "request...\n", ha->fw_dump); 198062306a36Sopenharmony_ci return; 198162306a36Sopenharmony_ci } 198262306a36Sopenharmony_ci QLA_FW_STOPPED(ha); 198362306a36Sopenharmony_ci fw = &ha->fw_dump->isp.isp83; 198462306a36Sopenharmony_ci qla2xxx_prep_dump(ha, ha->fw_dump); 198562306a36Sopenharmony_ci 198662306a36Sopenharmony_ci fw->host_status = htonl(rd_reg_dword(®->host_status)); 198762306a36Sopenharmony_ci 198862306a36Sopenharmony_ci /* 198962306a36Sopenharmony_ci * Pause RISC. No need to track timeout, as resetting the chip 199062306a36Sopenharmony_ci * is the right approach incase of pause timeout 199162306a36Sopenharmony_ci */ 199262306a36Sopenharmony_ci qla24xx_pause_risc(reg, ha); 199362306a36Sopenharmony_ci 199462306a36Sopenharmony_ci wrt_reg_dword(®->iobase_addr, 0x6000); 199562306a36Sopenharmony_ci dmp_reg = ®->iobase_window; 199662306a36Sopenharmony_ci rd_reg_dword(dmp_reg); 199762306a36Sopenharmony_ci wrt_reg_dword(dmp_reg, 0); 199862306a36Sopenharmony_ci 199962306a36Sopenharmony_ci dmp_reg = ®->unused_4_1[0]; 200062306a36Sopenharmony_ci rd_reg_dword(dmp_reg); 200162306a36Sopenharmony_ci wrt_reg_dword(dmp_reg, 0); 200262306a36Sopenharmony_ci 200362306a36Sopenharmony_ci wrt_reg_dword(®->iobase_addr, 0x6010); 200462306a36Sopenharmony_ci dmp_reg = ®->unused_4_1[2]; 200562306a36Sopenharmony_ci rd_reg_dword(dmp_reg); 200662306a36Sopenharmony_ci wrt_reg_dword(dmp_reg, 0); 200762306a36Sopenharmony_ci 200862306a36Sopenharmony_ci /* select PCR and disable ecc checking and correction */ 200962306a36Sopenharmony_ci wrt_reg_dword(®->iobase_addr, 0x0F70); 201062306a36Sopenharmony_ci rd_reg_dword(®->iobase_addr); 201162306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0x60000000); /* write to F0h = PCR */ 201262306a36Sopenharmony_ci 201362306a36Sopenharmony_ci /* Host/Risc registers. */ 201462306a36Sopenharmony_ci iter_reg = fw->host_risc_reg; 201562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7000, 16, iter_reg); 201662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7010, 16, iter_reg); 201762306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7040, 16, iter_reg); 201862306a36Sopenharmony_ci 201962306a36Sopenharmony_ci /* PCIe registers. */ 202062306a36Sopenharmony_ci wrt_reg_dword(®->iobase_addr, 0x7C00); 202162306a36Sopenharmony_ci rd_reg_dword(®->iobase_addr); 202262306a36Sopenharmony_ci wrt_reg_dword(®->iobase_window, 0x01); 202362306a36Sopenharmony_ci dmp_reg = ®->iobase_c4; 202462306a36Sopenharmony_ci fw->pcie_regs[0] = htonl(rd_reg_dword(dmp_reg)); 202562306a36Sopenharmony_ci dmp_reg++; 202662306a36Sopenharmony_ci fw->pcie_regs[1] = htonl(rd_reg_dword(dmp_reg)); 202762306a36Sopenharmony_ci dmp_reg++; 202862306a36Sopenharmony_ci fw->pcie_regs[2] = htonl(rd_reg_dword(dmp_reg)); 202962306a36Sopenharmony_ci fw->pcie_regs[3] = htonl(rd_reg_dword(®->iobase_window)); 203062306a36Sopenharmony_ci 203162306a36Sopenharmony_ci wrt_reg_dword(®->iobase_window, 0x00); 203262306a36Sopenharmony_ci rd_reg_dword(®->iobase_window); 203362306a36Sopenharmony_ci 203462306a36Sopenharmony_ci /* Host interface registers. */ 203562306a36Sopenharmony_ci dmp_reg = ®->flash_addr; 203662306a36Sopenharmony_ci for (cnt = 0; cnt < ARRAY_SIZE(fw->host_reg); cnt++, dmp_reg++) 203762306a36Sopenharmony_ci fw->host_reg[cnt] = htonl(rd_reg_dword(dmp_reg)); 203862306a36Sopenharmony_ci 203962306a36Sopenharmony_ci /* Disable interrupts. */ 204062306a36Sopenharmony_ci wrt_reg_dword(®->ictrl, 0); 204162306a36Sopenharmony_ci rd_reg_dword(®->ictrl); 204262306a36Sopenharmony_ci 204362306a36Sopenharmony_ci /* Shadow registers. */ 204462306a36Sopenharmony_ci wrt_reg_dword(®->iobase_addr, 0x0F70); 204562306a36Sopenharmony_ci rd_reg_dword(®->iobase_addr); 204662306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0000000); 204762306a36Sopenharmony_ci fw->shadow_reg[0] = htonl(rd_reg_dword(®->iobase_sdata)); 204862306a36Sopenharmony_ci 204962306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0100000); 205062306a36Sopenharmony_ci fw->shadow_reg[1] = htonl(rd_reg_dword(®->iobase_sdata)); 205162306a36Sopenharmony_ci 205262306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0200000); 205362306a36Sopenharmony_ci fw->shadow_reg[2] = htonl(rd_reg_dword(®->iobase_sdata)); 205462306a36Sopenharmony_ci 205562306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0300000); 205662306a36Sopenharmony_ci fw->shadow_reg[3] = htonl(rd_reg_dword(®->iobase_sdata)); 205762306a36Sopenharmony_ci 205862306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0400000); 205962306a36Sopenharmony_ci fw->shadow_reg[4] = htonl(rd_reg_dword(®->iobase_sdata)); 206062306a36Sopenharmony_ci 206162306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0500000); 206262306a36Sopenharmony_ci fw->shadow_reg[5] = htonl(rd_reg_dword(®->iobase_sdata)); 206362306a36Sopenharmony_ci 206462306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0600000); 206562306a36Sopenharmony_ci fw->shadow_reg[6] = htonl(rd_reg_dword(®->iobase_sdata)); 206662306a36Sopenharmony_ci 206762306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0700000); 206862306a36Sopenharmony_ci fw->shadow_reg[7] = htonl(rd_reg_dword(®->iobase_sdata)); 206962306a36Sopenharmony_ci 207062306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0800000); 207162306a36Sopenharmony_ci fw->shadow_reg[8] = htonl(rd_reg_dword(®->iobase_sdata)); 207262306a36Sopenharmony_ci 207362306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0900000); 207462306a36Sopenharmony_ci fw->shadow_reg[9] = htonl(rd_reg_dword(®->iobase_sdata)); 207562306a36Sopenharmony_ci 207662306a36Sopenharmony_ci wrt_reg_dword(®->iobase_select, 0xB0A00000); 207762306a36Sopenharmony_ci fw->shadow_reg[10] = htonl(rd_reg_dword(®->iobase_sdata)); 207862306a36Sopenharmony_ci 207962306a36Sopenharmony_ci /* RISC I/O register. */ 208062306a36Sopenharmony_ci wrt_reg_dword(®->iobase_addr, 0x0010); 208162306a36Sopenharmony_ci fw->risc_io_reg = htonl(rd_reg_dword(®->iobase_window)); 208262306a36Sopenharmony_ci 208362306a36Sopenharmony_ci /* Mailbox registers. */ 208462306a36Sopenharmony_ci mbx_reg = ®->mailbox0; 208562306a36Sopenharmony_ci for (cnt = 0; cnt < ARRAY_SIZE(fw->mailbox_reg); cnt++, mbx_reg++) 208662306a36Sopenharmony_ci fw->mailbox_reg[cnt] = htons(rd_reg_word(mbx_reg)); 208762306a36Sopenharmony_ci 208862306a36Sopenharmony_ci /* Transfer sequence registers. */ 208962306a36Sopenharmony_ci iter_reg = fw->xseq_gp_reg; 209062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBE00, 16, iter_reg); 209162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBE10, 16, iter_reg); 209262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBE20, 16, iter_reg); 209362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBE30, 16, iter_reg); 209462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBE40, 16, iter_reg); 209562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBE50, 16, iter_reg); 209662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBE60, 16, iter_reg); 209762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBE70, 16, iter_reg); 209862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg); 209962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg); 210062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg); 210162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg); 210262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg); 210362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg); 210462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg); 210562306a36Sopenharmony_ci qla24xx_read_window(reg, 0xBF70, 16, iter_reg); 210662306a36Sopenharmony_ci 210762306a36Sopenharmony_ci iter_reg = fw->xseq_0_reg; 210862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBFC0, 16, iter_reg); 210962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xBFD0, 16, iter_reg); 211062306a36Sopenharmony_ci qla24xx_read_window(reg, 0xBFE0, 16, iter_reg); 211162306a36Sopenharmony_ci 211262306a36Sopenharmony_ci qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg); 211362306a36Sopenharmony_ci 211462306a36Sopenharmony_ci qla24xx_read_window(reg, 0xBEF0, 16, fw->xseq_2_reg); 211562306a36Sopenharmony_ci 211662306a36Sopenharmony_ci /* Receive sequence registers. */ 211762306a36Sopenharmony_ci iter_reg = fw->rseq_gp_reg; 211862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFE00, 16, iter_reg); 211962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFE10, 16, iter_reg); 212062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFE20, 16, iter_reg); 212162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFE30, 16, iter_reg); 212262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFE40, 16, iter_reg); 212362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFE50, 16, iter_reg); 212462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFE60, 16, iter_reg); 212562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFE70, 16, iter_reg); 212662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg); 212762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg); 212862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg); 212962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg); 213062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg); 213162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg); 213262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg); 213362306a36Sopenharmony_ci qla24xx_read_window(reg, 0xFF70, 16, iter_reg); 213462306a36Sopenharmony_ci 213562306a36Sopenharmony_ci iter_reg = fw->rseq_0_reg; 213662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xFFC0, 16, iter_reg); 213762306a36Sopenharmony_ci qla24xx_read_window(reg, 0xFFD0, 16, iter_reg); 213862306a36Sopenharmony_ci 213962306a36Sopenharmony_ci qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg); 214062306a36Sopenharmony_ci qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg); 214162306a36Sopenharmony_ci qla24xx_read_window(reg, 0xFEF0, 16, fw->rseq_3_reg); 214262306a36Sopenharmony_ci 214362306a36Sopenharmony_ci /* Auxiliary sequence registers. */ 214462306a36Sopenharmony_ci iter_reg = fw->aseq_gp_reg; 214562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB000, 16, iter_reg); 214662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB010, 16, iter_reg); 214762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB020, 16, iter_reg); 214862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB030, 16, iter_reg); 214962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB040, 16, iter_reg); 215062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB050, 16, iter_reg); 215162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB060, 16, iter_reg); 215262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB070, 16, iter_reg); 215362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB100, 16, iter_reg); 215462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB110, 16, iter_reg); 215562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB120, 16, iter_reg); 215662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB130, 16, iter_reg); 215762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB140, 16, iter_reg); 215862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB150, 16, iter_reg); 215962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB160, 16, iter_reg); 216062306a36Sopenharmony_ci qla24xx_read_window(reg, 0xB170, 16, iter_reg); 216162306a36Sopenharmony_ci 216262306a36Sopenharmony_ci iter_reg = fw->aseq_0_reg; 216362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0xB0C0, 16, iter_reg); 216462306a36Sopenharmony_ci qla24xx_read_window(reg, 0xB0D0, 16, iter_reg); 216562306a36Sopenharmony_ci 216662306a36Sopenharmony_ci qla24xx_read_window(reg, 0xB0E0, 16, fw->aseq_1_reg); 216762306a36Sopenharmony_ci qla24xx_read_window(reg, 0xB0F0, 16, fw->aseq_2_reg); 216862306a36Sopenharmony_ci qla24xx_read_window(reg, 0xB1F0, 16, fw->aseq_3_reg); 216962306a36Sopenharmony_ci 217062306a36Sopenharmony_ci /* Command DMA registers. */ 217162306a36Sopenharmony_ci iter_reg = fw->cmd_dma_reg; 217262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7100, 16, iter_reg); 217362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7120, 16, iter_reg); 217462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7130, 16, iter_reg); 217562306a36Sopenharmony_ci qla24xx_read_window(reg, 0x71F0, 16, iter_reg); 217662306a36Sopenharmony_ci 217762306a36Sopenharmony_ci /* Queues. */ 217862306a36Sopenharmony_ci iter_reg = fw->req0_dma_reg; 217962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg); 218062306a36Sopenharmony_ci dmp_reg = ®->iobase_q; 218162306a36Sopenharmony_ci for (cnt = 0; cnt < 7; cnt++, dmp_reg++) 218262306a36Sopenharmony_ci *iter_reg++ = htonl(rd_reg_dword(dmp_reg)); 218362306a36Sopenharmony_ci 218462306a36Sopenharmony_ci iter_reg = fw->resp0_dma_reg; 218562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg); 218662306a36Sopenharmony_ci dmp_reg = ®->iobase_q; 218762306a36Sopenharmony_ci for (cnt = 0; cnt < 7; cnt++, dmp_reg++) 218862306a36Sopenharmony_ci *iter_reg++ = htonl(rd_reg_dword(dmp_reg)); 218962306a36Sopenharmony_ci 219062306a36Sopenharmony_ci iter_reg = fw->req1_dma_reg; 219162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg); 219262306a36Sopenharmony_ci dmp_reg = ®->iobase_q; 219362306a36Sopenharmony_ci for (cnt = 0; cnt < 7; cnt++, dmp_reg++) 219462306a36Sopenharmony_ci *iter_reg++ = htonl(rd_reg_dword(dmp_reg)); 219562306a36Sopenharmony_ci 219662306a36Sopenharmony_ci /* Transmit DMA registers. */ 219762306a36Sopenharmony_ci iter_reg = fw->xmt0_dma_reg; 219862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg); 219962306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7610, 16, iter_reg); 220062306a36Sopenharmony_ci 220162306a36Sopenharmony_ci iter_reg = fw->xmt1_dma_reg; 220262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg); 220362306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7630, 16, iter_reg); 220462306a36Sopenharmony_ci 220562306a36Sopenharmony_ci iter_reg = fw->xmt2_dma_reg; 220662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg); 220762306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7650, 16, iter_reg); 220862306a36Sopenharmony_ci 220962306a36Sopenharmony_ci iter_reg = fw->xmt3_dma_reg; 221062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg); 221162306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7670, 16, iter_reg); 221262306a36Sopenharmony_ci 221362306a36Sopenharmony_ci iter_reg = fw->xmt4_dma_reg; 221462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg); 221562306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7690, 16, iter_reg); 221662306a36Sopenharmony_ci 221762306a36Sopenharmony_ci qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg); 221862306a36Sopenharmony_ci 221962306a36Sopenharmony_ci /* Receive DMA registers. */ 222062306a36Sopenharmony_ci iter_reg = fw->rcvt0_data_dma_reg; 222162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg); 222262306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7710, 16, iter_reg); 222362306a36Sopenharmony_ci 222462306a36Sopenharmony_ci iter_reg = fw->rcvt1_data_dma_reg; 222562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg); 222662306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7730, 16, iter_reg); 222762306a36Sopenharmony_ci 222862306a36Sopenharmony_ci /* RISC registers. */ 222962306a36Sopenharmony_ci iter_reg = fw->risc_gp_reg; 223062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg); 223162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg); 223262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg); 223362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg); 223462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg); 223562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg); 223662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg); 223762306a36Sopenharmony_ci qla24xx_read_window(reg, 0x0F70, 16, iter_reg); 223862306a36Sopenharmony_ci 223962306a36Sopenharmony_ci /* Local memory controller registers. */ 224062306a36Sopenharmony_ci iter_reg = fw->lmc_reg; 224162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg); 224262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg); 224362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg); 224462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg); 224562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg); 224662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg); 224762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x3060, 16, iter_reg); 224862306a36Sopenharmony_ci qla24xx_read_window(reg, 0x3070, 16, iter_reg); 224962306a36Sopenharmony_ci 225062306a36Sopenharmony_ci /* Fibre Protocol Module registers. */ 225162306a36Sopenharmony_ci iter_reg = fw->fpm_hdw_reg; 225262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg); 225362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg); 225462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg); 225562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg); 225662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg); 225762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg); 225862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg); 225962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg); 226062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg); 226162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg); 226262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg); 226362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x40B0, 16, iter_reg); 226462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x40C0, 16, iter_reg); 226562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x40D0, 16, iter_reg); 226662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x40E0, 16, iter_reg); 226762306a36Sopenharmony_ci qla24xx_read_window(reg, 0x40F0, 16, iter_reg); 226862306a36Sopenharmony_ci 226962306a36Sopenharmony_ci /* RQ0 Array registers. */ 227062306a36Sopenharmony_ci iter_reg = fw->rq0_array_reg; 227162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5C00, 16, iter_reg); 227262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5C10, 16, iter_reg); 227362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5C20, 16, iter_reg); 227462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5C30, 16, iter_reg); 227562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5C40, 16, iter_reg); 227662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5C50, 16, iter_reg); 227762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5C60, 16, iter_reg); 227862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5C70, 16, iter_reg); 227962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5C80, 16, iter_reg); 228062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5C90, 16, iter_reg); 228162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5CA0, 16, iter_reg); 228262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5CB0, 16, iter_reg); 228362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5CC0, 16, iter_reg); 228462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5CD0, 16, iter_reg); 228562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5CE0, 16, iter_reg); 228662306a36Sopenharmony_ci qla24xx_read_window(reg, 0x5CF0, 16, iter_reg); 228762306a36Sopenharmony_ci 228862306a36Sopenharmony_ci /* RQ1 Array registers. */ 228962306a36Sopenharmony_ci iter_reg = fw->rq1_array_reg; 229062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5D00, 16, iter_reg); 229162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5D10, 16, iter_reg); 229262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5D20, 16, iter_reg); 229362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5D30, 16, iter_reg); 229462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5D40, 16, iter_reg); 229562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5D50, 16, iter_reg); 229662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5D60, 16, iter_reg); 229762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5D70, 16, iter_reg); 229862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5D80, 16, iter_reg); 229962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5D90, 16, iter_reg); 230062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5DA0, 16, iter_reg); 230162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5DB0, 16, iter_reg); 230262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5DC0, 16, iter_reg); 230362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5DD0, 16, iter_reg); 230462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5DE0, 16, iter_reg); 230562306a36Sopenharmony_ci qla24xx_read_window(reg, 0x5DF0, 16, iter_reg); 230662306a36Sopenharmony_ci 230762306a36Sopenharmony_ci /* RP0 Array registers. */ 230862306a36Sopenharmony_ci iter_reg = fw->rp0_array_reg; 230962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5E00, 16, iter_reg); 231062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5E10, 16, iter_reg); 231162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5E20, 16, iter_reg); 231262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5E30, 16, iter_reg); 231362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5E40, 16, iter_reg); 231462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5E50, 16, iter_reg); 231562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5E60, 16, iter_reg); 231662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5E70, 16, iter_reg); 231762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5E80, 16, iter_reg); 231862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5E90, 16, iter_reg); 231962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5EA0, 16, iter_reg); 232062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5EB0, 16, iter_reg); 232162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5EC0, 16, iter_reg); 232262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5ED0, 16, iter_reg); 232362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5EE0, 16, iter_reg); 232462306a36Sopenharmony_ci qla24xx_read_window(reg, 0x5EF0, 16, iter_reg); 232562306a36Sopenharmony_ci 232662306a36Sopenharmony_ci /* RP1 Array registers. */ 232762306a36Sopenharmony_ci iter_reg = fw->rp1_array_reg; 232862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5F00, 16, iter_reg); 232962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5F10, 16, iter_reg); 233062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5F20, 16, iter_reg); 233162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5F30, 16, iter_reg); 233262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5F40, 16, iter_reg); 233362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5F50, 16, iter_reg); 233462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5F60, 16, iter_reg); 233562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5F70, 16, iter_reg); 233662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5F80, 16, iter_reg); 233762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5F90, 16, iter_reg); 233862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5FA0, 16, iter_reg); 233962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5FB0, 16, iter_reg); 234062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5FC0, 16, iter_reg); 234162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5FD0, 16, iter_reg); 234262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x5FE0, 16, iter_reg); 234362306a36Sopenharmony_ci qla24xx_read_window(reg, 0x5FF0, 16, iter_reg); 234462306a36Sopenharmony_ci 234562306a36Sopenharmony_ci iter_reg = fw->at0_array_reg; 234662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7080, 16, iter_reg); 234762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x7090, 16, iter_reg); 234862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x70A0, 16, iter_reg); 234962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x70B0, 16, iter_reg); 235062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x70C0, 16, iter_reg); 235162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x70D0, 16, iter_reg); 235262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x70E0, 16, iter_reg); 235362306a36Sopenharmony_ci qla24xx_read_window(reg, 0x70F0, 16, iter_reg); 235462306a36Sopenharmony_ci 235562306a36Sopenharmony_ci /* I/O Queue Control registers. */ 235662306a36Sopenharmony_ci qla24xx_read_window(reg, 0x7800, 16, fw->queue_control_reg); 235762306a36Sopenharmony_ci 235862306a36Sopenharmony_ci /* Frame Buffer registers. */ 235962306a36Sopenharmony_ci iter_reg = fw->fb_hdw_reg; 236062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg); 236162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg); 236262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg); 236362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg); 236462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg); 236562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6060, 16, iter_reg); 236662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6070, 16, iter_reg); 236762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg); 236862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg); 236962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg); 237062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg); 237162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg); 237262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg); 237362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x61C0, 16, iter_reg); 237462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6530, 16, iter_reg); 237562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6540, 16, iter_reg); 237662306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6550, 16, iter_reg); 237762306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6560, 16, iter_reg); 237862306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6570, 16, iter_reg); 237962306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6580, 16, iter_reg); 238062306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x6590, 16, iter_reg); 238162306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x65A0, 16, iter_reg); 238262306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x65B0, 16, iter_reg); 238362306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x65C0, 16, iter_reg); 238462306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x65D0, 16, iter_reg); 238562306a36Sopenharmony_ci iter_reg = qla24xx_read_window(reg, 0x65E0, 16, iter_reg); 238662306a36Sopenharmony_ci qla24xx_read_window(reg, 0x6F00, 16, iter_reg); 238762306a36Sopenharmony_ci 238862306a36Sopenharmony_ci /* Multi queue registers */ 238962306a36Sopenharmony_ci nxt_chain = qla25xx_copy_mq(ha, (void *)ha->fw_dump + ha->chain_offset, 239062306a36Sopenharmony_ci &last_chain); 239162306a36Sopenharmony_ci 239262306a36Sopenharmony_ci rval = qla24xx_soft_reset(ha); 239362306a36Sopenharmony_ci if (rval != QLA_SUCCESS) { 239462306a36Sopenharmony_ci ql_log(ql_log_warn, vha, 0xd00e, 239562306a36Sopenharmony_ci "SOFT RESET FAILED, forcing continuation of dump!!!\n"); 239662306a36Sopenharmony_ci rval = QLA_SUCCESS; 239762306a36Sopenharmony_ci 239862306a36Sopenharmony_ci ql_log(ql_log_warn, vha, 0xd00f, "try a bigger hammer!!!\n"); 239962306a36Sopenharmony_ci 240062306a36Sopenharmony_ci wrt_reg_dword(®->hccr, HCCRX_SET_RISC_RESET); 240162306a36Sopenharmony_ci rd_reg_dword(®->hccr); 240262306a36Sopenharmony_ci 240362306a36Sopenharmony_ci wrt_reg_dword(®->hccr, HCCRX_REL_RISC_PAUSE); 240462306a36Sopenharmony_ci rd_reg_dword(®->hccr); 240562306a36Sopenharmony_ci 240662306a36Sopenharmony_ci wrt_reg_dword(®->hccr, HCCRX_CLR_RISC_RESET); 240762306a36Sopenharmony_ci rd_reg_dword(®->hccr); 240862306a36Sopenharmony_ci 240962306a36Sopenharmony_ci for (cnt = 30000; cnt && (rd_reg_word(®->mailbox0)); cnt--) 241062306a36Sopenharmony_ci udelay(5); 241162306a36Sopenharmony_ci 241262306a36Sopenharmony_ci if (!cnt) { 241362306a36Sopenharmony_ci nxt = fw->code_ram; 241462306a36Sopenharmony_ci nxt += sizeof(fw->code_ram); 241562306a36Sopenharmony_ci nxt += (ha->fw_memory_size - 0x100000 + 1); 241662306a36Sopenharmony_ci goto copy_queue; 241762306a36Sopenharmony_ci } else { 241862306a36Sopenharmony_ci set_bit(RISC_RDY_AFT_RESET, &ha->fw_dump_cap_flags); 241962306a36Sopenharmony_ci ql_log(ql_log_warn, vha, 0xd010, 242062306a36Sopenharmony_ci "bigger hammer success?\n"); 242162306a36Sopenharmony_ci } 242262306a36Sopenharmony_ci } 242362306a36Sopenharmony_ci 242462306a36Sopenharmony_ci rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram), 242562306a36Sopenharmony_ci &nxt); 242662306a36Sopenharmony_ci if (rval != QLA_SUCCESS) 242762306a36Sopenharmony_ci goto qla83xx_fw_dump_failed_0; 242862306a36Sopenharmony_ci 242962306a36Sopenharmony_cicopy_queue: 243062306a36Sopenharmony_ci nxt = qla2xxx_copy_queues(ha, nxt); 243162306a36Sopenharmony_ci 243262306a36Sopenharmony_ci qla24xx_copy_eft(ha, nxt); 243362306a36Sopenharmony_ci 243462306a36Sopenharmony_ci /* Chain entries -- started with MQ. */ 243562306a36Sopenharmony_ci nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain); 243662306a36Sopenharmony_ci nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain); 243762306a36Sopenharmony_ci nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain); 243862306a36Sopenharmony_ci nxt_chain = qla25xx_copy_exlogin(ha, nxt_chain, &last_chain); 243962306a36Sopenharmony_ci nxt_chain = qla81xx_copy_exchoffld(ha, nxt_chain, &last_chain); 244062306a36Sopenharmony_ci if (last_chain) { 244162306a36Sopenharmony_ci ha->fw_dump->version |= htonl(DUMP_CHAIN_VARIANT); 244262306a36Sopenharmony_ci *last_chain |= htonl(DUMP_CHAIN_LAST); 244362306a36Sopenharmony_ci } 244462306a36Sopenharmony_ci 244562306a36Sopenharmony_ci /* Adjust valid length. */ 244662306a36Sopenharmony_ci ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump); 244762306a36Sopenharmony_ci 244862306a36Sopenharmony_ciqla83xx_fw_dump_failed_0: 244962306a36Sopenharmony_ci qla2xxx_dump_post_process(base_vha, rval); 245062306a36Sopenharmony_ci} 245162306a36Sopenharmony_ci 245262306a36Sopenharmony_ci/****************************************************************************/ 245362306a36Sopenharmony_ci/* Driver Debug Functions. */ 245462306a36Sopenharmony_ci/****************************************************************************/ 245562306a36Sopenharmony_ci 245662306a36Sopenharmony_ci/* Write the debug message prefix into @pbuf. */ 245762306a36Sopenharmony_cistatic void ql_dbg_prefix(char *pbuf, int pbuf_size, struct pci_dev *pdev, 245862306a36Sopenharmony_ci const scsi_qla_host_t *vha, uint msg_id) 245962306a36Sopenharmony_ci{ 246062306a36Sopenharmony_ci if (vha) { 246162306a36Sopenharmony_ci const struct pci_dev *pdev = vha->hw->pdev; 246262306a36Sopenharmony_ci 246362306a36Sopenharmony_ci /* <module-name> [<dev-name>]-<msg-id>:<host>: */ 246462306a36Sopenharmony_ci snprintf(pbuf, pbuf_size, "%s [%s]-%04x:%lu: ", QL_MSGHDR, 246562306a36Sopenharmony_ci dev_name(&(pdev->dev)), msg_id, vha->host_no); 246662306a36Sopenharmony_ci } else if (pdev) { 246762306a36Sopenharmony_ci snprintf(pbuf, pbuf_size, "%s [%s]-%04x: : ", QL_MSGHDR, 246862306a36Sopenharmony_ci dev_name(&pdev->dev), msg_id); 246962306a36Sopenharmony_ci } else { 247062306a36Sopenharmony_ci /* <module-name> [<dev-name>]-<msg-id>: : */ 247162306a36Sopenharmony_ci snprintf(pbuf, pbuf_size, "%s [%s]-%04x: : ", QL_MSGHDR, 247262306a36Sopenharmony_ci "0000:00:00.0", msg_id); 247362306a36Sopenharmony_ci } 247462306a36Sopenharmony_ci} 247562306a36Sopenharmony_ci 247662306a36Sopenharmony_ci/* 247762306a36Sopenharmony_ci * This function is for formatting and logging debug information. 247862306a36Sopenharmony_ci * It is to be used when vha is available. It formats the message 247962306a36Sopenharmony_ci * and logs it to the messages file. 248062306a36Sopenharmony_ci * parameters: 248162306a36Sopenharmony_ci * level: The level of the debug messages to be printed. 248262306a36Sopenharmony_ci * If ql2xextended_error_logging value is correctly set, 248362306a36Sopenharmony_ci * this message will appear in the messages file. 248462306a36Sopenharmony_ci * vha: Pointer to the scsi_qla_host_t. 248562306a36Sopenharmony_ci * id: This is a unique identifier for the level. It identifies the 248662306a36Sopenharmony_ci * part of the code from where the message originated. 248762306a36Sopenharmony_ci * msg: The message to be displayed. 248862306a36Sopenharmony_ci */ 248962306a36Sopenharmony_civoid 249062306a36Sopenharmony_ciql_dbg(uint level, scsi_qla_host_t *vha, uint id, const char *fmt, ...) 249162306a36Sopenharmony_ci{ 249262306a36Sopenharmony_ci va_list va; 249362306a36Sopenharmony_ci struct va_format vaf; 249462306a36Sopenharmony_ci char pbuf[64]; 249562306a36Sopenharmony_ci 249662306a36Sopenharmony_ci ql_ktrace(1, level, pbuf, NULL, vha, id, fmt); 249762306a36Sopenharmony_ci 249862306a36Sopenharmony_ci if (!ql_mask_match(level)) 249962306a36Sopenharmony_ci return; 250062306a36Sopenharmony_ci 250162306a36Sopenharmony_ci if (!pbuf[0]) /* set by ql_ktrace */ 250262306a36Sopenharmony_ci ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), NULL, vha, id); 250362306a36Sopenharmony_ci 250462306a36Sopenharmony_ci va_start(va, fmt); 250562306a36Sopenharmony_ci 250662306a36Sopenharmony_ci vaf.fmt = fmt; 250762306a36Sopenharmony_ci vaf.va = &va; 250862306a36Sopenharmony_ci 250962306a36Sopenharmony_ci pr_warn("%s%pV", pbuf, &vaf); 251062306a36Sopenharmony_ci 251162306a36Sopenharmony_ci va_end(va); 251262306a36Sopenharmony_ci 251362306a36Sopenharmony_ci} 251462306a36Sopenharmony_ci 251562306a36Sopenharmony_ci/* 251662306a36Sopenharmony_ci * This function is for formatting and logging debug information. 251762306a36Sopenharmony_ci * It is to be used when vha is not available and pci is available, 251862306a36Sopenharmony_ci * i.e., before host allocation. It formats the message and logs it 251962306a36Sopenharmony_ci * to the messages file. 252062306a36Sopenharmony_ci * parameters: 252162306a36Sopenharmony_ci * level: The level of the debug messages to be printed. 252262306a36Sopenharmony_ci * If ql2xextended_error_logging value is correctly set, 252362306a36Sopenharmony_ci * this message will appear in the messages file. 252462306a36Sopenharmony_ci * pdev: Pointer to the struct pci_dev. 252562306a36Sopenharmony_ci * id: This is a unique id for the level. It identifies the part 252662306a36Sopenharmony_ci * of the code from where the message originated. 252762306a36Sopenharmony_ci * msg: The message to be displayed. 252862306a36Sopenharmony_ci */ 252962306a36Sopenharmony_civoid 253062306a36Sopenharmony_ciql_dbg_pci(uint level, struct pci_dev *pdev, uint id, const char *fmt, ...) 253162306a36Sopenharmony_ci{ 253262306a36Sopenharmony_ci va_list va; 253362306a36Sopenharmony_ci struct va_format vaf; 253462306a36Sopenharmony_ci char pbuf[128]; 253562306a36Sopenharmony_ci 253662306a36Sopenharmony_ci if (pdev == NULL) 253762306a36Sopenharmony_ci return; 253862306a36Sopenharmony_ci 253962306a36Sopenharmony_ci ql_ktrace(1, level, pbuf, pdev, NULL, id, fmt); 254062306a36Sopenharmony_ci 254162306a36Sopenharmony_ci if (!ql_mask_match(level)) 254262306a36Sopenharmony_ci return; 254362306a36Sopenharmony_ci 254462306a36Sopenharmony_ci va_start(va, fmt); 254562306a36Sopenharmony_ci 254662306a36Sopenharmony_ci vaf.fmt = fmt; 254762306a36Sopenharmony_ci vaf.va = &va; 254862306a36Sopenharmony_ci 254962306a36Sopenharmony_ci if (!pbuf[0]) /* set by ql_ktrace */ 255062306a36Sopenharmony_ci ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), pdev, NULL, 255162306a36Sopenharmony_ci id + ql_dbg_offset); 255262306a36Sopenharmony_ci pr_warn("%s%pV", pbuf, &vaf); 255362306a36Sopenharmony_ci 255462306a36Sopenharmony_ci va_end(va); 255562306a36Sopenharmony_ci} 255662306a36Sopenharmony_ci 255762306a36Sopenharmony_ci/* 255862306a36Sopenharmony_ci * This function is for formatting and logging log messages. 255962306a36Sopenharmony_ci * It is to be used when vha is available. It formats the message 256062306a36Sopenharmony_ci * and logs it to the messages file. All the messages will be logged 256162306a36Sopenharmony_ci * irrespective of value of ql2xextended_error_logging. 256262306a36Sopenharmony_ci * parameters: 256362306a36Sopenharmony_ci * level: The level of the log messages to be printed in the 256462306a36Sopenharmony_ci * messages file. 256562306a36Sopenharmony_ci * vha: Pointer to the scsi_qla_host_t 256662306a36Sopenharmony_ci * id: This is a unique id for the level. It identifies the 256762306a36Sopenharmony_ci * part of the code from where the message originated. 256862306a36Sopenharmony_ci * msg: The message to be displayed. 256962306a36Sopenharmony_ci */ 257062306a36Sopenharmony_civoid 257162306a36Sopenharmony_ciql_log(uint level, scsi_qla_host_t *vha, uint id, const char *fmt, ...) 257262306a36Sopenharmony_ci{ 257362306a36Sopenharmony_ci va_list va; 257462306a36Sopenharmony_ci struct va_format vaf; 257562306a36Sopenharmony_ci char pbuf[128]; 257662306a36Sopenharmony_ci 257762306a36Sopenharmony_ci if (level > ql_errlev) 257862306a36Sopenharmony_ci return; 257962306a36Sopenharmony_ci 258062306a36Sopenharmony_ci ql_ktrace(0, level, pbuf, NULL, vha, id, fmt); 258162306a36Sopenharmony_ci 258262306a36Sopenharmony_ci if (!pbuf[0]) /* set by ql_ktrace */ 258362306a36Sopenharmony_ci ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), NULL, vha, id); 258462306a36Sopenharmony_ci 258562306a36Sopenharmony_ci va_start(va, fmt); 258662306a36Sopenharmony_ci 258762306a36Sopenharmony_ci vaf.fmt = fmt; 258862306a36Sopenharmony_ci vaf.va = &va; 258962306a36Sopenharmony_ci 259062306a36Sopenharmony_ci switch (level) { 259162306a36Sopenharmony_ci case ql_log_fatal: /* FATAL LOG */ 259262306a36Sopenharmony_ci pr_crit("%s%pV", pbuf, &vaf); 259362306a36Sopenharmony_ci break; 259462306a36Sopenharmony_ci case ql_log_warn: 259562306a36Sopenharmony_ci pr_err("%s%pV", pbuf, &vaf); 259662306a36Sopenharmony_ci break; 259762306a36Sopenharmony_ci case ql_log_info: 259862306a36Sopenharmony_ci pr_warn("%s%pV", pbuf, &vaf); 259962306a36Sopenharmony_ci break; 260062306a36Sopenharmony_ci default: 260162306a36Sopenharmony_ci pr_info("%s%pV", pbuf, &vaf); 260262306a36Sopenharmony_ci break; 260362306a36Sopenharmony_ci } 260462306a36Sopenharmony_ci 260562306a36Sopenharmony_ci va_end(va); 260662306a36Sopenharmony_ci} 260762306a36Sopenharmony_ci 260862306a36Sopenharmony_ci/* 260962306a36Sopenharmony_ci * This function is for formatting and logging log messages. 261062306a36Sopenharmony_ci * It is to be used when vha is not available and pci is available, 261162306a36Sopenharmony_ci * i.e., before host allocation. It formats the message and logs 261262306a36Sopenharmony_ci * it to the messages file. All the messages are logged irrespective 261362306a36Sopenharmony_ci * of the value of ql2xextended_error_logging. 261462306a36Sopenharmony_ci * parameters: 261562306a36Sopenharmony_ci * level: The level of the log messages to be printed in the 261662306a36Sopenharmony_ci * messages file. 261762306a36Sopenharmony_ci * pdev: Pointer to the struct pci_dev. 261862306a36Sopenharmony_ci * id: This is a unique id for the level. It identifies the 261962306a36Sopenharmony_ci * part of the code from where the message originated. 262062306a36Sopenharmony_ci * msg: The message to be displayed. 262162306a36Sopenharmony_ci */ 262262306a36Sopenharmony_civoid 262362306a36Sopenharmony_ciql_log_pci(uint level, struct pci_dev *pdev, uint id, const char *fmt, ...) 262462306a36Sopenharmony_ci{ 262562306a36Sopenharmony_ci va_list va; 262662306a36Sopenharmony_ci struct va_format vaf; 262762306a36Sopenharmony_ci char pbuf[128]; 262862306a36Sopenharmony_ci 262962306a36Sopenharmony_ci if (pdev == NULL) 263062306a36Sopenharmony_ci return; 263162306a36Sopenharmony_ci if (level > ql_errlev) 263262306a36Sopenharmony_ci return; 263362306a36Sopenharmony_ci 263462306a36Sopenharmony_ci ql_ktrace(0, level, pbuf, pdev, NULL, id, fmt); 263562306a36Sopenharmony_ci 263662306a36Sopenharmony_ci if (!pbuf[0]) /* set by ql_ktrace */ 263762306a36Sopenharmony_ci ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), pdev, NULL, id); 263862306a36Sopenharmony_ci 263962306a36Sopenharmony_ci va_start(va, fmt); 264062306a36Sopenharmony_ci 264162306a36Sopenharmony_ci vaf.fmt = fmt; 264262306a36Sopenharmony_ci vaf.va = &va; 264362306a36Sopenharmony_ci 264462306a36Sopenharmony_ci switch (level) { 264562306a36Sopenharmony_ci case ql_log_fatal: /* FATAL LOG */ 264662306a36Sopenharmony_ci pr_crit("%s%pV", pbuf, &vaf); 264762306a36Sopenharmony_ci break; 264862306a36Sopenharmony_ci case ql_log_warn: 264962306a36Sopenharmony_ci pr_err("%s%pV", pbuf, &vaf); 265062306a36Sopenharmony_ci break; 265162306a36Sopenharmony_ci case ql_log_info: 265262306a36Sopenharmony_ci pr_warn("%s%pV", pbuf, &vaf); 265362306a36Sopenharmony_ci break; 265462306a36Sopenharmony_ci default: 265562306a36Sopenharmony_ci pr_info("%s%pV", pbuf, &vaf); 265662306a36Sopenharmony_ci break; 265762306a36Sopenharmony_ci } 265862306a36Sopenharmony_ci 265962306a36Sopenharmony_ci va_end(va); 266062306a36Sopenharmony_ci} 266162306a36Sopenharmony_ci 266262306a36Sopenharmony_civoid 266362306a36Sopenharmony_ciql_dump_regs(uint level, scsi_qla_host_t *vha, uint id) 266462306a36Sopenharmony_ci{ 266562306a36Sopenharmony_ci int i; 266662306a36Sopenharmony_ci struct qla_hw_data *ha = vha->hw; 266762306a36Sopenharmony_ci struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; 266862306a36Sopenharmony_ci struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24; 266962306a36Sopenharmony_ci struct device_reg_82xx __iomem *reg82 = &ha->iobase->isp82; 267062306a36Sopenharmony_ci __le16 __iomem *mbx_reg; 267162306a36Sopenharmony_ci 267262306a36Sopenharmony_ci if (!ql_mask_match(level)) 267362306a36Sopenharmony_ci return; 267462306a36Sopenharmony_ci 267562306a36Sopenharmony_ci if (IS_P3P_TYPE(ha)) 267662306a36Sopenharmony_ci mbx_reg = ®82->mailbox_in[0]; 267762306a36Sopenharmony_ci else if (IS_FWI2_CAPABLE(ha)) 267862306a36Sopenharmony_ci mbx_reg = ®24->mailbox0; 267962306a36Sopenharmony_ci else 268062306a36Sopenharmony_ci mbx_reg = MAILBOX_REG(ha, reg, 0); 268162306a36Sopenharmony_ci 268262306a36Sopenharmony_ci ql_dbg(level, vha, id, "Mailbox registers:\n"); 268362306a36Sopenharmony_ci for (i = 0; i < 6; i++, mbx_reg++) 268462306a36Sopenharmony_ci ql_dbg(level, vha, id, 268562306a36Sopenharmony_ci "mbox[%d] %#04x\n", i, rd_reg_word(mbx_reg)); 268662306a36Sopenharmony_ci} 268762306a36Sopenharmony_ci 268862306a36Sopenharmony_civoid 268962306a36Sopenharmony_ciql_dump_buffer(uint level, scsi_qla_host_t *vha, uint id, const void *buf, 269062306a36Sopenharmony_ci uint size) 269162306a36Sopenharmony_ci{ 269262306a36Sopenharmony_ci uint cnt; 269362306a36Sopenharmony_ci 269462306a36Sopenharmony_ci if (!ql_mask_match(level)) 269562306a36Sopenharmony_ci return; 269662306a36Sopenharmony_ci 269762306a36Sopenharmony_ci ql_dbg(level, vha, id, 269862306a36Sopenharmony_ci "%-+5d 0 1 2 3 4 5 6 7 8 9 A B C D E F\n", size); 269962306a36Sopenharmony_ci ql_dbg(level, vha, id, 270062306a36Sopenharmony_ci "----- -----------------------------------------------\n"); 270162306a36Sopenharmony_ci for (cnt = 0; cnt < size; cnt += 16) { 270262306a36Sopenharmony_ci ql_dbg(level, vha, id, "%04x: ", cnt); 270362306a36Sopenharmony_ci print_hex_dump(KERN_CONT, "", DUMP_PREFIX_NONE, 16, 1, 270462306a36Sopenharmony_ci buf + cnt, min(16U, size - cnt), false); 270562306a36Sopenharmony_ci } 270662306a36Sopenharmony_ci} 270762306a36Sopenharmony_ci 270862306a36Sopenharmony_ci/* 270962306a36Sopenharmony_ci * This function is for formatting and logging log messages. 271062306a36Sopenharmony_ci * It is to be used when vha is available. It formats the message 271162306a36Sopenharmony_ci * and logs it to the messages file. All the messages will be logged 271262306a36Sopenharmony_ci * irrespective of value of ql2xextended_error_logging. 271362306a36Sopenharmony_ci * parameters: 271462306a36Sopenharmony_ci * level: The level of the log messages to be printed in the 271562306a36Sopenharmony_ci * messages file. 271662306a36Sopenharmony_ci * vha: Pointer to the scsi_qla_host_t 271762306a36Sopenharmony_ci * id: This is a unique id for the level. It identifies the 271862306a36Sopenharmony_ci * part of the code from where the message originated. 271962306a36Sopenharmony_ci * msg: The message to be displayed. 272062306a36Sopenharmony_ci */ 272162306a36Sopenharmony_civoid 272262306a36Sopenharmony_ciql_log_qp(uint32_t level, struct qla_qpair *qpair, int32_t id, 272362306a36Sopenharmony_ci const char *fmt, ...) 272462306a36Sopenharmony_ci{ 272562306a36Sopenharmony_ci va_list va; 272662306a36Sopenharmony_ci struct va_format vaf; 272762306a36Sopenharmony_ci char pbuf[128]; 272862306a36Sopenharmony_ci 272962306a36Sopenharmony_ci if (level > ql_errlev) 273062306a36Sopenharmony_ci return; 273162306a36Sopenharmony_ci 273262306a36Sopenharmony_ci ql_ktrace(0, level, pbuf, NULL, qpair ? qpair->vha : NULL, id, fmt); 273362306a36Sopenharmony_ci 273462306a36Sopenharmony_ci if (!pbuf[0]) /* set by ql_ktrace */ 273562306a36Sopenharmony_ci ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), NULL, 273662306a36Sopenharmony_ci qpair ? qpair->vha : NULL, id); 273762306a36Sopenharmony_ci 273862306a36Sopenharmony_ci va_start(va, fmt); 273962306a36Sopenharmony_ci 274062306a36Sopenharmony_ci vaf.fmt = fmt; 274162306a36Sopenharmony_ci vaf.va = &va; 274262306a36Sopenharmony_ci 274362306a36Sopenharmony_ci switch (level) { 274462306a36Sopenharmony_ci case ql_log_fatal: /* FATAL LOG */ 274562306a36Sopenharmony_ci pr_crit("%s%pV", pbuf, &vaf); 274662306a36Sopenharmony_ci break; 274762306a36Sopenharmony_ci case ql_log_warn: 274862306a36Sopenharmony_ci pr_err("%s%pV", pbuf, &vaf); 274962306a36Sopenharmony_ci break; 275062306a36Sopenharmony_ci case ql_log_info: 275162306a36Sopenharmony_ci pr_warn("%s%pV", pbuf, &vaf); 275262306a36Sopenharmony_ci break; 275362306a36Sopenharmony_ci default: 275462306a36Sopenharmony_ci pr_info("%s%pV", pbuf, &vaf); 275562306a36Sopenharmony_ci break; 275662306a36Sopenharmony_ci } 275762306a36Sopenharmony_ci 275862306a36Sopenharmony_ci va_end(va); 275962306a36Sopenharmony_ci} 276062306a36Sopenharmony_ci 276162306a36Sopenharmony_ci/* 276262306a36Sopenharmony_ci * This function is for formatting and logging debug information. 276362306a36Sopenharmony_ci * It is to be used when vha is available. It formats the message 276462306a36Sopenharmony_ci * and logs it to the messages file. 276562306a36Sopenharmony_ci * parameters: 276662306a36Sopenharmony_ci * level: The level of the debug messages to be printed. 276762306a36Sopenharmony_ci * If ql2xextended_error_logging value is correctly set, 276862306a36Sopenharmony_ci * this message will appear in the messages file. 276962306a36Sopenharmony_ci * vha: Pointer to the scsi_qla_host_t. 277062306a36Sopenharmony_ci * id: This is a unique identifier for the level. It identifies the 277162306a36Sopenharmony_ci * part of the code from where the message originated. 277262306a36Sopenharmony_ci * msg: The message to be displayed. 277362306a36Sopenharmony_ci */ 277462306a36Sopenharmony_civoid 277562306a36Sopenharmony_ciql_dbg_qp(uint32_t level, struct qla_qpair *qpair, int32_t id, 277662306a36Sopenharmony_ci const char *fmt, ...) 277762306a36Sopenharmony_ci{ 277862306a36Sopenharmony_ci va_list va; 277962306a36Sopenharmony_ci struct va_format vaf; 278062306a36Sopenharmony_ci char pbuf[128]; 278162306a36Sopenharmony_ci 278262306a36Sopenharmony_ci ql_ktrace(1, level, pbuf, NULL, qpair ? qpair->vha : NULL, id, fmt); 278362306a36Sopenharmony_ci 278462306a36Sopenharmony_ci if (!ql_mask_match(level)) 278562306a36Sopenharmony_ci return; 278662306a36Sopenharmony_ci 278762306a36Sopenharmony_ci va_start(va, fmt); 278862306a36Sopenharmony_ci 278962306a36Sopenharmony_ci vaf.fmt = fmt; 279062306a36Sopenharmony_ci vaf.va = &va; 279162306a36Sopenharmony_ci 279262306a36Sopenharmony_ci if (!pbuf[0]) /* set by ql_ktrace */ 279362306a36Sopenharmony_ci ql_dbg_prefix(pbuf, ARRAY_SIZE(pbuf), NULL, 279462306a36Sopenharmony_ci qpair ? qpair->vha : NULL, id + ql_dbg_offset); 279562306a36Sopenharmony_ci 279662306a36Sopenharmony_ci pr_warn("%s%pV", pbuf, &vaf); 279762306a36Sopenharmony_ci 279862306a36Sopenharmony_ci va_end(va); 279962306a36Sopenharmony_ci 280062306a36Sopenharmony_ci} 2801