aboutsummaryrefslogtreecommitdiff
path: root/include/scsi/scsi_transport_fc.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/scsi/scsi_transport_fc.h')
-rw-r--r--include/scsi/scsi_transport_fc.h137
1 files changed, 128 insertions, 9 deletions
diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
index 878373c32ef..8c79980dc8f 100644
--- a/include/scsi/scsi_transport_fc.h
+++ b/include/scsi/scsi_transport_fc.h
@@ -33,7 +33,6 @@
struct scsi_transport_template;
-
/*
* FC Port definitions - Following FC HBAAPI guidelines
*
@@ -127,10 +126,11 @@ enum fc_vport_state {
incapable of reporting */
#define FC_PORTSPEED_1GBIT 1
#define FC_PORTSPEED_2GBIT 2
-#define FC_PORTSPEED_4GBIT 4
-#define FC_PORTSPEED_10GBIT 8
+#define FC_PORTSPEED_10GBIT 4
+#define FC_PORTSPEED_4GBIT 8
#define FC_PORTSPEED_8GBIT 0x10
#define FC_PORTSPEED_16GBIT 0x20
+#define FC_PORTSPEED_32GBIT 0x40
#define FC_PORTSPEED_NOT_NEGOTIATED (1 << 15) /* Speed not established */
/*
@@ -167,15 +167,35 @@ enum fc_tgtid_binding_type {
struct device_attribute dev_attr_vport_##_name = \
__ATTR(_name,_mode,_show,_store)
+/*
+ * fc_vport_identifiers: This set of data contains all elements
+ * to uniquely identify and instantiate a FC virtual port.
+ *
+ * Notes:
+ * symbolic_name: The driver is to append the symbolic_name string data
+ * to the symbolic_node_name data that it generates by default.
+ * the resulting combination should then be registered with the switch.
+ * It is expected that things like Xen may stuff a VM title into
+ * this field.
+ */
+#define FC_VPORT_SYMBOLIC_NAMELEN 64
+struct fc_vport_identifiers {
+ u64 node_name;
+ u64 port_name;
+ u32 roles;
+ bool disable;
+ enum fc_port_type vport_type; /* only FC_PORTTYPE_NPIV allowed */
+ char symbolic_name[FC_VPORT_SYMBOLIC_NAMELEN];
+};
/*
* 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
+ * ports has a unique presence 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,
+ * unique presence, 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
@@ -197,7 +217,6 @@ struct device_attribute dev_attr_vport_##_name = \
* managed by the transport w/o driver interaction.
*/
-#define FC_VPORT_SYMBOLIC_NAMELEN 64
struct fc_vport {
/* Fixed Attributes */
@@ -333,11 +352,14 @@ struct fc_rport { /* aka fc_starget_attrs */
struct delayed_work fail_io_work;
struct work_struct stgt_delete_work;
struct work_struct rport_delete_work;
+ struct request_queue *rqst_q; /* bsg support */
} __attribute__((aligned(sizeof(unsigned long))));
/* bit field values for struct fc_rport "flags" field: */
#define FC_RPORT_DEVLOSS_PENDING 0x01
#define FC_RPORT_SCAN_PENDING 0x02
+#define FC_RPORT_FAST_FAIL_TIMEDOUT 0x04
+#define FC_RPORT_DEVLOSS_CALLBK_DONE 0x08
#define dev_to_rport(d) \
container_of(d, struct fc_rport, dev)
@@ -349,7 +371,7 @@ struct fc_rport { /* aka fc_starget_attrs */
/*
* FC SCSI Target Attributes
*
- * The SCSI Target is considered an extention of a remote port (as
+ * The SCSI Target is considered an extension of a remote port (as
* a remote port can be more than a SCSI Target). Within the scsi
* subsystem, we leave the Target as a separate entity. Doing so
* provides backward compatibility with prior FC transport api's,
@@ -405,6 +427,18 @@ struct fc_host_statistics {
u64 fcp_control_requests;
u64 fcp_input_megabytes;
u64 fcp_output_megabytes;
+ u64 fcp_packet_alloc_failures; /* fcp packet allocation failures */
+ u64 fcp_packet_aborts; /* fcp packet aborted */
+ u64 fcp_frame_alloc_failures; /* fcp frame allocation failures */
+
+ /* fc exches statistics */
+ u64 fc_no_free_exch; /* no free exch memory */
+ u64 fc_no_free_exch_xid; /* no free exch id */
+ u64 fc_xid_not_found; /* exch not found for a response */
+ u64 fc_xid_busy; /* exch exist for new a request */
+ u64 fc_seq_not_found; /* seq is not found for exchange */
+ u64 fc_non_bls_resp; /* a non BLS response frame with
+ a sequence responder in new exch */
};
@@ -465,6 +499,13 @@ struct fc_host_attrs {
u32 maxframe_size;
u16 max_npiv_vports;
char serial_number[FC_SERIAL_NUMBER_SIZE];
+ char manufacturer[FC_SERIAL_NUMBER_SIZE];
+ char model[FC_SYMBOLIC_NAME_SIZE];
+ char model_description[FC_SYMBOLIC_NAME_SIZE];
+ char hardware_version[FC_VERSION_STRING_SIZE];
+ char driver_version[FC_VERSION_STRING_SIZE];
+ char firmware_version[FC_VERSION_STRING_SIZE];
+ char optionrom_version[FC_VERSION_STRING_SIZE];
/* Dynamic Attributes */
u32 port_id;
@@ -475,6 +516,7 @@ struct fc_host_attrs {
u64 fabric_name;
char symbolic_name[FC_SYMBOLIC_NAME_SIZE];
char system_hostname[FC_SYMBOLIC_NAME_SIZE];
+ u32 dev_loss_tmo;
/* Private (Transport-managed) Attributes */
enum fc_tgtid_binding_type tgtid_bind_type;
@@ -493,6 +535,9 @@ struct fc_host_attrs {
struct workqueue_struct *work_q;
char devloss_work_q_name[20];
struct workqueue_struct *devloss_work_q;
+
+ /* bsg support */
+ struct request_queue *rqst_q;
};
#define shost_to_fc_host(x) \
@@ -516,6 +561,20 @@ struct fc_host_attrs {
(((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_manufacturer(x) \
+ (((struct fc_host_attrs *)(x)->shost_data)->manufacturer)
+#define fc_host_model(x) \
+ (((struct fc_host_attrs *)(x)->shost_data)->model)
+#define fc_host_model_description(x) \
+ (((struct fc_host_attrs *)(x)->shost_data)->model_description)
+#define fc_host_hardware_version(x) \
+ (((struct fc_host_attrs *)(x)->shost_data)->hardware_version)
+#define fc_host_driver_version(x) \
+ (((struct fc_host_attrs *)(x)->shost_data)->driver_version)
+#define fc_host_firmware_version(x) \
+ (((struct fc_host_attrs *)(x)->shost_data)->firmware_version)
+#define fc_host_optionrom_version(x) \
+ (((struct fc_host_attrs *)(x)->shost_data)->optionrom_version)
#define fc_host_port_id(x) \
(((struct fc_host_attrs *)(x)->shost_data)->port_id)
#define fc_host_port_type(x) \
@@ -556,6 +615,49 @@ struct fc_host_attrs {
(((struct fc_host_attrs *)(x)->shost_data)->devloss_work_q_name)
#define fc_host_devloss_work_q(x) \
(((struct fc_host_attrs *)(x)->shost_data)->devloss_work_q)
+#define fc_host_dev_loss_tmo(x) \
+ (((struct fc_host_attrs *)(x)->shost_data)->dev_loss_tmo)
+
+
+struct fc_bsg_buffer {
+ unsigned int payload_len;
+ int sg_cnt;
+ struct scatterlist *sg_list;
+};
+
+/* Values for fc_bsg_job->state_flags (bitflags) */
+#define FC_RQST_STATE_INPROGRESS 0
+#define FC_RQST_STATE_DONE 1
+
+struct fc_bsg_job {
+ struct Scsi_Host *shost;
+ struct fc_rport *rport;
+ struct device *dev;
+ struct request *req;
+ spinlock_t job_lock;
+ unsigned int state_flags;
+ unsigned int ref_cnt;
+ void (*job_done)(struct fc_bsg_job *);
+
+ struct fc_bsg_request *request;
+ struct fc_bsg_reply *reply;
+ unsigned int request_len;
+ unsigned int reply_len;
+ /*
+ * On entry : reply_len indicates the buffer size allocated for
+ * the reply.
+ *
+ * Upon completion : the message handler must set reply_len
+ * to indicates the size of the reply to be returned to the
+ * caller.
+ */
+
+ /* DMA payloads for the request/response */
+ struct fc_bsg_buffer request_payload;
+ struct fc_bsg_buffer reply_payload;
+
+ void *dd_data; /* Used for driver-specific storage */
+};
/* The functions by which the transport class and the driver communicate */
@@ -593,9 +695,14 @@ struct fc_function_template {
int (* tsk_mgmt_response)(struct Scsi_Host *, u64, u64, int);
int (* it_nexus_response)(struct Scsi_Host *, u64, int);
+ /* bsg support */
+ int (*bsg_request)(struct fc_bsg_job *);
+ int (*bsg_timeout)(struct fc_bsg_job *);
+
/* allocation lengths for host-specific data */
u32 dd_fcrport_size;
u32 dd_fcvport_size;
+ u32 dd_bsg_size;
/*
* The driver sets these to tell the transport class it
@@ -627,6 +734,13 @@ struct fc_function_template {
unsigned long show_host_supported_speeds:1;
unsigned long show_host_maxframe_size:1;
unsigned long show_host_serial_number:1;
+ unsigned long show_host_manufacturer:1;
+ unsigned long show_host_model:1;
+ unsigned long show_host_model_description:1;
+ unsigned long show_host_hardware_version:1;
+ unsigned long show_host_driver_version:1;
+ unsigned long show_host_firmware_version:1;
+ unsigned long show_host_optionrom_version:1;
/* host dynamic attributes */
unsigned long show_host_port_id:1;
unsigned long show_host_port_type:1;
@@ -664,7 +778,10 @@ fc_remote_port_chkready(struct fc_rport *rport)
result = DID_NO_CONNECT << 16;
break;
case FC_PORTSTATE_BLOCKED:
- result = DID_IMM_RETRY << 16;
+ if (rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT)
+ result = DID_TRANSPORT_FAILFAST << 16;
+ else
+ result = DID_IMM_RETRY << 16;
break;
default:
result = DID_NO_CONNECT << 16;
@@ -713,7 +830,6 @@ fc_vport_set_state(struct fc_vport *vport, enum fc_vport_state new_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 *);
@@ -732,6 +848,9 @@ void fc_host_post_vendor_event(struct Scsi_Host *shost, u32 event_number,
* be sure to read the Vendor Type and ID formatting requirements
* specified in scsi_netlink.h
*/
+struct fc_vport *fc_vport_create(struct Scsi_Host *shost, int channel,
+ struct fc_vport_identifiers *);
int fc_vport_terminate(struct fc_vport *vport);
+int fc_block_scsi_eh(struct scsi_cmnd *cmnd);
#endif /* SCSI_TRANSPORT_FC_H */