aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2012-05-09 21:19:25 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-05-17 06:11:52 -0400
commit809c75368d94d73c1fb4f1e6e3578ae3b5b72b1c (patch)
tree9643edaae9384c8508fc59a1702137d394aaf962 /drivers/scsi/lpfc
parentee0f4fe17b0fda87c7f4eb3ec6e96ef8291419bd (diff)
[SCSI] lpfc 8.3.31: Debug helper utility routines for dumping various SLI4 queues
Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com> Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r--drivers/scsi/lpfc/lpfc.h3
-rw-r--r--drivers/scsi/lpfc/lpfc_debugfs.c46
-rw-r--r--drivers/scsi/lpfc/lpfc_debugfs.h418
3 files changed, 467 insertions, 0 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 3099047d3faf..e5da6da20f8a 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -93,6 +93,9 @@ struct lpfc_sli2_slim;
93/* lpfc wait event data ready flag */ 93/* lpfc wait event data ready flag */
94#define LPFC_DATA_READY (1<<0) 94#define LPFC_DATA_READY (1<<0)
95 95
96/* queue dump line buffer size */
97#define LPFC_LBUF_SZ 128
98
96enum lpfc_polling_flags { 99enum lpfc_polling_flags {
97 ENABLE_FCP_RING_POLLING = 0x1, 100 ENABLE_FCP_RING_POLLING = 0x1,
98 DISABLE_FCP_RING_INT = 0x2 101 DISABLE_FCP_RING_INT = 0x2
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index af04b0d6688d..3217d63ed282 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -4466,3 +4466,49 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport)
4466#endif 4466#endif
4467 return; 4467 return;
4468} 4468}
4469
4470/*
4471 * Driver debug utility routines outside of debugfs. The debug utility
4472 * routines implemented here is intended to be used in the instrumented
4473 * debug driver for debugging host or port issues.
4474 */
4475
4476/**
4477 * lpfc_debug_dump_all_queues - dump all the queues with a hba
4478 * @phba: Pointer to HBA context object.
4479 *
4480 * This function dumps entries of all the queues asociated with the @phba.
4481 **/
4482void
4483lpfc_debug_dump_all_queues(struct lpfc_hba *phba)
4484{
4485 int fcp_wqidx;
4486
4487 /*
4488 * Dump Work Queues (WQs)
4489 */
4490 lpfc_debug_dump_mbx_wq(phba);
4491 lpfc_debug_dump_els_wq(phba);
4492
4493 for (fcp_wqidx = 0; fcp_wqidx < phba->cfg_fcp_wq_count; fcp_wqidx++)
4494 lpfc_debug_dump_fcp_wq(phba, fcp_wqidx);
4495
4496 lpfc_debug_dump_hdr_rq(phba);
4497 lpfc_debug_dump_dat_rq(phba);
4498 /*
4499 * Dump Complete Queues (CQs)
4500 */
4501 lpfc_debug_dump_mbx_cq(phba);
4502 lpfc_debug_dump_els_cq(phba);
4503
4504 for (fcp_wqidx = 0; fcp_wqidx < phba->cfg_fcp_wq_count; fcp_wqidx++)
4505 lpfc_debug_dump_fcp_cq(phba, fcp_wqidx);
4506
4507 /*
4508 * Dump Event Queues (EQs)
4509 */
4510 lpfc_debug_dump_sp_eq(phba);
4511
4512 for (fcp_wqidx = 0; fcp_wqidx < phba->cfg_fcp_wq_count; fcp_wqidx++)
4513 lpfc_debug_dump_fcp_eq(phba, fcp_wqidx);
4514}
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.h b/drivers/scsi/lpfc/lpfc_debugfs.h
index f83bd944edd8..616c400dae14 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.h
+++ b/drivers/scsi/lpfc/lpfc_debugfs.h
@@ -267,3 +267,421 @@ struct lpfc_idiag {
267#define LPFC_DISC_TRC_DISCOVERY 0xef /* common mask for general 267#define LPFC_DISC_TRC_DISCOVERY 0xef /* common mask for general
268 * discovery */ 268 * discovery */
269#endif /* H_LPFC_DEBUG_FS */ 269#endif /* H_LPFC_DEBUG_FS */
270
271
272/*
273 * Driver debug utility routines outside of debugfs. The debug utility
274 * routines implemented here is intended to be used in the instrumented
275 * debug driver for debugging host or port issues.
276 */
277
278/**
279 * lpfc_debug_dump_qe - dump an specific entry from a queue
280 * @q: Pointer to the queue descriptor.
281 * @idx: Index to the entry on the queue.
282 *
283 * This function dumps an entry indexed by @idx from a queue specified by the
284 * queue descriptor @q.
285 **/
286static inline void
287lpfc_debug_dump_qe(struct lpfc_queue *q, uint32_t idx)
288{
289 char line_buf[LPFC_LBUF_SZ];
290 int i, esize, qe_word_cnt, len;
291 uint32_t *pword;
292
293 /* sanity checks */
294 if (!q)
295 return;
296 if (idx >= q->entry_count)
297 return;
298
299 esize = q->entry_size;
300 qe_word_cnt = esize / sizeof(uint32_t);
301 pword = q->qe[idx].address;
302
303 len = 0;
304 len += snprintf(line_buf+len, LPFC_LBUF_SZ-len, "QE[%04d]: ", idx);
305 if (qe_word_cnt > 8)
306 printk(KERN_ERR "%s\n", line_buf);
307
308 for (i = 0; i < qe_word_cnt; i++) {
309 if (!(i % 8)) {
310 if (i != 0)
311 printk(KERN_ERR "%s\n", line_buf);
312 if (qe_word_cnt > 8) {
313 len = 0;
314 memset(line_buf, 0, LPFC_LBUF_SZ);
315 len += snprintf(line_buf+len, LPFC_LBUF_SZ-len,
316 "%03d: ", i);
317 }
318 }
319 len += snprintf(line_buf+len, LPFC_LBUF_SZ-len, "%08x ",
320 ((uint32_t)*pword) & 0xffffffff);
321 pword++;
322 }
323 if (qe_word_cnt <= 8 || (i - 1) % 8)
324 printk(KERN_ERR "%s\n", line_buf);
325}
326
327/**
328 * lpfc_debug_dump_q - dump all entries from an specific queue
329 * @q: Pointer to the queue descriptor.
330 *
331 * This function dumps all entries from a queue specified by the queue
332 * descriptor @q.
333 **/
334static inline void
335lpfc_debug_dump_q(struct lpfc_queue *q)
336{
337 int idx, entry_count;
338
339 /* sanity check */
340 if (!q)
341 return;
342
343 dev_printk(KERN_ERR, &(((q->phba))->pcidev)->dev,
344 "%d: [qid:%d, type:%d, subtype:%d, "
345 "qe_size:%d, qe_count:%d, "
346 "host_index:%d, port_index:%d]\n",
347 (q->phba)->brd_no,
348 q->queue_id, q->type, q->subtype,
349 q->entry_size, q->entry_count,
350 q->host_index, q->hba_index);
351 entry_count = q->entry_count;
352 for (idx = 0; idx < entry_count; idx++)
353 lpfc_debug_dump_qe(q, idx);
354 printk(KERN_ERR "\n");
355}
356
357/**
358 * lpfc_debug_dump_fcp_wq - dump all entries from a fcp work queue
359 * @phba: Pointer to HBA context object.
360 * @fcp_wqidx: Index to a FCP work queue.
361 *
362 * This function dumps all entries from a FCP work queue specified by the
363 * @fcp_wqidx.
364 **/
365static inline void
366lpfc_debug_dump_fcp_wq(struct lpfc_hba *phba, int fcp_wqidx)
367{
368 /* sanity check */
369 if (fcp_wqidx >= phba->cfg_fcp_wq_count)
370 return;
371
372 printk(KERN_ERR "FCP WQ: WQ[Idx:%d|Qid:%d]\n",
373 fcp_wqidx, phba->sli4_hba.fcp_wq[fcp_wqidx]->queue_id);
374 lpfc_debug_dump_q(phba->sli4_hba.fcp_wq[fcp_wqidx]);
375}
376
377/**
378 * lpfc_debug_dump_fcp_cq - dump all entries from a fcp work queue's cmpl queue
379 * @phba: Pointer to HBA context object.
380 * @fcp_wqidx: Index to a FCP work queue.
381 *
382 * This function dumps all entries from a FCP complete queue which is
383 * associated to the FCP work queue specified by the @fcp_wqidx.
384 **/
385static inline void
386lpfc_debug_dump_fcp_cq(struct lpfc_hba *phba, int fcp_wqidx)
387{
388 int fcp_cqidx, fcp_cqid;
389
390 /* sanity check */
391 if (fcp_wqidx >= phba->cfg_fcp_wq_count)
392 return;
393
394 fcp_cqid = phba->sli4_hba.fcp_wq[fcp_wqidx]->assoc_qid;
395 for (fcp_cqidx = 0; fcp_cqidx < phba->cfg_fcp_eq_count; fcp_cqidx++)
396 if (phba->sli4_hba.fcp_cq[fcp_cqidx]->queue_id == fcp_cqid)
397 break;
398 if (fcp_cqidx >= phba->cfg_fcp_eq_count)
399 return;
400
401 printk(KERN_ERR "FCP CQ: WQ[Idx:%d|Qid%d]->CQ[Idx%d|Qid%d]:\n",
402 fcp_wqidx, phba->sli4_hba.fcp_wq[fcp_wqidx]->queue_id,
403 fcp_cqidx, fcp_cqid);
404 lpfc_debug_dump_q(phba->sli4_hba.fcp_cq[fcp_cqidx]);
405}
406
407/**
408 * lpfc_debug_dump_fcp_eq - dump all entries from a fcp work queue's evt queue
409 * @phba: Pointer to HBA context object.
410 * @fcp_wqidx: Index to a FCP work queue.
411 *
412 * This function dumps all entries from a FCP event queue which is
413 * associated to the FCP work queue specified by the @fcp_wqidx.
414 **/
415static inline void
416lpfc_debug_dump_fcp_eq(struct lpfc_hba *phba, int fcp_wqidx)
417{
418 struct lpfc_queue *qdesc;
419 int fcp_eqidx, fcp_eqid;
420 int fcp_cqidx, fcp_cqid;
421
422 /* sanity check */
423 if (fcp_wqidx >= phba->cfg_fcp_wq_count)
424 return;
425 fcp_cqid = phba->sli4_hba.fcp_wq[fcp_wqidx]->assoc_qid;
426 for (fcp_cqidx = 0; fcp_cqidx < phba->cfg_fcp_eq_count; fcp_cqidx++)
427 if (phba->sli4_hba.fcp_cq[fcp_cqidx]->queue_id == fcp_cqid)
428 break;
429 if (fcp_cqidx >= phba->cfg_fcp_eq_count)
430 return;
431
432 if (phba->cfg_fcp_eq_count == 0) {
433 fcp_eqidx = -1;
434 fcp_eqid = phba->sli4_hba.sp_eq->queue_id;
435 qdesc = phba->sli4_hba.sp_eq;
436 } else {
437 fcp_eqidx = fcp_cqidx;
438 fcp_eqid = phba->sli4_hba.fp_eq[fcp_eqidx]->queue_id;
439 qdesc = phba->sli4_hba.fp_eq[fcp_eqidx];
440 }
441
442 printk(KERN_ERR "FCP EQ: WQ[Idx:%d|Qid:%d]->CQ[Idx:%d|Qid:%d]->"
443 "EQ[Idx:%d|Qid:%d]\n",
444 fcp_wqidx, phba->sli4_hba.fcp_wq[fcp_wqidx]->queue_id,
445 fcp_cqidx, fcp_cqid, fcp_eqidx, fcp_eqid);
446 lpfc_debug_dump_q(qdesc);
447}
448
449/**
450 * lpfc_debug_dump_els_wq - dump all entries from the els work queue
451 * @phba: Pointer to HBA context object.
452 *
453 * This function dumps all entries from the ELS work queue.
454 **/
455static inline void
456lpfc_debug_dump_els_wq(struct lpfc_hba *phba)
457{
458 printk(KERN_ERR "ELS WQ: WQ[Qid:%d]:\n",
459 phba->sli4_hba.els_wq->queue_id);
460 lpfc_debug_dump_q(phba->sli4_hba.els_wq);
461}
462
463/**
464 * lpfc_debug_dump_mbx_wq - dump all entries from the mbox work queue
465 * @phba: Pointer to HBA context object.
466 *
467 * This function dumps all entries from the MBOX work queue.
468 **/
469static inline void
470lpfc_debug_dump_mbx_wq(struct lpfc_hba *phba)
471{
472 printk(KERN_ERR "MBX WQ: WQ[Qid:%d]\n",
473 phba->sli4_hba.mbx_wq->queue_id);
474 lpfc_debug_dump_q(phba->sli4_hba.mbx_wq);
475}
476
477/**
478 * lpfc_debug_dump_dat_rq - dump all entries from the receive data queue
479 * @phba: Pointer to HBA context object.
480 *
481 * This function dumps all entries from the receive data queue.
482 **/
483static inline void
484lpfc_debug_dump_dat_rq(struct lpfc_hba *phba)
485{
486 printk(KERN_ERR "DAT RQ: RQ[Qid:%d]\n",
487 phba->sli4_hba.dat_rq->queue_id);
488 lpfc_debug_dump_q(phba->sli4_hba.dat_rq);
489}
490
491/**
492 * lpfc_debug_dump_hdr_rq - dump all entries from the receive header queue
493 * @phba: Pointer to HBA context object.
494 *
495 * This function dumps all entries from the receive header queue.
496 **/
497static inline void
498lpfc_debug_dump_hdr_rq(struct lpfc_hba *phba)
499{
500 printk(KERN_ERR "HDR RQ: RQ[Qid:%d]\n",
501 phba->sli4_hba.hdr_rq->queue_id);
502 lpfc_debug_dump_q(phba->sli4_hba.hdr_rq);
503}
504
505/**
506 * lpfc_debug_dump_els_cq - dump all entries from the els complete queue
507 * @phba: Pointer to HBA context object.
508 *
509 * This function dumps all entries from the els complete queue.
510 **/
511static inline void
512lpfc_debug_dump_els_cq(struct lpfc_hba *phba)
513{
514 printk(KERN_ERR "ELS CQ: WQ[Qid:%d]->CQ[Qid:%d]\n",
515 phba->sli4_hba.els_wq->queue_id,
516 phba->sli4_hba.els_cq->queue_id);
517 lpfc_debug_dump_q(phba->sli4_hba.els_cq);
518}
519
520/**
521 * lpfc_debug_dump_mbx_cq - dump all entries from the mbox complete queue
522 * @phba: Pointer to HBA context object.
523 *
524 * This function dumps all entries from the mbox complete queue.
525 **/
526static inline void
527lpfc_debug_dump_mbx_cq(struct lpfc_hba *phba)
528{
529 printk(KERN_ERR "MBX CQ: WQ[Qid:%d]->CQ[Qid:%d]\n",
530 phba->sli4_hba.mbx_wq->queue_id,
531 phba->sli4_hba.mbx_cq->queue_id);
532 lpfc_debug_dump_q(phba->sli4_hba.mbx_cq);
533}
534
535/**
536 * lpfc_debug_dump_sp_eq - dump all entries from slow-path event queue
537 * @phba: Pointer to HBA context object.
538 *
539 * This function dumps all entries from the slow-path event queue.
540 **/
541static inline void
542lpfc_debug_dump_sp_eq(struct lpfc_hba *phba)
543{
544 printk(KERN_ERR "SP EQ: WQ[Qid:%d/Qid:%d]->CQ[Qid:%d/Qid:%d]->"
545 "EQ[Qid:%d]:\n",
546 phba->sli4_hba.mbx_wq->queue_id,
547 phba->sli4_hba.els_wq->queue_id,
548 phba->sli4_hba.mbx_cq->queue_id,
549 phba->sli4_hba.els_cq->queue_id,
550 phba->sli4_hba.sp_eq->queue_id);
551 lpfc_debug_dump_q(phba->sli4_hba.sp_eq);
552}
553
554/**
555 * lpfc_debug_dump_wq_by_id - dump all entries from a work queue by queue id
556 * @phba: Pointer to HBA context object.
557 * @qid: Work queue identifier.
558 *
559 * This function dumps all entries from a work queue identified by the queue
560 * identifier.
561 **/
562static inline void
563lpfc_debug_dump_wq_by_id(struct lpfc_hba *phba, int qid)
564{
565 int wq_idx;
566
567 for (wq_idx = 0; wq_idx < phba->cfg_fcp_wq_count; wq_idx++)
568 if (phba->sli4_hba.fcp_wq[wq_idx]->queue_id == qid)
569 break;
570 if (wq_idx < phba->cfg_fcp_wq_count) {
571 printk(KERN_ERR "FCP WQ[Idx:%d|Qid:%d]\n", wq_idx, qid);
572 lpfc_debug_dump_q(phba->sli4_hba.fcp_wq[wq_idx]);
573 return;
574 }
575
576 if (phba->sli4_hba.els_wq->queue_id == qid) {
577 printk(KERN_ERR "ELS WQ[Qid:%d]\n", qid);
578 lpfc_debug_dump_q(phba->sli4_hba.els_wq);
579 }
580}
581
582/**
583 * lpfc_debug_dump_mq_by_id - dump all entries from a mbox queue by queue id
584 * @phba: Pointer to HBA context object.
585 * @qid: Mbox work queue identifier.
586 *
587 * This function dumps all entries from a mbox work queue identified by the
588 * queue identifier.
589 **/
590static inline void
591lpfc_debug_dump_mq_by_id(struct lpfc_hba *phba, int qid)
592{
593 if (phba->sli4_hba.mbx_wq->queue_id == qid) {
594 printk(KERN_ERR "MBX WQ[Qid:%d]\n", qid);
595 lpfc_debug_dump_q(phba->sli4_hba.mbx_wq);
596 }
597}
598
599/**
600 * lpfc_debug_dump_rq_by_id - dump all entries from a receive queue by queue id
601 * @phba: Pointer to HBA context object.
602 * @qid: Receive queue identifier.
603 *
604 * This function dumps all entries from a receive queue identified by the
605 * queue identifier.
606 **/
607static inline void
608lpfc_debug_dump_rq_by_id(struct lpfc_hba *phba, int qid)
609{
610 if (phba->sli4_hba.hdr_rq->queue_id == qid) {
611 printk(KERN_ERR "HDR RQ[Qid:%d]\n", qid);
612 lpfc_debug_dump_q(phba->sli4_hba.hdr_rq);
613 return;
614 }
615 if (phba->sli4_hba.dat_rq->queue_id == qid) {
616 printk(KERN_ERR "DAT RQ[Qid:%d]\n", qid);
617 lpfc_debug_dump_q(phba->sli4_hba.dat_rq);
618 }
619}
620
621/**
622 * lpfc_debug_dump_cq_by_id - dump all entries from a cmpl queue by queue id
623 * @phba: Pointer to HBA context object.
624 * @qid: Complete queue identifier.
625 *
626 * This function dumps all entries from a complete queue identified by the
627 * queue identifier.
628 **/
629static inline void
630lpfc_debug_dump_cq_by_id(struct lpfc_hba *phba, int qid)
631{
632 int cq_idx = 0;
633
634 do {
635 if (phba->sli4_hba.fcp_cq[cq_idx]->queue_id == qid)
636 break;
637 } while (++cq_idx < phba->cfg_fcp_eq_count);
638
639 if (cq_idx < phba->cfg_fcp_eq_count) {
640 printk(KERN_ERR "FCP CQ[Idx:%d|Qid:%d]\n", cq_idx, qid);
641 lpfc_debug_dump_q(phba->sli4_hba.fcp_cq[cq_idx]);
642 return;
643 }
644
645 if (phba->sli4_hba.els_cq->queue_id == qid) {
646 printk(KERN_ERR "ELS CQ[Qid:%d]\n", qid);
647 lpfc_debug_dump_q(phba->sli4_hba.els_cq);
648 return;
649 }
650
651 if (phba->sli4_hba.mbx_cq->queue_id == qid) {
652 printk(KERN_ERR "MBX CQ[Qid:%d]\n", qid);
653 lpfc_debug_dump_q(phba->sli4_hba.mbx_cq);
654 }
655}
656
657/**
658 * lpfc_debug_dump_eq_by_id - dump all entries from an event queue by queue id
659 * @phba: Pointer to HBA context object.
660 * @qid: Complete queue identifier.
661 *
662 * This function dumps all entries from an event queue identified by the
663 * queue identifier.
664 **/
665static inline void
666lpfc_debug_dump_eq_by_id(struct lpfc_hba *phba, int qid)
667{
668 int eq_idx;
669
670 for (eq_idx = 0; eq_idx < phba->cfg_fcp_eq_count; eq_idx++) {
671 if (phba->sli4_hba.fp_eq[eq_idx]->queue_id == qid)
672 break;
673 }
674
675 if (eq_idx < phba->cfg_fcp_eq_count) {
676 printk(KERN_ERR "FCP EQ[Idx:%d|Qid:%d]\n", eq_idx, qid);
677 lpfc_debug_dump_q(phba->sli4_hba.fp_eq[eq_idx]);
678 return;
679 }
680
681 if (phba->sli4_hba.sp_eq->queue_id == qid) {
682 printk(KERN_ERR "SP EQ[|Qid:%d]\n", qid);
683 lpfc_debug_dump_q(phba->sli4_hba.sp_eq);
684 }
685}
686
687void lpfc_debug_dump_all_queues(struct lpfc_hba *);