Skip to content

Commit

Permalink
[SCSI] bfa: Defined a new LPS event to clear virtual link on a vport
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Krishna Gudipati authored and James Bottomley committed Mar 4, 2010
1 parent 4c147dd commit 5c1fb1d
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 3 deletions.
71 changes: 70 additions & 1 deletion drivers/scsi/bfa/bfa_lps.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ static void bfa_lps_send_login(struct bfa_lps_s *lps);
static void bfa_lps_send_logout(struct bfa_lps_s *lps);
static void bfa_lps_login_comp(struct bfa_lps_s *lps);
static void bfa_lps_logout_comp(struct bfa_lps_s *lps);

static void bfa_lps_cvl_event(struct bfa_lps_s *lps);

/**
* lps_pvt BFA LPS private functions
Expand All @@ -62,6 +62,7 @@ enum bfa_lps_event {
BFA_LPS_SM_RESUME = 4, /* space present in reqq queue */
BFA_LPS_SM_DELETE = 5, /* lps delete from user */
BFA_LPS_SM_OFFLINE = 6, /* Link is offline */
BFA_LPS_SM_RX_CVL = 7, /* Rx clear virtual link */
};

static void bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event);
Expand Down Expand Up @@ -101,6 +102,7 @@ bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event)
bfa_lps_free(lps);
break;

case BFA_LPS_SM_RX_CVL:
case BFA_LPS_SM_OFFLINE:
break;

Expand Down Expand Up @@ -162,6 +164,14 @@ bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event event)
bfa_reqq_wcancel(&lps->wqe);
break;

case BFA_LPS_SM_RX_CVL:
/*
* Login was not even sent out; so when getting out
* of this state, it will appear like a login retry
* after Clear virtual link
*/
break;

default:
bfa_assert(0);
}
Expand All @@ -187,6 +197,15 @@ bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event)
}
break;

case BFA_LPS_SM_RX_CVL:
bfa_sm_set_state(lps, bfa_lps_sm_init);

/* Let the vport module know about this event */
bfa_lps_cvl_event(lps);
bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx");
break;

case BFA_LPS_SM_OFFLINE:
case BFA_LPS_SM_DELETE:
bfa_sm_set_state(lps, bfa_lps_sm_init);
Expand Down Expand Up @@ -395,6 +414,20 @@ bfa_lps_logout_rsp(struct bfa_s *bfa, struct bfi_lps_logout_rsp_s *rsp)
bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP);
}

/**
* Firmware received a Clear virtual link request (for FCoE)
*/
static void
bfa_lps_rx_cvl_event(struct bfa_s *bfa, struct bfi_lps_cvl_event_s *cvl)
{
struct bfa_lps_mod_s *mod = BFA_LPS_MOD(bfa);
struct bfa_lps_s *lps;

lps = BFA_LPS_FROM_TAG(mod, cvl->lp_tag);

bfa_sm_send_event(lps, BFA_LPS_SM_RX_CVL);
}

/**
* Space is available in request queue, resume queueing request to firmware.
*/
Expand Down Expand Up @@ -531,7 +564,39 @@ bfa_lps_logout_comp(struct bfa_lps_s *lps)
bfa_cb_lps_flogo_comp(lps->bfa->bfad, lps->uarg);
}

/**
* Clear virtual link completion handler for non-fcs
*/
static void
bfa_lps_cvl_event_cb(void *arg, bfa_boolean_t complete)
{
struct bfa_lps_s *lps = arg;

if (!complete)
return;

/* Clear virtual link to base port will result in link down */
if (lps->fdisc)
bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg);
}

/**
* Received Clear virtual link event --direct call for fcs,
* queue for others
*/
static void
bfa_lps_cvl_event(struct bfa_lps_s *lps)
{
if (!lps->bfa->fcs) {
bfa_cb_queue(lps->bfa, &lps->hcb_qe, bfa_lps_cvl_event_cb,
lps);
return;
}

/* Clear virtual link to base port will result in link down */
if (lps->fdisc)
bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg);
}

