aboutsummaryrefslogtreecommitdiffstats
path: root/include/scsi
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2007-04-27 12:41:09 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-05-16 09:36:15 -0400
commita53eb5e060c0ec7245c8f93b9dcd94afa6041e06 (patch)
tree5e5747a715142c6eb1b89f9550477e2d1df318f0 /include/scsi
parent7b104bcb8e460e45a1aebe3da9b86aacdb4cab12 (diff)
[SCSI] FC Transport support for vports based on NPIV
This patch provides support for FC virtual ports based on NPIV. For information on the interfaces and design, please read the Documentation/scsi/scsi_fc_transport.txt file enclosed within the patch. The RFC was originally posted here: http://marc.info/?l=linux-scsi&m=117226959918393&w=2 Changes from the initial RFC: - Bug fix: needed a transport_class_unregister() for the vport class - Create a symlink to the vport in the shost device if it is not the parent of the vport. - Made symbolic name writable so it can be set after creation - Made the temporary fc_vport_identifiers struct private to the transport. - Deleted the vport_id field from the vport. I couldn't find any good use for it (and symname is a good replacement). - Made the vport_state and vport_last_state "private" attributes. Added the fc_vport_set_state() helper function to manage state transitions - Updated vport_create() to allow a vport to be created in a disabled state. - Added INITIALIZING and FAILED vport states - Added VPCERR_xxx defines for errors to be returned from vport_create() - Created a Documentation/scsi/scsi_fc_transport.txt file that describes the interfaces and expected LLDD behaviors. Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'include/scsi')
-rw-r--r--include/scsi/scsi_transport_fc.h173
1 files changed, 166 insertions, 7 deletions
diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
index 1e797308640a..81ea7b4bf81e 100644
--- a/include/scsi/scsi_transport_fc.h
+++ b/include/scsi/scsi_transport_fc.h
@@ -19,7 +19,7 @@
19 * 19 *
20 * ======== 20 * ========
21 * 21 *
22 * Copyright (C) 2004-2005 James Smart, Emulex Corporation 22 * Copyright (C) 2004-2007 James Smart, Emulex Corporation
23 * Rewrite for host, target, device, and remote port attributes, 23 * Rewrite for host, target, device, and remote port attributes,
24 * statistics, and service functions... 24 * statistics, and service functions...
25 * 25 *
@@ -62,8 +62,10 @@ enum fc_port_type {
62 FC_PORTTYPE_NLPORT, /* (Public) Loop w/ FLPort */ 62 FC_PORTTYPE_NLPORT, /* (Public) Loop w/ FLPort */
63 FC_PORTTYPE_LPORT, /* (Private) Loop w/o FLPort */ 63 FC_PORTTYPE_LPORT, /* (Private) Loop w/o FLPort */
64 FC_PORTTYPE_PTP, /* Point to Point w/ another NPort */ 64 FC_PORTTYPE_PTP, /* Point to Point w/ another NPort */
65 FC_PORTTYPE_NPIV, /* VPORT based on NPIV */
65}; 66};
66 67
68
67/* 69/*
68 * fc_port_state: If you alter this, you also need to alter scsi_transport_fc.c 70 * fc_port_state: If you alter this, you also need to alter scsi_transport_fc.c
69 * (for the ascii descriptions). 71 * (for the ascii descriptions).
@@ -83,6 +85,25 @@ enum fc_port_state {
83}; 85};
84 86
85 87
88/*
89 * fc_vport_state: If you alter this, you also need to alter
90 * scsi_transport_fc.c (for the ascii descriptions).
91 */
92enum fc_vport_state {
93 FC_VPORT_UNKNOWN,
94 FC_VPORT_ACTIVE,
95 FC_VPORT_DISABLED,
96 FC_VPORT_LINKDOWN,
97 FC_VPORT_INITIALIZING,
98 FC_VPORT_NO_FABRIC_SUPP,
99 FC_VPORT_NO_FABRIC_RSCS,
100 FC_VPORT_FABRIC_LOGOUT,
101 FC_VPORT_FABRIC_REJ_WWN,
102 FC_VPORT_FAILED,
103};
104
105
106
86/* 107/*
87 * FC Classes of Service 108 * FC Classes of Service
88 * Note: values are not enumerated, as they can be "or'd" together 109 * Note: values are not enumerated, as they can be "or'd" together
@@ -124,18 +145,115 @@ enum fc_tgtid_binding_type {
124}; 145};
125 146
126/* 147/*
127 * FC Remote Port Roles 148 * FC Port Roles
128 * Note: values are not enumerated, as they can be "or'd" together 149 * Note: values are not enumerated, as they can be "or'd" together
129 * for reporting (e.g. report roles). If you alter this list, 150 * for reporting (e.g. report roles). If you alter this list,
130 * you also need to alter scsi_transport_fc.c (for the ascii descriptions). 151 * you also need to alter scsi_transport_fc.c (for the ascii descriptions).
131 */ 152 */
132#define FC_RPORT_ROLE_UNKNOWN 0x00 153#define FC_PORT_ROLE_UNKNOWN 0x00
133#define FC_RPORT_ROLE_FCP_TARGET 0x01 154#define FC_PORT_ROLE_FCP_TARGET 0x01
134#define FC_RPORT_ROLE_FCP_INITIATOR 0x02 155#define FC_PORT_ROLE_FCP_INITIATOR 0x02
135#define FC_RPORT_ROLE_IP_PORT 0x04 156#define FC_PORT_ROLE_IP_PORT 0x04
157
158/* The following are for compatibility */
159#define FC_RPORT_ROLE_UNKNOWN FC_PORT_ROLE_UNKNOWN
160#define FC_RPORT_ROLE_FCP_TARGET FC_PORT_ROLE_FCP_TARGET
161#define FC_RPORT_ROLE_FCP_INITIATOR FC_PORT_ROLE_FCP_INITIATOR
162#define FC_RPORT_ROLE_IP_PORT FC_PORT_ROLE_IP_PORT
163
164
165/* Macro for use in defining Virtual Port attributes */
166#define FC_VPORT_ATTR(_name,_mode,_show,_store) \
167struct class_device_attribute class_device_attr_vport_##_name = \
168 __ATTR(_name,_mode,_show,_store)
136 169
137 170
138/* 171/*
172 * FC Virtual Port Attributes
173 *
174 * This structure exists for each FC port is a virtual FC port. Virtual
175 * ports share the physical link with the Physical port. Each virtual
176 * ports has a unique presense on the SAN, and may be instantiated via
177 * NPIV, Virtual Fabrics, or via additional ALPAs. As the vport is a
178 * unique presense, each vport has it's own view of the fabric,
179 * authentication priviledge, and priorities.
180 *
181 * A virtual port may support 1 or more FC4 roles. Typically it is a
182 * FCP Initiator. It could be a FCP Target, or exist sole for an IP over FC
183 * roles. FC port attributes for the vport will be reported on any
184 * fc_host class object allocated for an FCP Initiator.
185 *
186 * --
187 *
188 * Fixed attributes are not expected to change. The driver is
189 * expected to set these values after receiving the fc_vport structure
190 * via the vport_create() call from the transport.
191 * The transport fully manages all get functions w/o driver interaction.
192 *
193 * Dynamic attributes are expected to change. The driver participates
194 * in all get/set operations via functions provided by the driver.
195 *
196 * Private attributes are transport-managed values. They are fully
197 * managed by the transport w/o driver interaction.
198 */
199
200#define FC_VPORT_SYMBOLIC_NAMELEN 64
201struct fc_vport {
202 /* Fixed Attributes */
203
204 /* Dynamic Attributes */
205
206 /* Private (Transport-managed) Attributes */
207 enum fc_vport_state vport_state;
208 enum fc_vport_state vport_last_state;
209 u64 node_name;
210 u64 port_name;
211 u32 roles;
212 u32 vport_id; /* Admin Identifier for the vport */
213 enum fc_port_type vport_type;
214 char symbolic_name[FC_VPORT_SYMBOLIC_NAMELEN];
215
216 /* exported data */
217 void *dd_data; /* Used for driver-specific storage */
218
219 /* internal data */
220 struct Scsi_Host *shost; /* Physical Port Parent */
221 unsigned int channel;
222 u32 number;
223 u8 flags;
224 struct list_head peers;
225 struct device dev;
226} __attribute__((aligned(sizeof(unsigned long))));
227
228/* bit field values for struct fc_vport "flags" field: */
229#define FC_VPORT_CREATING 0x01
230#define FC_VPORT_DELETING 0x02
231#define FC_VPORT_DELETED 0x04
232#define FC_VPORT_DEL 0x06 /* Any DELETE state */
233
234#define dev_to_vport(d) \
235 container_of(d, struct fc_vport, dev)
236#define transport_class_to_vport(classdev) \
237 dev_to_vport(classdev->dev)
238#define vport_to_shost(v) \
239 (v->shost)
240#define vport_to_shost_channel(v) \
241 (v->channel)
242#define vport_to_parent(v) \
243 (v->dev.parent)
244
245
246/* Error return codes for vport_create() callback */
247#define VPCERR_UNSUPPORTED -ENOSYS /* no driver/adapter
248 support */
249#define VPCERR_BAD_WWN -ENOTUNIQ /* driver validation
250 of WWNs failed */
251#define VPCERR_NO_FABRIC_SUPP -EOPNOTSUPP /* Fabric connection
252 is loop or the
253 Fabric Port does
254 not support NPIV */
255
256/*
139 * fc_rport_identifiers: This set of data contains all elements 257 * fc_rport_identifiers: This set of data contains all elements
140 * to uniquely identify a remote FC port. The driver uses this data 258 * to uniquely identify a remote FC port. The driver uses this data
141 * to report the existence of a remote FC port in the topology. Internally, 259 * to report the existence of a remote FC port in the topology. Internally,
@@ -149,6 +267,7 @@ struct fc_rport_identifiers {
149 u32 roles; 267 u32 roles;
150}; 268};
151 269
270
152/* Macro for use in defining Remote Port attributes */ 271/* Macro for use in defining Remote Port attributes */
153#define FC_RPORT_ATTR(_name,_mode,_show,_store) \ 272#define FC_RPORT_ATTR(_name,_mode,_show,_store) \
154struct class_device_attribute class_device_attr_rport_##_name = \ 273struct class_device_attribute class_device_attr_rport_##_name = \
@@ -343,6 +462,7 @@ struct fc_host_attrs {
343 u8 supported_fc4s[FC_FC4_LIST_SIZE]; 462 u8 supported_fc4s[FC_FC4_LIST_SIZE];
344 u32 supported_speeds; 463 u32 supported_speeds;
345 u32 maxframe_size; 464 u32 maxframe_size;
465 u16 max_npiv_vports;
346 char serial_number[FC_SERIAL_NUMBER_SIZE]; 466 char serial_number[FC_SERIAL_NUMBER_SIZE];
347 467
348 /* Dynamic Attributes */ 468 /* Dynamic Attributes */
@@ -361,8 +481,11 @@ struct fc_host_attrs {
361 /* internal data */ 481 /* internal data */
362 struct list_head rports; 482 struct list_head rports;
363 struct list_head rport_bindings; 483 struct list_head rport_bindings;
484 struct list_head vports;
364 u32 next_rport_number; 485 u32 next_rport_number;
365 u32 next_target_id; 486 u32 next_target_id;
487 u32 next_vport_number;
488 u16 npiv_vports_inuse;
366 489
367 /* work queues for rport state manipulation */ 490 /* work queues for rport state manipulation */
368 char work_q_name[KOBJ_NAME_LEN]; 491 char work_q_name[KOBJ_NAME_LEN];
@@ -388,6 +511,8 @@ struct fc_host_attrs {
388 (((struct fc_host_attrs *)(x)->shost_data)->supported_speeds) 511 (((struct fc_host_attrs *)(x)->shost_data)->supported_speeds)
389#define fc_host_maxframe_size(x) \ 512#define fc_host_maxframe_size(x) \
390 (((struct fc_host_attrs *)(x)->shost_data)->maxframe_size) 513 (((struct fc_host_attrs *)(x)->shost_data)->maxframe_size)
514#define fc_host_max_npiv_vports(x) \
515 (((struct fc_host_attrs *)(x)->shost_data)->max_npiv_vports)
391#define fc_host_serial_number(x) \ 516#define fc_host_serial_number(x) \
392 (((struct fc_host_attrs *)(x)->shost_data)->serial_number) 517 (((struct fc_host_attrs *)(x)->shost_data)->serial_number)
393#define fc_host_port_id(x) \ 518#define fc_host_port_id(x) \
@@ -412,10 +537,16 @@ struct fc_host_attrs {
412 (((struct fc_host_attrs *)(x)->shost_data)->rports) 537 (((struct fc_host_attrs *)(x)->shost_data)->rports)
413#define fc_host_rport_bindings(x) \ 538#define fc_host_rport_bindings(x) \
414 (((struct fc_host_attrs *)(x)->shost_data)->rport_bindings) 539 (((struct fc_host_attrs *)(x)->shost_data)->rport_bindings)
540#define fc_host_vports(x) \
541 (((struct fc_host_attrs *)(x)->shost_data)->vports)
415#define fc_host_next_rport_number(x) \ 542#define fc_host_next_rport_number(x) \
416 (((struct fc_host_attrs *)(x)->shost_data)->next_rport_number) 543 (((struct fc_host_attrs *)(x)->shost_data)->next_rport_number)
417#define fc_host_next_target_id(x) \ 544#define fc_host_next_target_id(x) \
418 (((struct fc_host_attrs *)(x)->shost_data)->next_target_id) 545 (((struct fc_host_attrs *)(x)->shost_data)->next_target_id)
546#define fc_host_next_vport_number(x) \
547 (((struct fc_host_attrs *)(x)->shost_data)->next_vport_number)
548#define fc_host_npiv_vports_inuse(x) \
549 (((struct fc_host_attrs *)(x)->shost_data)->npiv_vports_inuse)
419#define fc_host_work_q_name(x) \ 550#define fc_host_work_q_name(x) \
420 (((struct fc_host_attrs *)(x)->shost_data)->work_q_name) 551 (((struct fc_host_attrs *)(x)->shost_data)->work_q_name)
421#define fc_host_work_q(x) \ 552#define fc_host_work_q(x) \
@@ -452,8 +583,14 @@ struct fc_function_template {
452 void (*dev_loss_tmo_callbk)(struct fc_rport *); 583 void (*dev_loss_tmo_callbk)(struct fc_rport *);
453 void (*terminate_rport_io)(struct fc_rport *); 584 void (*terminate_rport_io)(struct fc_rport *);
454 585
586 void (*set_vport_symbolic_name)(struct fc_vport *);
587 int (*vport_create)(struct fc_vport *, bool);
588 int (*vport_disable)(struct fc_vport *, bool);
589 int (*vport_delete)(struct fc_vport *);
590
455 /* allocation lengths for host-specific data */ 591 /* allocation lengths for host-specific data */
456 u32 dd_fcrport_size; 592 u32 dd_fcrport_size;
593 u32 dd_fcvport_size;
457 594
458 /* 595 /*
459 * The driver sets these to tell the transport class it 596 * The driver sets these to tell the transport class it
@@ -512,7 +649,7 @@ fc_remote_port_chkready(struct fc_rport *rport)
512 649
513 switch (rport->port_state) { 650 switch (rport->port_state) {
514 case FC_PORTSTATE_ONLINE: 651 case FC_PORTSTATE_ONLINE:
515 if (rport->roles & FC_RPORT_ROLE_FCP_TARGET) 652 if (rport->roles & FC_PORT_ROLE_FCP_TARGET)
516 result = 0; 653 result = 0;
517 else if (rport->flags & FC_RPORT_DEVLOSS_PENDING) 654 else if (rport->flags & FC_RPORT_DEVLOSS_PENDING)
518 result = DID_IMM_RETRY << 16; 655 result = DID_IMM_RETRY << 16;
@@ -549,6 +686,27 @@ static inline void u64_to_wwn(u64 inm, u8 *wwn)
549 wwn[7] = inm & 0xff; 686 wwn[7] = inm & 0xff;
550} 687}
551 688
689/**
690 * fc_vport_set_state() - called to set a vport's state. Saves the old state,
691 * excepting the transitory states of initializing and sending the ELS
692 * traffic to instantiate the vport on the link.
693 *
694 * Assumes the driver has surrounded this with the proper locking to ensure
695 * a coherent state change.
696 *
697 * @vport: virtual port whose state is changing
698 * @new_state: new state
699 **/
700static inline void
701fc_vport_set_state(struct fc_vport *vport, enum fc_vport_state new_state)
702{
703 if ((new_state != FC_VPORT_UNKNOWN) &&
704 (new_state != FC_VPORT_INITIALIZING))
705 vport->vport_last_state = vport->vport_state;
706 vport->vport_state = new_state;
707}
708
709
552struct scsi_transport_template *fc_attach_transport( 710struct scsi_transport_template *fc_attach_transport(
553 struct fc_function_template *); 711 struct fc_function_template *);
554void fc_release_transport(struct scsi_transport_template *); 712void fc_release_transport(struct scsi_transport_template *);
@@ -567,5 +725,6 @@ void fc_host_post_vendor_event(struct Scsi_Host *shost, u32 event_number,
567 * be sure to read the Vendor Type and ID formatting requirements 725 * be sure to read the Vendor Type and ID formatting requirements
568 * specified in scsi_netlink.h 726 * specified in scsi_netlink.h
569 */ 727 */
728int fc_vport_terminate(struct fc_vport *vport);
570 729
571#endif /* SCSI_TRANSPORT_FC_H */ 730#endif /* SCSI_TRANSPORT_FC_H */