diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_dbg.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_dbg.c | 462 |
1 files changed, 406 insertions, 56 deletions
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 1cf77772623b..34760f8d4f17 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c | |||
@@ -310,6 +310,76 @@ qla2xxx_read_window(struct device_reg_2xxx __iomem *reg, uint32_t count, | |||
310 | *buf++ = htons(RD_REG_WORD(dmp_reg++)); | 310 | *buf++ = htons(RD_REG_WORD(dmp_reg++)); |
311 | } | 311 | } |
312 | 312 | ||
313 | static inline void * | ||
314 | qla24xx_copy_eft(struct qla_hw_data *ha, void *ptr) | ||
315 | { | ||
316 | if (!ha->eft) | ||
317 | return ptr; | ||
318 | |||
319 | memcpy(ptr, ha->eft, ntohl(ha->fw_dump->eft_size)); | ||
320 | return ptr + ntohl(ha->fw_dump->eft_size); | ||
321 | } | ||
322 | |||
323 | static inline void * | ||
324 | qla25xx_copy_fce(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain) | ||
325 | { | ||
326 | uint32_t cnt; | ||
327 | uint32_t *iter_reg; | ||
328 | struct qla2xxx_fce_chain *fcec = ptr; | ||
329 | |||
330 | if (!ha->fce) | ||
331 | return ptr; | ||
332 | |||
333 | *last_chain = &fcec->type; | ||
334 | fcec->type = __constant_htonl(DUMP_CHAIN_FCE); | ||
335 | fcec->chain_size = htonl(sizeof(struct qla2xxx_fce_chain) + | ||
336 | fce_calc_size(ha->fce_bufs)); | ||
337 | fcec->size = htonl(fce_calc_size(ha->fce_bufs)); | ||
338 | fcec->addr_l = htonl(LSD(ha->fce_dma)); | ||
339 | fcec->addr_h = htonl(MSD(ha->fce_dma)); | ||
340 | |||
341 | iter_reg = fcec->eregs; | ||
342 | for (cnt = 0; cnt < 8; cnt++) | ||
343 | *iter_reg++ = htonl(ha->fce_mb[cnt]); | ||
344 | |||
345 | memcpy(iter_reg, ha->fce, ntohl(fcec->size)); | ||
346 | |||
347 | return iter_reg; | ||
348 | } | ||
349 | |||
350 | static inline void * | ||
351 | qla25xx_copy_mq(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain) | ||
352 | { | ||
353 | uint32_t cnt, que_idx; | ||
354 | uint8_t req_cnt, rsp_cnt, que_cnt; | ||
355 | struct qla2xxx_mq_chain *mq = ptr; | ||
356 | struct device_reg_25xxmq __iomem *reg; | ||
357 | |||
358 | if (!ha->mqenable) | ||
359 | return ptr; | ||
360 | |||
361 | mq = ptr; | ||
362 | *last_chain = &mq->type; | ||
363 | mq->type = __constant_htonl(DUMP_CHAIN_MQ); | ||
364 | mq->chain_size = __constant_htonl(sizeof(struct qla2xxx_mq_chain)); | ||
365 | |||
366 | req_cnt = find_first_zero_bit(ha->req_qid_map, ha->max_queues); | ||
367 | rsp_cnt = find_first_zero_bit(ha->rsp_qid_map, ha->max_queues); | ||
368 | que_cnt = req_cnt > rsp_cnt ? req_cnt : rsp_cnt; | ||
369 | mq->count = htonl(que_cnt); | ||
370 | for (cnt = 0; cnt < que_cnt; cnt++) { | ||
371 | reg = (struct device_reg_25xxmq *) ((void *) | ||
372 | ha->mqiobase + cnt * QLA_QUE_PAGE); | ||
373 | que_idx = cnt * 4; | ||
374 | mq->qregs[que_idx] = htonl(RD_REG_DWORD(®->req_q_in)); | ||
375 | mq->qregs[que_idx+1] = htonl(RD_REG_DWORD(®->req_q_out)); | ||
376 | mq->qregs[que_idx+2] = htonl(RD_REG_DWORD(®->rsp_q_in)); | ||
377 | mq->qregs[que_idx+3] = htonl(RD_REG_DWORD(®->rsp_q_out)); | ||
378 | } | ||
379 | |||
380 | return ptr + sizeof(struct qla2xxx_mq_chain); | ||
381 | } | ||
382 | |||
313 | /** | 383 | /** |
314 | * qla2300_fw_dump() - Dumps binary data from the 2300 firmware. | 384 | * qla2300_fw_dump() - Dumps binary data from the 2300 firmware. |
315 | * @ha: HA context | 385 | * @ha: HA context |
@@ -913,8 +983,8 @@ qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) | |||
913 | goto qla24xx_fw_dump_failed_0; | 983 | goto qla24xx_fw_dump_failed_0; |
914 | 984 | ||
915 | nxt = qla2xxx_copy_queues(ha, nxt); | 985 | nxt = qla2xxx_copy_queues(ha, nxt); |
916 | if (ha->eft) | 986 | |
917 | memcpy(nxt, ha->eft, ntohl(ha->fw_dump->eft_size)); | 987 | qla24xx_copy_eft(ha, nxt); |
918 | 988 | ||
919 | qla24xx_fw_dump_failed_0: | 989 | qla24xx_fw_dump_failed_0: |
920 | if (rval != QLA_SUCCESS) { | 990 | if (rval != QLA_SUCCESS) { |
@@ -942,19 +1012,14 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) | |||
942 | uint32_t risc_address; | 1012 | uint32_t risc_address; |
943 | struct qla_hw_data *ha = vha->hw; | 1013 | struct qla_hw_data *ha = vha->hw; |
944 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 1014 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
945 | struct device_reg_25xxmq __iomem *reg25; | ||
946 | uint32_t __iomem *dmp_reg; | 1015 | uint32_t __iomem *dmp_reg; |
947 | uint32_t *iter_reg; | 1016 | uint32_t *iter_reg; |
948 | uint16_t __iomem *mbx_reg; | 1017 | uint16_t __iomem *mbx_reg; |
949 | unsigned long flags; | 1018 | unsigned long flags; |
950 | struct qla25xx_fw_dump *fw; | 1019 | struct qla25xx_fw_dump *fw; |
951 | uint32_t ext_mem_cnt; | 1020 | uint32_t ext_mem_cnt; |
952 | void *nxt; | 1021 | void *nxt, *nxt_chain; |
953 | struct qla2xxx_fce_chain *fcec; | 1022 | uint32_t *last_chain = NULL; |
954 | struct qla2xxx_mq_chain *mq = NULL; | ||
955 | uint32_t qreg_size; | ||
956 | uint8_t req_cnt, rsp_cnt, que_cnt; | ||
957 | uint32_t que_idx; | ||
958 | struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); | 1023 | struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); |
959 | 1024 | ||
960 | risc_address = ext_mem_cnt = 0; | 1025 | risc_address = ext_mem_cnt = 0; |
@@ -1001,28 +1066,6 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) | |||
1001 | fw->pcie_regs[2] = htonl(RD_REG_DWORD(dmp_reg)); | 1066 | fw->pcie_regs[2] = htonl(RD_REG_DWORD(dmp_reg)); |
1002 | fw->pcie_regs[3] = htonl(RD_REG_DWORD(®->iobase_window)); | 1067 | fw->pcie_regs[3] = htonl(RD_REG_DWORD(®->iobase_window)); |
1003 | 1068 | ||
1004 | /* Multi queue registers */ | ||
1005 | if (ha->mqenable) { | ||
1006 | qreg_size = sizeof(struct qla2xxx_mq_chain); | ||
1007 | mq = kzalloc(qreg_size, GFP_KERNEL); | ||
1008 | if (!mq) | ||
1009 | goto qla25xx_fw_dump_failed_0; | ||
1010 | req_cnt = find_first_zero_bit(ha->req_qid_map, ha->max_queues); | ||
1011 | rsp_cnt = find_first_zero_bit(ha->rsp_qid_map, ha->max_queues); | ||
1012 | que_cnt = req_cnt > rsp_cnt ? req_cnt : rsp_cnt; | ||
1013 | mq->count = htonl(que_cnt); | ||
1014 | mq->chain_size = htonl(qreg_size); | ||
1015 | mq->type = __constant_htonl(DUMP_CHAIN_MQ); | ||
1016 | for (cnt = 0; cnt < que_cnt; cnt++) { | ||
1017 | reg25 = (struct device_reg_25xxmq *) ((void *) | ||
1018 | ha->mqiobase + cnt * QLA_QUE_PAGE); | ||
1019 | que_idx = cnt * 4; | ||
1020 | mq->qregs[que_idx] = htonl(reg25->req_q_in); | ||
1021 | mq->qregs[que_idx+1] = htonl(reg25->req_q_out); | ||
1022 | mq->qregs[que_idx+2] = htonl(reg25->rsp_q_in); | ||
1023 | mq->qregs[que_idx+3] = htonl(reg25->rsp_q_out); | ||
1024 | } | ||
1025 | } | ||
1026 | WRT_REG_DWORD(®->iobase_window, 0x00); | 1069 | WRT_REG_DWORD(®->iobase_window, 0x00); |
1027 | RD_REG_DWORD(®->iobase_window); | 1070 | RD_REG_DWORD(®->iobase_window); |
1028 | 1071 | ||
@@ -1240,6 +1283,10 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) | |||
1240 | iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg); | 1283 | iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg); |
1241 | qla24xx_read_window(reg, 0x6F00, 16, iter_reg); | 1284 | qla24xx_read_window(reg, 0x6F00, 16, iter_reg); |
1242 | 1285 | ||
1286 | /* Multi queue registers */ | ||
1287 | nxt_chain = qla25xx_copy_mq(ha, (void *)ha->fw_dump + ha->chain_offset, | ||
1288 | &last_chain); | ||
1289 | |||
1243 | rval = qla24xx_soft_reset(ha); | 1290 | rval = qla24xx_soft_reset(ha); |
1244 | if (rval != QLA_SUCCESS) | 1291 | if (rval != QLA_SUCCESS) |
1245 | goto qla25xx_fw_dump_failed_0; | 1292 | goto qla25xx_fw_dump_failed_0; |
@@ -1249,39 +1296,341 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) | |||
1249 | if (rval != QLA_SUCCESS) | 1296 | if (rval != QLA_SUCCESS) |
1250 | goto qla25xx_fw_dump_failed_0; | 1297 | goto qla25xx_fw_dump_failed_0; |
1251 | 1298 | ||
1252 | /* Fibre Channel Trace Buffer. */ | ||
1253 | nxt = qla2xxx_copy_queues(ha, nxt); | 1299 | nxt = qla2xxx_copy_queues(ha, nxt); |
1254 | if (ha->eft) | ||
1255 | memcpy(nxt, ha->eft, ntohl(ha->fw_dump->eft_size)); | ||
1256 | 1300 | ||
1257 | /* Fibre Channel Event Buffer. */ | 1301 | nxt = qla24xx_copy_eft(ha, nxt); |
1258 | if (!ha->fce) | 1302 | |
1259 | goto qla25xx_fw_dump_failed_0; | 1303 | /* Chain entries -- started with MQ. */ |
1304 | qla25xx_copy_fce(ha, nxt_chain, &last_chain); | ||
1305 | if (last_chain) { | ||
1306 | ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT); | ||
1307 | *last_chain |= __constant_htonl(DUMP_CHAIN_LAST); | ||
1308 | } | ||
1260 | 1309 | ||
1261 | ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT); | 1310 | qla25xx_fw_dump_failed_0: |
1311 | if (rval != QLA_SUCCESS) { | ||
1312 | qla_printk(KERN_WARNING, ha, | ||
1313 | "Failed to dump firmware (%x)!!!\n", rval); | ||
1314 | ha->fw_dumped = 0; | ||
1262 | 1315 | ||
1263 | if (ha->mqenable) { | ||
1264 | nxt = nxt + ntohl(ha->fw_dump->eft_size); | ||
1265 | memcpy(nxt, mq, qreg_size); | ||
1266 | kfree(mq); | ||
1267 | fcec = nxt + qreg_size; | ||
1268 | } else { | 1316 | } else { |
1269 | fcec = nxt + ntohl(ha->fw_dump->eft_size); | 1317 | qla_printk(KERN_INFO, ha, |
1318 | "Firmware dump saved to temp buffer (%ld/%p).\n", | ||
1319 | base_vha->host_no, ha->fw_dump); | ||
1320 | ha->fw_dumped = 1; | ||
1270 | } | 1321 | } |
1271 | fcec->type = __constant_htonl(DUMP_CHAIN_FCE | DUMP_CHAIN_LAST); | ||
1272 | fcec->chain_size = htonl(sizeof(struct qla2xxx_fce_chain) + | ||
1273 | fce_calc_size(ha->fce_bufs)); | ||
1274 | fcec->size = htonl(fce_calc_size(ha->fce_bufs)); | ||
1275 | fcec->addr_l = htonl(LSD(ha->fce_dma)); | ||
1276 | fcec->addr_h = htonl(MSD(ha->fce_dma)); | ||
1277 | 1322 | ||
1278 | iter_reg = fcec->eregs; | 1323 | qla25xx_fw_dump_failed: |
1279 | for (cnt = 0; cnt < 8; cnt++) | 1324 | if (!hardware_locked) |
1280 | *iter_reg++ = htonl(ha->fce_mb[cnt]); | 1325 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
1326 | } | ||
1281 | 1327 | ||
1282 | memcpy(iter_reg, ha->fce, ntohl(fcec->size)); | 1328 | void |
1329 | qla81xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) | ||
1330 | { | ||
1331 | int rval; | ||
1332 | uint32_t cnt; | ||
1333 | uint32_t risc_address; | ||
1334 | struct qla_hw_data *ha = vha->hw; | ||
1335 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | ||
1336 | uint32_t __iomem *dmp_reg; | ||
1337 | uint32_t *iter_reg; | ||
1338 | uint16_t __iomem *mbx_reg; | ||
1339 | unsigned long flags; | ||
1340 | struct qla81xx_fw_dump *fw; | ||
1341 | uint32_t ext_mem_cnt; | ||
1342 | void *nxt, *nxt_chain; | ||
1343 | uint32_t *last_chain = NULL; | ||
1344 | struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); | ||
1283 | 1345 | ||
1284 | qla25xx_fw_dump_failed_0: | 1346 | risc_address = ext_mem_cnt = 0; |
1347 | flags = 0; | ||
1348 | |||
1349 | if (!hardware_locked) | ||
1350 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
1351 | |||
1352 | if (!ha->fw_dump) { | ||
1353 | qla_printk(KERN_WARNING, ha, | ||
1354 | "No buffer available for dump!!!\n"); | ||
1355 | goto qla81xx_fw_dump_failed; | ||
1356 | } | ||
1357 | |||
1358 | if (ha->fw_dumped) { | ||
1359 | qla_printk(KERN_WARNING, ha, | ||
1360 | "Firmware has been previously dumped (%p) -- ignoring " | ||
1361 | "request...\n", ha->fw_dump); | ||
1362 | goto qla81xx_fw_dump_failed; | ||
1363 | } | ||
1364 | fw = &ha->fw_dump->isp.isp81; | ||
1365 | qla2xxx_prep_dump(ha, ha->fw_dump); | ||
1366 | |||
1367 | fw->host_status = htonl(RD_REG_DWORD(®->host_status)); | ||
1368 | |||
1369 | /* Pause RISC. */ | ||
1370 | rval = qla24xx_pause_risc(reg); | ||
1371 | if (rval != QLA_SUCCESS) | ||
1372 | goto qla81xx_fw_dump_failed_0; | ||
1373 | |||
1374 | /* Host/Risc registers. */ | ||
1375 | iter_reg = fw->host_risc_reg; | ||
1376 | iter_reg = qla24xx_read_window(reg, 0x7000, 16, iter_reg); | ||
1377 | qla24xx_read_window(reg, 0x7010, 16, iter_reg); | ||
1378 | |||
1379 | /* PCIe registers. */ | ||
1380 | WRT_REG_DWORD(®->iobase_addr, 0x7C00); | ||
1381 | RD_REG_DWORD(®->iobase_addr); | ||
1382 | WRT_REG_DWORD(®->iobase_window, 0x01); | ||
1383 | dmp_reg = ®->iobase_c4; | ||
1384 | fw->pcie_regs[0] = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1385 | fw->pcie_regs[1] = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1386 | fw->pcie_regs[2] = htonl(RD_REG_DWORD(dmp_reg)); | ||
1387 | fw->pcie_regs[3] = htonl(RD_REG_DWORD(®->iobase_window)); | ||
1388 | |||
1389 | WRT_REG_DWORD(®->iobase_window, 0x00); | ||
1390 | RD_REG_DWORD(®->iobase_window); | ||
1391 | |||
1392 | /* Host interface registers. */ | ||
1393 | dmp_reg = ®->flash_addr; | ||
1394 | for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++) | ||
1395 | fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1396 | |||
1397 | /* Disable interrupts. */ | ||
1398 | WRT_REG_DWORD(®->ictrl, 0); | ||
1399 | RD_REG_DWORD(®->ictrl); | ||
1400 | |||
1401 | /* Shadow registers. */ | ||
1402 | WRT_REG_DWORD(®->iobase_addr, 0x0F70); | ||
1403 | RD_REG_DWORD(®->iobase_addr); | ||
1404 | WRT_REG_DWORD(®->iobase_select, 0xB0000000); | ||
1405 | fw->shadow_reg[0] = htonl(RD_REG_DWORD(®->iobase_sdata)); | ||
1406 | |||
1407 | WRT_REG_DWORD(®->iobase_select, 0xB0100000); | ||
1408 | fw->shadow_reg[1] = htonl(RD_REG_DWORD(®->iobase_sdata)); | ||
1409 | |||
1410 | WRT_REG_DWORD(®->iobase_select, 0xB0200000); | ||
1411 | fw->shadow_reg[2] = htonl(RD_REG_DWORD(®->iobase_sdata)); | ||
1412 | |||
1413 | WRT_REG_DWORD(®->iobase_select, 0xB0300000); | ||
1414 | fw->shadow_reg[3] = htonl(RD_REG_DWORD(®->iobase_sdata)); | ||
1415 | |||
1416 | WRT_REG_DWORD(®->iobase_select, 0xB0400000); | ||
1417 | fw->shadow_reg[4] = htonl(RD_REG_DWORD(®->iobase_sdata)); | ||
1418 | |||
1419 | WRT_REG_DWORD(®->iobase_select, 0xB0500000); | ||
1420 | fw->shadow_reg[5] = htonl(RD_REG_DWORD(®->iobase_sdata)); | ||
1421 | |||
1422 | WRT_REG_DWORD(®->iobase_select, 0xB0600000); | ||
1423 | fw->shadow_reg[6] = htonl(RD_REG_DWORD(®->iobase_sdata)); | ||
1424 | |||
1425 | WRT_REG_DWORD(®->iobase_select, 0xB0700000); | ||
1426 | fw->shadow_reg[7] = htonl(RD_REG_DWORD(®->iobase_sdata)); | ||
1427 | |||
1428 | WRT_REG_DWORD(®->iobase_select, 0xB0800000); | ||
1429 | fw->shadow_reg[8] = htonl(RD_REG_DWORD(®->iobase_sdata)); | ||
1430 | |||
1431 | WRT_REG_DWORD(®->iobase_select, 0xB0900000); | ||
1432 | fw->shadow_reg[9] = htonl(RD_REG_DWORD(®->iobase_sdata)); | ||
1433 | |||
1434 | WRT_REG_DWORD(®->iobase_select, 0xB0A00000); | ||
1435 | fw->shadow_reg[10] = htonl(RD_REG_DWORD(®->iobase_sdata)); | ||
1436 | |||
1437 | /* RISC I/O register. */ | ||
1438 | WRT_REG_DWORD(®->iobase_addr, 0x0010); | ||
1439 | fw->risc_io_reg = htonl(RD_REG_DWORD(®->iobase_window)); | ||
1440 | |||
1441 | /* Mailbox registers. */ | ||
1442 | mbx_reg = ®->mailbox0; | ||
1443 | for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) | ||
1444 | fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++)); | ||
1445 | |||
1446 | /* Transfer sequence registers. */ | ||
1447 | iter_reg = fw->xseq_gp_reg; | ||
1448 | iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg); | ||
1449 | iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg); | ||
1450 | iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg); | ||
1451 | iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg); | ||
1452 | iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg); | ||
1453 | iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg); | ||
1454 | iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg); | ||
1455 | qla24xx_read_window(reg, 0xBF70, 16, iter_reg); | ||
1456 | |||
1457 | iter_reg = fw->xseq_0_reg; | ||
1458 | iter_reg = qla24xx_read_window(reg, 0xBFC0, 16, iter_reg); | ||
1459 | iter_reg = qla24xx_read_window(reg, 0xBFD0, 16, iter_reg); | ||
1460 | qla24xx_read_window(reg, 0xBFE0, 16, iter_reg); | ||
1461 | |||
1462 | qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg); | ||
1463 | |||
1464 | /* Receive sequence registers. */ | ||
1465 | iter_reg = fw->rseq_gp_reg; | ||
1466 | iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg); | ||
1467 | iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg); | ||
1468 | iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg); | ||
1469 | iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg); | ||
1470 | iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg); | ||
1471 | iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg); | ||
1472 | iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg); | ||
1473 | qla24xx_read_window(reg, 0xFF70, 16, iter_reg); | ||
1474 | |||
1475 | iter_reg = fw->rseq_0_reg; | ||
1476 | iter_reg = qla24xx_read_window(reg, 0xFFC0, 16, iter_reg); | ||
1477 | qla24xx_read_window(reg, 0xFFD0, 16, iter_reg); | ||
1478 | |||
1479 | qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg); | ||
1480 | qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg); | ||
1481 | |||
1482 | /* Auxiliary sequence registers. */ | ||
1483 | iter_reg = fw->aseq_gp_reg; | ||
1484 | iter_reg = qla24xx_read_window(reg, 0xB000, 16, iter_reg); | ||
1485 | iter_reg = qla24xx_read_window(reg, 0xB010, 16, iter_reg); | ||
1486 | iter_reg = qla24xx_read_window(reg, 0xB020, 16, iter_reg); | ||
1487 | iter_reg = qla24xx_read_window(reg, 0xB030, 16, iter_reg); | ||
1488 | iter_reg = qla24xx_read_window(reg, 0xB040, 16, iter_reg); | ||
1489 | iter_reg = qla24xx_read_window(reg, 0xB050, 16, iter_reg); | ||
1490 | iter_reg = qla24xx_read_window(reg, 0xB060, 16, iter_reg); | ||
1491 | qla24xx_read_window(reg, 0xB070, 16, iter_reg); | ||
1492 | |||
1493 | iter_reg = fw->aseq_0_reg; | ||
1494 | iter_reg = qla24xx_read_window(reg, 0xB0C0, 16, iter_reg); | ||
1495 | qla24xx_read_window(reg, 0xB0D0, 16, iter_reg); | ||
1496 | |||
1497 | qla24xx_read_window(reg, 0xB0E0, 16, fw->aseq_1_reg); | ||
1498 | qla24xx_read_window(reg, 0xB0F0, 16, fw->aseq_2_reg); | ||
1499 | |||
1500 | /* Command DMA registers. */ | ||
1501 | qla24xx_read_window(reg, 0x7100, 16, fw->cmd_dma_reg); | ||
1502 | |||
1503 | /* Queues. */ | ||
1504 | iter_reg = fw->req0_dma_reg; | ||
1505 | iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg); | ||
1506 | dmp_reg = ®->iobase_q; | ||
1507 | for (cnt = 0; cnt < 7; cnt++) | ||
1508 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1509 | |||
1510 | iter_reg = fw->resp0_dma_reg; | ||
1511 | iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg); | ||
1512 | dmp_reg = ®->iobase_q; | ||
1513 | for (cnt = 0; cnt < 7; cnt++) | ||
1514 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1515 | |||
1516 | iter_reg = fw->req1_dma_reg; | ||
1517 | iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg); | ||
1518 | dmp_reg = ®->iobase_q; | ||
1519 | for (cnt = 0; cnt < 7; cnt++) | ||
1520 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1521 | |||
1522 | /* Transmit DMA registers. */ | ||
1523 | iter_reg = fw->xmt0_dma_reg; | ||
1524 | iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg); | ||
1525 | qla24xx_read_window(reg, 0x7610, 16, iter_reg); | ||
1526 | |||
1527 | iter_reg = fw->xmt1_dma_reg; | ||
1528 | iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg); | ||
1529 | qla24xx_read_window(reg, 0x7630, 16, iter_reg); | ||
1530 | |||
1531 | iter_reg = fw->xmt2_dma_reg; | ||
1532 | iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg); | ||
1533 | qla24xx_read_window(reg, 0x7650, 16, iter_reg); | ||
1534 | |||
1535 | iter_reg = fw->xmt3_dma_reg; | ||
1536 | iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg); | ||
1537 | qla24xx_read_window(reg, 0x7670, 16, iter_reg); | ||
1538 | |||
1539 | iter_reg = fw->xmt4_dma_reg; | ||
1540 | iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg); | ||
1541 | qla24xx_read_window(reg, 0x7690, 16, iter_reg); | ||
1542 | |||
1543 | qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg); | ||
1544 | |||
1545 | /* Receive DMA registers. */ | ||
1546 | iter_reg = fw->rcvt0_data_dma_reg; | ||
1547 | iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg); | ||
1548 | qla24xx_read_window(reg, 0x7710, 16, iter_reg); | ||
1549 | |||
1550 | iter_reg = fw->rcvt1_data_dma_reg; | ||
1551 | iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg); | ||
1552 | qla24xx_read_window(reg, 0x7730, 16, iter_reg); | ||
1553 | |||
1554 | /* RISC registers. */ | ||
1555 | iter_reg = fw->risc_gp_reg; | ||
1556 | iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg); | ||
1557 | iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg); | ||
1558 | iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg); | ||
1559 | iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg); | ||
1560 | iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg); | ||
1561 | iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg); | ||
1562 | iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg); | ||
1563 | qla24xx_read_window(reg, 0x0F70, 16, iter_reg); | ||
1564 | |||
1565 | /* Local memory controller registers. */ | ||
1566 | iter_reg = fw->lmc_reg; | ||
1567 | iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg); | ||
1568 | iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg); | ||
1569 | iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg); | ||
1570 | iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg); | ||
1571 | iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg); | ||
1572 | iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg); | ||
1573 | iter_reg = qla24xx_read_window(reg, 0x3060, 16, iter_reg); | ||
1574 | qla24xx_read_window(reg, 0x3070, 16, iter_reg); | ||
1575 | |||
1576 | /* Fibre Protocol Module registers. */ | ||
1577 | iter_reg = fw->fpm_hdw_reg; | ||
1578 | iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg); | ||
1579 | iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg); | ||
1580 | iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg); | ||
1581 | iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg); | ||
1582 | iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg); | ||
1583 | iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg); | ||
1584 | iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg); | ||
1585 | iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg); | ||
1586 | iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg); | ||
1587 | iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg); | ||
1588 | iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg); | ||
1589 | iter_reg = qla24xx_read_window(reg, 0x40B0, 16, iter_reg); | ||
1590 | iter_reg = qla24xx_read_window(reg, 0x40C0, 16, iter_reg); | ||
1591 | qla24xx_read_window(reg, 0x40D0, 16, iter_reg); | ||
1592 | |||
1593 | /* Frame Buffer registers. */ | ||
1594 | iter_reg = fw->fb_hdw_reg; | ||
1595 | iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg); | ||
1596 | iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg); | ||
1597 | iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg); | ||
1598 | iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg); | ||
1599 | iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg); | ||
1600 | iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg); | ||
1601 | iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg); | ||
1602 | iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg); | ||
1603 | iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg); | ||
1604 | iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg); | ||
1605 | iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg); | ||
1606 | iter_reg = qla24xx_read_window(reg, 0x61C0, 16, iter_reg); | ||
1607 | qla24xx_read_window(reg, 0x6F00, 16, iter_reg); | ||
1608 | |||
1609 | /* Multi queue registers */ | ||
1610 | nxt_chain = qla25xx_copy_mq(ha, (void *)ha->fw_dump + ha->chain_offset, | ||
1611 | &last_chain); | ||
1612 | |||
1613 | rval = qla24xx_soft_reset(ha); | ||
1614 | if (rval != QLA_SUCCESS) | ||
1615 | goto qla81xx_fw_dump_failed_0; | ||
1616 | |||
1617 | rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram), | ||
1618 | &nxt); | ||
1619 | if (rval != QLA_SUCCESS) | ||
1620 | goto qla81xx_fw_dump_failed_0; | ||
1621 | |||
1622 | nxt = qla2xxx_copy_queues(ha, nxt); | ||
1623 | |||
1624 | nxt = qla24xx_copy_eft(ha, nxt); | ||
1625 | |||
1626 | /* Chain entries -- started with MQ. */ | ||
1627 | qla25xx_copy_fce(ha, nxt_chain, &last_chain); | ||
1628 | if (last_chain) { | ||
1629 | ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT); | ||
1630 | *last_chain |= __constant_htonl(DUMP_CHAIN_LAST); | ||
1631 | } | ||
1632 | |||
1633 | qla81xx_fw_dump_failed_0: | ||
1285 | if (rval != QLA_SUCCESS) { | 1634 | if (rval != QLA_SUCCESS) { |
1286 | qla_printk(KERN_WARNING, ha, | 1635 | qla_printk(KERN_WARNING, ha, |
1287 | "Failed to dump firmware (%x)!!!\n", rval); | 1636 | "Failed to dump firmware (%x)!!!\n", rval); |
@@ -1294,10 +1643,11 @@ qla25xx_fw_dump_failed_0: | |||
1294 | ha->fw_dumped = 1; | 1643 | ha->fw_dumped = 1; |
1295 | } | 1644 | } |
1296 | 1645 | ||
1297 | qla25xx_fw_dump_failed: | 1646 | qla81xx_fw_dump_failed: |
1298 | if (!hardware_locked) | 1647 | if (!hardware_locked) |
1299 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1648 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
1300 | } | 1649 | } |
1650 | |||
1301 | /****************************************************************************/ | 1651 | /****************************************************************************/ |
1302 | /* Driver Debug Functions. */ | 1652 | /* Driver Debug Functions. */ |
1303 | /****************************************************************************/ | 1653 | /****************************************************************************/ |