[SCSI] libfc: use ADISC to verify rport login state
When rport_login is called on an rport that is already thought to be logged in, use ADISC. If that fails, redo PLOGI. This is less disruptive after fabric changes that don't affect the state of the target. Implement the sending of ADISC via fc_els_fill. Add ADISC state to the rport state machine. This is entered from READY and returns to READY after successful completion. If it fails, the rport is either logged off and deleted or re-does PLOGI. Signed-off-by: Joe Eykholt <jeykholt@cisco.com> Signed-off-by: Robert Love <robert.w.love@intel.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
This commit is contained in:
committed by
James Bottomley
parent
68a1750b46
commit
370c3bd05c
@ -56,6 +56,23 @@ static inline void fc_fill_fc_hdr(struct fc_frame *fp, enum fc_rctl r_ctl,
|
||||
fh->fh_parm_offset = htonl(parm_offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* fc_adisc_fill() - Fill in adisc request frame
|
||||
* @lport: local port.
|
||||
* @fp: fc frame where payload will be placed.
|
||||
*/
|
||||
static inline void fc_adisc_fill(struct fc_lport *lport, struct fc_frame *fp)
|
||||
{
|
||||
struct fc_els_adisc *adisc;
|
||||
|
||||
adisc = fc_frame_payload_get(fp, sizeof(*adisc));
|
||||
memset(adisc, 0, sizeof(*adisc));
|
||||
adisc->adisc_cmd = ELS_ADISC;
|
||||
put_unaligned_be64(lport->wwpn, &adisc->adisc_wwpn);
|
||||
put_unaligned_be64(lport->wwnn, &adisc->adisc_wwnn);
|
||||
hton24(adisc->adisc_port_id, fc_host_port_id(lport->host));
|
||||
}
|
||||
|
||||
/**
|
||||
* fc_ct_hdr_fill- fills ct header and reset ct payload
|
||||
* returns pointer to ct request.
|
||||
@ -255,6 +272,10 @@ static inline int fc_els_fill(struct fc_lport *lport,
|
||||
enum fc_rctl *r_ctl, enum fc_fh_type *fh_type)
|
||||
{
|
||||
switch (op) {
|
||||
case ELS_ADISC:
|
||||
fc_adisc_fill(lport, fp);
|
||||
break;
|
||||
|
||||
case ELS_PLOGI:
|
||||
fc_plogi_fill(lport, fp, ELS_PLOGI);
|
||||
break;
|
||||
|
@ -143,6 +143,7 @@ enum fc_rport_state {
|
||||
RPORT_ST_RTV, /* waiting for RTV completion */
|
||||
RPORT_ST_READY, /* ready for use */
|
||||
RPORT_ST_LOGO, /* port logout sent */
|
||||
RPORT_ST_ADISC, /* Discover Address sent */
|
||||
RPORT_ST_DELETE, /* port being deleted */
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user