aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorKrishna Gudipati <kgudipat@brocade.com>2010-12-13 19:16:09 -0500
committerJames Bottomley <James.Bottomley@suse.de>2010-12-21 13:37:11 -0500
commit4e78efefa3c083240bd47153ffa99642bfdc7811 (patch)
tree22fc66e5ce15626437555a5574ca93323e8355a8 /drivers/scsi
parentda99dcc98dd66a2de4864645bcafffd93cf5a62f (diff)
[SCSI] bfa: IOC fwtrace save logic & state machine fixes.
- Move fw trace save logic to bfa_ioc_sm_fail_entry(), so that fw trace is saved irrespective of the cause of the failure. - Make bfa_ioc_sm_fail() a failure parking state. - Rename bfa_ioc_sm_initfail() to a more appropriate bfa_ioc_sm_fail_retry() as it is no longer a parking state. Signed-off-by: Krishna Gudipati <kgudipat@brocade.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/bfa/bfa_ioc.c141
1 files changed, 74 insertions, 67 deletions
diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c
index c4d56506e966..9173bf20ffba 100644
--- a/drivers/scsi/bfa/bfa_ioc.c
+++ b/drivers/scsi/bfa/bfa_ioc.c
@@ -88,6 +88,8 @@ static void bfa_ioc_recover(struct bfa_ioc_s *ioc);
88static void bfa_ioc_check_attr_wwns(struct bfa_ioc_s *ioc); 88static void bfa_ioc_check_attr_wwns(struct bfa_ioc_s *ioc);
89static void bfa_ioc_disable_comp(struct bfa_ioc_s *ioc); 89static void bfa_ioc_disable_comp(struct bfa_ioc_s *ioc);
90static void bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc); 90static void bfa_ioc_lpu_stop(struct bfa_ioc_s *ioc);
91static void bfa_ioc_debug_save_ftrc(struct bfa_ioc_s *ioc);
92static void bfa_ioc_fail_notify(struct bfa_ioc_s *ioc);
91static void bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc); 93static void bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc);
92 94
93 95
@@ -102,7 +104,7 @@ enum ioc_event {
102 IOC_E_ENABLED = 5, /* f/w enabled */ 104 IOC_E_ENABLED = 5, /* f/w enabled */
103 IOC_E_FWRSP_GETATTR = 6, /* IOC get attribute response */ 105 IOC_E_FWRSP_GETATTR = 6, /* IOC get attribute response */
104 IOC_E_DISABLED = 7, /* f/w disabled */ 106 IOC_E_DISABLED = 7, /* f/w disabled */
105 IOC_E_FAILED = 8, /* failure notice by iocpf sm */ 107 IOC_E_PFFAILED = 8, /* failure notice by iocpf sm */
106 IOC_E_HBFAIL = 9, /* heartbeat failure */ 108 IOC_E_HBFAIL = 9, /* heartbeat failure */
107 IOC_E_HWERROR = 10, /* hardware error interrupt */ 109 IOC_E_HWERROR = 10, /* hardware error interrupt */
108 IOC_E_TIMEOUT = 11, /* timeout */ 110 IOC_E_TIMEOUT = 11, /* timeout */
@@ -113,7 +115,7 @@ bfa_fsm_state_decl(bfa_ioc, reset, struct bfa_ioc_s, enum ioc_event);
113bfa_fsm_state_decl(bfa_ioc, enabling, struct bfa_ioc_s, enum ioc_event); 115bfa_fsm_state_decl(bfa_ioc, enabling, struct bfa_ioc_s, enum ioc_event);
114bfa_fsm_state_decl(bfa_ioc, getattr, struct bfa_ioc_s, enum ioc_event); 116bfa_fsm_state_decl(bfa_ioc, getattr, struct bfa_ioc_s, enum ioc_event);
115bfa_fsm_state_decl(bfa_ioc, op, struct bfa_ioc_s, enum ioc_event); 117bfa_fsm_state_decl(bfa_ioc, op, struct bfa_ioc_s, enum ioc_event);
116bfa_fsm_state_decl(bfa_ioc, initfail, struct bfa_ioc_s, enum ioc_event); 118bfa_fsm_state_decl(bfa_ioc, fail_retry, struct bfa_ioc_s, enum ioc_event);
117bfa_fsm_state_decl(bfa_ioc, fail, struct bfa_ioc_s, enum ioc_event); 119bfa_fsm_state_decl(bfa_ioc, fail, struct bfa_ioc_s, enum ioc_event);
118bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc_s, enum ioc_event); 120bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc_s, enum ioc_event);
119bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc_s, enum ioc_event); 121bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc_s, enum ioc_event);
@@ -124,7 +126,7 @@ static struct bfa_sm_table_s ioc_sm_table[] = {
124 {BFA_SM(bfa_ioc_sm_enabling), BFA_IOC_ENABLING}, 126 {BFA_SM(bfa_ioc_sm_enabling), BFA_IOC_ENABLING},
125 {BFA_SM(bfa_ioc_sm_getattr), BFA_IOC_GETATTR}, 127 {BFA_SM(bfa_ioc_sm_getattr), BFA_IOC_GETATTR},
126 {BFA_SM(bfa_ioc_sm_op), BFA_IOC_OPERATIONAL}, 128 {BFA_SM(bfa_ioc_sm_op), BFA_IOC_OPERATIONAL},
127 {BFA_SM(bfa_ioc_sm_initfail), BFA_IOC_INITFAIL}, 129 {BFA_SM(bfa_ioc_sm_fail_retry), BFA_IOC_INITFAIL},
128 {BFA_SM(bfa_ioc_sm_fail), BFA_IOC_FAIL}, 130 {BFA_SM(bfa_ioc_sm_fail), BFA_IOC_FAIL},
129 {BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING}, 131 {BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING},
130 {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED}, 132 {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED},
@@ -298,13 +300,13 @@ bfa_ioc_sm_enabling(struct bfa_ioc_s *ioc, enum ioc_event event)
298 bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr); 300 bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
299 break; 301 break;
300 302
301 case IOC_E_FAILED: 303 case IOC_E_PFFAILED:
302 bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail); 304 /* !!! fall through !!! */
303 break;
304
305 case IOC_E_HWERROR: 305 case IOC_E_HWERROR:
306 bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail); 306 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
307 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL); 307 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry);
308 if (event != IOC_E_PFFAILED)
309 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL);
308 break; 310 break;
309 311
310 case IOC_E_DISABLE: 312 case IOC_E_DISABLE:
@@ -347,18 +349,16 @@ bfa_ioc_sm_getattr(struct bfa_ioc_s *ioc, enum ioc_event event)
347 bfa_fsm_set_state(ioc, bfa_ioc_sm_op); 349 bfa_fsm_set_state(ioc, bfa_ioc_sm_op);
348 break; 350 break;
349 351
350 case IOC_E_FAILED:
351 bfa_ioc_timer_stop(ioc);
352 bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail);
353 break; 352 break;
354 353 case IOC_E_PFFAILED:
355 case IOC_E_HWERROR: 354 case IOC_E_HWERROR:
356 bfa_ioc_timer_stop(ioc); 355 bfa_ioc_timer_stop(ioc);
357 /* fall through */ 356 /* !!! fall through !!! */
358
359 case IOC_E_TIMEOUT: 357 case IOC_E_TIMEOUT:
360 bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail); 358 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
361 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_GETATTRFAIL); 359 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry);
360 if (event != IOC_E_PFFAILED)
361 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_GETATTRFAIL);
362 break; 362 break;
363 363
364 case IOC_E_DISABLE: 364 case IOC_E_DISABLE:
@@ -399,18 +399,20 @@ bfa_ioc_sm_op(struct bfa_ioc_s *ioc, enum ioc_event event)
399 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); 399 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
400 break; 400 break;
401 401
402 case IOC_E_FAILED: 402 case IOC_E_PFFAILED:
403 bfa_hb_timer_stop(ioc);
404 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
405 break;
406
407 case IOC_E_HWERROR: 403 case IOC_E_HWERROR:
408 bfa_hb_timer_stop(ioc); 404 bfa_hb_timer_stop(ioc);
409 /* !!! fall through !!! */ 405 /* !!! fall through !!! */
410
411 case IOC_E_HBFAIL: 406 case IOC_E_HBFAIL:
412 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail); 407 bfa_ioc_fail_notify(ioc);
413 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL); 408
409 if (ioc->iocpf.auto_recover)
410 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail_retry);
411 else
412 bfa_fsm_set_state(ioc, bfa_ioc_sm_fail);
413
414 if (event != IOC_E_PFFAILED)
415 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_FAIL);
414 break; 416 break;
415 417
416 default: 418 default:
@@ -489,16 +491,16 @@ bfa_ioc_sm_disabled(struct bfa_ioc_s *ioc, enum ioc_event event)
489 491
490 492
491static void 493static void
492bfa_ioc_sm_initfail_entry(struct bfa_ioc_s *ioc) 494bfa_ioc_sm_fail_retry_entry(struct bfa_ioc_s *ioc)
493{ 495{
494 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); 496 bfa_trc(ioc, 0);
495} 497}
496 498
497/* 499/*
498 * Hardware initialization failed. 500 * Hardware initialization failed.
499 */ 501 */
500static void 502static void
501bfa_ioc_sm_initfail(struct bfa_ioc_s *ioc, enum ioc_event event) 503bfa_ioc_sm_fail_retry(struct bfa_ioc_s *ioc, enum ioc_event event)
502{ 504{
503 bfa_trc(ioc, event); 505 bfa_trc(ioc, event);
504 506
@@ -507,11 +509,17 @@ bfa_ioc_sm_initfail(struct bfa_ioc_s *ioc, enum ioc_event event)
507 bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr); 509 bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
508 break; 510 break;
509 511
510 case IOC_E_FAILED: 512 case IOC_E_PFFAILED:
513 case IOC_E_HWERROR:
511 /* 514 /*
512 * Initialization failure during iocpf init retry. 515 * Initialization retry failed.
513 */ 516 */
514 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); 517 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
518 if (event != IOC_E_PFFAILED)
519 bfa_fsm_send_event(&ioc->iocpf, IOCPF_E_INITFAIL);
520 break;
521
522 case IOC_E_ENABLE:
515 break; 523 break;
516 524
517 case IOC_E_DISABLE: 525 case IOC_E_DISABLE:
@@ -532,21 +540,7 @@ bfa_ioc_sm_initfail(struct bfa_ioc_s *ioc, enum ioc_event event)
532static void 540static void
533bfa_ioc_sm_fail_entry(struct bfa_ioc_s *ioc) 541bfa_ioc_sm_fail_entry(struct bfa_ioc_s *ioc)
534{ 542{
535 struct list_head *qe; 543 bfa_trc(ioc, 0);
536 struct bfa_ioc_hbfail_notify_s *notify;
537 struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
538
539 /*
540 * Notify driver and common modules registered for notification.
541 */
542 ioc->cbfn->hbfail_cbfn(ioc->bfa);
543 list_for_each(qe, &ioc->hb_notify_q) {
544 notify = (struct bfa_ioc_hbfail_notify_s *) qe;
545 notify->cbfn(notify->cbarg);
546 }
547
548 BFA_LOG(KERN_CRIT, bfad, bfa_log_level,
549 "Heart Beat of IOC has failed\n");
550} 544}
551 545
552/* 546/*
@@ -559,19 +553,10 @@ bfa_ioc_sm_fail(struct bfa_ioc_s *ioc, enum ioc_event event)
559 553
560 switch (event) { 554 switch (event) {
561 555
562 case IOC_E_FAILED:
563 /*
564 * Initialization failure during iocpf recovery.
565 * !!! Fall through !!!
566 */
567 case IOC_E_ENABLE: 556 case IOC_E_ENABLE:
568 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); 557 ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE);
569 break; 558 break;
570 559
571 case IOC_E_ENABLED:
572 bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr);
573 break;
574
575 case IOC_E_DISABLE: 560 case IOC_E_DISABLE:
576 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); 561 bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling);
577 break; 562 break;
@@ -793,7 +778,7 @@ bfa_iocpf_sm_hwinit(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
793 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail); 778 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail);
794 779
795 if (event == IOCPF_E_TIMEOUT) 780 if (event == IOCPF_E_TIMEOUT)
796 bfa_fsm_send_event(ioc, IOC_E_FAILED); 781 bfa_fsm_send_event(ioc, IOC_E_PFFAILED);
797 break; 782 break;
798 783
799 case IOCPF_E_DISABLE: 784 case IOCPF_E_DISABLE:
@@ -850,7 +835,7 @@ bfa_iocpf_sm_enabling(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
850 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail); 835 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail);
851 836
852 if (event == IOCPF_E_TIMEOUT) 837 if (event == IOCPF_E_TIMEOUT)
853 bfa_fsm_send_event(ioc, IOC_E_FAILED); 838 bfa_fsm_send_event(ioc, IOC_E_PFFAILED);
854 break; 839 break;
855 840
856 case IOCPF_E_DISABLE: 841 case IOCPF_E_DISABLE:
@@ -900,7 +885,7 @@ bfa_iocpf_sm_ready(struct bfa_iocpf_s *iocpf, enum iocpf_event event)
900 else 885 else
901 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail); 886 bfa_fsm_set_state(iocpf, bfa_iocpf_sm_initfail);
902 887
903 bfa_fsm_send_event(ioc, IOC_E_FAILED); 888 bfa_fsm_send_event(ioc, IOC_E_PFFAILED);
904 break; 889 break;
905 890
906 default: 891 default:
@@ -1725,6 +1710,29 @@ bfa_ioc_smem_clr(struct bfa_ioc_s *ioc, u32 soff, u32 sz)
1725} 1710}
1726 1711
1727static void 1712static void
1713bfa_ioc_fail_notify(struct bfa_ioc_s *ioc)
1714{
1715 struct list_head *qe;
1716 struct bfa_ioc_hbfail_notify_s *notify;
1717 struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
1718
1719 /**
1720 * Notify driver and common modules registered for notification.
1721 */
1722 ioc->cbfn->hbfail_cbfn(ioc->bfa);
1723 list_for_each(qe, &ioc->hb_notify_q) {
1724 notify = (struct bfa_ioc_hbfail_notify_s *) qe;
1725 notify->cbfn(notify->cbarg);
1726 }
1727
1728 bfa_ioc_debug_save_ftrc(ioc);
1729
1730 BFA_LOG(KERN_CRIT, bfad, bfa_log_level,
1731 "Heart Beat of IOC has failed\n");
1732
1733}
1734
1735static void
1728bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc) 1736bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc)
1729{ 1737{
1730 struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad; 1738 struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad;
@@ -2187,7 +2195,8 @@ bfa_ioc_get_adapter_attr(struct bfa_ioc_s *ioc,
2187 bfa_ioc_get_pci_chip_rev(ioc, ad_attr->hw_ver); 2195 bfa_ioc_get_pci_chip_rev(ioc, ad_attr->hw_ver);
2188 2196
2189 ad_attr->cna_capable = ioc->cna; 2197 ad_attr->cna_capable = ioc->cna;
2190 ad_attr->trunk_capable = (ad_attr->nports > 1) && !ioc->cna; 2198 ad_attr->trunk_capable = (ad_attr->nports > 1) && !ioc->cna &&
2199 !ad_attr->is_mezz;
2191} 2200}
2192 2201
2193enum bfa_ioc_type_e 2202enum bfa_ioc_type_e
@@ -2530,13 +2539,16 @@ bfa_ioc_fw_stats_clear(struct bfa_ioc_s *ioc)
2530 * Save firmware trace if configured. 2539 * Save firmware trace if configured.
2531 */ 2540 */
2532static void 2541static void
2533bfa_ioc_debug_save(struct bfa_ioc_s *ioc) 2542bfa_ioc_debug_save_ftrc(struct bfa_ioc_s *ioc)
2534{ 2543{
2535 int tlen; 2544 int tlen;
2536 2545
2537 if (ioc->dbg_fwsave_len) { 2546 if (ioc->dbg_fwsave_once) {
2538 tlen = ioc->dbg_fwsave_len; 2547 ioc->dbg_fwsave_once = BFA_FALSE;
2539 bfa_ioc_debug_fwtrc(ioc, ioc->dbg_fwsave, &tlen); 2548 if (ioc->dbg_fwsave_len) {
2549 tlen = ioc->dbg_fwsave_len;
2550 bfa_ioc_debug_fwtrc(ioc, ioc->dbg_fwsave, &tlen);
2551 }
2540 } 2552 }
2541} 2553}
2542 2554
@@ -2546,11 +2558,6 @@ bfa_ioc_debug_save(struct bfa_ioc_s *ioc)
2546static void 2558static void
2547bfa_ioc_recover(struct bfa_ioc_s *ioc) 2559bfa_ioc_recover(struct bfa_ioc_s *ioc)
2548{ 2560{
2549 if (ioc->dbg_fwsave_once) {
2550 ioc->dbg_fwsave_once = BFA_FALSE;
2551 bfa_ioc_debug_save(ioc);
2552 }
2553
2554 bfa_ioc_stats(ioc, ioc_hbfails); 2561 bfa_ioc_stats(ioc, ioc_hbfails);
2555 bfa_fsm_send_event(ioc, IOC_E_HBFAIL); 2562 bfa_fsm_send_event(ioc, IOC_E_HBFAIL);
2556} 2563}