aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorKrishna Gudipati <kgudipat@brocade.com>2010-03-05 22:36:30 -0500
committerJames Bottomley <James.Bottomley@suse.de>2010-03-07 02:29:36 -0500
commit9693e7dff5c2911b4e445f5f656ef57b3a5bffac (patch)
treeaff9c3bc987ab561f828ad286b3edc30547531bd /drivers/scsi
parent738c9e66dcb7e17a962a7d65c976386b970d10ca (diff)
[SCSI] bfa: Introduce a link notification state machine.
Introduce a link notification state machine to handle next incoming link events while the current event is being delivered to the driver. When the event has been processed by the driver, the link notification state machine will queue the next event (if there is any) to the driver. 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_fcport.c232
-rw-r--r--drivers/scsi/bfa/bfa_port_priv.h13
2 files changed, 230 insertions, 15 deletions
diff --git a/drivers/scsi/bfa/bfa_fcport.c b/drivers/scsi/bfa/bfa_fcport.c
index aef648b55dfc..4ed048bf45cb 100644
--- a/drivers/scsi/bfa/bfa_fcport.c
+++ b/drivers/scsi/bfa/bfa_fcport.c
@@ -26,16 +26,6 @@
26BFA_TRC_FILE(HAL, PPORT); 26BFA_TRC_FILE(HAL, PPORT);
27BFA_MODULE(pport); 27BFA_MODULE(pport);
28 28
29#define bfa_pport_callback(__pport, __event) do { \
30 if ((__pport)->bfa->fcs) { \
31 (__pport)->event_cbfn((__pport)->event_cbarg, (__event)); \
32 } else { \
33 (__pport)->hcb_event = (__event); \
34 bfa_cb_queue((__pport)->bfa, &(__pport)->hcb_qe, \
35 __bfa_cb_port_event, (__pport)); \
36 } \
37} while (0)
38
39/* 29/*
40 * The port is considered disabled if corresponding physical port or IOC are 30 * The port is considered disabled if corresponding physical port or IOC are
41 * disabled explicitly 31 * disabled explicitly
@@ -57,7 +47,10 @@ static void __bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete);
57static void __bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete); 47static void __bfa_cb_port_stats_clr(void *cbarg, bfa_boolean_t complete);
58static void bfa_port_stats_timeout(void *cbarg); 48static void bfa_port_stats_timeout(void *cbarg);
59static void bfa_port_stats_clr_timeout(void *cbarg); 49static void bfa_port_stats_clr_timeout(void *cbarg);
60 50static void bfa_pport_callback(struct bfa_pport_s *pport,
51 enum bfa_pport_linkstate event);
52static void bfa_pport_queue_cb(struct bfa_pport_ln_s *ln,
53 enum bfa_pport_linkstate event);
61/** 54/**
62 * bfa_pport_private 55 * bfa_pport_private
63 */ 56 */
@@ -77,6 +70,16 @@ enum bfa_pport_sm_event {
77 BFA_PPORT_SM_HWFAIL = 9, /* IOC h/w failure */ 70 BFA_PPORT_SM_HWFAIL = 9, /* IOC h/w failure */
78}; 71};
79 72
73/**
74 * BFA port link notification state machine events
75 */
76
77enum bfa_pport_ln_sm_event {
78 BFA_PPORT_LN_SM_LINKUP = 1, /* linkup event */
79 BFA_PPORT_LN_SM_LINKDOWN = 2, /* linkdown event */
80 BFA_PPORT_LN_SM_NOTIFICATION = 3 /* done notification */
81};
82
80static void bfa_pport_sm_uninit(struct bfa_pport_s *pport, 83static void bfa_pport_sm_uninit(struct bfa_pport_s *pport,
81 enum bfa_pport_sm_event event); 84 enum bfa_pport_sm_event event);
82static void bfa_pport_sm_enabling_qwait(struct bfa_pport_s *pport, 85static void bfa_pport_sm_enabling_qwait(struct bfa_pport_s *pport,
@@ -100,6 +103,21 @@ static void bfa_pport_sm_iocdown(struct bfa_pport_s *pport,
100static void bfa_pport_sm_iocfail(struct bfa_pport_s *pport, 103static void bfa_pport_sm_iocfail(struct bfa_pport_s *pport,
101 enum bfa_pport_sm_event event); 104 enum bfa_pport_sm_event event);
102 105
106static void bfa_pport_ln_sm_dn(struct bfa_pport_ln_s *ln,
107 enum bfa_pport_ln_sm_event event);
108static void bfa_pport_ln_sm_dn_nf(struct bfa_pport_ln_s *ln,
109 enum bfa_pport_ln_sm_event event);
110static void bfa_pport_ln_sm_dn_up_nf(struct bfa_pport_ln_s *ln,
111 enum bfa_pport_ln_sm_event event);
112static void bfa_pport_ln_sm_up(struct bfa_pport_ln_s *ln,
113 enum bfa_pport_ln_sm_event event);
114static void bfa_pport_ln_sm_up_nf(struct bfa_pport_ln_s *ln,
115 enum bfa_pport_ln_sm_event event);
116static void bfa_pport_ln_sm_up_dn_nf(struct bfa_pport_ln_s *ln,
117 enum bfa_pport_ln_sm_event event);
118static void bfa_pport_ln_sm_up_dn_up_nf(struct bfa_pport_ln_s *ln,
119 enum bfa_pport_ln_sm_event event);
120
103static struct bfa_sm_table_s hal_pport_sm_table[] = { 121static struct bfa_sm_table_s hal_pport_sm_table[] = {
104 {BFA_SM(bfa_pport_sm_uninit), BFA_PPORT_ST_UNINIT}, 122 {BFA_SM(bfa_pport_sm_uninit), BFA_PPORT_ST_UNINIT},
105 {BFA_SM(bfa_pport_sm_enabling_qwait), BFA_PPORT_ST_ENABLING_QWAIT}, 123 {BFA_SM(bfa_pport_sm_enabling_qwait), BFA_PPORT_ST_ENABLING_QWAIT},
@@ -619,7 +637,163 @@ bfa_pport_sm_iocfail(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
619 } 637 }
620} 638}
621 639
640/**
641 * Link state is down
642 */
643static void
644bfa_pport_ln_sm_dn(struct bfa_pport_ln_s *ln,
645 enum bfa_pport_ln_sm_event event)
646{
647 bfa_trc(ln->pport->bfa, event);
648
649 switch (event) {
650 case BFA_PPORT_LN_SM_LINKUP:
651 bfa_sm_set_state(ln, bfa_pport_ln_sm_up_nf);
652 bfa_pport_queue_cb(ln, BFA_PPORT_LINKUP);
653 break;
654
655 default:
656 bfa_sm_fault(ln->pport->bfa, event);
657 }
658}
659
660/**
661 * Link state is waiting for down notification
662 */
663static void
664bfa_pport_ln_sm_dn_nf(struct bfa_pport_ln_s *ln,
665 enum bfa_pport_ln_sm_event event)
666{
667 bfa_trc(ln->pport->bfa, event);
668
669 switch (event) {
670 case BFA_PPORT_LN_SM_LINKUP:
671 bfa_sm_set_state(ln, bfa_pport_ln_sm_dn_up_nf);
672 break;
673
674 case BFA_PPORT_LN_SM_NOTIFICATION:
675 bfa_sm_set_state(ln, bfa_pport_ln_sm_dn);
676 break;
677
678 default:
679 bfa_sm_fault(ln->pport->bfa, event);
680 }
681}
682
683/**
684 * Link state is waiting for down notification and there is a pending up
685 */
686static void
687bfa_pport_ln_sm_dn_up_nf(struct bfa_pport_ln_s *ln,
688 enum bfa_pport_ln_sm_event event)
689{
690 bfa_trc(ln->pport->bfa, event);
691
692 switch (event) {
693 case BFA_PPORT_LN_SM_LINKDOWN:
694 bfa_sm_set_state(ln, bfa_pport_ln_sm_dn_nf);
695 break;
696
697 case BFA_PPORT_LN_SM_NOTIFICATION:
698 bfa_sm_set_state(ln, bfa_pport_ln_sm_up_nf);
699 bfa_pport_queue_cb(ln, BFA_PPORT_LINKUP);
700 break;
701
702 default:
703 bfa_sm_fault(ln->pport->bfa, event);
704 }
705}
706
707/**
708 * Link state is up
709 */
710static void
711bfa_pport_ln_sm_up(struct bfa_pport_ln_s *ln,
712 enum bfa_pport_ln_sm_event event)
713{
714 bfa_trc(ln->pport->bfa, event);
715
716 switch (event) {
717 case BFA_PPORT_LN_SM_LINKDOWN:
718 bfa_sm_set_state(ln, bfa_pport_ln_sm_dn_nf);
719 bfa_pport_queue_cb(ln, BFA_PPORT_LINKDOWN);
720 break;
721
722 default:
723 bfa_sm_fault(ln->pport->bfa, event);
724 }
725}
726
727/**
728 * Link state is waiting for up notification
729 */
730static void
731bfa_pport_ln_sm_up_nf(struct bfa_pport_ln_s *ln,
732 enum bfa_pport_ln_sm_event event)
733{
734 bfa_trc(ln->pport->bfa, event);
735
736 switch (event) {
737 case BFA_PPORT_LN_SM_LINKDOWN:
738 bfa_sm_set_state(ln, bfa_pport_ln_sm_up_dn_nf);
739 break;
740
741 case BFA_PPORT_LN_SM_NOTIFICATION:
742 bfa_sm_set_state(ln, bfa_pport_ln_sm_up);
743 break;
744
745 default:
746 bfa_sm_fault(ln->pport->bfa, event);
747 }
748}
749
750/**
751 * Link state is waiting for up notification and there is a pending down
752 */
753static void
754bfa_pport_ln_sm_up_dn_nf(struct bfa_pport_ln_s *ln,
755 enum bfa_pport_ln_sm_event event)
756{
757 bfa_trc(ln->pport->bfa, event);
622 758
759 switch (event) {
760 case BFA_PPORT_LN_SM_LINKUP:
761 bfa_sm_set_state(ln, bfa_pport_ln_sm_up_dn_up_nf);
762 break;
763
764 case BFA_PPORT_LN_SM_NOTIFICATION:
765 bfa_sm_set_state(ln, bfa_pport_ln_sm_dn_nf);
766 bfa_pport_queue_cb(ln, BFA_PPORT_LINKDOWN);
767 break;
768
769 default:
770 bfa_sm_fault(ln->pport->bfa, event);
771 }
772}
773
774/**
775 * Link state is waiting for up notification and there are pending down and up
776 */
777static void
778bfa_pport_ln_sm_up_dn_up_nf(struct bfa_pport_ln_s *ln,
779 enum bfa_pport_ln_sm_event event)
780{
781 bfa_trc(ln->pport->bfa, event);
782
783 switch (event) {
784 case BFA_PPORT_LN_SM_LINKDOWN:
785 bfa_sm_set_state(ln, bfa_pport_ln_sm_up_dn_nf);
786 break;
787
788 case BFA_PPORT_LN_SM_NOTIFICATION:
789 bfa_sm_set_state(ln, bfa_pport_ln_sm_dn_up_nf);
790 bfa_pport_queue_cb(ln, BFA_PPORT_LINKDOWN);
791 break;
792
793 default:
794 bfa_sm_fault(ln->pport->bfa, event);
795 }
796}
623 797
624/** 798/**
625 * bfa_pport_private 799 * bfa_pport_private
@@ -628,10 +802,12 @@ bfa_pport_sm_iocfail(struct bfa_pport_s *pport, enum bfa_pport_sm_event event)
628static void 802static void
629__bfa_cb_port_event(void *cbarg, bfa_boolean_t complete) 803__bfa_cb_port_event(void *cbarg, bfa_boolean_t complete)
630{ 804{
631 struct bfa_pport_s *pport = cbarg; 805 struct bfa_pport_ln_s *ln = cbarg;
632 806
633 if (complete) 807 if (complete)
634 pport->event_cbfn(pport->event_cbarg, pport->hcb_event); 808 ln->pport->event_cbfn(ln->pport->event_cbarg, ln->ln_event);
809 else
810 bfa_sm_send_event(ln, BFA_PPORT_LN_SM_NOTIFICATION);
635} 811}
636 812
637#define PPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_pport_stats_u), \ 813#define PPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_pport_stats_u), \
@@ -681,13 +857,16 @@ bfa_pport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
681{ 857{
682 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); 858 struct bfa_pport_s *pport = BFA_PORT_MOD(bfa);
683 struct bfa_pport_cfg_s *port_cfg = &pport->cfg; 859 struct bfa_pport_cfg_s *port_cfg = &pport->cfg;
860 struct bfa_pport_ln_s *ln = &pport->ln;
684 861
685 bfa_os_memset(pport, 0, sizeof(struct bfa_pport_s)); 862 bfa_os_memset(pport, 0, sizeof(struct bfa_pport_s));
686 pport->bfa = bfa; 863 pport->bfa = bfa;
864 ln->pport = pport;
687 865
688 bfa_pport_mem_claim(pport, meminfo); 866 bfa_pport_mem_claim(pport, meminfo);
689 867
690 bfa_sm_set_state(pport, bfa_pport_sm_uninit); 868 bfa_sm_set_state(pport, bfa_pport_sm_uninit);
869 bfa_sm_set_state(ln, bfa_pport_ln_sm_dn);
691 870
692 /** 871 /**
693 * initialize and set default configuration 872 * initialize and set default configuration
@@ -1369,6 +1548,33 @@ bfa_port_stats_clr_timeout(void *cbarg)
1369} 1548}
1370 1549
1371static void 1550static void
1551bfa_pport_callback(struct bfa_pport_s *pport, enum bfa_pport_linkstate event)
1552{
1553 if (pport->bfa->fcs) {
1554 pport->event_cbfn(pport->event_cbarg, event);
1555 return;
1556 }
1557
1558 switch (event) {
1559 case BFA_PPORT_LINKUP:
1560 bfa_sm_send_event(&pport->ln, BFA_PPORT_LN_SM_LINKUP);
1561 break;
1562 case BFA_PPORT_LINKDOWN:
1563 bfa_sm_send_event(&pport->ln, BFA_PPORT_LN_SM_LINKDOWN);
1564 break;
1565 default:
1566 bfa_assert(0);
1567 }
1568}
1569
1570static void
1571bfa_pport_queue_cb(struct bfa_pport_ln_s *ln, enum bfa_pport_linkstate event)
1572{
1573 ln->ln_event = event;
1574 bfa_cb_queue(ln->pport->bfa, &ln->ln_qe, __bfa_cb_port_event, ln);
1575}
1576
1577static void
1372__bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete) 1578__bfa_cb_port_stats(void *cbarg, bfa_boolean_t complete)
1373{ 1579{
1374 struct bfa_pport_s *port = cbarg; 1580 struct bfa_pport_s *port = cbarg;
diff --git a/drivers/scsi/bfa/bfa_port_priv.h b/drivers/scsi/bfa/bfa_port_priv.h
index 51f698a06b6d..f29701bd2369 100644
--- a/drivers/scsi/bfa/bfa_port_priv.h
+++ b/drivers/scsi/bfa/bfa_port_priv.h
@@ -23,6 +23,16 @@
23#include "bfa_intr_priv.h" 23#include "bfa_intr_priv.h"
24 24
25/** 25/**
26 * Link notification data structure
27 */
28struct bfa_pport_ln_s {
29 struct bfa_pport_s *pport;
30 bfa_sm_t sm;
31 struct bfa_cb_qe_s ln_qe; /* BFA callback queue elem for ln */
32 enum bfa_pport_linkstate ln_event; /* ln event for callback */
33};
34
35/**
26 * BFA physical port data structure 36 * BFA physical port data structure
27 */ 37 */
28struct bfa_pport_s { 38struct bfa_pport_s {
@@ -52,9 +62,8 @@ struct bfa_pport_s {
52 union bfi_pport_i2h_msg_u i2hmsg; 62 union bfi_pport_i2h_msg_u i2hmsg;
53 } event_arg; 63 } event_arg;
54 void *bfad; /* BFA driver handle */ 64 void *bfad; /* BFA driver handle */
65 struct bfa_pport_ln_s ln; /* Link Notification */
55 struct bfa_cb_qe_s hcb_qe; /* BFA callback queue elem */ 66 struct bfa_cb_qe_s hcb_qe; /* BFA callback queue elem */
56 enum bfa_pport_linkstate hcb_event;
57 /* link event for callback */
58 u32 msgtag; /* fimrware msg tag for reply */ 67 u32 msgtag; /* fimrware msg tag for reply */
59 u8 *stats_kva; 68 u8 *stats_kva;
60 u64 stats_pa; 69 u64 stats_pa;