/**
* lps_public BFA LPS public functions
Expand Down Expand Up @@ -773,6 +838,10 @@ bfa_lps_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
bfa_lps_logout_rsp(bfa, msg.logout_rsp);
break;

case BFI_LPS_H2I_CVL_EVENT:
bfa_lps_rx_cvl_event(bfa, msg.cvl_event);
break;

default:
bfa_trc(bfa, m->mhdr.msg_id);
bfa_assert(0);
Expand Down
1 change: 1 addition & 0 deletions drivers/scsi/bfa/include/bfa_svc.h
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ void bfa_cb_lps_flogi_comp(void *bfad, void *uarg, bfa_status_t status);
void bfa_cb_lps_flogo_comp(void *bfad, void *uarg);
void bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status);
void bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg);
void bfa_cb_lps_cvl_event(void *bfad, void *uarg);

#endif /* __BFA_SVC_H__ */

8 changes: 8 additions & 0 deletions drivers/scsi/bfa/include/bfi/bfi_lps.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ enum bfi_lps_h2i_msgs {
enum bfi_lps_i2h_msgs {
BFI_LPS_H2I_LOGIN_RSP = BFA_I2HM(1),
BFI_LPS_H2I_LOGOUT_RSP = BFA_I2HM(2),
BFI_LPS_H2I_CVL_EVENT = BFA_I2HM(3),
};

struct bfi_lps_login_req_s {
Expand Down Expand Up @@ -77,6 +78,12 @@ struct bfi_lps_logout_rsp_s {
u8 rsvd[2];
};

struct bfi_lps_cvl_event_s {
struct bfi_mhdr_s mh; /* common msg header */
u8 lp_tag;
u8 rsvd[3];
};

union bfi_lps_h2i_msg_u {
struct bfi_mhdr_s *msg;
struct bfi_lps_login_req_s *login_req;
Expand All @@ -87,6 +94,7 @@ union bfi_lps_i2h_msg_u {
struct bfi_msg_s *msg;
struct bfi_lps_login_rsp_s *login_rsp;
struct bfi_lps_logout_rsp_s *logout_rsp;
struct bfi_lps_cvl_event_s *cvl_event;
};

#pragma pack()
Expand Down
9 changes: 7 additions & 2 deletions drivers/scsi/bfa/include/cs/bfa_plog.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ enum bfa_plog_mid {
BFA_PL_MID_HAL_FCXP = 4,
BFA_PL_MID_HAL_UF = 5,
BFA_PL_MID_FCS = 6,
BFA_PL_MID_MAX = 7
BFA_PL_MID_LPS = 7,
BFA_PL_MID_MAX = 8
};

#define BFA_PL_MID_STRLEN 8
Expand Down Expand Up @@ -118,7 +119,11 @@ enum bfa_plog_eid {
BFA_PL_EID_RSCN = 17,
BFA_PL_EID_DEBUG = 18,
BFA_PL_EID_MISC = 19,
BFA_PL_EID_MAX = 20
BFA_PL_EID_FIP_FCF_DISC = 20,
BFA_PL_EID_FIP_FCF_CVL = 21,
BFA_PL_EID_LOGIN = 22,
BFA_PL_EID_LOGO = 23,
BFA_PL_EID_MAX = 24
};

#define BFA_PL_ENAME_STRLEN 8
Expand Down
11 changes: 11 additions & 0 deletions drivers/scsi/bfa/vport.c
Original file line number Diff line number Diff line change
Expand Up @@ -888,4 +888,15 @@ bfa_cb_lps_fdisclogo_comp(void *bfad, void *uarg)
bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_RSP_OK);
}

/**
* Received clear virtual link
*/
void
bfa_cb_lps_cvl_event(void *bfad, void *uarg)
{
struct bfa_fcs_vport_s *vport = uarg;

/* Send an Offline followed by an ONLINE */
bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_OFFLINE);
bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_ONLINE);
}

0 comments on commit 5c1fb1d

Please sign in to comment.