diff options
author | Krishna Gudipati <kgudipat@brocade.com> | 2010-03-03 20:42:39 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-03-04 05:39:37 -0500 |
commit | 5c1fb1d55672a74d1c318f67cdddbb599df9a76c (patch) | |
tree | 0f861cc0e81e201131c2997ae0c4d72b9c1c4247 /drivers/scsi | |
parent | 4c147dd81966bd4ba7f026476237ba67ea72d5d9 (diff) |
[SCSI] bfa: Defined a new LPS event to clear virtual link on a vport
Clear virtual links was not propagated upwards to bfa from fw.
This resulted in HBA and switch being in an inconsistent state.
So defined a new LPS event for clear virtual link on a vport,
and also now clear virtual link on a baseport, is sent as a
link down event from the fw.
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_lps.c | 71 | ||||
-rw-r--r-- | drivers/scsi/bfa/include/bfa_svc.h | 1 | ||||
-rw-r--r-- | drivers/scsi/bfa/include/bfi/bfi_lps.h | 8 | ||||
-rw-r--r-- | drivers/scsi/bfa/include/cs/bfa_plog.h | 9 | ||||
-rw-r--r-- | drivers/scsi/bfa/vport.c | 11 |
5 files changed, 97 insertions, 3 deletions
diff --git a/drivers/scsi/bfa/bfa_lps.c b/drivers/scsi/bfa/bfa_lps.c index 9844b45412b6..c8c2564af725 100644 --- a/drivers/scsi/bfa/bfa_lps.c +++ b/drivers/scsi/bfa/bfa_lps.c | |||
@@ -49,7 +49,7 @@ static void bfa_lps_send_login(struct bfa_lps_s *lps); | |||
49 | static void bfa_lps_send_logout(struct bfa_lps_s *lps); | 49 | static void bfa_lps_send_logout(struct bfa_lps_s *lps); |
50 | static void bfa_lps_login_comp(struct bfa_lps_s *lps); | 50 | static void bfa_lps_login_comp(struct bfa_lps_s *lps); |
51 | static void bfa_lps_logout_comp(struct bfa_lps_s *lps); | 51 | static void bfa_lps_logout_comp(struct bfa_lps_s *lps); |
52 | 52 | static void bfa_lps_cvl_event(struct bfa_lps_s *lps); | |
53 | 53 | ||
54 | /** | 54 | /** |
55 | * lps_pvt BFA LPS private functions | 55 | * lps_pvt BFA LPS private functions |
@@ -62,6 +62,7 @@ enum bfa_lps_event { | |||
62 | BFA_LPS_SM_RESUME = 4, /* space present in reqq queue */ | 62 | BFA_LPS_SM_RESUME = 4, /* space present in reqq queue */ |
63 | BFA_LPS_SM_DELETE = 5, /* lps delete from user */ | 63 | BFA_LPS_SM_DELETE = 5, /* lps delete from user */ |
64 | BFA_LPS_SM_OFFLINE = 6, /* Link is offline */ | 64 | BFA_LPS_SM_OFFLINE = 6, /* Link is offline */ |
65 | BFA_LPS_SM_RX_CVL = 7, /* Rx clear virtual link */ | ||
65 | }; | 66 | }; |
66 | 67 | ||
67 | static void bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event); | 68 | static void bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event); |
@@ -101,6 +102,7 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event) | |||
101 | bfa_lps_free(lps); | 102 | bfa_lps_free(lps); |
102 | break; | 103 | break; |
103 | 104 | ||
105 | case BFA_LPS_SM_RX_CVL: | ||
104 | case BFA_LPS_SM_OFFLINE: | 106 | case BFA_LPS_SM_OFFLINE: |
105 | break; | 107 | break; |
106 | 108 | ||
@@ -162,6 +164,14 @@ bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event event) | |||
162 | bfa_reqq_wcancel(&lps->wqe); | 164 | bfa_reqq_wcancel(&lps->wqe); |
163 | break; | 165 | break; |
164 | 166 | ||
167 | case BFA_LPS_SM_RX_CVL: | ||
168 | /* | ||
169 | * Login was not even sent out; so when getting out | ||
170 | * of this state, it will appear like a login retry | ||
171 | * after Clear virtual link | ||
172 | */ | ||
173 | break; | ||
174 | |||
165 | default: | 175 | default: |
166 | bfa_assert(0); | 176 | bfa_assert(0); |
167 | } | 177 | } |
@@ -187,6 +197,15 @@ bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event) | |||
187 | } | 197 | } |
188 | break; | 198 | break; |
189 | 199 | ||
200 | case BFA_LPS_SM_RX_CVL: | ||
201 | bfa_sm_set_state(lps, bfa_lps_sm_init); | ||
202 | |||
203 | /* Let the vport module know about this event */ | ||
204 | bfa_lps_cvl_event(lps); | ||
205 | bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS, | ||
206 | BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx"); | ||
207 | break; | ||
208 | |||
190 | case BFA_LPS_SM_OFFLINE: | 209 | case BFA_LPS_SM_OFFLINE: |
191 | case BFA_LPS_SM_DELETE: | 210 | case BFA_LPS_SM_DELETE: |
192 | bfa_sm_set_state(lps, bfa_lps_sm_init); | 211 | bfa_sm_set_state(lps, bfa_lps_sm_init); |
@@ -396,6 +415,20 @@ bfa_lps_logout_rsp(struct bfa_s *bfa, struct bfi_lps_logout_rsp_s *rsp) | |||
396 | } | 415 | } |
397 | 416 | ||
398 | /** | 417 | /** |
418 | * Firmware received a Clear virtual link request (for FCoE) | ||
419 | */ | ||
420 | static void | ||
421 | bfa_lps_rx_cvl_event(struct bfa_s *bfa, struct bfi_lps_cvl_event_s *cvl) | ||
422 | { | ||
423 | struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa); | ||
424 | struct bfa_lps_s *lps; | ||
425 | |||
426 | lps = BFA_LPS_FROM_TAG(mod, cvl->lp_tag); | ||
427 | |||
428 | bfa_sm_send_event(lps, BFA_LPS_SM_RX_CVL); | ||
429 | } | ||
430 | |||
431 | /** | ||
399 | * Space is available in request queue, resume queueing request to firmware. | 432 | * Space is available in request queue, resume queueing request to firmware. |
400 | */ | 433 | */ |
401 | static void | 434 | static void |
@@ -531,7 +564,39 @@ bfa_lps_logout_comp(struct bfa_lps_s *lps) | |||
531 | bfa_cb_lps_flogo_comp(lps->bfa->bfad, lps->uarg); | 564 | bfa_cb_lps_flogo_comp(lps->bfa->bfad, lps->uarg); |
532 | } | 565 | } |
533 | 566 | ||
567 | /** | ||
568 | * Clear virtual link completion handler for non-fcs | ||
569 | */ | ||
570 | static void | ||
571 | bfa_lps_cvl_event_cb(void *arg, bfa_boolean_t complete) | ||
572 | { | ||
573 | struct bfa_lps_s *lps = arg; | ||
574 | |||
575 | if (!complete) | ||
576 | return; | ||
577 | |||
578 | /* Clear virtual link to base port will result in link down */ | ||
579 | if (lps->fdisc) | ||
580 | bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg); | ||
581 | } | ||
582 | |||
583 | /** | ||
584 | * Received Clear virtual link event --direct call for fcs, | ||
585 | * queue for others | ||
586 | */ | ||
587 | static void | ||
588 | bfa_lps_cvl_event(struct bfa_lps_s *lps) | ||
589 | { | ||
590 | if (!lps->bfa->fcs) { | ||
591 | bfa_cb_queue(lps->bfa, &lps->hcb_qe, bfa_lps_cvl_event_cb, | ||
592 | lps); | ||
593 | return; | ||
594 | } | ||
534 | 595 | ||
596 | /* Clear virtual link to base port will result in link down */ | ||
597 | if (lps->fdisc) | ||
598 | bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg); | ||
599 | } | ||
535 | 600 | ||
536 | /** | 601 | /** |
537 | * lps_public BFA LPS public functions | 602 | * lps_public BFA LPS public functions |
@@ -773,6 +838,10 @@ bfa_lps_isr(struct bfa_s *bfa, struct bfi_msg_s *m) | |||
773 | bfa_lps_logout_rsp(bfa, msg.logout_rsp); | 838 | bfa_lps_logout_rsp(bfa, msg.logout_rsp); |
774 | break; | 839 | break; |
775 | 840 | ||
841 | case BFI_LPS_H2I_CVL_EVENT: | ||
842 | bfa_lps_rx_cvl_event(bfa, msg.cvl_event); | ||
843 | break; | ||
844 | |||
776 | default: | 845 | default: |
777 | bfa_trc(bfa, m->mhdr.msg_id); | 846 | bfa_trc(bfa, m->mhdr.msg_id); |
778 | bfa_assert(0); | 847 | bfa_assert(0); |
diff --git a/drivers/scsi/bfa/include/bfa_svc.h b/drivers/scsi/bfa/include/bfa_svc.h index 268d956bad89..2e4372f66b8b 100644 --- a/drivers/scsi/bfa/include/bfa_svc.h +++ b/drivers/scsi/bfa/include/bfa_svc.h | |||
@@ -319,6 +319,7 @@ void bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status); | |||
319 | void bfa_cb_lps_flogo_comp(void *bfad, void *uarg); | 319 | void bfa_cb_lps_flogo_comp(void *bfad, void *uarg); |
320 | void bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status); | 320 | void bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status); |
321 | void bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg); | 321 | void bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg); |
322 | void bfa_cb_lps_cvl_event(void *bfad, void *uarg); | ||
322 | 323 | ||
323 | #endif /* __BFA_SVC_H__ */ | 324 | #endif /* __BFA_SVC_H__ */ |
324 | 325 | ||
diff --git a/drivers/scsi/bfa/include/bfi/bfi_lps.h b/drivers/scsi/bfa/include/bfi/bfi_lps.h index c59d47badb4b..7ed31bbb8696 100644 --- a/drivers/scsi/bfa/include/bfi/bfi_lps.h +++ b/drivers/scsi/bfa/include/bfi/bfi_lps.h | |||
@@ -30,6 +30,7 @@ enum bfi_lps_h2i_msgs { | |||
30 | enum bfi_lps_i2h_msgs { | 30 | enum bfi_lps_i2h_msgs { |
31 | BFI_LPS_H2I_LOGIN_RSP = BFA_I2HM(1), | 31 | BFI_LPS_H2I_LOGIN_RSP = BFA_I2HM(1), |
32 | BFI_LPS_H2I_LOGOUT_RSP = BFA_I2HM(2), | 32 | BFI_LPS_H2I_LOGOUT_RSP = BFA_I2HM(2), |
33 | BFI_LPS_H2I_CVL_EVENT = BFA_I2HM(3), | ||
33 | }; | 34 | }; |
34 | 35 | ||
35 | struct bfi_lps_login_req_s { | 36 | struct bfi_lps_login_req_s { |
@@ -77,6 +78,12 @@ struct bfi_lps_logout_rsp_s { | |||
77 | u8 rsvd[2]; | 78 | u8 rsvd[2]; |
78 | }; | 79 | }; |
79 | 80 | ||
81 | struct bfi_lps_cvl_event_s { | ||
82 | struct bfi_mhdr_s mh; /* common msg header */ | ||
83 | u8 lp_tag; | ||
84 | u8 rsvd[3]; | ||
85 | }; | ||
86 | |||
80 | union bfi_lps_h2i_msg_u { | 87 | union bfi_lps_h2i_msg_u { |
81 | struct bfi_mhdr_s *msg; | 88 | struct bfi_mhdr_s *msg; |
82 | struct bfi_lps_login_req_s *login_req; | 89 | struct bfi_lps_login_req_s *login_req; |
@@ -87,6 +94,7 @@ union bfi_lps_i2h_msg_u { | |||
87 | struct bfi_msg_s *msg; | 94 | struct bfi_msg_s *msg; |
88 | struct bfi_lps_login_rsp_s *login_rsp; | 95 | struct bfi_lps_login_rsp_s *login_rsp; |
89 | struct bfi_lps_logout_rsp_s *logout_rsp; | 96 | struct bfi_lps_logout_rsp_s *logout_rsp; |
97 | struct bfi_lps_cvl_event_s *cvl_event; | ||
90 | }; | 98 | }; |
91 | 99 | ||
92 | #pragma pack() | 100 | #pragma pack() |
diff --git a/drivers/scsi/bfa/include/cs/bfa_plog.h b/drivers/scsi/bfa/include/cs/bfa_plog.h index 670f86e5fc6e..f5bef63b5877 100644 --- a/drivers/scsi/bfa/include/cs/bfa_plog.h +++ b/drivers/scsi/bfa/include/cs/bfa_plog.h | |||
@@ -80,7 +80,8 @@ enum bfa_plog_mid { | |||
80 | BFA_PL_MID_HAL_FCXP = 4, | 80 | BFA_PL_MID_HAL_FCXP = 4, |
81 | BFA_PL_MID_HAL_UF = 5, | 81 | BFA_PL_MID_HAL_UF = 5, |
82 | BFA_PL_MID_FCS = 6, | 82 | BFA_PL_MID_FCS = 6, |
83 | BFA_PL_MID_MAX = 7 | 83 | BFA_PL_MID_LPS = 7, |
84 | BFA_PL_MID_MAX = 8 | ||
84 | }; | 85 | }; |
85 | 86 | ||
86 | #define BFA_PL_MID_STRLEN 8 | 87 | #define BFA_PL_MID_STRLEN 8 |
@@ -118,7 +119,11 @@ enum bfa_plog_eid { | |||
118 | BFA_PL_EID_RSCN = 17, | 119 | BFA_PL_EID_RSCN = 17, |
119 | BFA_PL_EID_DEBUG = 18, | 120 | BFA_PL_EID_DEBUG = 18, |
120 | BFA_PL_EID_MISC = 19, | 121 | BFA_PL_EID_MISC = 19, |
121 | BFA_PL_EID_MAX = 20 | 122 | BFA_PL_EID_FIP_FCF_DISC = 20, |
123 | BFA_PL_EID_FIP_FCF_CVL = 21, | ||
124 | BFA_PL_EID_LOGIN = 22, | ||
125 | BFA_PL_EID_LOGO = 23, | ||
126 | BFA_PL_EID_MAX = 24 | ||
122 | }; | 127 | }; |
123 | 128 | ||
124 | #define BFA_PL_ENAME_STRLEN 8 | 129 | #define BFA_PL_ENAME_STRLEN 8 |
diff --git a/drivers/scsi/bfa/vport.c b/drivers/scsi/bfa/vport.c index e90f1e38c32d..8d18589e1da2 100644 --- a/drivers/scsi/bfa/vport.c +++ b/drivers/scsi/bfa/vport.c | |||
@@ -888,4 +888,15 @@ bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg) | |||
888 | bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK); | 888 | bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK); |
889 | } | 889 | } |
890 | 890 | ||
891 | /** | ||
892 | * Received clear virtual link | ||
893 | */ | ||
894 | void | ||
895 | bfa_cb_lps_cvl_event(void *bfad, void *uarg) | ||
896 | { | ||
897 | struct bfa_fcs_vport_s *vport = uarg; | ||
891 | 898 | ||
899 | /* Send an Offline followed by an ONLINE */ | ||
900 | bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE); | ||
901 | bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE); | ||
902 | } | ||