aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorKrishna Gudipati <kgudipat@brocade.com>2010-03-03 20:42:39 -0500
committerJames Bottomley <James.Bottomley@suse.de>2010-03-04 05:39:37 -0500
commit5c1fb1d55672a74d1c318f67cdddbb599df9a76c (patch)
tree0f861cc0e81e201131c2997ae0c4d72b9c1c4247 /drivers/scsi
parent4c147dd81966bd4ba7f026476237ba67ea72d5d9 (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.c71
-rw-r--r--drivers/scsi/bfa/include/bfa_svc.h1
-rw-r--r--drivers/scsi/bfa/include/bfi/bfi_lps.h8
-rw-r--r--drivers/scsi/bfa/include/cs/bfa_plog.h9
-rw-r--r--drivers/scsi/bfa/vport.c11
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);
49static void bfa_lps_send_logout(struct bfa_lps_s *lps); 49static void bfa_lps_send_logout(struct bfa_lps_s *lps);
50static void bfa_lps_login_comp(struct bfa_lps_s *lps); 50static void bfa_lps_login_comp(struct bfa_lps_s *lps);
51static void bfa_lps_logout_comp(struct bfa_lps_s *lps); 51static void bfa_lps_logout_comp(struct bfa_lps_s *lps);
52 52static 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
67static void bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event); 68static 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 */
420static void
421bfa_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 */
401static void 434static 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 */
570static void
571bfa_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 */
587static void
588bfa_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);
319void bfa_cb_lps_flogo_comp(void *bfad, void *uarg); 319void bfa_cb_lps_flogo_comp(void *bfad, void *uarg);
320void bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status); 320void bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status);
321void bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg); 321void bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg);
322void 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 {
30enum bfi_lps_i2h_msgs { 30enum 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
35struct bfi_lps_login_req_s { 36struct 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
81struct bfi_lps_cvl_event_s {
82 struct bfi_mhdr_s mh; /* common msg header */
83 u8 lp_tag;
84 u8 rsvd[3];
85};
86
80union bfi_lps_h2i_msg_u { 87union 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 */
894void
895bfa_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}