diff options
-rw-r--r-- | drivers/scsi/qla2xxx/qla_dbg.c | 83 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_dbg.h | 14 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 11 |
3 files changed, 105 insertions, 3 deletions
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 45cbf0ba624d..cdf061763544 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c | |||
@@ -375,6 +375,77 @@ qla25xx_copy_fce(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain) | |||
375 | } | 375 | } |
376 | 376 | ||
377 | static inline void * | 377 | static inline void * |
378 | qla25xx_copy_mqueues(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain) | ||
379 | { | ||
380 | struct qla2xxx_mqueue_chain *q; | ||
381 | struct qla2xxx_mqueue_header *qh; | ||
382 | struct req_que *req; | ||
383 | struct rsp_que *rsp; | ||
384 | int que; | ||
385 | |||
386 | if (!ha->mqenable) | ||
387 | return ptr; | ||
388 | |||
389 | /* Request queues */ | ||
390 | for (que = 1; que < ha->max_req_queues; que++) { | ||
391 | req = ha->req_q_map[que]; | ||
392 | if (!req) | ||
393 | break; | ||
394 | |||
395 | /* Add chain. */ | ||
396 | q = ptr; | ||
397 | *last_chain = &q->type; | ||
398 | q->type = __constant_htonl(DUMP_CHAIN_QUEUE); | ||
399 | q->chain_size = htonl( | ||
400 | sizeof(struct qla2xxx_mqueue_chain) + | ||
401 | sizeof(struct qla2xxx_mqueue_header) + | ||
402 | (req->length * sizeof(request_t))); | ||
403 | ptr += sizeof(struct qla2xxx_mqueue_chain); | ||
404 | |||
405 | /* Add header. */ | ||
406 | qh = ptr; | ||
407 | qh->queue = __constant_htonl(TYPE_REQUEST_QUEUE); | ||
408 | qh->number = htonl(que); | ||
409 | qh->size = htonl(req->length * sizeof(request_t)); | ||
410 | ptr += sizeof(struct qla2xxx_mqueue_header); | ||
411 | |||
412 | /* Add data. */ | ||
413 | memcpy(ptr, req->ring, req->length * sizeof(request_t)); | ||
414 | ptr += req->length * sizeof(request_t); | ||
415 | } | ||
416 | |||
417 | /* Response queues */ | ||
418 | for (que = 1; que < ha->max_rsp_queues; que++) { | ||
419 | rsp = ha->rsp_q_map[que]; | ||
420 | if (!rsp) | ||
421 | break; | ||
422 | |||
423 | /* Add chain. */ | ||
424 | q = ptr; | ||
425 | *last_chain = &q->type; | ||
426 | q->type = __constant_htonl(DUMP_CHAIN_QUEUE); | ||
427 | q->chain_size = htonl( | ||
428 | sizeof(struct qla2xxx_mqueue_chain) + | ||
429 | sizeof(struct qla2xxx_mqueue_header) + | ||
430 | (rsp->length * sizeof(response_t))); | ||
431 | ptr += sizeof(struct qla2xxx_mqueue_chain); | ||
432 | |||
433 | /* Add header. */ | ||
434 | qh = ptr; | ||
435 | qh->queue = __constant_htonl(TYPE_RESPONSE_QUEUE); | ||
436 | qh->number = htonl(que); | ||
437 | qh->size = htonl(rsp->length * sizeof(response_t)); | ||
438 | ptr += sizeof(struct qla2xxx_mqueue_header); | ||
439 | |||
440 | /* Add data. */ | ||
441 | memcpy(ptr, rsp->ring, rsp->length * sizeof(response_t)); | ||
442 | ptr += rsp->length * sizeof(response_t); | ||
443 | } | ||
444 | |||
445 | return ptr; | ||
446 | } | ||
447 | |||
448 | static inline void * | ||
378 | qla25xx_copy_mq(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain) | 449 | qla25xx_copy_mq(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain) |
379 | { | 450 | { |
380 | uint32_t cnt, que_idx; | 451 | uint32_t cnt, que_idx; |
@@ -1322,12 +1393,16 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) | |||
1322 | nxt = qla24xx_copy_eft(ha, nxt); | 1393 | nxt = qla24xx_copy_eft(ha, nxt); |
1323 | 1394 | ||
1324 | /* Chain entries -- started with MQ. */ | 1395 | /* Chain entries -- started with MQ. */ |
1325 | qla25xx_copy_fce(ha, nxt_chain, &last_chain); | 1396 | nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain); |
1397 | nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain); | ||
1326 | if (last_chain) { | 1398 | if (last_chain) { |
1327 | ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT); | 1399 | ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT); |
1328 | *last_chain |= __constant_htonl(DUMP_CHAIN_LAST); | 1400 | *last_chain |= __constant_htonl(DUMP_CHAIN_LAST); |
1329 | } | 1401 | } |
1330 | 1402 | ||
1403 | /* Adjust valid length. */ | ||
1404 | ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump); | ||
1405 | |||
1331 | qla25xx_fw_dump_failed_0: | 1406 | qla25xx_fw_dump_failed_0: |
1332 | qla2xxx_dump_post_process(base_vha, rval); | 1407 | qla2xxx_dump_post_process(base_vha, rval); |
1333 | 1408 | ||
@@ -1636,12 +1711,16 @@ qla81xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) | |||
1636 | nxt = qla24xx_copy_eft(ha, nxt); | 1711 | nxt = qla24xx_copy_eft(ha, nxt); |
1637 | 1712 | ||
1638 | /* Chain entries -- started with MQ. */ | 1713 | /* Chain entries -- started with MQ. */ |
1639 | qla25xx_copy_fce(ha, nxt_chain, &last_chain); | 1714 | nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain); |
1715 | nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain); | ||
1640 | if (last_chain) { | 1716 | if (last_chain) { |
1641 | ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT); | 1717 | ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT); |
1642 | *last_chain |= __constant_htonl(DUMP_CHAIN_LAST); | 1718 | *last_chain |= __constant_htonl(DUMP_CHAIN_LAST); |
1643 | } | 1719 | } |
1644 | 1720 | ||
1721 | /* Adjust valid length. */ | ||
1722 | ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump); | ||
1723 | |||
1645 | qla81xx_fw_dump_failed_0: | 1724 | qla81xx_fw_dump_failed_0: |
1646 | qla2xxx_dump_post_process(base_vha, rval); | 1725 | qla2xxx_dump_post_process(base_vha, rval); |
1647 | 1726 | ||
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index 5f1b6d9c3dcb..6b05cb1d1874 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h | |||
@@ -192,9 +192,23 @@ struct qla2xxx_mq_chain { | |||
192 | uint32_t qregs[4 * QLA_MQ_SIZE]; | 192 | uint32_t qregs[4 * QLA_MQ_SIZE]; |
193 | }; | 193 | }; |
194 | 194 | ||
195 | struct qla2xxx_mqueue_header { | ||
196 | uint32_t queue; | ||
197 | #define TYPE_REQUEST_QUEUE 0x1 | ||
198 | #define TYPE_RESPONSE_QUEUE 0x2 | ||
199 | uint32_t number; | ||
200 | uint32_t size; | ||
201 | }; | ||
202 | |||
203 | struct qla2xxx_mqueue_chain { | ||
204 | uint32_t type; | ||
205 | uint32_t chain_size; | ||
206 | }; | ||
207 | |||
195 | #define DUMP_CHAIN_VARIANT 0x80000000 | 208 | #define DUMP_CHAIN_VARIANT 0x80000000 |
196 | #define DUMP_CHAIN_FCE 0x7FFFFAF0 | 209 | #define DUMP_CHAIN_FCE 0x7FFFFAF0 |
197 | #define DUMP_CHAIN_MQ 0x7FFFFAF1 | 210 | #define DUMP_CHAIN_MQ 0x7FFFFAF1 |
211 | #define DUMP_CHAIN_QUEUE 0x7FFFFAF2 | ||
198 | #define DUMP_CHAIN_LAST 0x80000000 | 212 | #define DUMP_CHAIN_LAST 0x80000000 |
199 | 213 | ||
200 | struct qla2xxx_fw_dump { | 214 | struct qla2xxx_fw_dump { |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 1fa067e053d2..68555dfee6ac 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -1270,8 +1270,17 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) | |||
1270 | fixed_size = offsetof(struct qla24xx_fw_dump, ext_mem); | 1270 | fixed_size = offsetof(struct qla24xx_fw_dump, ext_mem); |
1271 | mem_size = (ha->fw_memory_size - 0x100000 + 1) * | 1271 | mem_size = (ha->fw_memory_size - 0x100000 + 1) * |
1272 | sizeof(uint32_t); | 1272 | sizeof(uint32_t); |
1273 | if (ha->mqenable) | 1273 | if (ha->mqenable) { |
1274 | mq_size = sizeof(struct qla2xxx_mq_chain); | 1274 | mq_size = sizeof(struct qla2xxx_mq_chain); |
1275 | /* | ||
1276 | * Allocate maximum buffer size for all queues. | ||
1277 | * Resizing must be done at end-of-dump processing. | ||
1278 | */ | ||
1279 | mq_size += ha->max_req_queues * | ||
1280 | (req->length * sizeof(request_t)); | ||
1281 | mq_size += ha->max_rsp_queues * | ||
1282 | (rsp->length * sizeof(response_t)); | ||
1283 | } | ||
1275 | /* Allocate memory for Fibre Channel Event Buffer. */ | 1284 | /* Allocate memory for Fibre Channel Event Buffer. */ |
1276 | if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha)) | 1285 | if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha)) |
1277 | goto try_eft; | 1286 | goto try_eft; |