From dd5aaf4536c5111784a18d935b9b5adeac9f914c Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Mon, 13 Jun 2011 15:51:24 -0700 Subject: [SCSI] bfa: Changes to support vport disable and enable operations. Made changes to FCS lport, vport state machines to support vport enable / disable operations. Signed-off-by: Krishna Gudipati Signed-off-by: James Bottomley --- drivers/scsi/bfa/bfa_fcs_lport.c | 147 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 146 insertions(+), 1 deletion(-) (limited to 'drivers/scsi/bfa/bfa_fcs_lport.c') diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c index 1d6be8c14473..a0c6f960b992 100644 --- a/drivers/scsi/bfa/bfa_fcs_lport.c +++ b/drivers/scsi/bfa/bfa_fcs_lport.c @@ -74,6 +74,7 @@ enum bfa_fcs_lport_event { BFA_FCS_PORT_SM_OFFLINE = 3, BFA_FCS_PORT_SM_DELETE = 4, BFA_FCS_PORT_SM_DELRPORT = 5, + BFA_FCS_PORT_SM_STOP = 6, }; static void bfa_fcs_lport_sm_uninit(struct bfa_fcs_lport_s *port, @@ -86,6 +87,8 @@ static void bfa_fcs_lport_sm_offline(struct bfa_fcs_lport_s *port, enum bfa_fcs_lport_event event); static void bfa_fcs_lport_sm_deleting(struct bfa_fcs_lport_s *port, enum bfa_fcs_lport_event event); +static void bfa_fcs_lport_sm_stopping(struct bfa_fcs_lport_s *port, + enum bfa_fcs_lport_event event); static void bfa_fcs_lport_sm_uninit( @@ -123,6 +126,12 @@ bfa_fcs_lport_sm_init(struct bfa_fcs_lport_s *port, bfa_fcs_lport_deleted(port); break; + case BFA_FCS_PORT_SM_STOP: + /* If vport - send completion call back */ + if (port->vport) + bfa_fcs_vport_stop_comp(port->vport); + break; + case BFA_FCS_PORT_SM_OFFLINE: break; @@ -148,6 +157,23 @@ bfa_fcs_lport_sm_online( bfa_fcs_lport_offline_actions(port); break; + case BFA_FCS_PORT_SM_STOP: + __port_action[port->fabric->fab_type].offline(port); + + if (port->num_rports == 0) { + bfa_sm_set_state(port, bfa_fcs_lport_sm_init); + /* If vport - send completion call back */ + if (port->vport) + bfa_fcs_vport_stop_comp(port->vport); + } else { + bfa_sm_set_state(port, bfa_fcs_lport_sm_stopping); + list_for_each_safe(qe, qen, &port->rport_q) { + rport = (struct bfa_fcs_rport_s *) qe; + bfa_sm_send_event(rport, RPSM_EVENT_DELETE); + } + } + break; + case BFA_FCS_PORT_SM_DELETE: __port_action[port->fabric->fab_type].offline(port); @@ -189,6 +215,21 @@ bfa_fcs_lport_sm_offline( bfa_fcs_lport_online_actions(port); break; + case BFA_FCS_PORT_SM_STOP: + if (port->num_rports == 0) { + bfa_sm_set_state(port, bfa_fcs_lport_sm_init); + /* If vport - send completion call back */ + if (port->vport) + bfa_fcs_vport_stop_comp(port->vport); + } else { + bfa_sm_set_state(port, bfa_fcs_lport_sm_stopping); + list_for_each_safe(qe, qen, &port->rport_q) { + rport = (struct bfa_fcs_rport_s *) qe; + bfa_sm_send_event(rport, RPSM_EVENT_DELETE); + } + } + break; + case BFA_FCS_PORT_SM_DELETE: if (port->num_rports == 0) { bfa_sm_set_state(port, bfa_fcs_lport_sm_uninit); @@ -211,6 +252,28 @@ bfa_fcs_lport_sm_offline( } } +static void +bfa_fcs_lport_sm_stopping(struct bfa_fcs_lport_s *port, + enum bfa_fcs_lport_event event) +{ + bfa_trc(port->fcs, port->port_cfg.pwwn); + bfa_trc(port->fcs, event); + + switch (event) { + case BFA_FCS_PORT_SM_DELRPORT: + if (port->num_rports == 0) { + bfa_sm_set_state(port, bfa_fcs_lport_sm_init); + /* If vport - send completion call back */ + if (port->vport) + bfa_fcs_vport_stop_comp(port->vport); + } + break; + + default: + bfa_sm_fault(port->fcs, event); + } +} + static void bfa_fcs_lport_sm_deleting( struct bfa_fcs_lport_s *port, @@ -1672,7 +1735,7 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld) memcpy(attr->value, fcs_hba_attr->driver_version, templen); templen = fc_roundup(templen, sizeof(u32)); curr_ptr += sizeof(attr->type) + sizeof(templen) + templen; - len += templen;; + len += templen; count++; attr->len = cpu_to_be16(templen + sizeof(attr->type) + sizeof(templen)); @@ -4918,6 +4981,7 @@ enum bfa_fcs_vport_event { BFA_FCS_VPORT_SM_DELCOMP = 11, /* lport delete completion */ BFA_FCS_VPORT_SM_RSP_DUP_WWN = 12, /* Dup wnn error*/ BFA_FCS_VPORT_SM_RSP_FAILED = 13, /* non-retryable failure */ + BFA_FCS_VPORT_SM_STOPCOMP = 14, /* vport delete completion */ }; static void bfa_fcs_vport_sm_uninit(struct bfa_fcs_vport_s *vport, @@ -4940,6 +5004,10 @@ static void bfa_fcs_vport_sm_logo(struct bfa_fcs_vport_s *vport, enum bfa_fcs_vport_event event); static void bfa_fcs_vport_sm_error(struct bfa_fcs_vport_s *vport, enum bfa_fcs_vport_event event); +static void bfa_fcs_vport_sm_stopping(struct bfa_fcs_vport_s *vport, + enum bfa_fcs_vport_event event); +static void bfa_fcs_vport_sm_logo_for_stop(struct bfa_fcs_vport_s *vport, + enum bfa_fcs_vport_event event); static struct bfa_sm_table_s vport_sm_table[] = { {BFA_SM(bfa_fcs_vport_sm_uninit), BFA_FCS_VPORT_UNINIT}, @@ -5042,6 +5110,11 @@ bfa_fcs_vport_sm_offline(struct bfa_fcs_vport_s *vport, bfa_fcs_vport_do_fdisc(vport); break; + case BFA_FCS_VPORT_SM_STOP: + bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); + bfa_sm_send_event(&vport->lport, BFA_FCS_PORT_SM_STOP); + break; + case BFA_FCS_VPORT_SM_OFFLINE: /* * This can happen if the vport couldn't be initialzied @@ -5155,6 +5228,11 @@ bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport, bfa_fcs_lport_delete(&vport->lport); break; + case BFA_FCS_VPORT_SM_STOP: + bfa_sm_set_state(vport, bfa_fcs_vport_sm_stopping); + bfa_sm_send_event(&vport->lport, BFA_FCS_PORT_SM_STOP); + break; + case BFA_FCS_VPORT_SM_OFFLINE: bfa_sm_set_state(vport, bfa_fcs_vport_sm_offline); bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); @@ -5166,6 +5244,32 @@ bfa_fcs_vport_sm_online(struct bfa_fcs_vport_s *vport, } } +/* + * Vport is being stopped - awaiting lport stop completion to send + * LOGO to fabric. + */ +static void +bfa_fcs_vport_sm_stopping(struct bfa_fcs_vport_s *vport, + enum bfa_fcs_vport_event event) +{ + bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); + bfa_trc(__vport_fcs(vport), event); + + switch (event) { + case BFA_FCS_VPORT_SM_STOPCOMP: + bfa_sm_set_state(vport, bfa_fcs_vport_sm_logo_for_stop); + bfa_fcs_vport_do_logo(vport); + break; + + case BFA_FCS_VPORT_SM_OFFLINE: + bfa_sm_set_state(vport, bfa_fcs_vport_sm_cleanup); + break; + + default: + bfa_sm_fault(__vport_fcs(vport), event); + } +} + /* * Vport is being deleted - awaiting lport delete completion to send * LOGO to fabric. @@ -5236,6 +5340,10 @@ bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport, bfa_fcs_vport_free(vport); break; + case BFA_FCS_VPORT_SM_STOPCOMP: + bfa_sm_set_state(vport, bfa_fcs_vport_sm_created); + break; + case BFA_FCS_VPORT_SM_DELETE: break; @@ -5244,6 +5352,34 @@ bfa_fcs_vport_sm_cleanup(struct bfa_fcs_vport_s *vport, } } +/* + * LOGO is sent to fabric. Vport stop is in progress. Lport stop cleanup + * is done. + */ +static void +bfa_fcs_vport_sm_logo_for_stop(struct bfa_fcs_vport_s *vport, + enum bfa_fcs_vport_event event) +{ + bfa_trc(__vport_fcs(vport), __vport_pwwn(vport)); + bfa_trc(__vport_fcs(vport), event); + + switch (event) { + case BFA_FCS_VPORT_SM_OFFLINE: + bfa_sm_send_event(vport->lps, BFA_LPS_SM_OFFLINE); + /* + * !!! fall through !!! + */ + + case BFA_FCS_VPORT_SM_RSP_OK: + case BFA_FCS_VPORT_SM_RSP_ERROR: + bfa_sm_set_state(vport, bfa_fcs_vport_sm_created); + break; + + default: + bfa_sm_fault(__vport_fcs(vport), event); + } +} + /* * LOGO is sent to fabric. Vport delete is in progress. Lport delete cleanup * is done. @@ -5421,6 +5557,15 @@ bfa_fcs_vport_fcs_delete(struct bfa_fcs_vport_s *vport) bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_DELETE); } +/* + * Stop completion callback from associated lport + */ +void +bfa_fcs_vport_stop_comp(struct bfa_fcs_vport_s *vport) +{ + bfa_sm_send_event(vport, BFA_FCS_VPORT_SM_STOPCOMP); +} + /* * Delete completion callback from associated lport */ -- cgit