diff options
author | Krishna Gudipati <kgudipat@brocade.com> | 2011-06-25 07:24:52 +0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-06-30 02:12:11 +0400 |
commit | d7be54cc5c5f6f9cb9ac67462aadda57813698b8 (patch) | |
tree | 2f77812fe06a7ed59172a51f11166aadd6a262d8 /drivers/scsi/bfa/bfa_fcs_rport.c | |
parent | 4507025d01149aea8705e43508d0ef11e7010cfd (diff) | |
download | linux-d7be54cc5c5f6f9cb9ac67462aadda57813698b8.tar.xz |
[SCSI] bfa: FCS bug fixes.
- Added logic to initiate a PLOGI to the target, while processing a LOGO
from the same target in Direct attach mode.
- Added logic to generate a FCCT Reject indicating unsupported command,
upon receiving FCCT/FCGS requests.
- Added logic to set the fcpim in offline state and avoid any PRLI retries
if a PRLI response is a reject with a reason Command Not Supported.
- Updated the FDMI Supported/Current speeds.
- Added logic to wait for the response from the firmware before sending
ACC to PLOGI and transitioning to subsequent states - while processing an
Incoming PLOGI in online state.
- Added a wait state in the fcs_vport state machine - For case where
FDISC is in progress and we get a vport delete request we wait for
fdisc response and will transition to the appropriate state based on
rsp status, else its causing both driver/fw resources to be not
freed.
- Remove the fc_credit_recovery module param.
Signed-off-by: Krishna Gudipati <kgudipat@brocade.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/bfa/bfa_fcs_rport.c')
-rw-r--r-- | drivers/scsi/bfa/bfa_fcs_rport.c | 45 |
1 files changed, 39 insertions, 6 deletions
diff --git a/drivers/scsi/bfa/bfa_fcs_rport.c b/drivers/scsi/bfa/bfa_fcs_rport.c index 2ec5719b654d..a42949d045eb 100644 --- a/drivers/scsi/bfa/bfa_fcs_rport.c +++ b/drivers/scsi/bfa/bfa_fcs_rport.c @@ -262,6 +262,7 @@ bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport, break; case RPSM_EVENT_PLOGI_RCVD: + case RPSM_EVENT_PLOGI_COMP: case RPSM_EVENT_SCN: /* * Ignore, SCN is possibly online notification. @@ -470,6 +471,7 @@ bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport, break; case RPSM_EVENT_PRLO_RCVD: + case RPSM_EVENT_PLOGI_COMP: break; case RPSM_EVENT_LOGO_RCVD: @@ -484,9 +486,9 @@ bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport, break; case RPSM_EVENT_PLOGI_RCVD: - bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); + rport->plogi_pending = BFA_TRUE; + bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline); bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE); - bfa_fcs_rport_send_plogiacc(rport, NULL); break; case RPSM_EVENT_DELETE: @@ -891,6 +893,18 @@ bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport, switch (event) { case RPSM_EVENT_HCB_OFFLINE: + if (bfa_fcs_lport_is_online(rport->port) && + (rport->plogi_pending)) { + rport->plogi_pending = BFA_FALSE; + bfa_sm_set_state(rport, + bfa_fcs_rport_sm_plogiacc_sending); + bfa_fcs_rport_send_plogiacc(rport, NULL); + break; + } + /* + * !! fall through !! + */ + case RPSM_EVENT_ADDRESS_CHANGE: if (bfa_fcs_lport_is_online(rport->port)) { if (bfa_fcs_fabric_is_switched(rport->port->fabric)) { @@ -921,6 +935,8 @@ bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport, case RPSM_EVENT_SCN: case RPSM_EVENT_LOGO_RCVD: case RPSM_EVENT_PRLO_RCVD: + case RPSM_EVENT_PLOGI_RCVD: + case RPSM_EVENT_LOGO_IMP: /* * Ignore, already offline. */ @@ -957,10 +973,18 @@ bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport, */ if (bfa_fcs_lport_is_online(rport->port) && (!BFA_FCS_PID_IS_WKA(rport->pid))) { - bfa_sm_set_state(rport, - bfa_fcs_rport_sm_nsdisc_sending); - rport->ns_retries = 0; - bfa_fcs_rport_send_nsdisc(rport, NULL); + if (bfa_fcs_fabric_is_switched(rport->port->fabric)) { + bfa_sm_set_state(rport, + bfa_fcs_rport_sm_nsdisc_sending); + rport->ns_retries = 0; + bfa_fcs_rport_send_nsdisc(rport, NULL); + } else { + /* For N2N Direct Attach, try to re-login */ + bfa_sm_set_state(rport, + bfa_fcs_rport_sm_plogi_sending); + rport->plogi_retries = 0; + bfa_fcs_rport_send_plogi(rport, NULL); + } } else { /* * if it is not a well known address, reset the @@ -2026,6 +2050,11 @@ bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport) rport->stats.onlines++; + if ((!rport->pid) || (!rport->pwwn)) { + bfa_trc(rport->fcs, rport->pid); + bfa_sm_fault(rport->fcs, rport->pid); + } + if (bfa_fcs_lport_is_initiator(port)) { bfa_fcs_itnim_rport_online(rport->itnim); if (!BFA_FCS_PID_IS_WKA(rport->pid)) @@ -2049,6 +2078,7 @@ bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport) char rpwwn_buf[BFA_STRING_32]; rport->stats.offlines++; + rport->plogi_pending = BFA_FALSE; wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); wwn2str(rpwwn_buf, rport->pwwn); @@ -2252,6 +2282,9 @@ bfa_fcs_rport_plogi(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs, rport->reply_oxid = rx_fchs->ox_id; bfa_trc(rport->fcs, rport->reply_oxid); + rport->pid = rx_fchs->s_id; + bfa_trc(rport->fcs, rport->pid); + rport->stats.plogi_rcvd++; bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD); } |