X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=include%2Fscsi%2Fscsi_transport_fc.h;h=878373c32ef7e434bdb6c840ca15b4ec0412d550;hb=7027ad72a689797475973c6feb5f0b673382f779;hp=c74be5dabfebb973e88fbab5ae8e4cbb2a9f4a6b;hpb=b8d08210126a7b769b857720a59721a453a57a1e;p=safe%2Fjmp%2Flinux-2.6 diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h index c74be5d..878373c 100644 --- a/include/scsi/scsi_transport_fc.h +++ b/include/scsi/scsi_transport_fc.h @@ -1,4 +1,4 @@ -/* +/* * FiberChannel transport specific attributes exported to sysfs. * * Copyright (c) 2003 Silicon Graphics, Inc. All rights reserved. @@ -19,7 +19,7 @@ * * ======== * - * Copyright (C) 2004-2005 James Smart, Emulex Corporation + * Copyright (C) 2004-2007 James Smart, Emulex Corporation * Rewrite for host, target, device, and remote port attributes, * statistics, and service functions... * @@ -29,6 +29,7 @@ #include #include +#include struct scsi_transport_template; @@ -61,8 +62,10 @@ enum fc_port_type { FC_PORTTYPE_NLPORT, /* (Public) Loop w/ FLPort */ FC_PORTTYPE_LPORT, /* (Private) Loop w/o FLPort */ FC_PORTTYPE_PTP, /* Point to Point w/ another NPort */ + FC_PORTTYPE_NPIV, /* VPORT based on NPIV */ }; + /* * fc_port_state: If you alter this, you also need to alter scsi_transport_fc.c * (for the ascii descriptions). @@ -82,7 +85,26 @@ enum fc_port_state { }; -/* +/* + * fc_vport_state: If you alter this, you also need to alter + * scsi_transport_fc.c (for the ascii descriptions). + */ +enum fc_vport_state { + FC_VPORT_UNKNOWN, + FC_VPORT_ACTIVE, + FC_VPORT_DISABLED, + FC_VPORT_LINKDOWN, + FC_VPORT_INITIALIZING, + FC_VPORT_NO_FABRIC_SUPP, + FC_VPORT_NO_FABRIC_RSCS, + FC_VPORT_FABRIC_LOGOUT, + FC_VPORT_FABRIC_REJ_WWN, + FC_VPORT_FAILED, +}; + + + +/* * FC Classes of Service * Note: values are not enumerated, as they can be "or'd" together * for reporting (e.g. report supported_classes). If you alter this list, @@ -95,7 +117,7 @@ enum fc_port_state { #define FC_COS_CLASS4 0x10 #define FC_COS_CLASS6 0x40 -/* +/* * FC Port Speeds * Note: values are not enumerated, as they can be "or'd" together * for reporting (e.g. report supported_speeds). If you alter this list, @@ -107,6 +129,8 @@ enum fc_port_state { #define FC_PORTSPEED_2GBIT 2 #define FC_PORTSPEED_4GBIT 4 #define FC_PORTSPEED_10GBIT 8 +#define FC_PORTSPEED_8GBIT 0x10 +#define FC_PORTSPEED_16GBIT 0x20 #define FC_PORTSPEED_NOT_NEGOTIATED (1 << 15) /* Speed not established */ /* @@ -121,18 +145,116 @@ enum fc_tgtid_binding_type { }; /* - * FC Remote Port Roles + * FC Port Roles * Note: values are not enumerated, as they can be "or'd" together * for reporting (e.g. report roles). If you alter this list, * you also need to alter scsi_transport_fc.c (for the ascii descriptions). */ -#define FC_RPORT_ROLE_UNKNOWN 0x00 -#define FC_RPORT_ROLE_FCP_TARGET 0x01 -#define FC_RPORT_ROLE_FCP_INITIATOR 0x02 -#define FC_RPORT_ROLE_IP_PORT 0x04 +#define FC_PORT_ROLE_UNKNOWN 0x00 +#define FC_PORT_ROLE_FCP_TARGET 0x01 +#define FC_PORT_ROLE_FCP_INITIATOR 0x02 +#define FC_PORT_ROLE_IP_PORT 0x04 + +/* The following are for compatibility */ +#define FC_RPORT_ROLE_UNKNOWN FC_PORT_ROLE_UNKNOWN +#define FC_RPORT_ROLE_FCP_TARGET FC_PORT_ROLE_FCP_TARGET +#define FC_RPORT_ROLE_FCP_INITIATOR FC_PORT_ROLE_FCP_INITIATOR +#define FC_RPORT_ROLE_IP_PORT FC_PORT_ROLE_IP_PORT + + +/* Macro for use in defining Virtual Port attributes */ +#define FC_VPORT_ATTR(_name,_mode,_show,_store) \ +struct device_attribute dev_attr_vport_##_name = \ + __ATTR(_name,_mode,_show,_store) /* + * FC Virtual Port Attributes + * + * This structure exists for each FC port is a virtual FC port. Virtual + * ports share the physical link with the Physical port. Each virtual + * ports has a unique presense on the SAN, and may be instantiated via + * NPIV, Virtual Fabrics, or via additional ALPAs. As the vport is a + * unique presense, each vport has it's own view of the fabric, + * authentication privilege, and priorities. + * + * A virtual port may support 1 or more FC4 roles. Typically it is a + * FCP Initiator. It could be a FCP Target, or exist sole for an IP over FC + * roles. FC port attributes for the vport will be reported on any + * fc_host class object allocated for an FCP Initiator. + * + * -- + * + * Fixed attributes are not expected to change. The driver is + * expected to set these values after receiving the fc_vport structure + * via the vport_create() call from the transport. + * The transport fully manages all get functions w/o driver interaction. + * + * Dynamic attributes are expected to change. The driver participates + * in all get/set operations via functions provided by the driver. + * + * Private attributes are transport-managed values. They are fully + * managed by the transport w/o driver interaction. + */ + +#define FC_VPORT_SYMBOLIC_NAMELEN 64 +struct fc_vport { + /* Fixed Attributes */ + + /* Dynamic Attributes */ + + /* Private (Transport-managed) Attributes */ + enum fc_vport_state vport_state; + enum fc_vport_state vport_last_state; + u64 node_name; + u64 port_name; + u32 roles; + u32 vport_id; /* Admin Identifier for the vport */ + enum fc_port_type vport_type; + char symbolic_name[FC_VPORT_SYMBOLIC_NAMELEN]; + + /* exported data */ + void *dd_data; /* Used for driver-specific storage */ + + /* internal data */ + struct Scsi_Host *shost; /* Physical Port Parent */ + unsigned int channel; + u32 number; + u8 flags; + struct list_head peers; + struct device dev; + struct work_struct vport_delete_work; +} __attribute__((aligned(sizeof(unsigned long)))); + +/* bit field values for struct fc_vport "flags" field: */ +#define FC_VPORT_CREATING 0x01 +#define FC_VPORT_DELETING 0x02 +#define FC_VPORT_DELETED 0x04 +#define FC_VPORT_DEL 0x06 /* Any DELETE state */ + +#define dev_to_vport(d) \ + container_of(d, struct fc_vport, dev) +#define transport_class_to_vport(dev) \ + dev_to_vport(dev->parent) +#define vport_to_shost(v) \ + (v->shost) +#define vport_to_shost_channel(v) \ + (v->channel) +#define vport_to_parent(v) \ + (v->dev.parent) + + +/* Error return codes for vport_create() callback */ +#define VPCERR_UNSUPPORTED -ENOSYS /* no driver/adapter + support */ +#define VPCERR_BAD_WWN -ENOTUNIQ /* driver validation + of WWNs failed */ +#define VPCERR_NO_FABRIC_SUPP -EOPNOTSUPP /* Fabric connection + is loop or the + Fabric Port does + not support NPIV */ + +/* * fc_rport_identifiers: This set of data contains all elements * to uniquely identify a remote FC port. The driver uses this data * to report the existence of a remote FC port in the topology. Internally, @@ -146,9 +268,10 @@ struct fc_rport_identifiers { u32 roles; }; + /* Macro for use in defining Remote Port attributes */ #define FC_RPORT_ATTR(_name,_mode,_show,_store) \ -struct class_device_attribute class_device_attr_rport_##_name = \ +struct device_attribute dev_attr_rport_##_name = \ __ATTR(_name,_mode,_show,_store) @@ -194,6 +317,7 @@ struct fc_rport { /* aka fc_starget_attrs */ u32 roles; enum fc_port_state port_state; /* Will only be ONLINE or UNKNOWN */ u32 scsi_target_id; + u32 fast_io_fail_tmo; /* exported data */ void *dd_data; /* Used for driver-specific storage */ @@ -204,8 +328,9 @@ struct fc_rport { /* aka fc_starget_attrs */ u8 flags; struct list_head peers; struct device dev; - struct work_struct dev_loss_work; + struct delayed_work dev_loss_work; struct work_struct scan_work; + struct delayed_work fail_io_work; struct work_struct stgt_delete_work; struct work_struct rport_delete_work; } __attribute__((aligned(sizeof(unsigned long)))); @@ -216,8 +341,8 @@ struct fc_rport { /* aka fc_starget_attrs */ #define dev_to_rport(d) \ container_of(d, struct fc_rport, dev) -#define transport_class_to_rport(classdev) \ - dev_to_rport(classdev->dev) +#define transport_class_to_rport(dev) \ + dev_to_rport(dev->parent) #define rport_to_shost(r) \ dev_to_shost(r->dev.parent) @@ -273,7 +398,7 @@ struct fc_host_statistics { u64 prim_seq_protocol_err_count; u64 invalid_tx_word_count; u64 invalid_crc_count; - + /* fc4 statistics (only FCP supported currently) */ u64 fcp_input_requests; u64 fcp_output_requests; @@ -284,6 +409,30 @@ struct fc_host_statistics { /* + * FC Event Codes - Polled and Async, following FC HBAAPI v2.0 guidelines + */ + +/* + * fc_host_event_code: If you alter this, you also need to alter + * scsi_transport_fc.c (for the ascii descriptions). + */ +enum fc_host_event_code { + FCH_EVT_LIP = 0x1, + FCH_EVT_LINKUP = 0x2, + FCH_EVT_LINKDOWN = 0x3, + FCH_EVT_LIPRESET = 0x4, + FCH_EVT_RSCN = 0x5, + FCH_EVT_ADAPTER_CHANGE = 0x103, + FCH_EVT_PORT_UNKNOWN = 0x200, + FCH_EVT_PORT_OFFLINE = 0x201, + FCH_EVT_PORT_ONLINE = 0x202, + FCH_EVT_PORT_FABRIC = 0x204, + FCH_EVT_LINK_UNKNOWN = 0x500, + FCH_EVT_VENDOR_UNIQUE = 0xffff, +}; + + +/* * FC Local Port (Host) Attributes * * Attributes are based on HBAAPI V2.0 definitions. @@ -314,6 +463,7 @@ struct fc_host_attrs { u8 supported_fc4s[FC_FC4_LIST_SIZE]; u32 supported_speeds; u32 maxframe_size; + u16 max_npiv_vports; char serial_number[FC_SERIAL_NUMBER_SIZE]; /* Dynamic Attributes */ @@ -332,13 +482,16 @@ struct fc_host_attrs { /* internal data */ struct list_head rports; struct list_head rport_bindings; + struct list_head vports; u32 next_rport_number; u32 next_target_id; + u32 next_vport_number; + u16 npiv_vports_inuse; /* work queues for rport state manipulation */ - char work_q_name[KOBJ_NAME_LEN]; + char work_q_name[20]; struct workqueue_struct *work_q; - char devloss_work_q_name[KOBJ_NAME_LEN]; + char devloss_work_q_name[20]; struct workqueue_struct *devloss_work_q; }; @@ -359,6 +512,8 @@ struct fc_host_attrs { (((struct fc_host_attrs *)(x)->shost_data)->supported_speeds) #define fc_host_maxframe_size(x) \ (((struct fc_host_attrs *)(x)->shost_data)->maxframe_size) +#define fc_host_max_npiv_vports(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->max_npiv_vports) #define fc_host_serial_number(x) \ (((struct fc_host_attrs *)(x)->shost_data)->serial_number) #define fc_host_port_id(x) \ @@ -383,10 +538,16 @@ struct fc_host_attrs { (((struct fc_host_attrs *)(x)->shost_data)->rports) #define fc_host_rport_bindings(x) \ (((struct fc_host_attrs *)(x)->shost_data)->rport_bindings) +#define fc_host_vports(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->vports) #define fc_host_next_rport_number(x) \ (((struct fc_host_attrs *)(x)->shost_data)->next_rport_number) #define fc_host_next_target_id(x) \ (((struct fc_host_attrs *)(x)->shost_data)->next_target_id) +#define fc_host_next_vport_number(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->next_vport_number) +#define fc_host_npiv_vports_inuse(x) \ + (((struct fc_host_attrs *)(x)->shost_data)->npiv_vports_inuse) #define fc_host_work_q_name(x) \ (((struct fc_host_attrs *)(x)->shost_data)->work_q_name) #define fc_host_work_q(x) \ @@ -420,14 +581,27 @@ struct fc_function_template { int (*issue_fc_host_lip)(struct Scsi_Host *); + void (*dev_loss_tmo_callbk)(struct fc_rport *); + void (*terminate_rport_io)(struct fc_rport *); + + void (*set_vport_symbolic_name)(struct fc_vport *); + int (*vport_create)(struct fc_vport *, bool); + int (*vport_disable)(struct fc_vport *, bool); + int (*vport_delete)(struct fc_vport *); + + /* target-mode drivers' functions */ + int (* tsk_mgmt_response)(struct Scsi_Host *, u64, u64, int); + int (* it_nexus_response)(struct Scsi_Host *, u64, int); + /* allocation lengths for host-specific data */ u32 dd_fcrport_size; + u32 dd_fcvport_size; - /* + /* * The driver sets these to tell the transport class it * wants the attributes displayed in sysfs. If the show_ flag * is not set, the attribute will be private to the transport - * class + * class */ /* remote port fixed attributes */ @@ -462,6 +636,8 @@ struct fc_function_template { unsigned long show_host_fabric_name:1; unsigned long show_host_symbolic_name:1; unsigned long show_host_system_hostname:1; + + unsigned long disable_target_scan:1; }; @@ -480,7 +656,7 @@ fc_remote_port_chkready(struct fc_rport *rport) switch (rport->port_state) { case FC_PORTSTATE_ONLINE: - if (rport->roles & FC_RPORT_ROLE_FCP_TARGET) + if (rport->roles & FC_PORT_ROLE_FCP_TARGET) result = 0; else if (rport->flags & FC_RPORT_DEVLOSS_PENDING) result = DID_IMM_RETRY << 16; @@ -517,6 +693,27 @@ static inline void u64_to_wwn(u64 inm, u8 *wwn) wwn[7] = inm & 0xff; } +/** + * fc_vport_set_state() - called to set a vport's state. Saves the old state, + * excepting the transitory states of initializing and sending the ELS + * traffic to instantiate the vport on the link. + * + * Assumes the driver has surrounded this with the proper locking to ensure + * a coherent state change. + * + * @vport: virtual port whose state is changing + * @new_state: new state + **/ +static inline void +fc_vport_set_state(struct fc_vport *vport, enum fc_vport_state new_state) +{ + if ((new_state != FC_VPORT_UNKNOWN) && + (new_state != FC_VPORT_INITIALIZING)) + vport->vport_last_state = vport->vport_state; + vport->vport_state = new_state; +} + + struct scsi_transport_template *fc_attach_transport( struct fc_function_template *); void fc_release_transport(struct scsi_transport_template *); @@ -526,5 +723,15 @@ struct fc_rport *fc_remote_port_add(struct Scsi_Host *shost, void fc_remote_port_delete(struct fc_rport *rport); void fc_remote_port_rolechg(struct fc_rport *rport, u32 roles); int scsi_is_fc_rport(const struct device *); +u32 fc_get_event_number(void); +void fc_host_post_event(struct Scsi_Host *shost, u32 event_number, + enum fc_host_event_code event_code, u32 event_data); +void fc_host_post_vendor_event(struct Scsi_Host *shost, u32 event_number, + u32 data_len, char * data_buf, u64 vendor_id); + /* Note: when specifying vendor_id to fc_host_post_vendor_event() + * be sure to read the Vendor Type and ID formatting requirements + * specified in scsi_netlink.h + */ +int fc_vport_terminate(struct fc_vport *vport); #endif /* SCSI_TRANSPORT_FC_H */