/** * fc_rport_enter_flogi() - Send a FLOGI request to the fabric manager * @lport: Fibre Channel local port to be logged in to the fabric * * Locking Note: The lport lock is expected to be held before calling * this routine. */ void fc_lport_enter_flogi(struct fc_lport *lport) { struct fc_frame *fp; FC_LPORT_DBG(lport, "Entered FLOGI state from %s state\n", fc_lport_state(lport)); fc_lport_state_enter(lport, LPORT_ST_FLOGI); if (lport->point_to_multipoint) { if (lport->port_id) fc_lport_enter_ready(lport); return; } fp = fc_frame_alloc(lport, sizeof(struct fc_els_flogi)); if (!fp) return fc_lport_error(lport, fp); if (!lport->tt.elsct_send(lport, FC_FID_FLOGI, fp, lport->vport ? ELS_FDISC : ELS_FLOGI, fc_lport_flogi_resp, lport, lport->vport ? 2 * lport->r_a_tov : lport->e_d_tov)) fc_lport_error(lport, NULL); }
/** * fc_lport_ptp_setup() - Create an rport for point-to-point mode * @lport: The lport to attach the ptp rport to * @remote_fid: The FID of the ptp rport * @remote_wwpn: The WWPN of the ptp rport * @remote_wwnn: The WWNN of the ptp rport */ static void fc_lport_ptp_setup(struct fc_lport *lport, u32 remote_fid, u64 remote_wwpn, u64 remote_wwnn) { mutex_lock(&lport->disc.disc_mutex); if (lport->ptp_rdata) lport->tt.rport_logoff(lport->ptp_rdata); lport->ptp_rdata = lport->tt.rport_create(lport, remote_fid); lport->ptp_rdata->ids.port_name = remote_wwpn; lport->ptp_rdata->ids.node_name = remote_wwnn; mutex_unlock(&lport->disc.disc_mutex); lport->tt.rport_login(lport->ptp_rdata); fc_lport_enter_ready(lport); }
/** * fc_lport_set_port_id() - set the local port Port ID for point-to-multipoint * @lport: The local port which will have its Port ID set. * @port_id: The new port ID. * * Called by the lower-level driver when transport sets the local port_id. * This is used in VN_port to VN_port mode for FCoE, and causes FLOGI and * discovery to be skipped. */ void fc_lport_set_local_id(struct fc_lport *lport, u32 port_id) { mutex_lock(&lport->lp_mutex); fc_lport_set_port_id(lport, port_id, NULL); switch (lport->state) { case LPORT_ST_RESET: case LPORT_ST_FLOGI: if (port_id) fc_lport_enter_ready(lport); break; default: break; } mutex_unlock(&lport->lp_mutex); }
/** * fc_lport_scr_resp() - Handle response to State Change Register (SCR) request * @sp: current sequence in SCR exchange * @fp: response frame * @lp_arg: Fibre Channel lport port instance that sent the registration request * * Locking Note: This function will be called without the lport lock * held, but it will lock, call an _enter_* function or fc_lport_error * and then unlock the lport. */ static void fc_lport_scr_resp(struct fc_seq *sp, struct fc_frame *fp, void *lp_arg) { struct fc_lport *lport = lp_arg; u8 op; FC_LPORT_DBG(lport, "Received a SCR %s\n", fc_els_resp_type(fp)); if (fp == ERR_PTR(-FC_EX_CLOSED)) return; mutex_lock(&lport->lp_mutex); if (lport->state != LPORT_ST_SCR) { FC_LPORT_DBG(lport, "Received a SCR response, but in state " "%s\n", fc_lport_state(lport)); if (IS_ERR(fp)) goto err; goto out; } if (IS_ERR(fp)) { fc_lport_error(lport, fp); goto err; } op = fc_frame_payload_op(fp); if (op == ELS_LS_ACC) fc_lport_enter_ready(lport); else fc_lport_error(lport, fp); out: fc_frame_free(fp); err: mutex_unlock(&lport->lp_mutex); }