aboutsummaryrefslogtreecommitdiffstats
path: root/include/scsi
diff options
context:
space:
mode:
authorJoe Eykholt <jeykholt@cisco.com>2009-08-25 17:03:47 -0400
committerJames Bottomley <James.Bottomley@suse.de>2009-09-10 13:08:02 -0400
commit370c3bd05cf02afabea9cd3f2de66202d6b516dc (patch)
tree832cf6b3091db117f119aa8692d050f43fe0a9cb /include/scsi
parent68a1750b46ad5177f7703081b5fe85624f1aa62b (diff)
[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>
Diffstat (limited to 'include/scsi')
-rw-r--r--include/scsi/fc_encode.h21
-rw-r--r--include/scsi/libfc.h1
2 files changed, 22 insertions, 0 deletions
diff --git a/include/scsi/fc_encode.h b/include/scsi/fc_encode.h
index 24bf764f9884..c5ee6bb79e05 100644
--- a/include/scsi/fc_encode.h
+++ b/include/scsi/fc_encode.h
@@ -57,6 +57,23 @@ static inline void fc_fill_fc_hdr(struct fc_frame *fp, enum fc_rctl r_ctl,
57} 57}
58 58
59/** 59/**
60 * fc_adisc_fill() - Fill in adisc request frame
61 * @lport: local port.
62 * @fp: fc frame where payload will be placed.
63 */
64static inline void fc_adisc_fill(struct fc_lport *lport, struct fc_frame *fp)
65{
66 struct fc_els_adisc *adisc;
67
68 adisc = fc_frame_payload_get(fp, sizeof(*adisc));
69 memset(adisc, 0, sizeof(*adisc));
70 adisc->adisc_cmd = ELS_ADISC;
71 put_unaligned_be64(lport->wwpn, &adisc->adisc_wwpn);
72 put_unaligned_be64(lport->wwnn, &adisc->adisc_wwnn);
73 hton24(adisc->adisc_port_id, fc_host_port_id(lport->host));
74}
75
76/**
60 * fc_ct_hdr_fill- fills ct header and reset ct payload 77 * fc_ct_hdr_fill- fills ct header and reset ct payload
61 * returns pointer to ct request. 78 * returns pointer to ct request.
62 */ 79 */
@@ -255,6 +272,10 @@ static inline int fc_els_fill(struct fc_lport *lport,
255 enum fc_rctl *r_ctl, enum fc_fh_type *fh_type) 272 enum fc_rctl *r_ctl, enum fc_fh_type *fh_type)
256{ 273{
257 switch (op) { 274 switch (op) {
275 case ELS_ADISC:
276 fc_adisc_fill(lport, fp);
277 break;
278
258 case ELS_PLOGI: 279 case ELS_PLOGI:
259 fc_plogi_fill(lport, fp, ELS_PLOGI); 280 fc_plogi_fill(lport, fp, ELS_PLOGI);
260 break; 281 break;
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index e18e5ce5af51..65dc9aacbf70 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -143,6 +143,7 @@ enum fc_rport_state {
143 RPORT_ST_RTV, /* waiting for RTV completion */ 143 RPORT_ST_RTV, /* waiting for RTV completion */
144 RPORT_ST_READY, /* ready for use */ 144 RPORT_ST_READY, /* ready for use */
145 RPORT_ST_LOGO, /* port logout sent */ 145 RPORT_ST_LOGO, /* port logout sent */
146 RPORT_ST_ADISC, /* Discover Address sent */
146 RPORT_ST_DELETE, /* port being deleted */ 147 RPORT_ST_DELETE, /* port being deleted */
147}; 148};
148 149