11da177e4SLinus Torvalds /* 2fa90c54fSAndrew Vasquez * QLogic Fibre Channel HBA Driver 3bd21eaf9SArmen Baloyan * Copyright (c) 2003-2014 QLogic Corporation 41da177e4SLinus Torvalds * 5fa90c54fSAndrew Vasquez * See LICENSE.qla2xxx for copyright and licensing details. 61da177e4SLinus Torvalds */ 73ce8866cSSaurav Kashyap 83ce8866cSSaurav Kashyap /* 93ce8866cSSaurav Kashyap * Table for showing the current message id in use for particular level 103ce8866cSSaurav Kashyap * Change this table for addition of log/debug messages. 11e02587d7SArun Easi * ---------------------------------------------------------------------- 12e02587d7SArun Easi * | Level | Last Value Used | Holes | 13e02587d7SArun Easi * ---------------------------------------------------------------------- 14f73cb695SChad Dupuis * | Module Init and Probe | 0x017d | 0x004b,0x0141 | 15f73cb695SChad Dupuis * | | | 0x0144,0x0146 | 16f73cb695SChad Dupuis * | | | 0x015b-0x0160 | 17f73cb695SChad Dupuis * | | | 0x016e-0x0170 | 18e8887c51SJoe Carnuccio * | Mailbox commands | 0x118d | 0x1018-0x1019 | 191ae47cf3SJoe Carnuccio * | | | 0x10ca | 20f73cb695SChad Dupuis * | | | 0x1115-0x1116 | 21f73cb695SChad Dupuis * | | | 0x111a-0x111b | 22f73cb695SChad Dupuis * | | | 0x1155-0x1158 | 238ae6d9c7SGiridhar Malavali * | Device Discovery | 0x2095 | 0x2020-0x2022, | 246593d5bdSBart Van Assche * | | | 0x2011-0x2012, | 252a8593f8SSaurav Kashyap * | | | 0x2016 | 2636008cf1SChad Dupuis * | Queue Command and IO tracing | 0x3059 | 0x3006-0x300b | 279e522cd8SArun Easi * | | | 0x3027-0x3028 | 288ae6d9c7SGiridhar Malavali * | | | 0x303d-0x3041 | 298ae6d9c7SGiridhar Malavali * | | | 0x302d,0x3033 | 308ae6d9c7SGiridhar Malavali * | | | 0x3036,0x3038 | 318ae6d9c7SGiridhar Malavali * | | | 0x303a | 32e8f5e95dSArmen Baloyan * | DPC Thread | 0x4023 | 0x4002,0x4013 | 33454073c9SSantosh Vernekar * | Async Events | 0x5087 | 0x502b-0x502f | 349ba56b95SGiridhar Malavali * | | | 0x5047,0x5052 | 356ddcfef7SSaurav Kashyap * | | | 0x5084,0x5075 | 36a78951b2SChad Dupuis * | | | 0x503d,0x5044 | 37faef62d1SArmen Baloyan * | | | 0x507b | 3871e56003SArmen Baloyan * | Timer Routines | 0x6012 | | 39f73cb695SChad Dupuis * | User Space Interactions | 0x70e2 | 0x7018,0x702e | 40f73cb695SChad Dupuis * | | | 0x7020,0x7024 | 41f73cb695SChad Dupuis * | | | 0x7039,0x7045 | 42f73cb695SChad Dupuis * | | | 0x7073-0x7075 | 43f73cb695SChad Dupuis * | | | 0x70a5-0x70a6 | 44f73cb695SChad Dupuis * | | | 0x70a8,0x70ab | 45f73cb695SChad Dupuis * | | | 0x70ad-0x70ae | 46f73cb695SChad Dupuis * | | | 0x70d7-0x70db | 47f73cb695SChad Dupuis * | | | 0x70de-0x70df | 48*7108b76eSChad Dupuis * | Task Management | 0x803d | 0x8000,0x800b | 49*7108b76eSChad Dupuis * | | | 0x8025,0x8026 | 50*7108b76eSChad Dupuis * | | | 0x8031,0x8032 | 51*7108b76eSChad Dupuis * | | | 0x8039,0x803c | 525f28d2d7SSaurav Kashyap * | AER/EEH | 0x9011 | | 53e02587d7SArun Easi * | Virtual Port | 0xa007 | | 5427f4b72fSAtul Deshmukh * | ISP82XX Specific | 0xb157 | 0xb002,0xb024 | 557ec0effdSAtul Deshmukh * | | | 0xb09e,0xb0ae | 56a018d8ffSHiral Patel * | | | 0xb0c3,0xb0c6 | 577ec0effdSAtul Deshmukh * | | | 0xb0e0-0xb0ef | 587ec0effdSAtul Deshmukh * | | | 0xb085,0xb0dc | 597ec0effdSAtul Deshmukh * | | | 0xb107,0xb108 | 607ec0effdSAtul Deshmukh * | | | 0xb111,0xb11e | 617ec0effdSAtul Deshmukh * | | | 0xb12c,0xb12d | 627ec0effdSAtul Deshmukh * | | | 0xb13a,0xb142 | 637ec0effdSAtul Deshmukh * | | | 0xb13c-0xb140 | 646ddcfef7SSaurav Kashyap * | | | 0xb149 | 656246b8a1SGiridhar Malavali * | MultiQ | 0xc00c | | 66c0496401SJoe Carnuccio * | Misc | 0xd212 | 0xd017-0xd019 | 67f73cb695SChad Dupuis * | | | 0xd020 | 68c0496401SJoe Carnuccio * | | | 0xd030-0xd0ff | 69f73cb695SChad Dupuis * | | | 0xd101-0xd1fe | 70c0496401SJoe Carnuccio * | | | 0xd213-0xd2fe | 71f83adb61SQuinn Tran * | Target Mode | 0xe078 | | 726ddcfef7SSaurav Kashyap * | Target Mode Management | 0xf072 | 0xf002-0xf003 | 736ddcfef7SSaurav Kashyap * | | | 0xf046-0xf049 | 742d70c103SNicholas Bellinger * | Target Mode Task Management | 0x1000b | | 75e02587d7SArun Easi * ---------------------------------------------------------------------- 763ce8866cSSaurav Kashyap */ 773ce8866cSSaurav Kashyap 781da177e4SLinus Torvalds #include "qla_def.h" 791da177e4SLinus Torvalds 801da177e4SLinus Torvalds #include <linux/delay.h> 811da177e4SLinus Torvalds 823ce8866cSSaurav Kashyap static uint32_t ql_dbg_offset = 0x800; 833ce8866cSSaurav Kashyap 84a7a167bfSAndrew Vasquez static inline void 857b867cf7SAnirban Chakraborty qla2xxx_prep_dump(struct qla_hw_data *ha, struct qla2xxx_fw_dump *fw_dump) 86a7a167bfSAndrew Vasquez { 87a7a167bfSAndrew Vasquez fw_dump->fw_major_version = htonl(ha->fw_major_version); 88a7a167bfSAndrew Vasquez fw_dump->fw_minor_version = htonl(ha->fw_minor_version); 89a7a167bfSAndrew Vasquez fw_dump->fw_subminor_version = htonl(ha->fw_subminor_version); 90a7a167bfSAndrew Vasquez fw_dump->fw_attributes = htonl(ha->fw_attributes); 91a7a167bfSAndrew Vasquez 92a7a167bfSAndrew Vasquez fw_dump->vendor = htonl(ha->pdev->vendor); 93a7a167bfSAndrew Vasquez fw_dump->device = htonl(ha->pdev->device); 94a7a167bfSAndrew Vasquez fw_dump->subsystem_vendor = htonl(ha->pdev->subsystem_vendor); 95a7a167bfSAndrew Vasquez fw_dump->subsystem_device = htonl(ha->pdev->subsystem_device); 96a7a167bfSAndrew Vasquez } 97a7a167bfSAndrew Vasquez 98a7a167bfSAndrew Vasquez static inline void * 9973208dfdSAnirban Chakraborty qla2xxx_copy_queues(struct qla_hw_data *ha, void *ptr) 100a7a167bfSAndrew Vasquez { 10173208dfdSAnirban Chakraborty struct req_que *req = ha->req_q_map[0]; 10273208dfdSAnirban Chakraborty struct rsp_que *rsp = ha->rsp_q_map[0]; 103a7a167bfSAndrew Vasquez /* Request queue. */ 1047b867cf7SAnirban Chakraborty memcpy(ptr, req->ring, req->length * 105a7a167bfSAndrew Vasquez sizeof(request_t)); 106a7a167bfSAndrew Vasquez 107a7a167bfSAndrew Vasquez /* Response queue. */ 1087b867cf7SAnirban Chakraborty ptr += req->length * sizeof(request_t); 1097b867cf7SAnirban Chakraborty memcpy(ptr, rsp->ring, rsp->length * 110a7a167bfSAndrew Vasquez sizeof(response_t)); 111a7a167bfSAndrew Vasquez 1127b867cf7SAnirban Chakraborty return ptr + (rsp->length * sizeof(response_t)); 113a7a167bfSAndrew Vasquez } 1141da177e4SLinus Torvalds 115f73cb695SChad Dupuis int 116f73cb695SChad Dupuis qla27xx_dump_mpi_ram(struct qla_hw_data *ha, uint32_t addr, uint32_t *ram, 117f73cb695SChad Dupuis uint32_t ram_dwords, void **nxt) 118f73cb695SChad Dupuis { 119f73cb695SChad Dupuis int rval; 120f73cb695SChad Dupuis uint32_t cnt, stat, timer, dwords, idx; 121f73cb695SChad Dupuis uint16_t mb0, mb1; 122f73cb695SChad Dupuis struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; 123f73cb695SChad Dupuis dma_addr_t dump_dma = ha->gid_list_dma; 124f73cb695SChad Dupuis uint32_t *dump = (uint32_t *)ha->gid_list; 125f73cb695SChad Dupuis 126f73cb695SChad Dupuis rval = QLA_SUCCESS; 127f73cb695SChad Dupuis mb0 = 0; 128f73cb695SChad Dupuis 129f73cb695SChad Dupuis WRT_REG_WORD(®->mailbox0, MBC_LOAD_DUMP_MPI_RAM); 130f73cb695SChad Dupuis clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); 131f73cb695SChad Dupuis 132f73cb695SChad Dupuis dwords = qla2x00_gid_list_size(ha) / 4; 133f73cb695SChad Dupuis for (cnt = 0; cnt < ram_dwords && rval == QLA_SUCCESS; 134f73cb695SChad Dupuis cnt += dwords, addr += dwords) { 135f73cb695SChad Dupuis if (cnt + dwords > ram_dwords) 136f73cb695SChad Dupuis dwords = ram_dwords - cnt; 137f73cb695SChad Dupuis 138f73cb695SChad Dupuis WRT_REG_WORD(®->mailbox1, LSW(addr)); 139f73cb695SChad Dupuis WRT_REG_WORD(®->mailbox8, MSW(addr)); 140f73cb695SChad Dupuis 141f73cb695SChad Dupuis WRT_REG_WORD(®->mailbox2, MSW(dump_dma)); 142f73cb695SChad Dupuis WRT_REG_WORD(®->mailbox3, LSW(dump_dma)); 143f73cb695SChad Dupuis WRT_REG_WORD(®->mailbox6, MSW(MSD(dump_dma))); 144f73cb695SChad Dupuis WRT_REG_WORD(®->mailbox7, LSW(MSD(dump_dma))); 145f73cb695SChad Dupuis 146f73cb695SChad Dupuis WRT_REG_WORD(®->mailbox4, MSW(dwords)); 147f73cb695SChad Dupuis WRT_REG_WORD(®->mailbox5, LSW(dwords)); 148f73cb695SChad Dupuis 149f73cb695SChad Dupuis WRT_REG_WORD(®->mailbox9, 0); 150f73cb695SChad Dupuis WRT_REG_DWORD(®->hccr, HCCRX_SET_HOST_INT); 151f73cb695SChad Dupuis 152f73cb695SChad Dupuis ha->flags.mbox_int = 0; 153f73cb695SChad Dupuis for (timer = 6000000; timer; timer--) { 154f73cb695SChad Dupuis /* Check for pending interrupts. */ 155f73cb695SChad Dupuis stat = RD_REG_DWORD(®->host_status); 156f73cb695SChad Dupuis if (stat & HSRX_RISC_INT) { 157f73cb695SChad Dupuis stat &= 0xff; 158f73cb695SChad Dupuis 159f73cb695SChad Dupuis if (stat == 0x1 || stat == 0x2 || 160f73cb695SChad Dupuis stat == 0x10 || stat == 0x11) { 161f73cb695SChad Dupuis set_bit(MBX_INTERRUPT, 162f73cb695SChad Dupuis &ha->mbx_cmd_flags); 163f73cb695SChad Dupuis 164f73cb695SChad Dupuis mb0 = RD_REG_WORD(®->mailbox0); 165f73cb695SChad Dupuis mb1 = RD_REG_WORD(®->mailbox1); 166f73cb695SChad Dupuis 167f73cb695SChad Dupuis WRT_REG_DWORD(®->hccr, 168f73cb695SChad Dupuis HCCRX_CLR_RISC_INT); 169f73cb695SChad Dupuis RD_REG_DWORD(®->hccr); 170f73cb695SChad Dupuis break; 171f73cb695SChad Dupuis } 172f73cb695SChad Dupuis 173f73cb695SChad Dupuis /* Clear this intr; it wasn't a mailbox intr */ 174f73cb695SChad Dupuis WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); 175f73cb695SChad Dupuis RD_REG_DWORD(®->hccr); 176f73cb695SChad Dupuis } 177f73cb695SChad Dupuis udelay(5); 178f73cb695SChad Dupuis } 179f73cb695SChad Dupuis ha->flags.mbox_int = 1; 180f73cb695SChad Dupuis 181f73cb695SChad Dupuis if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { 182f73cb695SChad Dupuis rval = mb0 & MBS_MASK; 183f73cb695SChad Dupuis for (idx = 0; idx < dwords; idx++) 184f73cb695SChad Dupuis ram[cnt + idx] = IS_QLA27XX(ha) ? 185f73cb695SChad Dupuis le32_to_cpu(dump[idx]) : swab32(dump[idx]); 186f73cb695SChad Dupuis } else { 187f73cb695SChad Dupuis rval = QLA_FUNCTION_FAILED; 188f73cb695SChad Dupuis } 189f73cb695SChad Dupuis } 190f73cb695SChad Dupuis 191f73cb695SChad Dupuis *nxt = rval == QLA_SUCCESS ? &ram[cnt] : NULL; 192f73cb695SChad Dupuis return rval; 193f73cb695SChad Dupuis } 194f73cb695SChad Dupuis 195f73cb695SChad Dupuis int 1967b867cf7SAnirban Chakraborty qla24xx_dump_ram(struct qla_hw_data *ha, uint32_t addr, uint32_t *ram, 197c5722708SAndrew Vasquez uint32_t ram_dwords, void **nxt) 198c3a2f0dfSAndrew Vasquez { 199c3a2f0dfSAndrew Vasquez int rval; 200c5722708SAndrew Vasquez uint32_t cnt, stat, timer, dwords, idx; 201c5722708SAndrew Vasquez uint16_t mb0; 202c3a2f0dfSAndrew Vasquez struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; 203c5722708SAndrew Vasquez dma_addr_t dump_dma = ha->gid_list_dma; 204c5722708SAndrew Vasquez uint32_t *dump = (uint32_t *)ha->gid_list; 205c3a2f0dfSAndrew Vasquez 206c3a2f0dfSAndrew Vasquez rval = QLA_SUCCESS; 207c5722708SAndrew Vasquez mb0 = 0; 208c5722708SAndrew Vasquez 209c5722708SAndrew Vasquez WRT_REG_WORD(®->mailbox0, MBC_DUMP_RISC_RAM_EXTENDED); 210c5722708SAndrew Vasquez clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); 211c5722708SAndrew Vasquez 212642ef983SChad Dupuis dwords = qla2x00_gid_list_size(ha) / 4; 213c5722708SAndrew Vasquez for (cnt = 0; cnt < ram_dwords && rval == QLA_SUCCESS; 214c5722708SAndrew Vasquez cnt += dwords, addr += dwords) { 215c5722708SAndrew Vasquez if (cnt + dwords > ram_dwords) 216c5722708SAndrew Vasquez dwords = ram_dwords - cnt; 217c5722708SAndrew Vasquez 218c5722708SAndrew Vasquez WRT_REG_WORD(®->mailbox1, LSW(addr)); 219c5722708SAndrew Vasquez WRT_REG_WORD(®->mailbox8, MSW(addr)); 220c5722708SAndrew Vasquez 221c5722708SAndrew Vasquez WRT_REG_WORD(®->mailbox2, MSW(dump_dma)); 222c5722708SAndrew Vasquez WRT_REG_WORD(®->mailbox3, LSW(dump_dma)); 223c5722708SAndrew Vasquez WRT_REG_WORD(®->mailbox6, MSW(MSD(dump_dma))); 224c5722708SAndrew Vasquez WRT_REG_WORD(®->mailbox7, LSW(MSD(dump_dma))); 225c5722708SAndrew Vasquez 226c5722708SAndrew Vasquez WRT_REG_WORD(®->mailbox4, MSW(dwords)); 227c5722708SAndrew Vasquez WRT_REG_WORD(®->mailbox5, LSW(dwords)); 228c5722708SAndrew Vasquez WRT_REG_DWORD(®->hccr, HCCRX_SET_HOST_INT); 229c5722708SAndrew Vasquez 230f73cb695SChad Dupuis ha->flags.mbox_int = 0; 231c5722708SAndrew Vasquez for (timer = 6000000; timer; timer--) { 232c5722708SAndrew Vasquez /* Check for pending interrupts. */ 233c5722708SAndrew Vasquez stat = RD_REG_DWORD(®->host_status); 234c5722708SAndrew Vasquez if (stat & HSRX_RISC_INT) { 235c5722708SAndrew Vasquez stat &= 0xff; 236c5722708SAndrew Vasquez 237c5722708SAndrew Vasquez if (stat == 0x1 || stat == 0x2 || 238c5722708SAndrew Vasquez stat == 0x10 || stat == 0x11) { 239c5722708SAndrew Vasquez set_bit(MBX_INTERRUPT, 240c5722708SAndrew Vasquez &ha->mbx_cmd_flags); 241c5722708SAndrew Vasquez 242c5722708SAndrew Vasquez mb0 = RD_REG_WORD(®->mailbox0); 243c5722708SAndrew Vasquez 244c5722708SAndrew Vasquez WRT_REG_DWORD(®->hccr, 245c5722708SAndrew Vasquez HCCRX_CLR_RISC_INT); 246c5722708SAndrew Vasquez RD_REG_DWORD(®->hccr); 247c5722708SAndrew Vasquez break; 248c5722708SAndrew Vasquez } 249c5722708SAndrew Vasquez 250c5722708SAndrew Vasquez /* Clear this intr; it wasn't a mailbox intr */ 251c5722708SAndrew Vasquez WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); 252c5722708SAndrew Vasquez RD_REG_DWORD(®->hccr); 253c5722708SAndrew Vasquez } 254c5722708SAndrew Vasquez udelay(5); 255c5722708SAndrew Vasquez } 256f73cb695SChad Dupuis ha->flags.mbox_int = 1; 257c5722708SAndrew Vasquez 258c5722708SAndrew Vasquez if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { 259c5722708SAndrew Vasquez rval = mb0 & MBS_MASK; 260c5722708SAndrew Vasquez for (idx = 0; idx < dwords; idx++) 261f73cb695SChad Dupuis ram[cnt + idx] = IS_QLA27XX(ha) ? 262f73cb695SChad Dupuis le32_to_cpu(dump[idx]) : swab32(dump[idx]); 263c5722708SAndrew Vasquez } else { 264c5722708SAndrew Vasquez rval = QLA_FUNCTION_FAILED; 265c5722708SAndrew Vasquez } 266c5722708SAndrew Vasquez } 267c5722708SAndrew Vasquez 268c5722708SAndrew Vasquez *nxt = rval == QLA_SUCCESS ? &ram[cnt]: NULL; 269c5722708SAndrew Vasquez return rval; 270c5722708SAndrew Vasquez } 271c5722708SAndrew Vasquez 272c5722708SAndrew Vasquez static int 2737b867cf7SAnirban Chakraborty qla24xx_dump_memory(struct qla_hw_data *ha, uint32_t *code_ram, 274c5722708SAndrew Vasquez uint32_t cram_size, void **nxt) 275c5722708SAndrew Vasquez { 276c5722708SAndrew Vasquez int rval; 277c3a2f0dfSAndrew Vasquez 278c3a2f0dfSAndrew Vasquez /* Code RAM. */ 279c5722708SAndrew Vasquez rval = qla24xx_dump_ram(ha, 0x20000, code_ram, cram_size / 4, nxt); 280c5722708SAndrew Vasquez if (rval != QLA_SUCCESS) 281c3a2f0dfSAndrew Vasquez return rval; 282c5722708SAndrew Vasquez 28361f098ddSHiral Patel set_bit(RISC_SRAM_DUMP_CMPL, &ha->fw_dump_cap_flags); 28461f098ddSHiral Patel 285c5722708SAndrew Vasquez /* External Memory. */ 28661f098ddSHiral Patel rval = qla24xx_dump_ram(ha, 0x100000, *nxt, 287c5722708SAndrew Vasquez ha->fw_memory_size - 0x100000 + 1, nxt); 28861f098ddSHiral Patel if (rval == QLA_SUCCESS) 28961f098ddSHiral Patel set_bit(RISC_EXT_MEM_DUMP_CMPL, &ha->fw_dump_cap_flags); 29061f098ddSHiral Patel 29161f098ddSHiral Patel return rval; 292c3a2f0dfSAndrew Vasquez } 293c3a2f0dfSAndrew Vasquez 294c81d04c9SAndrew Vasquez static uint32_t * 295c81d04c9SAndrew Vasquez qla24xx_read_window(struct device_reg_24xx __iomem *reg, uint32_t iobase, 296c81d04c9SAndrew Vasquez uint32_t count, uint32_t *buf) 297c81d04c9SAndrew Vasquez { 298c81d04c9SAndrew Vasquez uint32_t __iomem *dmp_reg; 299c81d04c9SAndrew Vasquez 300c81d04c9SAndrew Vasquez WRT_REG_DWORD(®->iobase_addr, iobase); 301c81d04c9SAndrew Vasquez dmp_reg = ®->iobase_window; 302c81d04c9SAndrew Vasquez while (count--) 303c81d04c9SAndrew Vasquez *buf++ = htonl(RD_REG_DWORD(dmp_reg++)); 304c81d04c9SAndrew Vasquez 305c81d04c9SAndrew Vasquez return buf; 306c81d04c9SAndrew Vasquez } 307c81d04c9SAndrew Vasquez 3082f389fc4SHiral Patel void 30961f098ddSHiral Patel qla24xx_pause_risc(struct device_reg_24xx __iomem *reg, struct qla_hw_data *ha) 310c81d04c9SAndrew Vasquez { 311c81d04c9SAndrew Vasquez WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_PAUSE); 312c81d04c9SAndrew Vasquez 3132f389fc4SHiral Patel /* 100 usec delay is sufficient enough for hardware to pause RISC */ 3142f389fc4SHiral Patel udelay(100); 31561f098ddSHiral Patel if (RD_REG_DWORD(®->host_status) & HSRX_RISC_PAUSED) 31661f098ddSHiral Patel set_bit(RISC_PAUSE_CMPL, &ha->fw_dump_cap_flags); 317c81d04c9SAndrew Vasquez } 318c81d04c9SAndrew Vasquez 319f73cb695SChad Dupuis int 3207b867cf7SAnirban Chakraborty qla24xx_soft_reset(struct qla_hw_data *ha) 321c81d04c9SAndrew Vasquez { 322c81d04c9SAndrew Vasquez int rval = QLA_SUCCESS; 323c81d04c9SAndrew Vasquez uint32_t cnt; 3242f389fc4SHiral Patel uint16_t wd; 325c81d04c9SAndrew Vasquez struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; 326c81d04c9SAndrew Vasquez 3272f389fc4SHiral Patel /* 3282f389fc4SHiral Patel * Reset RISC. The delay is dependent on system architecture. 3292f389fc4SHiral Patel * Driver can proceed with the reset sequence after waiting 3302f389fc4SHiral Patel * for a timeout period. 3312f389fc4SHiral Patel */ 332c81d04c9SAndrew Vasquez WRT_REG_DWORD(®->ctrl_status, CSRX_DMA_SHUTDOWN|MWB_4096_BYTES); 333c81d04c9SAndrew Vasquez for (cnt = 0; cnt < 30000; cnt++) { 334c81d04c9SAndrew Vasquez if ((RD_REG_DWORD(®->ctrl_status) & CSRX_DMA_ACTIVE) == 0) 335c81d04c9SAndrew Vasquez break; 336c81d04c9SAndrew Vasquez 337c81d04c9SAndrew Vasquez udelay(10); 338c81d04c9SAndrew Vasquez } 33961f098ddSHiral Patel if (!(RD_REG_DWORD(®->ctrl_status) & CSRX_DMA_ACTIVE)) 34061f098ddSHiral Patel set_bit(DMA_SHUTDOWN_CMPL, &ha->fw_dump_cap_flags); 341c81d04c9SAndrew Vasquez 342c81d04c9SAndrew Vasquez WRT_REG_DWORD(®->ctrl_status, 343c81d04c9SAndrew Vasquez CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES); 344c81d04c9SAndrew Vasquez pci_read_config_word(ha->pdev, PCI_COMMAND, &wd); 345c81d04c9SAndrew Vasquez 346c81d04c9SAndrew Vasquez udelay(100); 347c81d04c9SAndrew Vasquez 348c81d04c9SAndrew Vasquez /* Wait for soft-reset to complete. */ 349c81d04c9SAndrew Vasquez for (cnt = 0; cnt < 30000; cnt++) { 350c81d04c9SAndrew Vasquez if ((RD_REG_DWORD(®->ctrl_status) & 351c81d04c9SAndrew Vasquez CSRX_ISP_SOFT_RESET) == 0) 352c81d04c9SAndrew Vasquez break; 353c81d04c9SAndrew Vasquez 354c81d04c9SAndrew Vasquez udelay(10); 355c81d04c9SAndrew Vasquez } 35661f098ddSHiral Patel if (!(RD_REG_DWORD(®->ctrl_status) & CSRX_ISP_SOFT_RESET)) 35761f098ddSHiral Patel set_bit(ISP_RESET_CMPL, &ha->fw_dump_cap_flags); 35861f098ddSHiral Patel 359c81d04c9SAndrew Vasquez WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_RESET); 360c81d04c9SAndrew Vasquez RD_REG_DWORD(®->hccr); /* PCI Posting. */ 361c81d04c9SAndrew Vasquez 3622f389fc4SHiral Patel for (cnt = 10000; RD_REG_WORD(®->mailbox0) != 0 && 363c81d04c9SAndrew Vasquez rval == QLA_SUCCESS; cnt--) { 364c81d04c9SAndrew Vasquez if (cnt) 3652f389fc4SHiral Patel udelay(10); 366c81d04c9SAndrew Vasquez else 367c81d04c9SAndrew Vasquez rval = QLA_FUNCTION_TIMEOUT; 368c81d04c9SAndrew Vasquez } 36961f098ddSHiral Patel if (rval == QLA_SUCCESS) 37061f098ddSHiral Patel set_bit(RISC_RDY_AFT_RESET, &ha->fw_dump_cap_flags); 371c81d04c9SAndrew Vasquez 372c81d04c9SAndrew Vasquez return rval; 373c81d04c9SAndrew Vasquez } 374c81d04c9SAndrew Vasquez 375c5722708SAndrew Vasquez static int 3767b867cf7SAnirban Chakraborty qla2xxx_dump_ram(struct qla_hw_data *ha, uint32_t addr, uint16_t *ram, 377e18e963bSAndrew Vasquez uint32_t ram_words, void **nxt) 378c5722708SAndrew Vasquez { 379c5722708SAndrew Vasquez int rval; 380c5722708SAndrew Vasquez uint32_t cnt, stat, timer, words, idx; 381c5722708SAndrew Vasquez uint16_t mb0; 382c5722708SAndrew Vasquez struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; 383c5722708SAndrew Vasquez dma_addr_t dump_dma = ha->gid_list_dma; 384c5722708SAndrew Vasquez uint16_t *dump = (uint16_t *)ha->gid_list; 385c5722708SAndrew Vasquez 386c5722708SAndrew Vasquez rval = QLA_SUCCESS; 387c5722708SAndrew Vasquez mb0 = 0; 388c5722708SAndrew Vasquez 389c5722708SAndrew Vasquez WRT_MAILBOX_REG(ha, reg, 0, MBC_DUMP_RISC_RAM_EXTENDED); 390c5722708SAndrew Vasquez clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); 391c5722708SAndrew Vasquez 392642ef983SChad Dupuis words = qla2x00_gid_list_size(ha) / 2; 393c5722708SAndrew Vasquez for (cnt = 0; cnt < ram_words && rval == QLA_SUCCESS; 394c5722708SAndrew Vasquez cnt += words, addr += words) { 395c5722708SAndrew Vasquez if (cnt + words > ram_words) 396c5722708SAndrew Vasquez words = ram_words - cnt; 397c5722708SAndrew Vasquez 398c5722708SAndrew Vasquez WRT_MAILBOX_REG(ha, reg, 1, LSW(addr)); 399c5722708SAndrew Vasquez WRT_MAILBOX_REG(ha, reg, 8, MSW(addr)); 400c5722708SAndrew Vasquez 401c5722708SAndrew Vasquez WRT_MAILBOX_REG(ha, reg, 2, MSW(dump_dma)); 402c5722708SAndrew Vasquez WRT_MAILBOX_REG(ha, reg, 3, LSW(dump_dma)); 403c5722708SAndrew Vasquez WRT_MAILBOX_REG(ha, reg, 6, MSW(MSD(dump_dma))); 404c5722708SAndrew Vasquez WRT_MAILBOX_REG(ha, reg, 7, LSW(MSD(dump_dma))); 405c5722708SAndrew Vasquez 406c5722708SAndrew Vasquez WRT_MAILBOX_REG(ha, reg, 4, words); 407c5722708SAndrew Vasquez WRT_REG_WORD(®->hccr, HCCR_SET_HOST_INT); 408c5722708SAndrew Vasquez 409c5722708SAndrew Vasquez for (timer = 6000000; timer; timer--) { 410c5722708SAndrew Vasquez /* Check for pending interrupts. */ 411c5722708SAndrew Vasquez stat = RD_REG_DWORD(®->u.isp2300.host_status); 412c5722708SAndrew Vasquez if (stat & HSR_RISC_INT) { 413c5722708SAndrew Vasquez stat &= 0xff; 414c5722708SAndrew Vasquez 415c5722708SAndrew Vasquez if (stat == 0x1 || stat == 0x2) { 416c5722708SAndrew Vasquez set_bit(MBX_INTERRUPT, 417c5722708SAndrew Vasquez &ha->mbx_cmd_flags); 418c5722708SAndrew Vasquez 419c5722708SAndrew Vasquez mb0 = RD_MAILBOX_REG(ha, reg, 0); 420c5722708SAndrew Vasquez 421c5722708SAndrew Vasquez /* Release mailbox registers. */ 422c5722708SAndrew Vasquez WRT_REG_WORD(®->semaphore, 0); 423c5722708SAndrew Vasquez WRT_REG_WORD(®->hccr, 424c5722708SAndrew Vasquez HCCR_CLR_RISC_INT); 425c5722708SAndrew Vasquez RD_REG_WORD(®->hccr); 426c5722708SAndrew Vasquez break; 427c5722708SAndrew Vasquez } else if (stat == 0x10 || stat == 0x11) { 428c5722708SAndrew Vasquez set_bit(MBX_INTERRUPT, 429c5722708SAndrew Vasquez &ha->mbx_cmd_flags); 430c5722708SAndrew Vasquez 431c5722708SAndrew Vasquez mb0 = RD_MAILBOX_REG(ha, reg, 0); 432c5722708SAndrew Vasquez 433c5722708SAndrew Vasquez WRT_REG_WORD(®->hccr, 434c5722708SAndrew Vasquez HCCR_CLR_RISC_INT); 435c5722708SAndrew Vasquez RD_REG_WORD(®->hccr); 436c5722708SAndrew Vasquez break; 437c5722708SAndrew Vasquez } 438c5722708SAndrew Vasquez 439c5722708SAndrew Vasquez /* clear this intr; it wasn't a mailbox intr */ 440c5722708SAndrew Vasquez WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT); 441c5722708SAndrew Vasquez RD_REG_WORD(®->hccr); 442c5722708SAndrew Vasquez } 443c5722708SAndrew Vasquez udelay(5); 444c5722708SAndrew Vasquez } 445c5722708SAndrew Vasquez 446c5722708SAndrew Vasquez if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { 447c5722708SAndrew Vasquez rval = mb0 & MBS_MASK; 448c5722708SAndrew Vasquez for (idx = 0; idx < words; idx++) 449c5722708SAndrew Vasquez ram[cnt + idx] = swab16(dump[idx]); 450c5722708SAndrew Vasquez } else { 451c5722708SAndrew Vasquez rval = QLA_FUNCTION_FAILED; 452c5722708SAndrew Vasquez } 453c5722708SAndrew Vasquez } 454c5722708SAndrew Vasquez 455c5722708SAndrew Vasquez *nxt = rval == QLA_SUCCESS ? &ram[cnt]: NULL; 456c5722708SAndrew Vasquez return rval; 457c5722708SAndrew Vasquez } 458c5722708SAndrew Vasquez 459c81d04c9SAndrew Vasquez static inline void 460c81d04c9SAndrew Vasquez qla2xxx_read_window(struct device_reg_2xxx __iomem *reg, uint32_t count, 461c81d04c9SAndrew Vasquez uint16_t *buf) 462c81d04c9SAndrew Vasquez { 463c81d04c9SAndrew Vasquez uint16_t __iomem *dmp_reg = ®->u.isp2300.fb_cmd; 464c81d04c9SAndrew Vasquez 465c81d04c9SAndrew Vasquez while (count--) 466c81d04c9SAndrew Vasquez *buf++ = htons(RD_REG_WORD(dmp_reg++)); 467c81d04c9SAndrew Vasquez } 468c81d04c9SAndrew Vasquez 469bb99de67SAndrew Vasquez static inline void * 470bb99de67SAndrew Vasquez qla24xx_copy_eft(struct qla_hw_data *ha, void *ptr) 471bb99de67SAndrew Vasquez { 472bb99de67SAndrew Vasquez if (!ha->eft) 473bb99de67SAndrew Vasquez return ptr; 474bb99de67SAndrew Vasquez 475bb99de67SAndrew Vasquez memcpy(ptr, ha->eft, ntohl(ha->fw_dump->eft_size)); 476bb99de67SAndrew Vasquez return ptr + ntohl(ha->fw_dump->eft_size); 477bb99de67SAndrew Vasquez } 478bb99de67SAndrew Vasquez 479bb99de67SAndrew Vasquez static inline void * 480bb99de67SAndrew Vasquez qla25xx_copy_fce(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain) 481bb99de67SAndrew Vasquez { 482bb99de67SAndrew Vasquez uint32_t cnt; 483bb99de67SAndrew Vasquez uint32_t *iter_reg; 484bb99de67SAndrew Vasquez struct qla2xxx_fce_chain *fcec = ptr; 485bb99de67SAndrew Vasquez 486bb99de67SAndrew Vasquez if (!ha->fce) 487bb99de67SAndrew Vasquez return ptr; 488bb99de67SAndrew Vasquez 489bb99de67SAndrew Vasquez *last_chain = &fcec->type; 490bb99de67SAndrew Vasquez fcec->type = __constant_htonl(DUMP_CHAIN_FCE); 491bb99de67SAndrew Vasquez fcec->chain_size = htonl(sizeof(struct qla2xxx_fce_chain) + 492bb99de67SAndrew Vasquez fce_calc_size(ha->fce_bufs)); 493bb99de67SAndrew Vasquez fcec->size = htonl(fce_calc_size(ha->fce_bufs)); 494bb99de67SAndrew Vasquez fcec->addr_l = htonl(LSD(ha->fce_dma)); 495bb99de67SAndrew Vasquez fcec->addr_h = htonl(MSD(ha->fce_dma)); 496bb99de67SAndrew Vasquez 497bb99de67SAndrew Vasquez iter_reg = fcec->eregs; 498bb99de67SAndrew Vasquez for (cnt = 0; cnt < 8; cnt++) 499bb99de67SAndrew Vasquez *iter_reg++ = htonl(ha->fce_mb[cnt]); 500bb99de67SAndrew Vasquez 501bb99de67SAndrew Vasquez memcpy(iter_reg, ha->fce, ntohl(fcec->size)); 502bb99de67SAndrew Vasquez 5033cb0a67dSGiridhar Malavali return (char *)iter_reg + ntohl(fcec->size); 504bb99de67SAndrew Vasquez } 505bb99de67SAndrew Vasquez 506d63ab533SAndrew Vasquez static inline void * 5072d70c103SNicholas Bellinger qla2xxx_copy_atioqueues(struct qla_hw_data *ha, void *ptr, 5082d70c103SNicholas Bellinger uint32_t **last_chain) 5092d70c103SNicholas Bellinger { 5102d70c103SNicholas Bellinger struct qla2xxx_mqueue_chain *q; 5112d70c103SNicholas Bellinger struct qla2xxx_mqueue_header *qh; 5122d70c103SNicholas Bellinger uint32_t num_queues; 5132d70c103SNicholas Bellinger int que; 5142d70c103SNicholas Bellinger struct { 5152d70c103SNicholas Bellinger int length; 5162d70c103SNicholas Bellinger void *ring; 5172d70c103SNicholas Bellinger } aq, *aqp; 5182d70c103SNicholas Bellinger 51900876ae8SArun Easi if (!ha->tgt.atio_ring) 5202d70c103SNicholas Bellinger return ptr; 5212d70c103SNicholas Bellinger 5222d70c103SNicholas Bellinger num_queues = 1; 5232d70c103SNicholas Bellinger aqp = &aq; 5242d70c103SNicholas Bellinger aqp->length = ha->tgt.atio_q_length; 5252d70c103SNicholas Bellinger aqp->ring = ha->tgt.atio_ring; 5262d70c103SNicholas Bellinger 5272d70c103SNicholas Bellinger for (que = 0; que < num_queues; que++) { 5282d70c103SNicholas Bellinger /* aqp = ha->atio_q_map[que]; */ 5292d70c103SNicholas Bellinger q = ptr; 5302d70c103SNicholas Bellinger *last_chain = &q->type; 5312d70c103SNicholas Bellinger q->type = __constant_htonl(DUMP_CHAIN_QUEUE); 5322d70c103SNicholas Bellinger q->chain_size = htonl( 5332d70c103SNicholas Bellinger sizeof(struct qla2xxx_mqueue_chain) + 5342d70c103SNicholas Bellinger sizeof(struct qla2xxx_mqueue_header) + 5352d70c103SNicholas Bellinger (aqp->length * sizeof(request_t))); 5362d70c103SNicholas Bellinger ptr += sizeof(struct qla2xxx_mqueue_chain); 5372d70c103SNicholas Bellinger 5382d70c103SNicholas Bellinger /* Add header. */ 5392d70c103SNicholas Bellinger qh = ptr; 5402d70c103SNicholas Bellinger qh->queue = __constant_htonl(TYPE_ATIO_QUEUE); 5412d70c103SNicholas Bellinger qh->number = htonl(que); 5422d70c103SNicholas Bellinger qh->size = htonl(aqp->length * sizeof(request_t)); 5432d70c103SNicholas Bellinger ptr += sizeof(struct qla2xxx_mqueue_header); 5442d70c103SNicholas Bellinger 5452d70c103SNicholas Bellinger /* Add data. */ 5462d70c103SNicholas Bellinger memcpy(ptr, aqp->ring, aqp->length * sizeof(request_t)); 5472d70c103SNicholas Bellinger 5482d70c103SNicholas Bellinger ptr += aqp->length * sizeof(request_t); 5492d70c103SNicholas Bellinger } 5502d70c103SNicholas Bellinger 5512d70c103SNicholas Bellinger return ptr; 5522d70c103SNicholas Bellinger } 5532d70c103SNicholas Bellinger 5542d70c103SNicholas Bellinger static inline void * 555050c9bb1SGiridhar Malavali qla25xx_copy_mqueues(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain) 556050c9bb1SGiridhar Malavali { 557050c9bb1SGiridhar Malavali struct qla2xxx_mqueue_chain *q; 558050c9bb1SGiridhar Malavali struct qla2xxx_mqueue_header *qh; 559050c9bb1SGiridhar Malavali struct req_que *req; 560050c9bb1SGiridhar Malavali struct rsp_que *rsp; 561050c9bb1SGiridhar Malavali int que; 562050c9bb1SGiridhar Malavali 563050c9bb1SGiridhar Malavali if (!ha->mqenable) 564050c9bb1SGiridhar Malavali return ptr; 565050c9bb1SGiridhar Malavali 566050c9bb1SGiridhar Malavali /* Request queues */ 567050c9bb1SGiridhar Malavali for (que = 1; que < ha->max_req_queues; que++) { 568050c9bb1SGiridhar Malavali req = ha->req_q_map[que]; 569050c9bb1SGiridhar Malavali if (!req) 570050c9bb1SGiridhar Malavali break; 571050c9bb1SGiridhar Malavali 572050c9bb1SGiridhar Malavali /* Add chain. */ 573050c9bb1SGiridhar Malavali q = ptr; 574050c9bb1SGiridhar Malavali *last_chain = &q->type; 575050c9bb1SGiridhar Malavali q->type = __constant_htonl(DUMP_CHAIN_QUEUE); 576050c9bb1SGiridhar Malavali q->chain_size = htonl( 577050c9bb1SGiridhar Malavali sizeof(struct qla2xxx_mqueue_chain) + 578050c9bb1SGiridhar Malavali sizeof(struct qla2xxx_mqueue_header) + 579050c9bb1SGiridhar Malavali (req->length * sizeof(request_t))); 580050c9bb1SGiridhar Malavali ptr += sizeof(struct qla2xxx_mqueue_chain); 581050c9bb1SGiridhar Malavali 582050c9bb1SGiridhar Malavali /* Add header. */ 583050c9bb1SGiridhar Malavali qh = ptr; 584050c9bb1SGiridhar Malavali qh->queue = __constant_htonl(TYPE_REQUEST_QUEUE); 585050c9bb1SGiridhar Malavali qh->number = htonl(que); 586050c9bb1SGiridhar Malavali qh->size = htonl(req->length * sizeof(request_t)); 587050c9bb1SGiridhar Malavali ptr += sizeof(struct qla2xxx_mqueue_header); 588050c9bb1SGiridhar Malavali 589050c9bb1SGiridhar Malavali /* Add data. */ 590050c9bb1SGiridhar Malavali memcpy(ptr, req->ring, req->length * sizeof(request_t)); 591050c9bb1SGiridhar Malavali ptr += req->length * sizeof(request_t); 592050c9bb1SGiridhar Malavali } 593050c9bb1SGiridhar Malavali 594050c9bb1SGiridhar Malavali /* Response queues */ 595050c9bb1SGiridhar Malavali for (que = 1; que < ha->max_rsp_queues; que++) { 596050c9bb1SGiridhar Malavali rsp = ha->rsp_q_map[que]; 597050c9bb1SGiridhar Malavali if (!rsp) 598050c9bb1SGiridhar Malavali break; 599050c9bb1SGiridhar Malavali 600050c9bb1SGiridhar Malavali /* Add chain. */ 601050c9bb1SGiridhar Malavali q = ptr; 602050c9bb1SGiridhar Malavali *last_chain = &q->type; 603050c9bb1SGiridhar Malavali q->type = __constant_htonl(DUMP_CHAIN_QUEUE); 604050c9bb1SGiridhar Malavali q->chain_size = htonl( 605050c9bb1SGiridhar Malavali sizeof(struct qla2xxx_mqueue_chain) + 606050c9bb1SGiridhar Malavali sizeof(struct qla2xxx_mqueue_header) + 607050c9bb1SGiridhar Malavali (rsp->length * sizeof(response_t))); 608050c9bb1SGiridhar Malavali ptr += sizeof(struct qla2xxx_mqueue_chain); 609050c9bb1SGiridhar Malavali 610050c9bb1SGiridhar Malavali /* Add header. */ 611050c9bb1SGiridhar Malavali qh = ptr; 612050c9bb1SGiridhar Malavali qh->queue = __constant_htonl(TYPE_RESPONSE_QUEUE); 613050c9bb1SGiridhar Malavali qh->number = htonl(que); 614050c9bb1SGiridhar Malavali qh->size = htonl(rsp->length * sizeof(response_t)); 615050c9bb1SGiridhar Malavali ptr += sizeof(struct qla2xxx_mqueue_header); 616050c9bb1SGiridhar Malavali 617050c9bb1SGiridhar Malavali /* Add data. */ 618050c9bb1SGiridhar Malavali memcpy(ptr, rsp->ring, rsp->length * sizeof(response_t)); 619050c9bb1SGiridhar Malavali ptr += rsp->length * sizeof(response_t); 620050c9bb1SGiridhar Malavali } 621050c9bb1SGiridhar Malavali 622050c9bb1SGiridhar Malavali return ptr; 623050c9bb1SGiridhar Malavali } 624050c9bb1SGiridhar Malavali 625050c9bb1SGiridhar Malavali static inline void * 626d63ab533SAndrew Vasquez qla25xx_copy_mq(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain) 627d63ab533SAndrew Vasquez { 628d63ab533SAndrew Vasquez uint32_t cnt, que_idx; 6292afa19a9SAnirban Chakraborty uint8_t que_cnt; 630d63ab533SAndrew Vasquez struct qla2xxx_mq_chain *mq = ptr; 631da9b1d5cSAndrew Vasquez device_reg_t __iomem *reg; 632d63ab533SAndrew Vasquez 633f73cb695SChad Dupuis if (!ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha)) 634d63ab533SAndrew Vasquez return ptr; 635d63ab533SAndrew Vasquez 636d63ab533SAndrew Vasquez mq = ptr; 637d63ab533SAndrew Vasquez *last_chain = &mq->type; 638d63ab533SAndrew Vasquez mq->type = __constant_htonl(DUMP_CHAIN_MQ); 639d63ab533SAndrew Vasquez mq->chain_size = __constant_htonl(sizeof(struct qla2xxx_mq_chain)); 640d63ab533SAndrew Vasquez 6412afa19a9SAnirban Chakraborty que_cnt = ha->max_req_queues > ha->max_rsp_queues ? 6422afa19a9SAnirban Chakraborty ha->max_req_queues : ha->max_rsp_queues; 643d63ab533SAndrew Vasquez mq->count = htonl(que_cnt); 644d63ab533SAndrew Vasquez for (cnt = 0; cnt < que_cnt; cnt++) { 645da9b1d5cSAndrew Vasquez reg = ISP_QUE_REG(ha, cnt); 646d63ab533SAndrew Vasquez que_idx = cnt * 4; 647da9b1d5cSAndrew Vasquez mq->qregs[que_idx] = 648da9b1d5cSAndrew Vasquez htonl(RD_REG_DWORD(®->isp25mq.req_q_in)); 649da9b1d5cSAndrew Vasquez mq->qregs[que_idx+1] = 650da9b1d5cSAndrew Vasquez htonl(RD_REG_DWORD(®->isp25mq.req_q_out)); 651da9b1d5cSAndrew Vasquez mq->qregs[que_idx+2] = 652da9b1d5cSAndrew Vasquez htonl(RD_REG_DWORD(®->isp25mq.rsp_q_in)); 653da9b1d5cSAndrew Vasquez mq->qregs[que_idx+3] = 654da9b1d5cSAndrew Vasquez htonl(RD_REG_DWORD(®->isp25mq.rsp_q_out)); 655d63ab533SAndrew Vasquez } 656d63ab533SAndrew Vasquez 657d63ab533SAndrew Vasquez return ptr + sizeof(struct qla2xxx_mq_chain); 658d63ab533SAndrew Vasquez } 659d63ab533SAndrew Vasquez 66008de2844SGiridhar Malavali void 6613420d36cSAndrew Vasquez qla2xxx_dump_post_process(scsi_qla_host_t *vha, int rval) 6623420d36cSAndrew Vasquez { 6633420d36cSAndrew Vasquez struct qla_hw_data *ha = vha->hw; 6643420d36cSAndrew Vasquez 6653420d36cSAndrew Vasquez if (rval != QLA_SUCCESS) { 6667c3df132SSaurav Kashyap ql_log(ql_log_warn, vha, 0xd000, 66761f098ddSHiral Patel "Failed to dump firmware (%x), dump status flags (0x%lx).\n", 66861f098ddSHiral Patel rval, ha->fw_dump_cap_flags); 6693420d36cSAndrew Vasquez ha->fw_dumped = 0; 6703420d36cSAndrew Vasquez } else { 6717c3df132SSaurav Kashyap ql_log(ql_log_info, vha, 0xd001, 67261f098ddSHiral Patel "Firmware dump saved to temp buffer (%ld/%p), dump status flags (0x%lx).\n", 67361f098ddSHiral Patel vha->host_no, ha->fw_dump, ha->fw_dump_cap_flags); 6743420d36cSAndrew Vasquez ha->fw_dumped = 1; 6753420d36cSAndrew Vasquez qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP); 6763420d36cSAndrew Vasquez } 6773420d36cSAndrew Vasquez } 6783420d36cSAndrew Vasquez 6791da177e4SLinus Torvalds /** 6801da177e4SLinus Torvalds * qla2300_fw_dump() - Dumps binary data from the 2300 firmware. 6811da177e4SLinus Torvalds * @ha: HA context 6821da177e4SLinus Torvalds * @hardware_locked: Called with the hardware_lock 6831da177e4SLinus Torvalds */ 6841da177e4SLinus Torvalds void 6857b867cf7SAnirban Chakraborty qla2300_fw_dump(scsi_qla_host_t *vha, int hardware_locked) 6861da177e4SLinus Torvalds { 6871da177e4SLinus Torvalds int rval; 688c5722708SAndrew Vasquez uint32_t cnt; 6897b867cf7SAnirban Chakraborty struct qla_hw_data *ha = vha->hw; 6903d71644cSAndrew Vasquez struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; 6911da177e4SLinus Torvalds uint16_t __iomem *dmp_reg; 6921da177e4SLinus Torvalds unsigned long flags; 6931da177e4SLinus Torvalds struct qla2300_fw_dump *fw; 694c5722708SAndrew Vasquez void *nxt; 69573208dfdSAnirban Chakraborty struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); 6961da177e4SLinus Torvalds 6971da177e4SLinus Torvalds flags = 0; 6981da177e4SLinus Torvalds 6991da177e4SLinus Torvalds if (!hardware_locked) 7001da177e4SLinus Torvalds spin_lock_irqsave(&ha->hardware_lock, flags); 7011da177e4SLinus Torvalds 702d4e3e04dSAndrew Vasquez if (!ha->fw_dump) { 7037c3df132SSaurav Kashyap ql_log(ql_log_warn, vha, 0xd002, 7047c3df132SSaurav Kashyap "No buffer available for dump.\n"); 7051da177e4SLinus Torvalds goto qla2300_fw_dump_failed; 7061da177e4SLinus Torvalds } 7071da177e4SLinus Torvalds 708d4e3e04dSAndrew Vasquez if (ha->fw_dumped) { 7097c3df132SSaurav Kashyap ql_log(ql_log_warn, vha, 0xd003, 7107c3df132SSaurav Kashyap "Firmware has been previously dumped (%p) " 7117c3df132SSaurav Kashyap "-- ignoring request.\n", 7127c3df132SSaurav Kashyap ha->fw_dump); 7131da177e4SLinus Torvalds goto qla2300_fw_dump_failed; 7141da177e4SLinus Torvalds } 715a7a167bfSAndrew Vasquez fw = &ha->fw_dump->isp.isp23; 716a7a167bfSAndrew Vasquez qla2xxx_prep_dump(ha, ha->fw_dump); 7171da177e4SLinus Torvalds 7181da177e4SLinus Torvalds rval = QLA_SUCCESS; 719a7a167bfSAndrew Vasquez fw->hccr = htons(RD_REG_WORD(®->hccr)); 7201da177e4SLinus Torvalds 7211da177e4SLinus Torvalds /* Pause RISC. */ 7221da177e4SLinus Torvalds WRT_REG_WORD(®->hccr, HCCR_PAUSE_RISC); 7231da177e4SLinus Torvalds if (IS_QLA2300(ha)) { 7241da177e4SLinus Torvalds for (cnt = 30000; 7251da177e4SLinus Torvalds (RD_REG_WORD(®->hccr) & HCCR_RISC_PAUSE) == 0 && 7261da177e4SLinus Torvalds rval == QLA_SUCCESS; cnt--) { 7271da177e4SLinus Torvalds if (cnt) 7281da177e4SLinus Torvalds udelay(100); 7291da177e4SLinus Torvalds else 7301da177e4SLinus Torvalds rval = QLA_FUNCTION_TIMEOUT; 7311da177e4SLinus Torvalds } 7321da177e4SLinus Torvalds } else { 7331da177e4SLinus Torvalds RD_REG_WORD(®->hccr); /* PCI Posting. */ 7341da177e4SLinus Torvalds udelay(10); 7351da177e4SLinus Torvalds } 7361da177e4SLinus Torvalds 7371da177e4SLinus Torvalds if (rval == QLA_SUCCESS) { 738c81d04c9SAndrew Vasquez dmp_reg = ®->flash_address; 7391da177e4SLinus Torvalds for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++) 740a7a167bfSAndrew Vasquez fw->pbiu_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); 7411da177e4SLinus Torvalds 742c81d04c9SAndrew Vasquez dmp_reg = ®->u.isp2300.req_q_in; 7431da177e4SLinus Torvalds for (cnt = 0; cnt < sizeof(fw->risc_host_reg) / 2; cnt++) 744a7a167bfSAndrew Vasquez fw->risc_host_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); 7451da177e4SLinus Torvalds 746c81d04c9SAndrew Vasquez dmp_reg = ®->u.isp2300.mailbox0; 7471da177e4SLinus Torvalds for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) 748a7a167bfSAndrew Vasquez fw->mailbox_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); 7491da177e4SLinus Torvalds 7501da177e4SLinus Torvalds WRT_REG_WORD(®->ctrl_status, 0x40); 751c81d04c9SAndrew Vasquez qla2xxx_read_window(reg, 32, fw->resp_dma_reg); 7521da177e4SLinus Torvalds 7531da177e4SLinus Torvalds WRT_REG_WORD(®->ctrl_status, 0x50); 754c81d04c9SAndrew Vasquez qla2xxx_read_window(reg, 48, fw->dma_reg); 7551da177e4SLinus Torvalds 7561da177e4SLinus Torvalds WRT_REG_WORD(®->ctrl_status, 0x00); 757c81d04c9SAndrew Vasquez dmp_reg = ®->risc_hw; 7581da177e4SLinus Torvalds for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++) 759a7a167bfSAndrew Vasquez fw->risc_hdw_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); 7601da177e4SLinus Torvalds 7611da177e4SLinus Torvalds WRT_REG_WORD(®->pcr, 0x2000); 762c81d04c9SAndrew Vasquez qla2xxx_read_window(reg, 16, fw->risc_gp0_reg); 7631da177e4SLinus Torvalds 7641da177e4SLinus Torvalds WRT_REG_WORD(®->pcr, 0x2200); 765c81d04c9SAndrew Vasquez qla2xxx_read_window(reg, 16, fw->risc_gp1_reg); 7661da177e4SLinus Torvalds 7671da177e4SLinus Torvalds WRT_REG_WORD(®->pcr, 0x2400); 768c81d04c9SAndrew Vasquez qla2xxx_read_window(reg, 16, fw->risc_gp2_reg); 7691da177e4SLinus Torvalds 7701da177e4SLinus Torvalds WRT_REG_WORD(®->pcr, 0x2600); 771c81d04c9SAndrew Vasquez qla2xxx_read_window(reg, 16, fw->risc_gp3_reg); 7721da177e4SLinus Torvalds 7731da177e4SLinus Torvalds WRT_REG_WORD(®->pcr, 0x2800); 774c81d04c9SAndrew Vasquez qla2xxx_read_window(reg, 16, fw->risc_gp4_reg); 7751da177e4SLinus Torvalds 7761da177e4SLinus Torvalds WRT_REG_WORD(®->pcr, 0x2A00); 777c81d04c9SAndrew Vasquez qla2xxx_read_window(reg, 16, fw->risc_gp5_reg); 7781da177e4SLinus Torvalds 7791da177e4SLinus Torvalds WRT_REG_WORD(®->pcr, 0x2C00); 780c81d04c9SAndrew Vasquez qla2xxx_read_window(reg, 16, fw->risc_gp6_reg); 7811da177e4SLinus Torvalds 7821da177e4SLinus Torvalds WRT_REG_WORD(®->pcr, 0x2E00); 783c81d04c9SAndrew Vasquez qla2xxx_read_window(reg, 16, fw->risc_gp7_reg); 7841da177e4SLinus Torvalds 7851da177e4SLinus Torvalds WRT_REG_WORD(®->ctrl_status, 0x10); 786c81d04c9SAndrew Vasquez qla2xxx_read_window(reg, 64, fw->frame_buf_hdw_reg); 7871da177e4SLinus Torvalds 7881da177e4SLinus Torvalds WRT_REG_WORD(®->ctrl_status, 0x20); 789c81d04c9SAndrew Vasquez qla2xxx_read_window(reg, 64, fw->fpm_b0_reg); 7901da177e4SLinus Torvalds 7911da177e4SLinus Torvalds WRT_REG_WORD(®->ctrl_status, 0x30); 792c81d04c9SAndrew Vasquez qla2xxx_read_window(reg, 64, fw->fpm_b1_reg); 7931da177e4SLinus Torvalds 7941da177e4SLinus Torvalds /* Reset RISC. */ 7951da177e4SLinus Torvalds WRT_REG_WORD(®->ctrl_status, CSR_ISP_SOFT_RESET); 7961da177e4SLinus Torvalds for (cnt = 0; cnt < 30000; cnt++) { 7971da177e4SLinus Torvalds if ((RD_REG_WORD(®->ctrl_status) & 7981da177e4SLinus Torvalds CSR_ISP_SOFT_RESET) == 0) 7991da177e4SLinus Torvalds break; 8001da177e4SLinus Torvalds 8011da177e4SLinus Torvalds udelay(10); 8021da177e4SLinus Torvalds } 8031da177e4SLinus Torvalds } 8041da177e4SLinus Torvalds 8051da177e4SLinus Torvalds if (!IS_QLA2300(ha)) { 8061da177e4SLinus Torvalds for (cnt = 30000; RD_MAILBOX_REG(ha, reg, 0) != 0 && 8071da177e4SLinus Torvalds rval == QLA_SUCCESS; cnt--) { 8081da177e4SLinus Torvalds if (cnt) 8091da177e4SLinus Torvalds udelay(100); 8101da177e4SLinus Torvalds else 8111da177e4SLinus Torvalds rval = QLA_FUNCTION_TIMEOUT; 8121da177e4SLinus Torvalds } 8131da177e4SLinus Torvalds } 8141da177e4SLinus Torvalds 8151da177e4SLinus Torvalds /* Get RISC SRAM. */ 816c5722708SAndrew Vasquez if (rval == QLA_SUCCESS) 817c5722708SAndrew Vasquez rval = qla2xxx_dump_ram(ha, 0x800, fw->risc_ram, 818c5722708SAndrew Vasquez sizeof(fw->risc_ram) / 2, &nxt); 8191da177e4SLinus Torvalds 8201da177e4SLinus Torvalds /* Get stack SRAM. */ 821c5722708SAndrew Vasquez if (rval == QLA_SUCCESS) 822c5722708SAndrew Vasquez rval = qla2xxx_dump_ram(ha, 0x10000, fw->stack_ram, 823c5722708SAndrew Vasquez sizeof(fw->stack_ram) / 2, &nxt); 8241da177e4SLinus Torvalds 8251da177e4SLinus Torvalds /* Get data SRAM. */ 826c5722708SAndrew Vasquez if (rval == QLA_SUCCESS) 827c5722708SAndrew Vasquez rval = qla2xxx_dump_ram(ha, 0x11000, fw->data_ram, 828c5722708SAndrew Vasquez ha->fw_memory_size - 0x11000 + 1, &nxt); 8291da177e4SLinus Torvalds 830a7a167bfSAndrew Vasquez if (rval == QLA_SUCCESS) 83173208dfdSAnirban Chakraborty qla2xxx_copy_queues(ha, nxt); 832a7a167bfSAndrew Vasquez 8333420d36cSAndrew Vasquez qla2xxx_dump_post_process(base_vha, rval); 8341da177e4SLinus Torvalds 8351da177e4SLinus Torvalds qla2300_fw_dump_failed: 8361da177e4SLinus Torvalds if (!hardware_locked) 8371da177e4SLinus Torvalds spin_unlock_irqrestore(&ha->hardware_lock, flags); 8381da177e4SLinus Torvalds } 8391da177e4SLinus Torvalds 8401da177e4SLinus Torvalds /** 8411da177e4SLinus Torvalds * qla2100_fw_dump() - Dumps binary data from the 2100/2200 firmware. 8421da177e4SLinus Torvalds * @ha: HA context 8431da177e4SLinus Torvalds * @hardware_locked: Called with the hardware_lock 8441da177e4SLinus Torvalds */ 8451da177e4SLinus Torvalds void 8467b867cf7SAnirban Chakraborty qla2100_fw_dump(scsi_qla_host_t *vha, int hardware_locked) 8471da177e4SLinus Torvalds { 8481da177e4SLinus Torvalds int rval; 8491da177e4SLinus Torvalds uint32_t cnt, timer; 8501da177e4SLinus Torvalds uint16_t risc_address; 8511da177e4SLinus Torvalds uint16_t mb0, mb2; 8527b867cf7SAnirban Chakraborty struct qla_hw_data *ha = vha->hw; 8533d71644cSAndrew Vasquez struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; 8541da177e4SLinus Torvalds uint16_t __iomem *dmp_reg; 8551da177e4SLinus Torvalds unsigned long flags; 8561da177e4SLinus Torvalds struct qla2100_fw_dump *fw; 85773208dfdSAnirban Chakraborty struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); 8581da177e4SLinus Torvalds 8591da177e4SLinus Torvalds risc_address = 0; 8601da177e4SLinus Torvalds mb0 = mb2 = 0; 8611da177e4SLinus Torvalds flags = 0; 8621da177e4SLinus Torvalds 8631da177e4SLinus Torvalds if (!hardware_locked) 8641da177e4SLinus Torvalds spin_lock_irqsave(&ha->hardware_lock, flags); 8651da177e4SLinus Torvalds 866d4e3e04dSAndrew Vasquez if (!ha->fw_dump) { 8677c3df132SSaurav Kashyap ql_log(ql_log_warn, vha, 0xd004, 8687c3df132SSaurav Kashyap "No buffer available for dump.\n"); 8691da177e4SLinus Torvalds goto qla2100_fw_dump_failed; 8701da177e4SLinus Torvalds } 8711da177e4SLinus Torvalds 872d4e3e04dSAndrew Vasquez if (ha->fw_dumped) { 8737c3df132SSaurav Kashyap ql_log(ql_log_warn, vha, 0xd005, 8747c3df132SSaurav Kashyap "Firmware has been previously dumped (%p) " 8757c3df132SSaurav Kashyap "-- ignoring request.\n", 8767c3df132SSaurav Kashyap ha->fw_dump); 8771da177e4SLinus Torvalds goto qla2100_fw_dump_failed; 8781da177e4SLinus Torvalds } 879a7a167bfSAndrew Vasquez fw = &ha->fw_dump->isp.isp21; 880a7a167bfSAndrew Vasquez qla2xxx_prep_dump(ha, ha->fw_dump); 8811da177e4SLinus Torvalds 8821da177e4SLinus Torvalds rval = QLA_SUCCESS; 883a7a167bfSAndrew Vasquez fw->hccr = htons(RD_REG_WORD(®->hccr)); 8841da177e4SLinus Torvalds 8851da177e4SLinus Torvalds /* Pause RISC. */ 8861da177e4SLinus Torvalds WRT_REG_WORD(®->hccr, HCCR_PAUSE_RISC); 8871da177e4SLinus Torvalds for (cnt = 30000; (RD_REG_WORD(®->hccr) & HCCR_RISC_PAUSE) == 0 && 8881da177e4SLinus Torvalds rval == QLA_SUCCESS; cnt--) { 8891da177e4SLinus Torvalds if (cnt) 8901da177e4SLinus Torvalds udelay(100); 8911da177e4SLinus Torvalds else 8921da177e4SLinus Torvalds rval = QLA_FUNCTION_TIMEOUT; 8931da177e4SLinus Torvalds } 8941da177e4SLinus Torvalds if (rval == QLA_SUCCESS) { 895c81d04c9SAndrew Vasquez dmp_reg = ®->flash_address; 8961da177e4SLinus Torvalds for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++) 897a7a167bfSAndrew Vasquez fw->pbiu_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); 8981da177e4SLinus Torvalds 899c81d04c9SAndrew Vasquez dmp_reg = ®->u.isp2100.mailbox0; 9001da177e4SLinus Torvalds for (cnt = 0; cnt < ha->mbx_count; cnt++) { 901c81d04c9SAndrew Vasquez if (cnt == 8) 902c81d04c9SAndrew Vasquez dmp_reg = ®->u_end.isp2200.mailbox8; 903c81d04c9SAndrew Vasquez 904a7a167bfSAndrew Vasquez fw->mailbox_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); 9051da177e4SLinus Torvalds } 9061da177e4SLinus Torvalds 907c81d04c9SAndrew Vasquez dmp_reg = ®->u.isp2100.unused_2[0]; 9081da177e4SLinus Torvalds for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++) 909a7a167bfSAndrew Vasquez fw->dma_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); 9101da177e4SLinus Torvalds 9111da177e4SLinus Torvalds WRT_REG_WORD(®->ctrl_status, 0x00); 912c81d04c9SAndrew Vasquez dmp_reg = ®->risc_hw; 9131da177e4SLinus Torvalds for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++) 914a7a167bfSAndrew Vasquez fw->risc_hdw_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); 9151da177e4SLinus Torvalds 9161da177e4SLinus Torvalds WRT_REG_WORD(®->pcr, 0x2000); 917c81d04c9SAndrew Vasquez qla2xxx_read_window(reg, 16, fw->risc_gp0_reg); 9181da177e4SLinus Torvalds 9191da177e4SLinus Torvalds WRT_REG_WORD(®->pcr, 0x2100); 920c81d04c9SAndrew Vasquez qla2xxx_read_window(reg, 16, fw->risc_gp1_reg); 9211da177e4SLinus Torvalds 9221da177e4SLinus Torvalds WRT_REG_WORD(®->pcr, 0x2200); 923c81d04c9SAndrew Vasquez qla2xxx_read_window(reg, 16, fw->risc_gp2_reg); 9241da177e4SLinus Torvalds 9251da177e4SLinus Torvalds WRT_REG_WORD(®->pcr, 0x2300); 926c81d04c9SAndrew Vasquez qla2xxx_read_window(reg, 16, fw->risc_gp3_reg); 9271da177e4SLinus Torvalds 9281da177e4SLinus Torvalds WRT_REG_WORD(®->pcr, 0x2400); 929c81d04c9SAndrew Vasquez qla2xxx_read_window(reg, 16, fw->risc_gp4_reg); 9301da177e4SLinus Torvalds 9311da177e4SLinus Torvalds WRT_REG_WORD(®->pcr, 0x2500); 932c81d04c9SAndrew Vasquez qla2xxx_read_window(reg, 16, fw->risc_gp5_reg); 9331da177e4SLinus Torvalds 9341da177e4SLinus Torvalds WRT_REG_WORD(®->pcr, 0x2600); 935c81d04c9SAndrew Vasquez qla2xxx_read_window(reg, 16, fw->risc_gp6_reg); 9361da177e4SLinus Torvalds 9371da177e4SLinus Torvalds WRT_REG_WORD(®->pcr, 0x2700); 938c81d04c9SAndrew Vasquez qla2xxx_read_window(reg, 16, fw->risc_gp7_reg); 9391da177e4SLinus Torvalds 9401da177e4SLinus Torvalds WRT_REG_WORD(®->ctrl_status, 0x10); 941c81d04c9SAndrew Vasquez qla2xxx_read_window(reg, 16, fw->frame_buf_hdw_reg); 9421da177e4SLinus Torvalds 9431da177e4SLinus Torvalds WRT_REG_WORD(®->ctrl_status, 0x20); 944c81d04c9SAndrew Vasquez qla2xxx_read_window(reg, 64, fw->fpm_b0_reg); 9451da177e4SLinus Torvalds 9461da177e4SLinus Torvalds WRT_REG_WORD(®->ctrl_status, 0x30); 947c81d04c9SAndrew Vasquez qla2xxx_read_window(reg, 64, fw->fpm_b1_reg); 9481da177e4SLinus Torvalds 9491da177e4SLinus Torvalds /* Reset the ISP. */ 9501da177e4SLinus Torvalds WRT_REG_WORD(®->ctrl_status, CSR_ISP_SOFT_RESET); 9511da177e4SLinus Torvalds } 9521da177e4SLinus Torvalds 9531da177e4SLinus Torvalds for (cnt = 30000; RD_MAILBOX_REG(ha, reg, 0) != 0 && 9541da177e4SLinus Torvalds rval == QLA_SUCCESS; cnt--) { 9551da177e4SLinus Torvalds if (cnt) 9561da177e4SLinus Torvalds udelay(100); 9571da177e4SLinus Torvalds else 9581da177e4SLinus Torvalds rval = QLA_FUNCTION_TIMEOUT; 9591da177e4SLinus Torvalds } 9601da177e4SLinus Torvalds 9611da177e4SLinus Torvalds /* Pause RISC. */ 9621da177e4SLinus Torvalds if (rval == QLA_SUCCESS && (IS_QLA2200(ha) || (IS_QLA2100(ha) && 9631da177e4SLinus Torvalds (RD_REG_WORD(®->mctr) & (BIT_1 | BIT_0)) != 0))) { 9641da177e4SLinus Torvalds 9651da177e4SLinus Torvalds WRT_REG_WORD(®->hccr, HCCR_PAUSE_RISC); 9661da177e4SLinus Torvalds for (cnt = 30000; 9671da177e4SLinus Torvalds (RD_REG_WORD(®->hccr) & HCCR_RISC_PAUSE) == 0 && 9681da177e4SLinus Torvalds rval == QLA_SUCCESS; cnt--) { 9691da177e4SLinus Torvalds if (cnt) 9701da177e4SLinus Torvalds udelay(100); 9711da177e4SLinus Torvalds else 9721da177e4SLinus Torvalds rval = QLA_FUNCTION_TIMEOUT; 9731da177e4SLinus Torvalds } 9741da177e4SLinus Torvalds if (rval == QLA_SUCCESS) { 9751da177e4SLinus Torvalds /* Set memory configuration and timing. */ 9761da177e4SLinus Torvalds if (IS_QLA2100(ha)) 9771da177e4SLinus Torvalds WRT_REG_WORD(®->mctr, 0xf1); 9781da177e4SLinus Torvalds else 9791da177e4SLinus Torvalds WRT_REG_WORD(®->mctr, 0xf2); 9801da177e4SLinus Torvalds RD_REG_WORD(®->mctr); /* PCI Posting. */ 9811da177e4SLinus Torvalds 9821da177e4SLinus Torvalds /* Release RISC. */ 9831da177e4SLinus Torvalds WRT_REG_WORD(®->hccr, HCCR_RELEASE_RISC); 9841da177e4SLinus Torvalds } 9851da177e4SLinus Torvalds } 9861da177e4SLinus Torvalds 9871da177e4SLinus Torvalds if (rval == QLA_SUCCESS) { 9881da177e4SLinus Torvalds /* Get RISC SRAM. */ 9891da177e4SLinus Torvalds risc_address = 0x1000; 9901da177e4SLinus Torvalds WRT_MAILBOX_REG(ha, reg, 0, MBC_READ_RAM_WORD); 9911da177e4SLinus Torvalds clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); 9921da177e4SLinus Torvalds } 9931da177e4SLinus Torvalds for (cnt = 0; cnt < sizeof(fw->risc_ram) / 2 && rval == QLA_SUCCESS; 9941da177e4SLinus Torvalds cnt++, risc_address++) { 9951da177e4SLinus Torvalds WRT_MAILBOX_REG(ha, reg, 1, risc_address); 9961da177e4SLinus Torvalds WRT_REG_WORD(®->hccr, HCCR_SET_HOST_INT); 9971da177e4SLinus Torvalds 9981da177e4SLinus Torvalds for (timer = 6000000; timer != 0; timer--) { 9991da177e4SLinus Torvalds /* Check for pending interrupts. */ 10001da177e4SLinus Torvalds if (RD_REG_WORD(®->istatus) & ISR_RISC_INT) { 10011da177e4SLinus Torvalds if (RD_REG_WORD(®->semaphore) & BIT_0) { 10021da177e4SLinus Torvalds set_bit(MBX_INTERRUPT, 10031da177e4SLinus Torvalds &ha->mbx_cmd_flags); 10041da177e4SLinus Torvalds 10051da177e4SLinus Torvalds mb0 = RD_MAILBOX_REG(ha, reg, 0); 10061da177e4SLinus Torvalds mb2 = RD_MAILBOX_REG(ha, reg, 2); 10071da177e4SLinus Torvalds 10081da177e4SLinus Torvalds WRT_REG_WORD(®->semaphore, 0); 10091da177e4SLinus Torvalds WRT_REG_WORD(®->hccr, 10101da177e4SLinus Torvalds HCCR_CLR_RISC_INT); 10111da177e4SLinus Torvalds RD_REG_WORD(®->hccr); 10121da177e4SLinus Torvalds break; 10131da177e4SLinus Torvalds } 10141da177e4SLinus Torvalds WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT); 10151da177e4SLinus Torvalds RD_REG_WORD(®->hccr); 10161da177e4SLinus Torvalds } 10171da177e4SLinus Torvalds udelay(5); 10181da177e4SLinus Torvalds } 10191da177e4SLinus Torvalds 10201da177e4SLinus Torvalds if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) { 10211da177e4SLinus Torvalds rval = mb0 & MBS_MASK; 1022a7a167bfSAndrew Vasquez fw->risc_ram[cnt] = htons(mb2); 10231da177e4SLinus Torvalds } else { 10241da177e4SLinus Torvalds rval = QLA_FUNCTION_FAILED; 10251da177e4SLinus Torvalds } 10261da177e4SLinus Torvalds } 10271da177e4SLinus Torvalds 1028a7a167bfSAndrew Vasquez if (rval == QLA_SUCCESS) 102973208dfdSAnirban Chakraborty qla2xxx_copy_queues(ha, &fw->risc_ram[cnt]); 1030a7a167bfSAndrew Vasquez 10313420d36cSAndrew Vasquez qla2xxx_dump_post_process(base_vha, rval); 10321da177e4SLinus Torvalds 10331da177e4SLinus Torvalds qla2100_fw_dump_failed: 10341da177e4SLinus Torvalds if (!hardware_locked) 10351da177e4SLinus Torvalds spin_unlock_irqrestore(&ha->hardware_lock, flags); 10361da177e4SLinus Torvalds } 10371da177e4SLinus Torvalds 10386d9b61edSAndrew Vasquez void 10397b867cf7SAnirban Chakraborty qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) 10406d9b61edSAndrew Vasquez { 10416d9b61edSAndrew Vasquez int rval; 1042c3a2f0dfSAndrew Vasquez uint32_t cnt; 10436d9b61edSAndrew Vasquez uint32_t risc_address; 10447b867cf7SAnirban Chakraborty struct qla_hw_data *ha = vha->hw; 10456d9b61edSAndrew Vasquez struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; 10466d9b61edSAndrew Vasquez uint32_t __iomem *dmp_reg; 10476d9b61edSAndrew Vasquez uint32_t *iter_reg; 10486d9b61edSAndrew Vasquez uint16_t __iomem *mbx_reg; 10496d9b61edSAndrew Vasquez unsigned long flags; 10506d9b61edSAndrew Vasquez struct qla24xx_fw_dump *fw; 10516d9b61edSAndrew Vasquez uint32_t ext_mem_cnt; 1052c3a2f0dfSAndrew Vasquez void *nxt; 10532d70c103SNicholas Bellinger void *nxt_chain; 10542d70c103SNicholas Bellinger uint32_t *last_chain = NULL; 105573208dfdSAnirban Chakraborty struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); 10566d9b61edSAndrew Vasquez 10577ec0effdSAtul Deshmukh if (IS_P3P_TYPE(ha)) 1058a9083016SGiridhar Malavali return; 1059a9083016SGiridhar Malavali 10606d9b61edSAndrew Vasquez risc_address = ext_mem_cnt = 0; 10616d9b61edSAndrew Vasquez flags = 0; 106261f098ddSHiral Patel ha->fw_dump_cap_flags = 0; 10636d9b61edSAndrew Vasquez 10646d9b61edSAndrew Vasquez if (!hardware_locked) 10656d9b61edSAndrew Vasquez spin_lock_irqsave(&ha->hardware_lock, flags); 10666d9b61edSAndrew Vasquez 1067d4e3e04dSAndrew Vasquez if (!ha->fw_dump) { 10687c3df132SSaurav Kashyap ql_log(ql_log_warn, vha, 0xd006, 10697c3df132SSaurav Kashyap "No buffer available for dump.\n"); 10706d9b61edSAndrew Vasquez goto qla24xx_fw_dump_failed; 10716d9b61edSAndrew Vasquez } 10726d9b61edSAndrew Vasquez 10736d9b61edSAndrew Vasquez if (ha->fw_dumped) { 10747c3df132SSaurav Kashyap ql_log(ql_log_warn, vha, 0xd007, 10757c3df132SSaurav Kashyap "Firmware has been previously dumped (%p) " 10767c3df132SSaurav Kashyap "-- ignoring request.\n", 10777c3df132SSaurav Kashyap ha->fw_dump); 10786d9b61edSAndrew Vasquez goto qla24xx_fw_dump_failed; 10796d9b61edSAndrew Vasquez } 1080a7a167bfSAndrew Vasquez fw = &ha->fw_dump->isp.isp24; 1081a7a167bfSAndrew Vasquez qla2xxx_prep_dump(ha, ha->fw_dump); 10826d9b61edSAndrew Vasquez 1083a7a167bfSAndrew Vasquez fw->host_status = htonl(RD_REG_DWORD(®->host_status)); 10846d9b61edSAndrew Vasquez 10852f389fc4SHiral Patel /* 10862f389fc4SHiral Patel * Pause RISC. No need to track timeout, as resetting the chip 10872f389fc4SHiral Patel * is the right approach incase of pause timeout 10882f389fc4SHiral Patel */ 108961f098ddSHiral Patel qla24xx_pause_risc(reg, ha); 10906d9b61edSAndrew Vasquez 10916d9b61edSAndrew Vasquez /* Host interface registers. */ 1092c81d04c9SAndrew Vasquez dmp_reg = ®->flash_addr; 10936d9b61edSAndrew Vasquez for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++) 1094a7a167bfSAndrew Vasquez fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); 10956d9b61edSAndrew Vasquez 1096210d5350Sandrew.vasquez@qlogic.com /* Disable interrupts. */ 1097210d5350Sandrew.vasquez@qlogic.com WRT_REG_DWORD(®->ictrl, 0); 1098210d5350Sandrew.vasquez@qlogic.com RD_REG_DWORD(®->ictrl); 1099210d5350Sandrew.vasquez@qlogic.com 1100210d5350Sandrew.vasquez@qlogic.com /* Shadow registers. */ 1101210d5350Sandrew.vasquez@qlogic.com WRT_REG_DWORD(®->iobase_addr, 0x0F70); 1102210d5350Sandrew.vasquez@qlogic.com RD_REG_DWORD(®->iobase_addr); 1103c3a2f0dfSAndrew Vasquez WRT_REG_DWORD(®->iobase_select, 0xB0000000); 1104c3a2f0dfSAndrew Vasquez fw->shadow_reg[0] = htonl(RD_REG_DWORD(®->iobase_sdata)); 1105210d5350Sandrew.vasquez@qlogic.com 1106c3a2f0dfSAndrew Vasquez WRT_REG_DWORD(®->iobase_select, 0xB0100000); 1107c3a2f0dfSAndrew Vasquez fw->shadow_reg[1] = htonl(RD_REG_DWORD(®->iobase_sdata)); 1108210d5350Sandrew.vasquez@qlogic.com 1109c3a2f0dfSAndrew Vasquez WRT_REG_DWORD(®->iobase_select, 0xB0200000); 1110c3a2f0dfSAndrew Vasquez fw->shadow_reg[2] = htonl(RD_REG_DWORD(®->iobase_sdata)); 1111210d5350Sandrew.vasquez@qlogic.com 1112c3a2f0dfSAndrew Vasquez WRT_REG_DWORD(®->iobase_select, 0xB0300000); 1113c3a2f0dfSAndrew Vasquez fw->shadow_reg[3] = htonl(RD_REG_DWORD(®->iobase_sdata)); 1114210d5350Sandrew.vasquez@qlogic.com 1115c3a2f0dfSAndrew Vasquez WRT_REG_DWORD(®->iobase_select, 0xB0400000); 1116c3a2f0dfSAndrew Vasquez fw->shadow_reg[4] = htonl(RD_REG_DWORD(®->iobase_sdata)); 1117210d5350Sandrew.vasquez@qlogic.com 1118c3a2f0dfSAndrew Vasquez WRT_REG_DWORD(®->iobase_select, 0xB0500000); 1119c3a2f0dfSAndrew Vasquez fw->shadow_reg[5] = htonl(RD_REG_DWORD(®->iobase_sdata)); 1120210d5350Sandrew.vasquez@qlogic.com 1121c3a2f0dfSAndrew Vasquez WRT_REG_DWORD(®->iobase_select, 0xB0600000); 1122c3a2f0dfSAndrew Vasquez fw->shadow_reg[6] = htonl(RD_REG_DWORD(®->iobase_sdata)); 1123210d5350Sandrew.vasquez@qlogic.com 11246d9b61edSAndrew Vasquez /* Mailbox registers. */ 1125c3a2f0dfSAndrew Vasquez mbx_reg = ®->mailbox0; 11266d9b61edSAndrew Vasquez for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) 1127a7a167bfSAndrew Vasquez fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++)); 11286d9b61edSAndrew Vasquez 11296d9b61edSAndrew Vasquez /* Transfer sequence registers. */ 11306d9b61edSAndrew Vasquez iter_reg = fw->xseq_gp_reg; 1131c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg); 1132c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg); 1133c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg); 1134c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg); 1135c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg); 1136c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg); 1137c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg); 1138c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0xBF70, 16, iter_reg); 11396d9b61edSAndrew Vasquez 1140c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0xBFE0, 16, fw->xseq_0_reg); 1141c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg); 11426d9b61edSAndrew Vasquez 11436d9b61edSAndrew Vasquez /* Receive sequence registers. */ 11446d9b61edSAndrew Vasquez iter_reg = fw->rseq_gp_reg; 1145c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg); 1146c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg); 1147c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg); 1148c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg); 1149c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg); 1150c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg); 1151c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg); 1152c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0xFF70, 16, iter_reg); 11536d9b61edSAndrew Vasquez 1154c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0xFFD0, 16, fw->rseq_0_reg); 1155c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg); 1156c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg); 11576d9b61edSAndrew Vasquez 11586d9b61edSAndrew Vasquez /* Command DMA registers. */ 1159c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0x7100, 16, fw->cmd_dma_reg); 11606d9b61edSAndrew Vasquez 11616d9b61edSAndrew Vasquez /* Queues. */ 11626d9b61edSAndrew Vasquez iter_reg = fw->req0_dma_reg; 1163c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg); 1164c3a2f0dfSAndrew Vasquez dmp_reg = ®->iobase_q; 11656d9b61edSAndrew Vasquez for (cnt = 0; cnt < 7; cnt++) 1166a7a167bfSAndrew Vasquez *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); 11676d9b61edSAndrew Vasquez 11686d9b61edSAndrew Vasquez iter_reg = fw->resp0_dma_reg; 1169c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg); 1170c3a2f0dfSAndrew Vasquez dmp_reg = ®->iobase_q; 11716d9b61edSAndrew Vasquez for (cnt = 0; cnt < 7; cnt++) 1172a7a167bfSAndrew Vasquez *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); 11736d9b61edSAndrew Vasquez 11746d9b61edSAndrew Vasquez iter_reg = fw->req1_dma_reg; 1175c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg); 1176c3a2f0dfSAndrew Vasquez dmp_reg = ®->iobase_q; 11776d9b61edSAndrew Vasquez for (cnt = 0; cnt < 7; cnt++) 1178a7a167bfSAndrew Vasquez *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); 11796d9b61edSAndrew Vasquez 11806d9b61edSAndrew Vasquez /* Transmit DMA registers. */ 11816d9b61edSAndrew Vasquez iter_reg = fw->xmt0_dma_reg; 1182c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg); 1183c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0x7610, 16, iter_reg); 11846d9b61edSAndrew Vasquez 11856d9b61edSAndrew Vasquez iter_reg = fw->xmt1_dma_reg; 1186c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg); 1187c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0x7630, 16, iter_reg); 11886d9b61edSAndrew Vasquez 11896d9b61edSAndrew Vasquez iter_reg = fw->xmt2_dma_reg; 1190c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg); 1191c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0x7650, 16, iter_reg); 11926d9b61edSAndrew Vasquez 11936d9b61edSAndrew Vasquez iter_reg = fw->xmt3_dma_reg; 1194c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg); 1195c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0x7670, 16, iter_reg); 11966d9b61edSAndrew Vasquez 11976d9b61edSAndrew Vasquez iter_reg = fw->xmt4_dma_reg; 1198c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg); 1199c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0x7690, 16, iter_reg); 12006d9b61edSAndrew Vasquez 1201c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg); 12026d9b61edSAndrew Vasquez 12036d9b61edSAndrew Vasquez /* Receive DMA registers. */ 12046d9b61edSAndrew Vasquez iter_reg = fw->rcvt0_data_dma_reg; 1205c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg); 1206c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0x7710, 16, iter_reg); 12076d9b61edSAndrew Vasquez 12086d9b61edSAndrew Vasquez iter_reg = fw->rcvt1_data_dma_reg; 1209c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg); 1210c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0x7730, 16, iter_reg); 12116d9b61edSAndrew Vasquez 12126d9b61edSAndrew Vasquez /* RISC registers. */ 12136d9b61edSAndrew Vasquez iter_reg = fw->risc_gp_reg; 1214c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg); 1215c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg); 1216c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg); 1217c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg); 1218c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg); 1219c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg); 1220c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg); 1221c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0x0F70, 16, iter_reg); 12226d9b61edSAndrew Vasquez 12236d9b61edSAndrew Vasquez /* Local memory controller registers. */ 12246d9b61edSAndrew Vasquez iter_reg = fw->lmc_reg; 1225c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg); 1226c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg); 1227c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg); 1228c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg); 1229c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg); 1230c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg); 1231c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0x3060, 16, iter_reg); 12326d9b61edSAndrew Vasquez 12336d9b61edSAndrew Vasquez /* Fibre Protocol Module registers. */ 12346d9b61edSAndrew Vasquez iter_reg = fw->fpm_hdw_reg; 1235c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg); 1236c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg); 1237c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg); 1238c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg); 1239c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg); 1240c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg); 1241c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg); 1242c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg); 1243c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg); 1244c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg); 1245c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg); 1246c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0x40B0, 16, iter_reg); 12476d9b61edSAndrew Vasquez 12486d9b61edSAndrew Vasquez /* Frame Buffer registers. */ 12496d9b61edSAndrew Vasquez iter_reg = fw->fb_hdw_reg; 1250c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg); 1251c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg); 1252c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg); 1253c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg); 1254c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg); 1255c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg); 1256c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg); 1257c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg); 1258c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg); 1259c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg); 1260c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0x61B0, 16, iter_reg); 12616d9b61edSAndrew Vasquez 1262c81d04c9SAndrew Vasquez rval = qla24xx_soft_reset(ha); 1263c81d04c9SAndrew Vasquez if (rval != QLA_SUCCESS) 1264c81d04c9SAndrew Vasquez goto qla24xx_fw_dump_failed_0; 12656d9b61edSAndrew Vasquez 1266c81d04c9SAndrew Vasquez rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram), 1267c5722708SAndrew Vasquez &nxt); 1268c81d04c9SAndrew Vasquez if (rval != QLA_SUCCESS) 1269c81d04c9SAndrew Vasquez goto qla24xx_fw_dump_failed_0; 12706d9b61edSAndrew Vasquez 127173208dfdSAnirban Chakraborty nxt = qla2xxx_copy_queues(ha, nxt); 1272bb99de67SAndrew Vasquez 1273bb99de67SAndrew Vasquez qla24xx_copy_eft(ha, nxt); 1274a7a167bfSAndrew Vasquez 12752d70c103SNicholas Bellinger nxt_chain = (void *)ha->fw_dump + ha->chain_offset; 12762d70c103SNicholas Bellinger nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain); 12772d70c103SNicholas Bellinger if (last_chain) { 12782d70c103SNicholas Bellinger ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT); 12792d70c103SNicholas Bellinger *last_chain |= __constant_htonl(DUMP_CHAIN_LAST); 12802d70c103SNicholas Bellinger } 12812d70c103SNicholas Bellinger 12822d70c103SNicholas Bellinger /* Adjust valid length. */ 12832d70c103SNicholas Bellinger ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump); 12842d70c103SNicholas Bellinger 1285c81d04c9SAndrew Vasquez qla24xx_fw_dump_failed_0: 12863420d36cSAndrew Vasquez qla2xxx_dump_post_process(base_vha, rval); 12876d9b61edSAndrew Vasquez 12886d9b61edSAndrew Vasquez qla24xx_fw_dump_failed: 12896d9b61edSAndrew Vasquez if (!hardware_locked) 12906d9b61edSAndrew Vasquez spin_unlock_irqrestore(&ha->hardware_lock, flags); 12916d9b61edSAndrew Vasquez } 12926d9b61edSAndrew Vasquez 1293c3a2f0dfSAndrew Vasquez void 12947b867cf7SAnirban Chakraborty qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) 1295c3a2f0dfSAndrew Vasquez { 1296c3a2f0dfSAndrew Vasquez int rval; 1297c3a2f0dfSAndrew Vasquez uint32_t cnt; 1298c3a2f0dfSAndrew Vasquez uint32_t risc_address; 12997b867cf7SAnirban Chakraborty struct qla_hw_data *ha = vha->hw; 1300c3a2f0dfSAndrew Vasquez struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; 1301c3a2f0dfSAndrew Vasquez uint32_t __iomem *dmp_reg; 1302c3a2f0dfSAndrew Vasquez uint32_t *iter_reg; 1303c3a2f0dfSAndrew Vasquez uint16_t __iomem *mbx_reg; 1304c3a2f0dfSAndrew Vasquez unsigned long flags; 1305c3a2f0dfSAndrew Vasquez struct qla25xx_fw_dump *fw; 1306c3a2f0dfSAndrew Vasquez uint32_t ext_mem_cnt; 1307d63ab533SAndrew Vasquez void *nxt, *nxt_chain; 1308bb99de67SAndrew Vasquez uint32_t *last_chain = NULL; 130973208dfdSAnirban Chakraborty struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); 1310c3a2f0dfSAndrew Vasquez 1311c3a2f0dfSAndrew Vasquez risc_address = ext_mem_cnt = 0; 1312c3a2f0dfSAndrew Vasquez flags = 0; 131361f098ddSHiral Patel ha->fw_dump_cap_flags = 0; 1314c3a2f0dfSAndrew Vasquez 1315c3a2f0dfSAndrew Vasquez if (!hardware_locked) 1316c3a2f0dfSAndrew Vasquez spin_lock_irqsave(&ha->hardware_lock, flags); 1317c3a2f0dfSAndrew Vasquez 1318c3a2f0dfSAndrew Vasquez if (!ha->fw_dump) { 13197c3df132SSaurav Kashyap ql_log(ql_log_warn, vha, 0xd008, 13207c3df132SSaurav Kashyap "No buffer available for dump.\n"); 1321c3a2f0dfSAndrew Vasquez goto qla25xx_fw_dump_failed; 1322c3a2f0dfSAndrew Vasquez } 1323c3a2f0dfSAndrew Vasquez 1324c3a2f0dfSAndrew Vasquez if (ha->fw_dumped) { 13257c3df132SSaurav Kashyap ql_log(ql_log_warn, vha, 0xd009, 13267c3df132SSaurav Kashyap "Firmware has been previously dumped (%p) " 13277c3df132SSaurav Kashyap "-- ignoring request.\n", 13287c3df132SSaurav Kashyap ha->fw_dump); 1329c3a2f0dfSAndrew Vasquez goto qla25xx_fw_dump_failed; 1330c3a2f0dfSAndrew Vasquez } 1331c3a2f0dfSAndrew Vasquez fw = &ha->fw_dump->isp.isp25; 1332c3a2f0dfSAndrew Vasquez qla2xxx_prep_dump(ha, ha->fw_dump); 1333b5836927SAndrew Vasquez ha->fw_dump->version = __constant_htonl(2); 1334c3a2f0dfSAndrew Vasquez 1335c3a2f0dfSAndrew Vasquez fw->host_status = htonl(RD_REG_DWORD(®->host_status)); 1336c3a2f0dfSAndrew Vasquez 13372f389fc4SHiral Patel /* 13382f389fc4SHiral Patel * Pause RISC. No need to track timeout, as resetting the chip 13392f389fc4SHiral Patel * is the right approach incase of pause timeout 13402f389fc4SHiral Patel */ 134161f098ddSHiral Patel qla24xx_pause_risc(reg, ha); 1342c3a2f0dfSAndrew Vasquez 1343b5836927SAndrew Vasquez /* Host/Risc registers. */ 1344b5836927SAndrew Vasquez iter_reg = fw->host_risc_reg; 1345b5836927SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7000, 16, iter_reg); 1346b5836927SAndrew Vasquez qla24xx_read_window(reg, 0x7010, 16, iter_reg); 1347b5836927SAndrew Vasquez 1348b5836927SAndrew Vasquez /* PCIe registers. */ 1349b5836927SAndrew Vasquez WRT_REG_DWORD(®->iobase_addr, 0x7C00); 1350b5836927SAndrew Vasquez RD_REG_DWORD(®->iobase_addr); 1351b5836927SAndrew Vasquez WRT_REG_DWORD(®->iobase_window, 0x01); 1352b5836927SAndrew Vasquez dmp_reg = ®->iobase_c4; 1353b5836927SAndrew Vasquez fw->pcie_regs[0] = htonl(RD_REG_DWORD(dmp_reg++)); 1354b5836927SAndrew Vasquez fw->pcie_regs[1] = htonl(RD_REG_DWORD(dmp_reg++)); 1355b5836927SAndrew Vasquez fw->pcie_regs[2] = htonl(RD_REG_DWORD(dmp_reg)); 1356b5836927SAndrew Vasquez fw->pcie_regs[3] = htonl(RD_REG_DWORD(®->iobase_window)); 135773208dfdSAnirban Chakraborty 1358b5836927SAndrew Vasquez WRT_REG_DWORD(®->iobase_window, 0x00); 1359b5836927SAndrew Vasquez RD_REG_DWORD(®->iobase_window); 1360b5836927SAndrew Vasquez 1361c3a2f0dfSAndrew Vasquez /* Host interface registers. */ 1362c81d04c9SAndrew Vasquez dmp_reg = ®->flash_addr; 1363c3a2f0dfSAndrew Vasquez for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++) 1364c3a2f0dfSAndrew Vasquez fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); 1365c3a2f0dfSAndrew Vasquez 1366c3a2f0dfSAndrew Vasquez /* Disable interrupts. */ 1367c3a2f0dfSAndrew Vasquez WRT_REG_DWORD(®->ictrl, 0); 1368c3a2f0dfSAndrew Vasquez RD_REG_DWORD(®->ictrl); 1369c3a2f0dfSAndrew Vasquez 1370c3a2f0dfSAndrew Vasquez /* Shadow registers. */ 1371c3a2f0dfSAndrew Vasquez WRT_REG_DWORD(®->iobase_addr, 0x0F70); 1372c3a2f0dfSAndrew Vasquez RD_REG_DWORD(®->iobase_addr); 1373c3a2f0dfSAndrew Vasquez WRT_REG_DWORD(®->iobase_select, 0xB0000000); 1374c3a2f0dfSAndrew Vasquez fw->shadow_reg[0] = htonl(RD_REG_DWORD(®->iobase_sdata)); 1375c3a2f0dfSAndrew Vasquez 1376c3a2f0dfSAndrew Vasquez WRT_REG_DWORD(®->iobase_select, 0xB0100000); 1377c3a2f0dfSAndrew Vasquez fw->shadow_reg[1] = htonl(RD_REG_DWORD(®->iobase_sdata)); 1378c3a2f0dfSAndrew Vasquez 1379c3a2f0dfSAndrew Vasquez WRT_REG_DWORD(®->iobase_select, 0xB0200000); 1380c3a2f0dfSAndrew Vasquez fw->shadow_reg[2] = htonl(RD_REG_DWORD(®->iobase_sdata)); 1381c3a2f0dfSAndrew Vasquez 1382c3a2f0dfSAndrew Vasquez WRT_REG_DWORD(®->iobase_select, 0xB0300000); 1383c3a2f0dfSAndrew Vasquez fw->shadow_reg[3] = htonl(RD_REG_DWORD(®->iobase_sdata)); 1384c3a2f0dfSAndrew Vasquez 1385c3a2f0dfSAndrew Vasquez WRT_REG_DWORD(®->iobase_select, 0xB0400000); 1386c3a2f0dfSAndrew Vasquez fw->shadow_reg[4] = htonl(RD_REG_DWORD(®->iobase_sdata)); 1387c3a2f0dfSAndrew Vasquez 1388c3a2f0dfSAndrew Vasquez WRT_REG_DWORD(®->iobase_select, 0xB0500000); 1389c3a2f0dfSAndrew Vasquez fw->shadow_reg[5] = htonl(RD_REG_DWORD(®->iobase_sdata)); 1390c3a2f0dfSAndrew Vasquez 1391c3a2f0dfSAndrew Vasquez WRT_REG_DWORD(®->iobase_select, 0xB0600000); 1392c3a2f0dfSAndrew Vasquez fw->shadow_reg[6] = htonl(RD_REG_DWORD(®->iobase_sdata)); 1393c3a2f0dfSAndrew Vasquez 1394c3a2f0dfSAndrew Vasquez WRT_REG_DWORD(®->iobase_select, 0xB0700000); 1395c3a2f0dfSAndrew Vasquez fw->shadow_reg[7] = htonl(RD_REG_DWORD(®->iobase_sdata)); 1396c3a2f0dfSAndrew Vasquez 1397c3a2f0dfSAndrew Vasquez WRT_REG_DWORD(®->iobase_select, 0xB0800000); 1398c3a2f0dfSAndrew Vasquez fw->shadow_reg[8] = htonl(RD_REG_DWORD(®->iobase_sdata)); 1399c3a2f0dfSAndrew Vasquez 1400c3a2f0dfSAndrew Vasquez WRT_REG_DWORD(®->iobase_select, 0xB0900000); 1401c3a2f0dfSAndrew Vasquez fw->shadow_reg[9] = htonl(RD_REG_DWORD(®->iobase_sdata)); 1402c3a2f0dfSAndrew Vasquez 1403c3a2f0dfSAndrew Vasquez WRT_REG_DWORD(®->iobase_select, 0xB0A00000); 1404c3a2f0dfSAndrew Vasquez fw->shadow_reg[10] = htonl(RD_REG_DWORD(®->iobase_sdata)); 1405c3a2f0dfSAndrew Vasquez 1406c3a2f0dfSAndrew Vasquez /* RISC I/O register. */ 1407c3a2f0dfSAndrew Vasquez WRT_REG_DWORD(®->iobase_addr, 0x0010); 1408c3a2f0dfSAndrew Vasquez fw->risc_io_reg = htonl(RD_REG_DWORD(®->iobase_window)); 1409c3a2f0dfSAndrew Vasquez 1410c3a2f0dfSAndrew Vasquez /* Mailbox registers. */ 1411c3a2f0dfSAndrew Vasquez mbx_reg = ®->mailbox0; 1412c3a2f0dfSAndrew Vasquez for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) 1413c3a2f0dfSAndrew Vasquez fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++)); 1414c3a2f0dfSAndrew Vasquez 1415c3a2f0dfSAndrew Vasquez /* Transfer sequence registers. */ 1416c3a2f0dfSAndrew Vasquez iter_reg = fw->xseq_gp_reg; 1417c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg); 1418c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg); 1419c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg); 1420c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg); 1421c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg); 1422c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg); 1423c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg); 1424c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0xBF70, 16, iter_reg); 1425c3a2f0dfSAndrew Vasquez 1426c3a2f0dfSAndrew Vasquez iter_reg = fw->xseq_0_reg; 1427c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xBFC0, 16, iter_reg); 1428c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xBFD0, 16, iter_reg); 1429c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0xBFE0, 16, iter_reg); 1430c3a2f0dfSAndrew Vasquez 1431c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg); 1432c3a2f0dfSAndrew Vasquez 1433c3a2f0dfSAndrew Vasquez /* Receive sequence registers. */ 1434c3a2f0dfSAndrew Vasquez iter_reg = fw->rseq_gp_reg; 1435c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg); 1436c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg); 1437c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg); 1438c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg); 1439c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg); 1440c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg); 1441c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg); 1442c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0xFF70, 16, iter_reg); 1443c3a2f0dfSAndrew Vasquez 1444c3a2f0dfSAndrew Vasquez iter_reg = fw->rseq_0_reg; 1445c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xFFC0, 16, iter_reg); 1446c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0xFFD0, 16, iter_reg); 1447c3a2f0dfSAndrew Vasquez 1448c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg); 1449c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg); 1450c3a2f0dfSAndrew Vasquez 1451c3a2f0dfSAndrew Vasquez /* Auxiliary sequence registers. */ 1452c3a2f0dfSAndrew Vasquez iter_reg = fw->aseq_gp_reg; 1453c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xB000, 16, iter_reg); 1454c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xB010, 16, iter_reg); 1455c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xB020, 16, iter_reg); 1456c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xB030, 16, iter_reg); 1457c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xB040, 16, iter_reg); 1458c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xB050, 16, iter_reg); 1459c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xB060, 16, iter_reg); 1460c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0xB070, 16, iter_reg); 1461c3a2f0dfSAndrew Vasquez 1462c3a2f0dfSAndrew Vasquez iter_reg = fw->aseq_0_reg; 1463c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xB0C0, 16, iter_reg); 1464c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0xB0D0, 16, iter_reg); 1465c3a2f0dfSAndrew Vasquez 1466c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0xB0E0, 16, fw->aseq_1_reg); 1467c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0xB0F0, 16, fw->aseq_2_reg); 1468c3a2f0dfSAndrew Vasquez 1469c3a2f0dfSAndrew Vasquez /* Command DMA registers. */ 1470c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0x7100, 16, fw->cmd_dma_reg); 1471c3a2f0dfSAndrew Vasquez 1472c3a2f0dfSAndrew Vasquez /* Queues. */ 1473c3a2f0dfSAndrew Vasquez iter_reg = fw->req0_dma_reg; 1474c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg); 1475c3a2f0dfSAndrew Vasquez dmp_reg = ®->iobase_q; 1476c3a2f0dfSAndrew Vasquez for (cnt = 0; cnt < 7; cnt++) 1477c3a2f0dfSAndrew Vasquez *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); 1478c3a2f0dfSAndrew Vasquez 1479c3a2f0dfSAndrew Vasquez iter_reg = fw->resp0_dma_reg; 1480c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg); 1481c3a2f0dfSAndrew Vasquez dmp_reg = ®->iobase_q; 1482c3a2f0dfSAndrew Vasquez for (cnt = 0; cnt < 7; cnt++) 1483c3a2f0dfSAndrew Vasquez *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); 1484c3a2f0dfSAndrew Vasquez 1485c3a2f0dfSAndrew Vasquez iter_reg = fw->req1_dma_reg; 1486c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg); 1487c3a2f0dfSAndrew Vasquez dmp_reg = ®->iobase_q; 1488c3a2f0dfSAndrew Vasquez for (cnt = 0; cnt < 7; cnt++) 1489c3a2f0dfSAndrew Vasquez *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); 1490c3a2f0dfSAndrew Vasquez 1491c3a2f0dfSAndrew Vasquez /* Transmit DMA registers. */ 1492c3a2f0dfSAndrew Vasquez iter_reg = fw->xmt0_dma_reg; 1493c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg); 1494c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0x7610, 16, iter_reg); 1495c3a2f0dfSAndrew Vasquez 1496c3a2f0dfSAndrew Vasquez iter_reg = fw->xmt1_dma_reg; 1497c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg); 1498c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0x7630, 16, iter_reg); 1499c3a2f0dfSAndrew Vasquez 1500c3a2f0dfSAndrew Vasquez iter_reg = fw->xmt2_dma_reg; 1501c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg); 1502c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0x7650, 16, iter_reg); 1503c3a2f0dfSAndrew Vasquez 1504c3a2f0dfSAndrew Vasquez iter_reg = fw->xmt3_dma_reg; 1505c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg); 1506c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0x7670, 16, iter_reg); 1507c3a2f0dfSAndrew Vasquez 1508c3a2f0dfSAndrew Vasquez iter_reg = fw->xmt4_dma_reg; 1509c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg); 1510c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0x7690, 16, iter_reg); 1511c3a2f0dfSAndrew Vasquez 1512c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg); 1513c3a2f0dfSAndrew Vasquez 1514c3a2f0dfSAndrew Vasquez /* Receive DMA registers. */ 1515c3a2f0dfSAndrew Vasquez iter_reg = fw->rcvt0_data_dma_reg; 1516c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg); 1517c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0x7710, 16, iter_reg); 1518c3a2f0dfSAndrew Vasquez 1519c3a2f0dfSAndrew Vasquez iter_reg = fw->rcvt1_data_dma_reg; 1520c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg); 1521c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0x7730, 16, iter_reg); 1522c3a2f0dfSAndrew Vasquez 1523c3a2f0dfSAndrew Vasquez /* RISC registers. */ 1524c3a2f0dfSAndrew Vasquez iter_reg = fw->risc_gp_reg; 1525c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg); 1526c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg); 1527c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg); 1528c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg); 1529c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg); 1530c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg); 1531c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg); 1532c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0x0F70, 16, iter_reg); 1533c3a2f0dfSAndrew Vasquez 1534c3a2f0dfSAndrew Vasquez /* Local memory controller registers. */ 1535c3a2f0dfSAndrew Vasquez iter_reg = fw->lmc_reg; 1536c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg); 1537c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg); 1538c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg); 1539c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg); 1540c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg); 1541c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg); 1542c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x3060, 16, iter_reg); 1543c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0x3070, 16, iter_reg); 1544c3a2f0dfSAndrew Vasquez 1545c3a2f0dfSAndrew Vasquez /* Fibre Protocol Module registers. */ 1546c3a2f0dfSAndrew Vasquez iter_reg = fw->fpm_hdw_reg; 1547c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg); 1548c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg); 1549c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg); 1550c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg); 1551c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg); 1552c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg); 1553c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg); 1554c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg); 1555c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg); 1556c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg); 1557c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg); 1558c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0x40B0, 16, iter_reg); 1559c3a2f0dfSAndrew Vasquez 1560c3a2f0dfSAndrew Vasquez /* Frame Buffer registers. */ 1561c3a2f0dfSAndrew Vasquez iter_reg = fw->fb_hdw_reg; 1562c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg); 1563c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg); 1564c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg); 1565c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg); 1566c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg); 1567c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg); 1568c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg); 1569c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg); 1570c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg); 1571c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg); 1572c81d04c9SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg); 1573c81d04c9SAndrew Vasquez qla24xx_read_window(reg, 0x6F00, 16, iter_reg); 1574c3a2f0dfSAndrew Vasquez 1575d63ab533SAndrew Vasquez /* Multi queue registers */ 1576d63ab533SAndrew Vasquez nxt_chain = qla25xx_copy_mq(ha, (void *)ha->fw_dump + ha->chain_offset, 1577d63ab533SAndrew Vasquez &last_chain); 1578d63ab533SAndrew Vasquez 1579c81d04c9SAndrew Vasquez rval = qla24xx_soft_reset(ha); 1580c81d04c9SAndrew Vasquez if (rval != QLA_SUCCESS) 1581c81d04c9SAndrew Vasquez goto qla25xx_fw_dump_failed_0; 1582c3a2f0dfSAndrew Vasquez 1583c81d04c9SAndrew Vasquez rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram), 1584c5722708SAndrew Vasquez &nxt); 1585c81d04c9SAndrew Vasquez if (rval != QLA_SUCCESS) 1586c81d04c9SAndrew Vasquez goto qla25xx_fw_dump_failed_0; 1587c3a2f0dfSAndrew Vasquez 158873208dfdSAnirban Chakraborty nxt = qla2xxx_copy_queues(ha, nxt); 1589c3a2f0dfSAndrew Vasquez 15907f544d00SBart Van Assche qla24xx_copy_eft(ha, nxt); 1591df613b96SAndrew Vasquez 1592d63ab533SAndrew Vasquez /* Chain entries -- started with MQ. */ 1593050c9bb1SGiridhar Malavali nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain); 1594050c9bb1SGiridhar Malavali nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain); 15952d70c103SNicholas Bellinger nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain); 1596bb99de67SAndrew Vasquez if (last_chain) { 1597bb99de67SAndrew Vasquez ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT); 1598bb99de67SAndrew Vasquez *last_chain |= __constant_htonl(DUMP_CHAIN_LAST); 1599bb99de67SAndrew Vasquez } 1600df613b96SAndrew Vasquez 1601050c9bb1SGiridhar Malavali /* Adjust valid length. */ 1602050c9bb1SGiridhar Malavali ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump); 1603050c9bb1SGiridhar Malavali 1604c81d04c9SAndrew Vasquez qla25xx_fw_dump_failed_0: 16053420d36cSAndrew Vasquez qla2xxx_dump_post_process(base_vha, rval); 1606c3a2f0dfSAndrew Vasquez 1607c3a2f0dfSAndrew Vasquez qla25xx_fw_dump_failed: 1608c3a2f0dfSAndrew Vasquez if (!hardware_locked) 1609c3a2f0dfSAndrew Vasquez spin_unlock_irqrestore(&ha->hardware_lock, flags); 1610c3a2f0dfSAndrew Vasquez } 16113a03eb79SAndrew Vasquez 16123a03eb79SAndrew Vasquez void 16133a03eb79SAndrew Vasquez qla81xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) 16143a03eb79SAndrew Vasquez { 16153a03eb79SAndrew Vasquez int rval; 16163a03eb79SAndrew Vasquez uint32_t cnt; 16173a03eb79SAndrew Vasquez uint32_t risc_address; 16183a03eb79SAndrew Vasquez struct qla_hw_data *ha = vha->hw; 16193a03eb79SAndrew Vasquez struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; 16203a03eb79SAndrew Vasquez uint32_t __iomem *dmp_reg; 16213a03eb79SAndrew Vasquez uint32_t *iter_reg; 16223a03eb79SAndrew Vasquez uint16_t __iomem *mbx_reg; 16233a03eb79SAndrew Vasquez unsigned long flags; 16243a03eb79SAndrew Vasquez struct qla81xx_fw_dump *fw; 16253a03eb79SAndrew Vasquez uint32_t ext_mem_cnt; 16263a03eb79SAndrew Vasquez void *nxt, *nxt_chain; 16273a03eb79SAndrew Vasquez uint32_t *last_chain = NULL; 16283a03eb79SAndrew Vasquez struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); 16293a03eb79SAndrew Vasquez 16303a03eb79SAndrew Vasquez risc_address = ext_mem_cnt = 0; 16313a03eb79SAndrew Vasquez flags = 0; 163261f098ddSHiral Patel ha->fw_dump_cap_flags = 0; 16333a03eb79SAndrew Vasquez 16343a03eb79SAndrew Vasquez if (!hardware_locked) 16353a03eb79SAndrew Vasquez spin_lock_irqsave(&ha->hardware_lock, flags); 16363a03eb79SAndrew Vasquez 16373a03eb79SAndrew Vasquez if (!ha->fw_dump) { 16387c3df132SSaurav Kashyap ql_log(ql_log_warn, vha, 0xd00a, 16397c3df132SSaurav Kashyap "No buffer available for dump.\n"); 16403a03eb79SAndrew Vasquez goto qla81xx_fw_dump_failed; 16413a03eb79SAndrew Vasquez } 16423a03eb79SAndrew Vasquez 16433a03eb79SAndrew Vasquez if (ha->fw_dumped) { 16447c3df132SSaurav Kashyap ql_log(ql_log_warn, vha, 0xd00b, 16457c3df132SSaurav Kashyap "Firmware has been previously dumped (%p) " 16467c3df132SSaurav Kashyap "-- ignoring request.\n", 16477c3df132SSaurav Kashyap ha->fw_dump); 16483a03eb79SAndrew Vasquez goto qla81xx_fw_dump_failed; 16493a03eb79SAndrew Vasquez } 16503a03eb79SAndrew Vasquez fw = &ha->fw_dump->isp.isp81; 16513a03eb79SAndrew Vasquez qla2xxx_prep_dump(ha, ha->fw_dump); 16523a03eb79SAndrew Vasquez 16533a03eb79SAndrew Vasquez fw->host_status = htonl(RD_REG_DWORD(®->host_status)); 16543a03eb79SAndrew Vasquez 16552f389fc4SHiral Patel /* 16562f389fc4SHiral Patel * Pause RISC. No need to track timeout, as resetting the chip 16572f389fc4SHiral Patel * is the right approach incase of pause timeout 16582f389fc4SHiral Patel */ 165961f098ddSHiral Patel qla24xx_pause_risc(reg, ha); 16603a03eb79SAndrew Vasquez 16613a03eb79SAndrew Vasquez /* Host/Risc registers. */ 16623a03eb79SAndrew Vasquez iter_reg = fw->host_risc_reg; 16633a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7000, 16, iter_reg); 16643a03eb79SAndrew Vasquez qla24xx_read_window(reg, 0x7010, 16, iter_reg); 16653a03eb79SAndrew Vasquez 16663a03eb79SAndrew Vasquez /* PCIe registers. */ 16673a03eb79SAndrew Vasquez WRT_REG_DWORD(®->iobase_addr, 0x7C00); 16683a03eb79SAndrew Vasquez RD_REG_DWORD(®->iobase_addr); 16693a03eb79SAndrew Vasquez WRT_REG_DWORD(®->iobase_window, 0x01); 16703a03eb79SAndrew Vasquez dmp_reg = ®->iobase_c4; 16713a03eb79SAndrew Vasquez fw->pcie_regs[0] = htonl(RD_REG_DWORD(dmp_reg++)); 16723a03eb79SAndrew Vasquez fw->pcie_regs[1] = htonl(RD_REG_DWORD(dmp_reg++)); 16733a03eb79SAndrew Vasquez fw->pcie_regs[2] = htonl(RD_REG_DWORD(dmp_reg)); 16743a03eb79SAndrew Vasquez fw->pcie_regs[3] = htonl(RD_REG_DWORD(®->iobase_window)); 16753a03eb79SAndrew Vasquez 16763a03eb79SAndrew Vasquez WRT_REG_DWORD(®->iobase_window, 0x00); 16773a03eb79SAndrew Vasquez RD_REG_DWORD(®->iobase_window); 16783a03eb79SAndrew Vasquez 16793a03eb79SAndrew Vasquez /* Host interface registers. */ 16803a03eb79SAndrew Vasquez dmp_reg = ®->flash_addr; 16813a03eb79SAndrew Vasquez for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++) 16823a03eb79SAndrew Vasquez fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); 16833a03eb79SAndrew Vasquez 16843a03eb79SAndrew Vasquez /* Disable interrupts. */ 16853a03eb79SAndrew Vasquez WRT_REG_DWORD(®->ictrl, 0); 16863a03eb79SAndrew Vasquez RD_REG_DWORD(®->ictrl); 16873a03eb79SAndrew Vasquez 16883a03eb79SAndrew Vasquez /* Shadow registers. */ 16893a03eb79SAndrew Vasquez WRT_REG_DWORD(®->iobase_addr, 0x0F70); 16903a03eb79SAndrew Vasquez RD_REG_DWORD(®->iobase_addr); 16913a03eb79SAndrew Vasquez WRT_REG_DWORD(®->iobase_select, 0xB0000000); 16923a03eb79SAndrew Vasquez fw->shadow_reg[0] = htonl(RD_REG_DWORD(®->iobase_sdata)); 16933a03eb79SAndrew Vasquez 16943a03eb79SAndrew Vasquez WRT_REG_DWORD(®->iobase_select, 0xB0100000); 16953a03eb79SAndrew Vasquez fw->shadow_reg[1] = htonl(RD_REG_DWORD(®->iobase_sdata)); 16963a03eb79SAndrew Vasquez 16973a03eb79SAndrew Vasquez WRT_REG_DWORD(®->iobase_select, 0xB0200000); 16983a03eb79SAndrew Vasquez fw->shadow_reg[2] = htonl(RD_REG_DWORD(®->iobase_sdata)); 16993a03eb79SAndrew Vasquez 17003a03eb79SAndrew Vasquez WRT_REG_DWORD(®->iobase_select, 0xB0300000); 17013a03eb79SAndrew Vasquez fw->shadow_reg[3] = htonl(RD_REG_DWORD(®->iobase_sdata)); 17023a03eb79SAndrew Vasquez 17033a03eb79SAndrew Vasquez WRT_REG_DWORD(®->iobase_select, 0xB0400000); 17043a03eb79SAndrew Vasquez fw->shadow_reg[4] = htonl(RD_REG_DWORD(®->iobase_sdata)); 17053a03eb79SAndrew Vasquez 17063a03eb79SAndrew Vasquez WRT_REG_DWORD(®->iobase_select, 0xB0500000); 17073a03eb79SAndrew Vasquez fw->shadow_reg[5] = htonl(RD_REG_DWORD(®->iobase_sdata)); 17083a03eb79SAndrew Vasquez 17093a03eb79SAndrew Vasquez WRT_REG_DWORD(®->iobase_select, 0xB0600000); 17103a03eb79SAndrew Vasquez fw->shadow_reg[6] = htonl(RD_REG_DWORD(®->iobase_sdata)); 17113a03eb79SAndrew Vasquez 17123a03eb79SAndrew Vasquez WRT_REG_DWORD(®->iobase_select, 0xB0700000); 17133a03eb79SAndrew Vasquez fw->shadow_reg[7] = htonl(RD_REG_DWORD(®->iobase_sdata)); 17143a03eb79SAndrew Vasquez 17153a03eb79SAndrew Vasquez WRT_REG_DWORD(®->iobase_select, 0xB0800000); 17163a03eb79SAndrew Vasquez fw->shadow_reg[8] = htonl(RD_REG_DWORD(®->iobase_sdata)); 17173a03eb79SAndrew Vasquez 17183a03eb79SAndrew Vasquez WRT_REG_DWORD(®->iobase_select, 0xB0900000); 17193a03eb79SAndrew Vasquez fw->shadow_reg[9] = htonl(RD_REG_DWORD(®->iobase_sdata)); 17203a03eb79SAndrew Vasquez 17213a03eb79SAndrew Vasquez WRT_REG_DWORD(®->iobase_select, 0xB0A00000); 17223a03eb79SAndrew Vasquez fw->shadow_reg[10] = htonl(RD_REG_DWORD(®->iobase_sdata)); 17233a03eb79SAndrew Vasquez 17243a03eb79SAndrew Vasquez /* RISC I/O register. */ 17253a03eb79SAndrew Vasquez WRT_REG_DWORD(®->iobase_addr, 0x0010); 17263a03eb79SAndrew Vasquez fw->risc_io_reg = htonl(RD_REG_DWORD(®->iobase_window)); 17273a03eb79SAndrew Vasquez 17283a03eb79SAndrew Vasquez /* Mailbox registers. */ 17293a03eb79SAndrew Vasquez mbx_reg = ®->mailbox0; 17303a03eb79SAndrew Vasquez for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) 17313a03eb79SAndrew Vasquez fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++)); 17323a03eb79SAndrew Vasquez 17333a03eb79SAndrew Vasquez /* Transfer sequence registers. */ 17343a03eb79SAndrew Vasquez iter_reg = fw->xseq_gp_reg; 17353a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg); 17363a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg); 17373a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg); 17383a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg); 17393a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg); 17403a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg); 17413a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg); 17423a03eb79SAndrew Vasquez qla24xx_read_window(reg, 0xBF70, 16, iter_reg); 17433a03eb79SAndrew Vasquez 17443a03eb79SAndrew Vasquez iter_reg = fw->xseq_0_reg; 17453a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xBFC0, 16, iter_reg); 17463a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xBFD0, 16, iter_reg); 17473a03eb79SAndrew Vasquez qla24xx_read_window(reg, 0xBFE0, 16, iter_reg); 17483a03eb79SAndrew Vasquez 17493a03eb79SAndrew Vasquez qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg); 17503a03eb79SAndrew Vasquez 17513a03eb79SAndrew Vasquez /* Receive sequence registers. */ 17523a03eb79SAndrew Vasquez iter_reg = fw->rseq_gp_reg; 17533a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg); 17543a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg); 17553a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg); 17563a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg); 17573a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg); 17583a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg); 17593a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg); 17603a03eb79SAndrew Vasquez qla24xx_read_window(reg, 0xFF70, 16, iter_reg); 17613a03eb79SAndrew Vasquez 17623a03eb79SAndrew Vasquez iter_reg = fw->rseq_0_reg; 17633a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xFFC0, 16, iter_reg); 17643a03eb79SAndrew Vasquez qla24xx_read_window(reg, 0xFFD0, 16, iter_reg); 17653a03eb79SAndrew Vasquez 17663a03eb79SAndrew Vasquez qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg); 17673a03eb79SAndrew Vasquez qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg); 17683a03eb79SAndrew Vasquez 17693a03eb79SAndrew Vasquez /* Auxiliary sequence registers. */ 17703a03eb79SAndrew Vasquez iter_reg = fw->aseq_gp_reg; 17713a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xB000, 16, iter_reg); 17723a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xB010, 16, iter_reg); 17733a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xB020, 16, iter_reg); 17743a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xB030, 16, iter_reg); 17753a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xB040, 16, iter_reg); 17763a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xB050, 16, iter_reg); 17773a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xB060, 16, iter_reg); 17783a03eb79SAndrew Vasquez qla24xx_read_window(reg, 0xB070, 16, iter_reg); 17793a03eb79SAndrew Vasquez 17803a03eb79SAndrew Vasquez iter_reg = fw->aseq_0_reg; 17813a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0xB0C0, 16, iter_reg); 17823a03eb79SAndrew Vasquez qla24xx_read_window(reg, 0xB0D0, 16, iter_reg); 17833a03eb79SAndrew Vasquez 17843a03eb79SAndrew Vasquez qla24xx_read_window(reg, 0xB0E0, 16, fw->aseq_1_reg); 17853a03eb79SAndrew Vasquez qla24xx_read_window(reg, 0xB0F0, 16, fw->aseq_2_reg); 17863a03eb79SAndrew Vasquez 17873a03eb79SAndrew Vasquez /* Command DMA registers. */ 17883a03eb79SAndrew Vasquez qla24xx_read_window(reg, 0x7100, 16, fw->cmd_dma_reg); 17893a03eb79SAndrew Vasquez 17903a03eb79SAndrew Vasquez /* Queues. */ 17913a03eb79SAndrew Vasquez iter_reg = fw->req0_dma_reg; 17923a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg); 17933a03eb79SAndrew Vasquez dmp_reg = ®->iobase_q; 17943a03eb79SAndrew Vasquez for (cnt = 0; cnt < 7; cnt++) 17953a03eb79SAndrew Vasquez *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); 17963a03eb79SAndrew Vasquez 17973a03eb79SAndrew Vasquez iter_reg = fw->resp0_dma_reg; 17983a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg); 17993a03eb79SAndrew Vasquez dmp_reg = ®->iobase_q; 18003a03eb79SAndrew Vasquez for (cnt = 0; cnt < 7; cnt++) 18013a03eb79SAndrew Vasquez *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); 18023a03eb79SAndrew Vasquez 18033a03eb79SAndrew Vasquez iter_reg = fw->req1_dma_reg; 18043a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg); 18053a03eb79SAndrew Vasquez dmp_reg = ®->iobase_q; 18063a03eb79SAndrew Vasquez for (cnt = 0; cnt < 7; cnt++) 18073a03eb79SAndrew Vasquez *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); 18083a03eb79SAndrew Vasquez 18093a03eb79SAndrew Vasquez /* Transmit DMA registers. */ 18103a03eb79SAndrew Vasquez iter_reg = fw->xmt0_dma_reg; 18113a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg); 18123a03eb79SAndrew Vasquez qla24xx_read_window(reg, 0x7610, 16, iter_reg); 18133a03eb79SAndrew Vasquez 18143a03eb79SAndrew Vasquez iter_reg = fw->xmt1_dma_reg; 18153a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg); 18163a03eb79SAndrew Vasquez qla24xx_read_window(reg, 0x7630, 16, iter_reg); 18173a03eb79SAndrew Vasquez 18183a03eb79SAndrew Vasquez iter_reg = fw->xmt2_dma_reg; 18193a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg); 18203a03eb79SAndrew Vasquez qla24xx_read_window(reg, 0x7650, 16, iter_reg); 18213a03eb79SAndrew Vasquez 18223a03eb79SAndrew Vasquez iter_reg = fw->xmt3_dma_reg; 18233a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg); 18243a03eb79SAndrew Vasquez qla24xx_read_window(reg, 0x7670, 16, iter_reg); 18253a03eb79SAndrew Vasquez 18263a03eb79SAndrew Vasquez iter_reg = fw->xmt4_dma_reg; 18273a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg); 18283a03eb79SAndrew Vasquez qla24xx_read_window(reg, 0x7690, 16, iter_reg); 18293a03eb79SAndrew Vasquez 18303a03eb79SAndrew Vasquez qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg); 18313a03eb79SAndrew Vasquez 18323a03eb79SAndrew Vasquez /* Receive DMA registers. */ 18333a03eb79SAndrew Vasquez iter_reg = fw->rcvt0_data_dma_reg; 18343a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg); 18353a03eb79SAndrew Vasquez qla24xx_read_window(reg, 0x7710, 16, iter_reg); 18363a03eb79SAndrew Vasquez 18373a03eb79SAndrew Vasquez iter_reg = fw->rcvt1_data_dma_reg; 18383a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg); 18393a03eb79SAndrew Vasquez qla24xx_read_window(reg, 0x7730, 16, iter_reg); 18403a03eb79SAndrew Vasquez 18413a03eb79SAndrew Vasquez /* RISC registers. */ 18423a03eb79SAndrew Vasquez iter_reg = fw->risc_gp_reg; 18433a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg); 18443a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg); 18453a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg); 18463a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg); 18473a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg); 18483a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg); 18493a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg); 18503a03eb79SAndrew Vasquez qla24xx_read_window(reg, 0x0F70, 16, iter_reg); 18513a03eb79SAndrew Vasquez 18523a03eb79SAndrew Vasquez /* Local memory controller registers. */ 18533a03eb79SAndrew Vasquez iter_reg = fw->lmc_reg; 18543a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg); 18553a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg); 18563a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg); 18573a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg); 18583a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg); 18593a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg); 18603a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x3060, 16, iter_reg); 18613a03eb79SAndrew Vasquez qla24xx_read_window(reg, 0x3070, 16, iter_reg); 18623a03eb79SAndrew Vasquez 18633a03eb79SAndrew Vasquez /* Fibre Protocol Module registers. */ 18643a03eb79SAndrew Vasquez iter_reg = fw->fpm_hdw_reg; 18653a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg); 18663a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg); 18673a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg); 18683a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg); 18693a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg); 18703a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg); 18713a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg); 18723a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg); 18733a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg); 18743a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg); 18753a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg); 18763a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x40B0, 16, iter_reg); 18773a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x40C0, 16, iter_reg); 18783a03eb79SAndrew Vasquez qla24xx_read_window(reg, 0x40D0, 16, iter_reg); 18793a03eb79SAndrew Vasquez 18803a03eb79SAndrew Vasquez /* Frame Buffer registers. */ 18813a03eb79SAndrew Vasquez iter_reg = fw->fb_hdw_reg; 18823a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg); 18833a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg); 18843a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg); 18853a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg); 18863a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg); 18873a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg); 18883a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg); 18893a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg); 18903a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg); 18913a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg); 18923a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg); 18933a03eb79SAndrew Vasquez iter_reg = qla24xx_read_window(reg, 0x61C0, 16, iter_reg); 18943a03eb79SAndrew Vasquez qla24xx_read_window(reg, 0x6F00, 16, iter_reg); 18953a03eb79SAndrew Vasquez 18963a03eb79SAndrew Vasquez /* Multi queue registers */ 18973a03eb79SAndrew Vasquez nxt_chain = qla25xx_copy_mq(ha, (void *)ha->fw_dump + ha->chain_offset, 18983a03eb79SAndrew Vasquez &last_chain); 18993a03eb79SAndrew Vasquez 19003a03eb79SAndrew Vasquez rval = qla24xx_soft_reset(ha); 19013a03eb79SAndrew Vasquez if (rval != QLA_SUCCESS) 19023a03eb79SAndrew Vasquez goto qla81xx_fw_dump_failed_0; 19033a03eb79SAndrew Vasquez 19043a03eb79SAndrew Vasquez rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram), 19053a03eb79SAndrew Vasquez &nxt); 19063a03eb79SAndrew Vasquez if (rval != QLA_SUCCESS) 19073a03eb79SAndrew Vasquez goto qla81xx_fw_dump_failed_0; 19083a03eb79SAndrew Vasquez 19093a03eb79SAndrew Vasquez nxt = qla2xxx_copy_queues(ha, nxt); 19103a03eb79SAndrew Vasquez 19117f544d00SBart Van Assche qla24xx_copy_eft(ha, nxt); 19123a03eb79SAndrew Vasquez 19133a03eb79SAndrew Vasquez /* Chain entries -- started with MQ. */ 1914050c9bb1SGiridhar Malavali nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain); 1915050c9bb1SGiridhar Malavali nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain); 19162d70c103SNicholas Bellinger nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain); 19173a03eb79SAndrew Vasquez if (last_chain) { 19183a03eb79SAndrew Vasquez ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT); 19193a03eb79SAndrew Vasquez *last_chain |= __constant_htonl(DUMP_CHAIN_LAST); 19203a03eb79SAndrew Vasquez } 19213a03eb79SAndrew Vasquez 1922050c9bb1SGiridhar Malavali /* Adjust valid length. */ 1923050c9bb1SGiridhar Malavali ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump); 1924050c9bb1SGiridhar Malavali 19253a03eb79SAndrew Vasquez qla81xx_fw_dump_failed_0: 19263420d36cSAndrew Vasquez qla2xxx_dump_post_process(base_vha, rval); 19273a03eb79SAndrew Vasquez 19283a03eb79SAndrew Vasquez qla81xx_fw_dump_failed: 19293a03eb79SAndrew Vasquez if (!hardware_locked) 19303a03eb79SAndrew Vasquez spin_unlock_irqrestore(&ha->hardware_lock, flags); 19313a03eb79SAndrew Vasquez } 19323a03eb79SAndrew Vasquez 19336246b8a1SGiridhar Malavali void 19346246b8a1SGiridhar Malavali qla83xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) 19356246b8a1SGiridhar Malavali { 19366246b8a1SGiridhar Malavali int rval; 19376246b8a1SGiridhar Malavali uint32_t cnt, reg_data; 19386246b8a1SGiridhar Malavali uint32_t risc_address; 19396246b8a1SGiridhar Malavali struct qla_hw_data *ha = vha->hw; 19406246b8a1SGiridhar Malavali struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; 19416246b8a1SGiridhar Malavali uint32_t __iomem *dmp_reg; 19426246b8a1SGiridhar Malavali uint32_t *iter_reg; 19436246b8a1SGiridhar Malavali uint16_t __iomem *mbx_reg; 19446246b8a1SGiridhar Malavali unsigned long flags; 19456246b8a1SGiridhar Malavali struct qla83xx_fw_dump *fw; 19466246b8a1SGiridhar Malavali uint32_t ext_mem_cnt; 19476246b8a1SGiridhar Malavali void *nxt, *nxt_chain; 19486246b8a1SGiridhar Malavali uint32_t *last_chain = NULL; 19496246b8a1SGiridhar Malavali struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); 19506246b8a1SGiridhar Malavali 19516246b8a1SGiridhar Malavali risc_address = ext_mem_cnt = 0; 19526246b8a1SGiridhar Malavali flags = 0; 195361f098ddSHiral Patel ha->fw_dump_cap_flags = 0; 19546246b8a1SGiridhar Malavali 19556246b8a1SGiridhar Malavali if (!hardware_locked) 19566246b8a1SGiridhar Malavali spin_lock_irqsave(&ha->hardware_lock, flags); 19576246b8a1SGiridhar Malavali 19586246b8a1SGiridhar Malavali if (!ha->fw_dump) { 19596246b8a1SGiridhar Malavali ql_log(ql_log_warn, vha, 0xd00c, 19606246b8a1SGiridhar Malavali "No buffer available for dump!!!\n"); 19616246b8a1SGiridhar Malavali goto qla83xx_fw_dump_failed; 19626246b8a1SGiridhar Malavali } 19636246b8a1SGiridhar Malavali 19646246b8a1SGiridhar Malavali if (ha->fw_dumped) { 19656246b8a1SGiridhar Malavali ql_log(ql_log_warn, vha, 0xd00d, 19666246b8a1SGiridhar Malavali "Firmware has been previously dumped (%p) -- ignoring " 19676246b8a1SGiridhar Malavali "request...\n", ha->fw_dump); 19686246b8a1SGiridhar Malavali goto qla83xx_fw_dump_failed; 19696246b8a1SGiridhar Malavali } 19706246b8a1SGiridhar Malavali fw = &ha->fw_dump->isp.isp83; 19716246b8a1SGiridhar Malavali qla2xxx_prep_dump(ha, ha->fw_dump); 19726246b8a1SGiridhar Malavali 19736246b8a1SGiridhar Malavali fw->host_status = htonl(RD_REG_DWORD(®->host_status)); 19746246b8a1SGiridhar Malavali 19752f389fc4SHiral Patel /* 19762f389fc4SHiral Patel * Pause RISC. No need to track timeout, as resetting the chip 19772f389fc4SHiral Patel * is the right approach incase of pause timeout 19782f389fc4SHiral Patel */ 197961f098ddSHiral Patel qla24xx_pause_risc(reg, ha); 19806246b8a1SGiridhar Malavali 19816246b8a1SGiridhar Malavali WRT_REG_DWORD(®->iobase_addr, 0x6000); 19826246b8a1SGiridhar Malavali dmp_reg = ®->iobase_window; 19836246b8a1SGiridhar Malavali reg_data = RD_REG_DWORD(dmp_reg); 19846246b8a1SGiridhar Malavali WRT_REG_DWORD(dmp_reg, 0); 19856246b8a1SGiridhar Malavali 19866246b8a1SGiridhar Malavali dmp_reg = ®->unused_4_1[0]; 19876246b8a1SGiridhar Malavali reg_data = RD_REG_DWORD(dmp_reg); 19886246b8a1SGiridhar Malavali WRT_REG_DWORD(dmp_reg, 0); 19896246b8a1SGiridhar Malavali 19906246b8a1SGiridhar Malavali WRT_REG_DWORD(®->iobase_addr, 0x6010); 19916246b8a1SGiridhar Malavali dmp_reg = ®->unused_4_1[2]; 19926246b8a1SGiridhar Malavali reg_data = RD_REG_DWORD(dmp_reg); 19936246b8a1SGiridhar Malavali WRT_REG_DWORD(dmp_reg, 0); 19946246b8a1SGiridhar Malavali 19956246b8a1SGiridhar Malavali /* select PCR and disable ecc checking and correction */ 19966246b8a1SGiridhar Malavali WRT_REG_DWORD(®->iobase_addr, 0x0F70); 19976246b8a1SGiridhar Malavali RD_REG_DWORD(®->iobase_addr); 19986246b8a1SGiridhar Malavali WRT_REG_DWORD(®->iobase_select, 0x60000000); /* write to F0h = PCR */ 19996246b8a1SGiridhar Malavali 20006246b8a1SGiridhar Malavali /* Host/Risc registers. */ 20016246b8a1SGiridhar Malavali iter_reg = fw->host_risc_reg; 20026246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x7000, 16, iter_reg); 20036246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x7010, 16, iter_reg); 20046246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0x7040, 16, iter_reg); 20056246b8a1SGiridhar Malavali 20066246b8a1SGiridhar Malavali /* PCIe registers. */ 20076246b8a1SGiridhar Malavali WRT_REG_DWORD(®->iobase_addr, 0x7C00); 20086246b8a1SGiridhar Malavali RD_REG_DWORD(®->iobase_addr); 20096246b8a1SGiridhar Malavali WRT_REG_DWORD(®->iobase_window, 0x01); 20106246b8a1SGiridhar Malavali dmp_reg = ®->iobase_c4; 20116246b8a1SGiridhar Malavali fw->pcie_regs[0] = htonl(RD_REG_DWORD(dmp_reg++)); 20126246b8a1SGiridhar Malavali fw->pcie_regs[1] = htonl(RD_REG_DWORD(dmp_reg++)); 20136246b8a1SGiridhar Malavali fw->pcie_regs[2] = htonl(RD_REG_DWORD(dmp_reg)); 20146246b8a1SGiridhar Malavali fw->pcie_regs[3] = htonl(RD_REG_DWORD(®->iobase_window)); 20156246b8a1SGiridhar Malavali 20166246b8a1SGiridhar Malavali WRT_REG_DWORD(®->iobase_window, 0x00); 20176246b8a1SGiridhar Malavali RD_REG_DWORD(®->iobase_window); 20186246b8a1SGiridhar Malavali 20196246b8a1SGiridhar Malavali /* Host interface registers. */ 20206246b8a1SGiridhar Malavali dmp_reg = ®->flash_addr; 20216246b8a1SGiridhar Malavali for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++) 20226246b8a1SGiridhar Malavali fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); 20236246b8a1SGiridhar Malavali 20246246b8a1SGiridhar Malavali /* Disable interrupts. */ 20256246b8a1SGiridhar Malavali WRT_REG_DWORD(®->ictrl, 0); 20266246b8a1SGiridhar Malavali RD_REG_DWORD(®->ictrl); 20276246b8a1SGiridhar Malavali 20286246b8a1SGiridhar Malavali /* Shadow registers. */ 20296246b8a1SGiridhar Malavali WRT_REG_DWORD(®->iobase_addr, 0x0F70); 20306246b8a1SGiridhar Malavali RD_REG_DWORD(®->iobase_addr); 20316246b8a1SGiridhar Malavali WRT_REG_DWORD(®->iobase_select, 0xB0000000); 20326246b8a1SGiridhar Malavali fw->shadow_reg[0] = htonl(RD_REG_DWORD(®->iobase_sdata)); 20336246b8a1SGiridhar Malavali 20346246b8a1SGiridhar Malavali WRT_REG_DWORD(®->iobase_select, 0xB0100000); 20356246b8a1SGiridhar Malavali fw->shadow_reg[1] = htonl(RD_REG_DWORD(®->iobase_sdata)); 20366246b8a1SGiridhar Malavali 20376246b8a1SGiridhar Malavali WRT_REG_DWORD(®->iobase_select, 0xB0200000); 20386246b8a1SGiridhar Malavali fw->shadow_reg[2] = htonl(RD_REG_DWORD(®->iobase_sdata)); 20396246b8a1SGiridhar Malavali 20406246b8a1SGiridhar Malavali WRT_REG_DWORD(®->iobase_select, 0xB0300000); 20416246b8a1SGiridhar Malavali fw->shadow_reg[3] = htonl(RD_REG_DWORD(®->iobase_sdata)); 20426246b8a1SGiridhar Malavali 20436246b8a1SGiridhar Malavali WRT_REG_DWORD(®->iobase_select, 0xB0400000); 20446246b8a1SGiridhar Malavali fw->shadow_reg[4] = htonl(RD_REG_DWORD(®->iobase_sdata)); 20456246b8a1SGiridhar Malavali 20466246b8a1SGiridhar Malavali WRT_REG_DWORD(®->iobase_select, 0xB0500000); 20476246b8a1SGiridhar Malavali fw->shadow_reg[5] = htonl(RD_REG_DWORD(®->iobase_sdata)); 20486246b8a1SGiridhar Malavali 20496246b8a1SGiridhar Malavali WRT_REG_DWORD(®->iobase_select, 0xB0600000); 20506246b8a1SGiridhar Malavali fw->shadow_reg[6] = htonl(RD_REG_DWORD(®->iobase_sdata)); 20516246b8a1SGiridhar Malavali 20526246b8a1SGiridhar Malavali WRT_REG_DWORD(®->iobase_select, 0xB0700000); 20536246b8a1SGiridhar Malavali fw->shadow_reg[7] = htonl(RD_REG_DWORD(®->iobase_sdata)); 20546246b8a1SGiridhar Malavali 20556246b8a1SGiridhar Malavali WRT_REG_DWORD(®->iobase_select, 0xB0800000); 20566246b8a1SGiridhar Malavali fw->shadow_reg[8] = htonl(RD_REG_DWORD(®->iobase_sdata)); 20576246b8a1SGiridhar Malavali 20586246b8a1SGiridhar Malavali WRT_REG_DWORD(®->iobase_select, 0xB0900000); 20596246b8a1SGiridhar Malavali fw->shadow_reg[9] = htonl(RD_REG_DWORD(®->iobase_sdata)); 20606246b8a1SGiridhar Malavali 20616246b8a1SGiridhar Malavali WRT_REG_DWORD(®->iobase_select, 0xB0A00000); 20626246b8a1SGiridhar Malavali fw->shadow_reg[10] = htonl(RD_REG_DWORD(®->iobase_sdata)); 20636246b8a1SGiridhar Malavali 20646246b8a1SGiridhar Malavali /* RISC I/O register. */ 20656246b8a1SGiridhar Malavali WRT_REG_DWORD(®->iobase_addr, 0x0010); 20666246b8a1SGiridhar Malavali fw->risc_io_reg = htonl(RD_REG_DWORD(®->iobase_window)); 20676246b8a1SGiridhar Malavali 20686246b8a1SGiridhar Malavali /* Mailbox registers. */ 20696246b8a1SGiridhar Malavali mbx_reg = ®->mailbox0; 20706246b8a1SGiridhar Malavali for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) 20716246b8a1SGiridhar Malavali fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++)); 20726246b8a1SGiridhar Malavali 20736246b8a1SGiridhar Malavali /* Transfer sequence registers. */ 20746246b8a1SGiridhar Malavali iter_reg = fw->xseq_gp_reg; 20756246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xBE00, 16, iter_reg); 20766246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xBE10, 16, iter_reg); 20776246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xBE20, 16, iter_reg); 20786246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xBE30, 16, iter_reg); 20796246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xBE40, 16, iter_reg); 20806246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xBE50, 16, iter_reg); 20816246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xBE60, 16, iter_reg); 20826246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xBE70, 16, iter_reg); 20836246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg); 20846246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg); 20856246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg); 20866246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg); 20876246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg); 20886246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg); 20896246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg); 20906246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0xBF70, 16, iter_reg); 20916246b8a1SGiridhar Malavali 20926246b8a1SGiridhar Malavali iter_reg = fw->xseq_0_reg; 20936246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xBFC0, 16, iter_reg); 20946246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xBFD0, 16, iter_reg); 20956246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0xBFE0, 16, iter_reg); 20966246b8a1SGiridhar Malavali 20976246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg); 20986246b8a1SGiridhar Malavali 20996246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0xBEF0, 16, fw->xseq_2_reg); 21006246b8a1SGiridhar Malavali 21016246b8a1SGiridhar Malavali /* Receive sequence registers. */ 21026246b8a1SGiridhar Malavali iter_reg = fw->rseq_gp_reg; 21036246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xFE00, 16, iter_reg); 21046246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xFE10, 16, iter_reg); 21056246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xFE20, 16, iter_reg); 21066246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xFE30, 16, iter_reg); 21076246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xFE40, 16, iter_reg); 21086246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xFE50, 16, iter_reg); 21096246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xFE60, 16, iter_reg); 21106246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xFE70, 16, iter_reg); 21116246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg); 21126246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg); 21136246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg); 21146246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg); 21156246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg); 21166246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg); 21176246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg); 21186246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0xFF70, 16, iter_reg); 21196246b8a1SGiridhar Malavali 21206246b8a1SGiridhar Malavali iter_reg = fw->rseq_0_reg; 21216246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xFFC0, 16, iter_reg); 21226246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0xFFD0, 16, iter_reg); 21236246b8a1SGiridhar Malavali 21246246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg); 21256246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg); 21266246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0xFEF0, 16, fw->rseq_3_reg); 21276246b8a1SGiridhar Malavali 21286246b8a1SGiridhar Malavali /* Auxiliary sequence registers. */ 21296246b8a1SGiridhar Malavali iter_reg = fw->aseq_gp_reg; 21306246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xB000, 16, iter_reg); 21316246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xB010, 16, iter_reg); 21326246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xB020, 16, iter_reg); 21336246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xB030, 16, iter_reg); 21346246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xB040, 16, iter_reg); 21356246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xB050, 16, iter_reg); 21366246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xB060, 16, iter_reg); 21376246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xB070, 16, iter_reg); 21386246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xB100, 16, iter_reg); 21396246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xB110, 16, iter_reg); 21406246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xB120, 16, iter_reg); 21416246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xB130, 16, iter_reg); 21426246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xB140, 16, iter_reg); 21436246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xB150, 16, iter_reg); 21446246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xB160, 16, iter_reg); 21456246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0xB170, 16, iter_reg); 21466246b8a1SGiridhar Malavali 21476246b8a1SGiridhar Malavali iter_reg = fw->aseq_0_reg; 21486246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0xB0C0, 16, iter_reg); 21496246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0xB0D0, 16, iter_reg); 21506246b8a1SGiridhar Malavali 21516246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0xB0E0, 16, fw->aseq_1_reg); 21526246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0xB0F0, 16, fw->aseq_2_reg); 21536246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0xB1F0, 16, fw->aseq_3_reg); 21546246b8a1SGiridhar Malavali 21556246b8a1SGiridhar Malavali /* Command DMA registers. */ 21566246b8a1SGiridhar Malavali iter_reg = fw->cmd_dma_reg; 21576246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x7100, 16, iter_reg); 21586246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x7120, 16, iter_reg); 21596246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x7130, 16, iter_reg); 21606246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0x71F0, 16, iter_reg); 21616246b8a1SGiridhar Malavali 21626246b8a1SGiridhar Malavali /* Queues. */ 21636246b8a1SGiridhar Malavali iter_reg = fw->req0_dma_reg; 21646246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg); 21656246b8a1SGiridhar Malavali dmp_reg = ®->iobase_q; 21666246b8a1SGiridhar Malavali for (cnt = 0; cnt < 7; cnt++) 21676246b8a1SGiridhar Malavali *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); 21686246b8a1SGiridhar Malavali 21696246b8a1SGiridhar Malavali iter_reg = fw->resp0_dma_reg; 21706246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg); 21716246b8a1SGiridhar Malavali dmp_reg = ®->iobase_q; 21726246b8a1SGiridhar Malavali for (cnt = 0; cnt < 7; cnt++) 21736246b8a1SGiridhar Malavali *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); 21746246b8a1SGiridhar Malavali 21756246b8a1SGiridhar Malavali iter_reg = fw->req1_dma_reg; 21766246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg); 21776246b8a1SGiridhar Malavali dmp_reg = ®->iobase_q; 21786246b8a1SGiridhar Malavali for (cnt = 0; cnt < 7; cnt++) 21796246b8a1SGiridhar Malavali *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); 21806246b8a1SGiridhar Malavali 21816246b8a1SGiridhar Malavali /* Transmit DMA registers. */ 21826246b8a1SGiridhar Malavali iter_reg = fw->xmt0_dma_reg; 21836246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg); 21846246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0x7610, 16, iter_reg); 21856246b8a1SGiridhar Malavali 21866246b8a1SGiridhar Malavali iter_reg = fw->xmt1_dma_reg; 21876246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg); 21886246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0x7630, 16, iter_reg); 21896246b8a1SGiridhar Malavali 21906246b8a1SGiridhar Malavali iter_reg = fw->xmt2_dma_reg; 21916246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg); 21926246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0x7650, 16, iter_reg); 21936246b8a1SGiridhar Malavali 21946246b8a1SGiridhar Malavali iter_reg = fw->xmt3_dma_reg; 21956246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg); 21966246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0x7670, 16, iter_reg); 21976246b8a1SGiridhar Malavali 21986246b8a1SGiridhar Malavali iter_reg = fw->xmt4_dma_reg; 21996246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg); 22006246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0x7690, 16, iter_reg); 22016246b8a1SGiridhar Malavali 22026246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg); 22036246b8a1SGiridhar Malavali 22046246b8a1SGiridhar Malavali /* Receive DMA registers. */ 22056246b8a1SGiridhar Malavali iter_reg = fw->rcvt0_data_dma_reg; 22066246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg); 22076246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0x7710, 16, iter_reg); 22086246b8a1SGiridhar Malavali 22096246b8a1SGiridhar Malavali iter_reg = fw->rcvt1_data_dma_reg; 22106246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg); 22116246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0x7730, 16, iter_reg); 22126246b8a1SGiridhar Malavali 22136246b8a1SGiridhar Malavali /* RISC registers. */ 22146246b8a1SGiridhar Malavali iter_reg = fw->risc_gp_reg; 22156246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg); 22166246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg); 22176246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg); 22186246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg); 22196246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg); 22206246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg); 22216246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg); 22226246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0x0F70, 16, iter_reg); 22236246b8a1SGiridhar Malavali 22246246b8a1SGiridhar Malavali /* Local memory controller registers. */ 22256246b8a1SGiridhar Malavali iter_reg = fw->lmc_reg; 22266246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg); 22276246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg); 22286246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg); 22296246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg); 22306246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg); 22316246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg); 22326246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x3060, 16, iter_reg); 22336246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0x3070, 16, iter_reg); 22346246b8a1SGiridhar Malavali 22356246b8a1SGiridhar Malavali /* Fibre Protocol Module registers. */ 22366246b8a1SGiridhar Malavali iter_reg = fw->fpm_hdw_reg; 22376246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg); 22386246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg); 22396246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg); 22406246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg); 22416246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg); 22426246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg); 22436246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg); 22446246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg); 22456246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg); 22466246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg); 22476246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg); 22486246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x40B0, 16, iter_reg); 22496246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x40C0, 16, iter_reg); 22506246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x40D0, 16, iter_reg); 22516246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x40E0, 16, iter_reg); 22526246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0x40F0, 16, iter_reg); 22536246b8a1SGiridhar Malavali 22546246b8a1SGiridhar Malavali /* RQ0 Array registers. */ 22556246b8a1SGiridhar Malavali iter_reg = fw->rq0_array_reg; 22566246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5C00, 16, iter_reg); 22576246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5C10, 16, iter_reg); 22586246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5C20, 16, iter_reg); 22596246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5C30, 16, iter_reg); 22606246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5C40, 16, iter_reg); 22616246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5C50, 16, iter_reg); 22626246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5C60, 16, iter_reg); 22636246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5C70, 16, iter_reg); 22646246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5C80, 16, iter_reg); 22656246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5C90, 16, iter_reg); 22666246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5CA0, 16, iter_reg); 22676246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5CB0, 16, iter_reg); 22686246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5CC0, 16, iter_reg); 22696246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5CD0, 16, iter_reg); 22706246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5CE0, 16, iter_reg); 22716246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0x5CF0, 16, iter_reg); 22726246b8a1SGiridhar Malavali 22736246b8a1SGiridhar Malavali /* RQ1 Array registers. */ 22746246b8a1SGiridhar Malavali iter_reg = fw->rq1_array_reg; 22756246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5D00, 16, iter_reg); 22766246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5D10, 16, iter_reg); 22776246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5D20, 16, iter_reg); 22786246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5D30, 16, iter_reg); 22796246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5D40, 16, iter_reg); 22806246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5D50, 16, iter_reg); 22816246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5D60, 16, iter_reg); 22826246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5D70, 16, iter_reg); 22836246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5D80, 16, iter_reg); 22846246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5D90, 16, iter_reg); 22856246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5DA0, 16, iter_reg); 22866246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5DB0, 16, iter_reg); 22876246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5DC0, 16, iter_reg); 22886246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5DD0, 16, iter_reg); 22896246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5DE0, 16, iter_reg); 22906246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0x5DF0, 16, iter_reg); 22916246b8a1SGiridhar Malavali 22926246b8a1SGiridhar Malavali /* RP0 Array registers. */ 22936246b8a1SGiridhar Malavali iter_reg = fw->rp0_array_reg; 22946246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5E00, 16, iter_reg); 22956246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5E10, 16, iter_reg); 22966246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5E20, 16, iter_reg); 22976246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5E30, 16, iter_reg); 22986246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5E40, 16, iter_reg); 22996246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5E50, 16, iter_reg); 23006246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5E60, 16, iter_reg); 23016246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5E70, 16, iter_reg); 23026246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5E80, 16, iter_reg); 23036246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5E90, 16, iter_reg); 23046246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5EA0, 16, iter_reg); 23056246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5EB0, 16, iter_reg); 23066246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5EC0, 16, iter_reg); 23076246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5ED0, 16, iter_reg); 23086246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5EE0, 16, iter_reg); 23096246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0x5EF0, 16, iter_reg); 23106246b8a1SGiridhar Malavali 23116246b8a1SGiridhar Malavali /* RP1 Array registers. */ 23126246b8a1SGiridhar Malavali iter_reg = fw->rp1_array_reg; 23136246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5F00, 16, iter_reg); 23146246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5F10, 16, iter_reg); 23156246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5F20, 16, iter_reg); 23166246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5F30, 16, iter_reg); 23176246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5F40, 16, iter_reg); 23186246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5F50, 16, iter_reg); 23196246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5F60, 16, iter_reg); 23206246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5F70, 16, iter_reg); 23216246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5F80, 16, iter_reg); 23226246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5F90, 16, iter_reg); 23236246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5FA0, 16, iter_reg); 23246246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5FB0, 16, iter_reg); 23256246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5FC0, 16, iter_reg); 23266246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5FD0, 16, iter_reg); 23276246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x5FE0, 16, iter_reg); 23286246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0x5FF0, 16, iter_reg); 23296246b8a1SGiridhar Malavali 23306246b8a1SGiridhar Malavali iter_reg = fw->at0_array_reg; 23316246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x7080, 16, iter_reg); 23326246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x7090, 16, iter_reg); 23336246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x70A0, 16, iter_reg); 23346246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x70B0, 16, iter_reg); 23356246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x70C0, 16, iter_reg); 23366246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x70D0, 16, iter_reg); 23376246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x70E0, 16, iter_reg); 23386246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0x70F0, 16, iter_reg); 23396246b8a1SGiridhar Malavali 23406246b8a1SGiridhar Malavali /* I/O Queue Control registers. */ 23416246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0x7800, 16, fw->queue_control_reg); 23426246b8a1SGiridhar Malavali 23436246b8a1SGiridhar Malavali /* Frame Buffer registers. */ 23446246b8a1SGiridhar Malavali iter_reg = fw->fb_hdw_reg; 23456246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg); 23466246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg); 23476246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg); 23486246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg); 23496246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg); 23506246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x6060, 16, iter_reg); 23516246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x6070, 16, iter_reg); 23526246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg); 23536246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg); 23546246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg); 23556246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg); 23566246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg); 23576246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg); 23586246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x61C0, 16, iter_reg); 23596246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x6530, 16, iter_reg); 23606246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x6540, 16, iter_reg); 23616246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x6550, 16, iter_reg); 23626246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x6560, 16, iter_reg); 23636246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x6570, 16, iter_reg); 23646246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x6580, 16, iter_reg); 23656246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x6590, 16, iter_reg); 23666246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x65A0, 16, iter_reg); 23676246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x65B0, 16, iter_reg); 23686246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x65C0, 16, iter_reg); 23696246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x65D0, 16, iter_reg); 23706246b8a1SGiridhar Malavali iter_reg = qla24xx_read_window(reg, 0x65E0, 16, iter_reg); 23716246b8a1SGiridhar Malavali qla24xx_read_window(reg, 0x6F00, 16, iter_reg); 23726246b8a1SGiridhar Malavali 23736246b8a1SGiridhar Malavali /* Multi queue registers */ 23746246b8a1SGiridhar Malavali nxt_chain = qla25xx_copy_mq(ha, (void *)ha->fw_dump + ha->chain_offset, 23756246b8a1SGiridhar Malavali &last_chain); 23766246b8a1SGiridhar Malavali 23776246b8a1SGiridhar Malavali rval = qla24xx_soft_reset(ha); 23786246b8a1SGiridhar Malavali if (rval != QLA_SUCCESS) { 23796246b8a1SGiridhar Malavali ql_log(ql_log_warn, vha, 0xd00e, 23806246b8a1SGiridhar Malavali "SOFT RESET FAILED, forcing continuation of dump!!!\n"); 23816246b8a1SGiridhar Malavali rval = QLA_SUCCESS; 23826246b8a1SGiridhar Malavali 23836246b8a1SGiridhar Malavali ql_log(ql_log_warn, vha, 0xd00f, "try a bigger hammer!!!\n"); 23846246b8a1SGiridhar Malavali 23856246b8a1SGiridhar Malavali WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_RESET); 23866246b8a1SGiridhar Malavali RD_REG_DWORD(®->hccr); 23876246b8a1SGiridhar Malavali 23886246b8a1SGiridhar Malavali WRT_REG_DWORD(®->hccr, HCCRX_REL_RISC_PAUSE); 23896246b8a1SGiridhar Malavali RD_REG_DWORD(®->hccr); 23906246b8a1SGiridhar Malavali 23916246b8a1SGiridhar Malavali WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_RESET); 23926246b8a1SGiridhar Malavali RD_REG_DWORD(®->hccr); 23936246b8a1SGiridhar Malavali 23946246b8a1SGiridhar Malavali for (cnt = 30000; cnt && (RD_REG_WORD(®->mailbox0)); cnt--) 23956246b8a1SGiridhar Malavali udelay(5); 23966246b8a1SGiridhar Malavali 23976246b8a1SGiridhar Malavali if (!cnt) { 23986246b8a1SGiridhar Malavali nxt = fw->code_ram; 23998c0bc701SSaurav Kashyap nxt += sizeof(fw->code_ram); 24006246b8a1SGiridhar Malavali nxt += (ha->fw_memory_size - 0x100000 + 1); 24016246b8a1SGiridhar Malavali goto copy_queue; 240261f098ddSHiral Patel } else { 240361f098ddSHiral Patel set_bit(RISC_RDY_AFT_RESET, &ha->fw_dump_cap_flags); 24046246b8a1SGiridhar Malavali ql_log(ql_log_warn, vha, 0xd010, 24056246b8a1SGiridhar Malavali "bigger hammer success?\n"); 24066246b8a1SGiridhar Malavali } 240761f098ddSHiral Patel } 24086246b8a1SGiridhar Malavali 24096246b8a1SGiridhar Malavali rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram), 24106246b8a1SGiridhar Malavali &nxt); 24116246b8a1SGiridhar Malavali if (rval != QLA_SUCCESS) 24126246b8a1SGiridhar Malavali goto qla83xx_fw_dump_failed_0; 24136246b8a1SGiridhar Malavali 24146246b8a1SGiridhar Malavali copy_queue: 24156246b8a1SGiridhar Malavali nxt = qla2xxx_copy_queues(ha, nxt); 24166246b8a1SGiridhar Malavali 24177f544d00SBart Van Assche qla24xx_copy_eft(ha, nxt); 24186246b8a1SGiridhar Malavali 24196246b8a1SGiridhar Malavali /* Chain entries -- started with MQ. */ 24206246b8a1SGiridhar Malavali nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain); 24216246b8a1SGiridhar Malavali nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain); 24222d70c103SNicholas Bellinger nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain); 24236246b8a1SGiridhar Malavali if (last_chain) { 24246246b8a1SGiridhar Malavali ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT); 24256246b8a1SGiridhar Malavali *last_chain |= __constant_htonl(DUMP_CHAIN_LAST); 24266246b8a1SGiridhar Malavali } 24276246b8a1SGiridhar Malavali 24286246b8a1SGiridhar Malavali /* Adjust valid length. */ 24296246b8a1SGiridhar Malavali ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump); 24306246b8a1SGiridhar Malavali 24316246b8a1SGiridhar Malavali qla83xx_fw_dump_failed_0: 24326246b8a1SGiridhar Malavali qla2xxx_dump_post_process(base_vha, rval); 24336246b8a1SGiridhar Malavali 24346246b8a1SGiridhar Malavali qla83xx_fw_dump_failed: 24356246b8a1SGiridhar Malavali if (!hardware_locked) 24366246b8a1SGiridhar Malavali spin_unlock_irqrestore(&ha->hardware_lock, flags); 24376246b8a1SGiridhar Malavali } 24386246b8a1SGiridhar Malavali 24391da177e4SLinus Torvalds /****************************************************************************/ 24401da177e4SLinus Torvalds /* Driver Debug Functions. */ 24411da177e4SLinus Torvalds /****************************************************************************/ 2442cfb0919cSChad Dupuis 2443cfb0919cSChad Dupuis static inline int 2444cfb0919cSChad Dupuis ql_mask_match(uint32_t level) 2445cfb0919cSChad Dupuis { 2446cfb0919cSChad Dupuis if (ql2xextended_error_logging == 1) 2447cfb0919cSChad Dupuis ql2xextended_error_logging = QL_DBG_DEFAULT1_MASK; 2448cfb0919cSChad Dupuis return (level & ql2xextended_error_logging) == level; 2449cfb0919cSChad Dupuis } 2450cfb0919cSChad Dupuis 24513ce8866cSSaurav Kashyap /* 24523ce8866cSSaurav Kashyap * This function is for formatting and logging debug information. 24533ce8866cSSaurav Kashyap * It is to be used when vha is available. It formats the message 24543ce8866cSSaurav Kashyap * and logs it to the messages file. 24553ce8866cSSaurav Kashyap * parameters: 24563ce8866cSSaurav Kashyap * level: The level of the debug messages to be printed. 24573ce8866cSSaurav Kashyap * If ql2xextended_error_logging value is correctly set, 24583ce8866cSSaurav Kashyap * this message will appear in the messages file. 24593ce8866cSSaurav Kashyap * vha: Pointer to the scsi_qla_host_t. 24603ce8866cSSaurav Kashyap * id: This is a unique identifier for the level. It identifies the 24613ce8866cSSaurav Kashyap * part of the code from where the message originated. 24623ce8866cSSaurav Kashyap * msg: The message to be displayed. 24633ce8866cSSaurav Kashyap */ 24643ce8866cSSaurav Kashyap void 2465086b3e8aSJoe Perches ql_dbg(uint32_t level, scsi_qla_host_t *vha, int32_t id, const char *fmt, ...) 2466086b3e8aSJoe Perches { 2467086b3e8aSJoe Perches va_list va; 2468086b3e8aSJoe Perches struct va_format vaf; 24693ce8866cSSaurav Kashyap 2470cfb0919cSChad Dupuis if (!ql_mask_match(level)) 2471086b3e8aSJoe Perches return; 24723ce8866cSSaurav Kashyap 2473086b3e8aSJoe Perches va_start(va, fmt); 24743ce8866cSSaurav Kashyap 2475086b3e8aSJoe Perches vaf.fmt = fmt; 2476086b3e8aSJoe Perches vaf.va = &va; 24773ce8866cSSaurav Kashyap 24783ce8866cSSaurav Kashyap if (vha != NULL) { 2479086b3e8aSJoe Perches const struct pci_dev *pdev = vha->hw->pdev; 24803ce8866cSSaurav Kashyap /* <module-name> <pci-name> <msg-id>:<host> Message */ 2481086b3e8aSJoe Perches pr_warn("%s [%s]-%04x:%ld: %pV", 2482086b3e8aSJoe Perches QL_MSGHDR, dev_name(&(pdev->dev)), id + ql_dbg_offset, 2483086b3e8aSJoe Perches vha->host_no, &vaf); 2484086b3e8aSJoe Perches } else { 2485086b3e8aSJoe Perches pr_warn("%s [%s]-%04x: : %pV", 2486086b3e8aSJoe Perches QL_MSGHDR, "0000:00:00.0", id + ql_dbg_offset, &vaf); 24873ce8866cSSaurav Kashyap } 24883ce8866cSSaurav Kashyap 2489086b3e8aSJoe Perches va_end(va); 24903ce8866cSSaurav Kashyap 24913ce8866cSSaurav Kashyap } 24923ce8866cSSaurav Kashyap 24933ce8866cSSaurav Kashyap /* 24943ce8866cSSaurav Kashyap * This function is for formatting and logging debug information. 2495d6a03581SMasanari Iida * It is to be used when vha is not available and pci is available, 24963ce8866cSSaurav Kashyap * i.e., before host allocation. It formats the message and logs it 24973ce8866cSSaurav Kashyap * to the messages file. 24983ce8866cSSaurav Kashyap * parameters: 24993ce8866cSSaurav Kashyap * level: The level of the debug messages to be printed. 25003ce8866cSSaurav Kashyap * If ql2xextended_error_logging value is correctly set, 25013ce8866cSSaurav Kashyap * this message will appear in the messages file. 25023ce8866cSSaurav Kashyap * pdev: Pointer to the struct pci_dev. 25033ce8866cSSaurav Kashyap * id: This is a unique id for the level. It identifies the part 25043ce8866cSSaurav Kashyap * of the code from where the message originated. 25053ce8866cSSaurav Kashyap * msg: The message to be displayed. 25063ce8866cSSaurav Kashyap */ 25073ce8866cSSaurav Kashyap void 2508086b3e8aSJoe Perches ql_dbg_pci(uint32_t level, struct pci_dev *pdev, int32_t id, 2509086b3e8aSJoe Perches const char *fmt, ...) 2510086b3e8aSJoe Perches { 2511086b3e8aSJoe Perches va_list va; 2512086b3e8aSJoe Perches struct va_format vaf; 25133ce8866cSSaurav Kashyap 25143ce8866cSSaurav Kashyap if (pdev == NULL) 25153ce8866cSSaurav Kashyap return; 2516cfb0919cSChad Dupuis if (!ql_mask_match(level)) 2517086b3e8aSJoe Perches return; 25183ce8866cSSaurav Kashyap 2519086b3e8aSJoe Perches va_start(va, fmt); 25203ce8866cSSaurav Kashyap 2521086b3e8aSJoe Perches vaf.fmt = fmt; 2522086b3e8aSJoe Perches vaf.va = &va; 25233ce8866cSSaurav Kashyap 25243ce8866cSSaurav Kashyap /* <module-name> <dev-name>:<msg-id> Message */ 2525086b3e8aSJoe Perches pr_warn("%s [%s]-%04x: : %pV", 2526086b3e8aSJoe Perches QL_MSGHDR, dev_name(&(pdev->dev)), id + ql_dbg_offset, &vaf); 25273ce8866cSSaurav Kashyap 2528086b3e8aSJoe Perches va_end(va); 25293ce8866cSSaurav Kashyap } 25303ce8866cSSaurav Kashyap 25313ce8866cSSaurav Kashyap /* 25323ce8866cSSaurav Kashyap * This function is for formatting and logging log messages. 25333ce8866cSSaurav Kashyap * It is to be used when vha is available. It formats the message 25343ce8866cSSaurav Kashyap * and logs it to the messages file. All the messages will be logged 25353ce8866cSSaurav Kashyap * irrespective of value of ql2xextended_error_logging. 25363ce8866cSSaurav Kashyap * parameters: 25373ce8866cSSaurav Kashyap * level: The level of the log messages to be printed in the 25383ce8866cSSaurav Kashyap * messages file. 25393ce8866cSSaurav Kashyap * vha: Pointer to the scsi_qla_host_t 25403ce8866cSSaurav Kashyap * id: This is a unique id for the level. It identifies the 25413ce8866cSSaurav Kashyap * part of the code from where the message originated. 25423ce8866cSSaurav Kashyap * msg: The message to be displayed. 25433ce8866cSSaurav Kashyap */ 25443ce8866cSSaurav Kashyap void 2545086b3e8aSJoe Perches ql_log(uint32_t level, scsi_qla_host_t *vha, int32_t id, const char *fmt, ...) 2546086b3e8aSJoe Perches { 2547086b3e8aSJoe Perches va_list va; 2548086b3e8aSJoe Perches struct va_format vaf; 2549086b3e8aSJoe Perches char pbuf[128]; 25503ce8866cSSaurav Kashyap 2551086b3e8aSJoe Perches if (level > ql_errlev) 2552086b3e8aSJoe Perches return; 25533ce8866cSSaurav Kashyap 25543ce8866cSSaurav Kashyap if (vha != NULL) { 2555086b3e8aSJoe Perches const struct pci_dev *pdev = vha->hw->pdev; 25563ce8866cSSaurav Kashyap /* <module-name> <msg-id>:<host> Message */ 2557086b3e8aSJoe Perches snprintf(pbuf, sizeof(pbuf), "%s [%s]-%04x:%ld: ", 2558086b3e8aSJoe Perches QL_MSGHDR, dev_name(&(pdev->dev)), id, vha->host_no); 2559086b3e8aSJoe Perches } else { 2560086b3e8aSJoe Perches snprintf(pbuf, sizeof(pbuf), "%s [%s]-%04x: : ", 2561086b3e8aSJoe Perches QL_MSGHDR, "0000:00:00.0", id); 2562086b3e8aSJoe Perches } 2563086b3e8aSJoe Perches pbuf[sizeof(pbuf) - 1] = 0; 25643ce8866cSSaurav Kashyap 2565086b3e8aSJoe Perches va_start(va, fmt); 2566086b3e8aSJoe Perches 2567086b3e8aSJoe Perches vaf.fmt = fmt; 2568086b3e8aSJoe Perches vaf.va = &va; 25693ce8866cSSaurav Kashyap 25703ce8866cSSaurav Kashyap switch (level) { 257170a3fc76SChad Dupuis case ql_log_fatal: /* FATAL LOG */ 2572086b3e8aSJoe Perches pr_crit("%s%pV", pbuf, &vaf); 25733ce8866cSSaurav Kashyap break; 257470a3fc76SChad Dupuis case ql_log_warn: 2575086b3e8aSJoe Perches pr_err("%s%pV", pbuf, &vaf); 25763ce8866cSSaurav Kashyap break; 257770a3fc76SChad Dupuis case ql_log_info: 2578086b3e8aSJoe Perches pr_warn("%s%pV", pbuf, &vaf); 25793ce8866cSSaurav Kashyap break; 25803ce8866cSSaurav Kashyap default: 2581086b3e8aSJoe Perches pr_info("%s%pV", pbuf, &vaf); 25823ce8866cSSaurav Kashyap break; 25833ce8866cSSaurav Kashyap } 25843ce8866cSSaurav Kashyap 2585086b3e8aSJoe Perches va_end(va); 25863ce8866cSSaurav Kashyap } 25873ce8866cSSaurav Kashyap 25883ce8866cSSaurav Kashyap /* 25893ce8866cSSaurav Kashyap * This function is for formatting and logging log messages. 2590d6a03581SMasanari Iida * It is to be used when vha is not available and pci is available, 25913ce8866cSSaurav Kashyap * i.e., before host allocation. It formats the message and logs 25923ce8866cSSaurav Kashyap * it to the messages file. All the messages are logged irrespective 25933ce8866cSSaurav Kashyap * of the value of ql2xextended_error_logging. 25943ce8866cSSaurav Kashyap * parameters: 25953ce8866cSSaurav Kashyap * level: The level of the log messages to be printed in the 25963ce8866cSSaurav Kashyap * messages file. 25973ce8866cSSaurav Kashyap * pdev: Pointer to the struct pci_dev. 25983ce8866cSSaurav Kashyap * id: This is a unique id for the level. It identifies the 25993ce8866cSSaurav Kashyap * part of the code from where the message originated. 26003ce8866cSSaurav Kashyap * msg: The message to be displayed. 26013ce8866cSSaurav Kashyap */ 26023ce8866cSSaurav Kashyap void 2603086b3e8aSJoe Perches ql_log_pci(uint32_t level, struct pci_dev *pdev, int32_t id, 2604086b3e8aSJoe Perches const char *fmt, ...) 2605086b3e8aSJoe Perches { 2606086b3e8aSJoe Perches va_list va; 2607086b3e8aSJoe Perches struct va_format vaf; 2608086b3e8aSJoe Perches char pbuf[128]; 26093ce8866cSSaurav Kashyap 26103ce8866cSSaurav Kashyap if (pdev == NULL) 26113ce8866cSSaurav Kashyap return; 2612086b3e8aSJoe Perches if (level > ql_errlev) 2613086b3e8aSJoe Perches return; 26143ce8866cSSaurav Kashyap 26153ce8866cSSaurav Kashyap /* <module-name> <dev-name>:<msg-id> Message */ 2616086b3e8aSJoe Perches snprintf(pbuf, sizeof(pbuf), "%s [%s]-%04x: : ", 2617086b3e8aSJoe Perches QL_MSGHDR, dev_name(&(pdev->dev)), id); 2618086b3e8aSJoe Perches pbuf[sizeof(pbuf) - 1] = 0; 26193ce8866cSSaurav Kashyap 2620086b3e8aSJoe Perches va_start(va, fmt); 2621086b3e8aSJoe Perches 2622086b3e8aSJoe Perches vaf.fmt = fmt; 2623086b3e8aSJoe Perches vaf.va = &va; 2624086b3e8aSJoe Perches 26253ce8866cSSaurav Kashyap switch (level) { 262670a3fc76SChad Dupuis case ql_log_fatal: /* FATAL LOG */ 2627086b3e8aSJoe Perches pr_crit("%s%pV", pbuf, &vaf); 26283ce8866cSSaurav Kashyap break; 262970a3fc76SChad Dupuis case ql_log_warn: 2630086b3e8aSJoe Perches pr_err("%s%pV", pbuf, &vaf); 26313ce8866cSSaurav Kashyap break; 263270a3fc76SChad Dupuis case ql_log_info: 2633086b3e8aSJoe Perches pr_warn("%s%pV", pbuf, &vaf); 26343ce8866cSSaurav Kashyap break; 26353ce8866cSSaurav Kashyap default: 2636086b3e8aSJoe Perches pr_info("%s%pV", pbuf, &vaf); 26373ce8866cSSaurav Kashyap break; 26383ce8866cSSaurav Kashyap } 26393ce8866cSSaurav Kashyap 2640086b3e8aSJoe Perches va_end(va); 26413ce8866cSSaurav Kashyap } 26423ce8866cSSaurav Kashyap 26433ce8866cSSaurav Kashyap void 26443ce8866cSSaurav Kashyap ql_dump_regs(uint32_t level, scsi_qla_host_t *vha, int32_t id) 26453ce8866cSSaurav Kashyap { 26463ce8866cSSaurav Kashyap int i; 26473ce8866cSSaurav Kashyap struct qla_hw_data *ha = vha->hw; 26483ce8866cSSaurav Kashyap struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; 26493ce8866cSSaurav Kashyap struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24; 26503ce8866cSSaurav Kashyap struct device_reg_82xx __iomem *reg82 = &ha->iobase->isp82; 26513ce8866cSSaurav Kashyap uint16_t __iomem *mbx_reg; 26523ce8866cSSaurav Kashyap 2653cfb0919cSChad Dupuis if (!ql_mask_match(level)) 2654cfb0919cSChad Dupuis return; 26553ce8866cSSaurav Kashyap 26567ec0effdSAtul Deshmukh if (IS_P3P_TYPE(ha)) 26573ce8866cSSaurav Kashyap mbx_reg = ®82->mailbox_in[0]; 26583ce8866cSSaurav Kashyap else if (IS_FWI2_CAPABLE(ha)) 26593ce8866cSSaurav Kashyap mbx_reg = ®24->mailbox0; 26603ce8866cSSaurav Kashyap else 26613ce8866cSSaurav Kashyap mbx_reg = MAILBOX_REG(ha, reg, 0); 26623ce8866cSSaurav Kashyap 26633ce8866cSSaurav Kashyap ql_dbg(level, vha, id, "Mailbox registers:\n"); 26643ce8866cSSaurav Kashyap for (i = 0; i < 6; i++) 26653ce8866cSSaurav Kashyap ql_dbg(level, vha, id, 26663ce8866cSSaurav Kashyap "mbox[%d] 0x%04x\n", i, RD_REG_WORD(mbx_reg++)); 26673ce8866cSSaurav Kashyap } 26683ce8866cSSaurav Kashyap 26693ce8866cSSaurav Kashyap 26703ce8866cSSaurav Kashyap void 26713ce8866cSSaurav Kashyap ql_dump_buffer(uint32_t level, scsi_qla_host_t *vha, int32_t id, 26723ce8866cSSaurav Kashyap uint8_t *b, uint32_t size) 26733ce8866cSSaurav Kashyap { 26743ce8866cSSaurav Kashyap uint32_t cnt; 26753ce8866cSSaurav Kashyap uint8_t c; 2676cfb0919cSChad Dupuis 2677cfb0919cSChad Dupuis if (!ql_mask_match(level)) 2678cfb0919cSChad Dupuis return; 26793ce8866cSSaurav Kashyap 26803ce8866cSSaurav Kashyap ql_dbg(level, vha, id, " 0 1 2 3 4 5 6 7 8 " 26813ce8866cSSaurav Kashyap "9 Ah Bh Ch Dh Eh Fh\n"); 26823ce8866cSSaurav Kashyap ql_dbg(level, vha, id, "----------------------------------" 26833ce8866cSSaurav Kashyap "----------------------------\n"); 26843ce8866cSSaurav Kashyap 26853ce8866cSSaurav Kashyap ql_dbg(level, vha, id, " "); 26863ce8866cSSaurav Kashyap for (cnt = 0; cnt < size;) { 26873ce8866cSSaurav Kashyap c = *b++; 26883ce8866cSSaurav Kashyap printk("%02x", (uint32_t) c); 26893ce8866cSSaurav Kashyap cnt++; 26903ce8866cSSaurav Kashyap if (!(cnt % 16)) 26913ce8866cSSaurav Kashyap printk("\n"); 26923ce8866cSSaurav Kashyap else 26933ce8866cSSaurav Kashyap printk(" "); 26943ce8866cSSaurav Kashyap } 26953ce8866cSSaurav Kashyap if (cnt % 16) 26963ce8866cSSaurav Kashyap ql_dbg(level, vha, id, "\n"); 26973ce8866cSSaurav Kashyap } 2698