diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/pci_ids.h | 2 | ||||
-rw-r--r-- | include/scsi/fc/fc_ns.h | 11 | ||||
-rw-r--r-- | include/scsi/fc_encode.h | 26 | ||||
-rw-r--r-- | include/scsi/libfc.h | 74 | ||||
-rw-r--r-- | include/scsi/libfcoe.h | 105 | ||||
-rw-r--r-- | include/scsi/libiscsi.h | 8 | ||||
-rw-r--r-- | include/scsi/scsi.h | 5 | ||||
-rw-r--r-- | include/scsi/scsi_device.h | 1 | ||||
-rw-r--r-- | include/scsi/scsi_transport_iscsi.h | 6 | ||||
-rw-r--r-- | include/trace/events/scsi.h | 28 |
10 files changed, 244 insertions, 22 deletions
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 5b038d410e2..511e5ee809e 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2079,6 +2079,8 @@ #define PCI_DEVICE_ID_TIGON3_5723 0x165b #define PCI_DEVICE_ID_TIGON3_5705M 0x165d #define PCI_DEVICE_ID_TIGON3_5705M_2 0x165e +#define PCI_DEVICE_ID_NX2_57712 0x1662 +#define PCI_DEVICE_ID_NX2_57712E 0x1663 #define PCI_DEVICE_ID_TIGON3_5714 0x1668 #define PCI_DEVICE_ID_TIGON3_5714S 0x1669 #define PCI_DEVICE_ID_TIGON3_5780 0x166a diff --git a/include/scsi/fc/fc_ns.h b/include/scsi/fc/fc_ns.h index 185015dd116..f7751d53f1d 100644 --- a/include/scsi/fc/fc_ns.h +++ b/include/scsi/fc/fc_ns.h @@ -41,6 +41,7 @@ enum fc_ns_req { FC_NS_GI_A = 0x0101, /* get identifiers - scope */ FC_NS_GPN_ID = 0x0112, /* get port name by ID */ FC_NS_GNN_ID = 0x0113, /* get node name by ID */ + FC_NS_GSPN_ID = 0x0118, /* get symbolic port name */ FC_NS_GID_PN = 0x0121, /* get ID for port name */ FC_NS_GID_NN = 0x0131, /* get IDs for node name */ FC_NS_GID_FT = 0x0171, /* get IDs by FC4 type */ @@ -144,7 +145,7 @@ struct fc_ns_gid_pn { }; /* - * GID_PN response + * GID_PN response or GSPN_ID request */ struct fc_gid_pn_resp { __u8 fp_resvd; @@ -152,6 +153,14 @@ struct fc_gid_pn_resp { }; /* + * GSPN_ID response + */ +struct fc_gspn_resp { + __u8 fp_name_len; + char fp_name[]; +}; + +/* * RFT_ID request - register FC-4 types for ID. */ struct fc_ns_rft_id { diff --git a/include/scsi/fc_encode.h b/include/scsi/fc_encode.h index 6d293c846a4..be418d8448a 100644 --- a/include/scsi/fc_encode.h +++ b/include/scsi/fc_encode.h @@ -46,16 +46,11 @@ struct fc_ct_req { } payload; }; -/** - * fill FC header fields in specified fc_frame - */ -static inline void fc_fill_fc_hdr(struct fc_frame *fp, enum fc_rctl r_ctl, - u32 did, u32 sid, enum fc_fh_type type, - u32 f_ctl, u32 parm_offset) +static inline void __fc_fill_fc_hdr(struct fc_frame_header *fh, + enum fc_rctl r_ctl, + u32 did, u32 sid, enum fc_fh_type type, + u32 f_ctl, u32 parm_offset) { - struct fc_frame_header *fh; - - fh = fc_frame_header_get(fp); WARN_ON(r_ctl == 0); fh->fh_r_ctl = r_ctl; hton24(fh->fh_d_id, did); @@ -68,6 +63,19 @@ static inline void fc_fill_fc_hdr(struct fc_frame *fp, enum fc_rctl r_ctl, } /** + * fill FC header fields in specified fc_frame + */ +static inline void fc_fill_fc_hdr(struct fc_frame *fp, enum fc_rctl r_ctl, + u32 did, u32 sid, enum fc_fh_type type, + u32 f_ctl, u32 parm_offset) +{ + struct fc_frame_header *fh; + + fh = fc_frame_header_get(fp); + __fc_fill_fc_hdr(fh, r_ctl, did, sid, type, f_ctl, parm_offset); +} + +/** * fc_adisc_fill() - Fill in adisc request frame * @lport: local port. * @fp: fc frame where payload will be placed. diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h index f53c8e31d5f..24193c1b0da 100644 --- a/include/scsi/libfc.h +++ b/include/scsi/libfc.h @@ -35,6 +35,8 @@ #include <scsi/fc_frame.h> +#define FC_FC4_PROV_SIZE (FC_TYPE_FCP + 1) /* size of tables */ + /* * libfc error codes */ @@ -156,6 +158,7 @@ struct fc_rport_libfc_priv { #define FC_RP_FLAGS_REC_SUPPORTED (1 << 0) #define FC_RP_FLAGS_RETRY (1 << 1) #define FC_RP_STARTED (1 << 2) + #define FC_RP_FLAGS_CONF_REQ (1 << 3) unsigned int e_d_tov; unsigned int r_a_tov; }; @@ -179,6 +182,7 @@ struct fc_rport_libfc_priv { * @rp_mutex: The mutex that protects the remote port * @retry_work: Handle for retries * @event_callback: Callback when READY, FAILED or LOGO states complete + * @prli_count: Count of open PRLI sessions in providers * @rcu: Structure used for freeing in an RCU-safe manner */ struct fc_rport_priv { @@ -202,7 +206,13 @@ struct fc_rport_priv { struct list_head peers; struct work_struct event_work; u32 supported_classes; + u16 prli_count; struct rcu_head rcu; + u16 sp_features; + u8 spp_type; + void (*lld_event_callback)(struct fc_lport *, + struct fc_rport_priv *, + enum fc_rport_event); }; /** @@ -551,6 +561,16 @@ struct libfc_function_template { struct fc_seq *(*seq_start_next)(struct fc_seq *); /* + * Set a response handler for the exchange of the sequence. + * + * STATUS: OPTIONAL + */ + void (*seq_set_resp)(struct fc_seq *sp, + void (*resp)(struct fc_seq *, struct fc_frame *, + void *), + void *arg); + + /* * Assign a sequence for an incoming request frame. * * STATUS: OPTIONAL @@ -558,6 +578,13 @@ struct libfc_function_template { struct fc_seq *(*seq_assign)(struct fc_lport *, struct fc_frame *); /* + * Release the reference on the sequence returned by seq_assign(). + * + * STATUS: OPTIONAL + */ + void (*seq_release)(struct fc_seq *); + + /* * Reset an exchange manager, completing all sequences and exchanges. * If s_id is non-zero, reset only exchanges originating from that FID. * If d_id is non-zero, reset only exchanges sending to that FID. @@ -656,6 +683,15 @@ struct libfc_function_template { void (*rport_destroy)(struct kref *); /* + * Callback routine after the remote port is logged in + * + * STATUS: OPTIONAL + */ + void (*rport_event_callback)(struct fc_lport *, + struct fc_rport_priv *, + enum fc_rport_event); + + /* * Send a fcp cmd from fsp pkt. * Called with the SCSI host lock unlocked and irqs disabled. * @@ -749,6 +785,15 @@ struct fc_disc { enum fc_disc_event); }; +/* + * Local port notifier and events. + */ +extern struct blocking_notifier_head fc_lport_notifier_head; +enum fc_lport_event { + FC_LPORT_EV_ADD, + FC_LPORT_EV_DEL, +}; + /** * struct fc_lport - Local port * @host: The SCSI host associated with a local port @@ -789,8 +834,10 @@ struct fc_disc { * @lso_max: The maximum large offload send size * @fcts: FC-4 type mask * @lp_mutex: Mutex to protect the local port - * @list: Handle for list of local ports + * @list: Linkage on list of vport peers * @retry_work: Handle to local port for delayed retry context + * @prov: Pointers available for use by passive FC-4 providers + * @lport_list: Linkage on module-wide list of local ports */ struct fc_lport { /* Associations */ @@ -846,8 +893,32 @@ struct fc_lport { struct mutex lp_mutex; struct list_head list; struct delayed_work retry_work; + void *prov[FC_FC4_PROV_SIZE]; + struct list_head lport_list; }; +/** + * struct fc4_prov - FC-4 provider registration + * @prli: Handler for incoming PRLI + * @prlo: Handler for session reset + * @recv: Handler for incoming request + * @module: Pointer to module. May be NULL. + */ +struct fc4_prov { + int (*prli)(struct fc_rport_priv *, u32 spp_len, + const struct fc_els_spp *spp_in, + struct fc_els_spp *spp_out); + void (*prlo)(struct fc_rport_priv *); + void (*recv)(struct fc_lport *, struct fc_frame *); + struct module *module; +}; + +/* + * Register FC-4 provider with libfc. + */ +int fc_fc4_register_provider(enum fc_fh_type type, struct fc4_prov *); +void fc_fc4_deregister_provider(enum fc_fh_type type, struct fc4_prov *); + /* * FC_LPORT HELPER FUNCTIONS *****************************/ @@ -978,6 +1049,7 @@ struct fc_lport *libfc_vport_create(struct fc_vport *, int privsize); struct fc_lport *fc_vport_id_lookup(struct fc_lport *, u32 port_id); int fc_lport_bsg_request(struct fc_bsg_job *); void fc_lport_set_local_id(struct fc_lport *, u32 port_id); +void fc_lport_iterate(void (*func)(struct fc_lport *, void *), void *); /* * REMOTE PORT LAYER diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h index feb6a94c90e..8c1638b8c28 100644 --- a/include/scsi/libfcoe.h +++ b/include/scsi/libfcoe.h @@ -33,6 +33,12 @@ #define FCOE_MAX_CMD_LEN 16 /* Supported CDB length */ /* + * Max MTU for FCoE: 14 (FCoE header) + 24 (FC header) + 2112 (max FC payload) + * + 4 (FC CRC) + 4 (FCoE trailer) = 2158 bytes + */ +#define FCOE_MTU 2158 + +/* * FIP tunable parameters. */ #define FCOE_CTLR_START_DELAY 2000 /* mS after first adv. to choose FCF */ @@ -221,6 +227,8 @@ int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *, struct fc_lport *, u64 fcoe_wwn_from_mac(unsigned char mac[], unsigned int, unsigned int); int fcoe_libfc_config(struct fc_lport *, struct fcoe_ctlr *, const struct libfc_function_template *, int init_fcp); +u32 fcoe_fc_crc(struct fc_frame *fp); +int fcoe_start_io(struct sk_buff *skb); /** * is_fip_mode() - returns true if FIP mode selected. @@ -231,5 +239,102 @@ static inline bool is_fip_mode(struct fcoe_ctlr *fip) return fip->state == FIP_ST_ENABLED; } +/* helper for FCoE SW HBA drivers, can include subven and subdev if needed. The + * modpost would use pci_device_id table to auto-generate formatted module alias + * into the corresponding .mod.c file, but there may or may not be a pci device + * id table for FCoE drivers so we use the following helper for build the fcoe + * driver module alias. + */ +#define MODULE_ALIAS_FCOE_PCI(ven, dev) \ + MODULE_ALIAS("fcoe-pci:" \ + "v" __stringify(ven) \ + "d" __stringify(dev) "sv*sd*bc*sc*i*") + +/* the name of the default FCoE transport driver fcoe.ko */ +#define FCOE_TRANSPORT_DEFAULT "fcoe" + +/* struct fcoe_transport - The FCoE transport interface + * @name: a vendor specific name for their FCoE transport driver + * @attached: whether this transport is already attached + * @list: list linkage to all attached transports + * @match: handler to allow the transport driver to match up a given netdev + * @create: handler to sysfs entry of create for FCoE instances + * @destroy: handler to sysfs entry of destroy for FCoE instances + * @enable: handler to sysfs entry of enable for FCoE instances + * @disable: handler to sysfs entry of disable for FCoE instances + */ +struct fcoe_transport { + char name[IFNAMSIZ]; + bool attached; + struct list_head list; + bool (*match) (struct net_device *device); + int (*create) (struct net_device *device, enum fip_state fip_mode); + int (*destroy) (struct net_device *device); + int (*enable) (struct net_device *device); + int (*disable) (struct net_device *device); +}; + +/** + * struct fcoe_percpu_s - The context for FCoE receive thread(s) + * @thread: The thread context + * @fcoe_rx_list: The queue of pending packets to process + * @page: The memory page for calculating frame trailer CRCs + * @crc_eof_offset: The offset into the CRC page pointing to available + * memory for a new trailer + */ +struct fcoe_percpu_s { + struct task_struct *thread; + struct sk_buff_head fcoe_rx_list; + struct page *crc_eof_page; + int crc_eof_offset; +}; + +/** + * struct fcoe_port - The FCoE private structure + * @priv: The associated fcoe interface. The structure is + * defined by the low level driver + * @lport: The associated local port + * @fcoe_pending_queue: The pending Rx queue of skbs + * @fcoe_pending_queue_active: Indicates if the pending queue is active + * @max_queue_depth: Max queue depth of pending queue + * @min_queue_depth: Min queue depth of pending queue + * @timer: The queue timer + * @destroy_work: Handle for work context + * (to prevent RTNL deadlocks) + * @data_srt_addr: Source address for data + * + * An instance of this structure is to be allocated along with the + * Scsi_Host and libfc fc_lport structures. + */ +struct fcoe_port { + void *priv; + struct fc_lport *lport; + struct sk_buff_head fcoe_pending_queue; + u8 fcoe_pending_queue_active; + u32 max_queue_depth; + u32 min_queue_depth; + struct timer_list timer; + struct work_struct destroy_work; + u8 data_src_addr[ETH_ALEN]; +}; +void fcoe_clean_pending_queue(struct fc_lport *); +void fcoe_check_wait_queue(struct fc_lport *lport, struct sk_buff *skb); +void fcoe_queue_timer(ulong lport); +int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen, + struct fcoe_percpu_s *fps); + +/** + * struct netdev_list + * A mapping from netdevice to fcoe_transport + */ +struct fcoe_netdev_mapping { + struct list_head list; + struct net_device *netdev; + struct fcoe_transport *ft; +}; + +/* fcoe transports registration and deregistration */ +int fcoe_transport_attach(struct fcoe_transport *ft); +int fcoe_transport_detach(struct fcoe_transport *ft); #endif /* _LIBFCOE_H */ diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 748382b32b5..0f4367751b7 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -212,9 +212,6 @@ struct iscsi_conn { /* values userspace uses to id a conn */ int persistent_port; char *persistent_address; - /* remote portal currently connected to */ - int portal_port; - char portal_address[ISCSI_ADDRESS_BUF_LEN]; /* MIB-statistics */ uint64_t txdata_octets; @@ -319,9 +316,6 @@ struct iscsi_host { /* hw address or netdev iscsi connection is bound to */ char *hwaddress; char *netdev; - /* local address */ - int local_port; - char local_address[ISCSI_ADDRESS_BUF_LEN]; wait_queue_head_t session_removal_wq; /* protects sessions and state */ @@ -394,6 +388,8 @@ extern void iscsi_session_failure(struct iscsi_session *session, enum iscsi_err err); extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, char *buf); +extern int iscsi_conn_get_addr_param(struct sockaddr_storage *addr, + enum iscsi_param param, char *buf); extern void iscsi_suspend_tx(struct iscsi_conn *conn); extern void iscsi_suspend_queue(struct iscsi_conn *conn); extern void iscsi_conn_queue_work(struct iscsi_conn *conn); diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h index b76d4006e36..3668903e397 100644 --- a/include/scsi/scsi.h +++ b/include/scsi/scsi.h @@ -435,6 +435,10 @@ static inline int scsi_is_wlun(unsigned int lun) * recover the link. Transport class will * retry or fail IO */ #define DID_TRANSPORT_FAILFAST 0x0f /* Transport class fastfailed the io */ +#define DID_TARGET_FAILURE 0x10 /* Permanent target failure, do not retry on + * other paths */ +#define DID_NEXUS_FAILURE 0x11 /* Permanent nexus failure, retry on other + * paths might yield different results */ #define DRIVER_OK 0x00 /* Driver status */ /* @@ -464,6 +468,7 @@ static inline int scsi_is_wlun(unsigned int lun) #define TIMEOUT_ERROR 0x2007 #define SCSI_RETURN_NOT_HANDLED 0x2008 #define FAST_IO_FAIL 0x2009 +#define TARGET_ERROR 0x200A /* * Midlevel queue return values. diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 85867dcde33..f171c65dc5a 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -184,6 +184,7 @@ typedef void (*activate_complete)(void *, int); struct scsi_device_handler { /* Used by the infrastructure */ struct list_head list; /* list of scsi_device_handlers */ + int idx; /* Filled by the hardware handler */ struct module *module; diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index 7fff94b3b2a..bf8f5296567 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -101,6 +101,8 @@ struct iscsi_transport { void (*destroy_conn) (struct iscsi_cls_conn *conn); int (*set_param) (struct iscsi_cls_conn *conn, enum iscsi_param param, char *buf, int buflen); + int (*get_ep_param) (struct iscsi_endpoint *ep, enum iscsi_param param, + char *buf); int (*get_conn_param) (struct iscsi_cls_conn *conn, enum iscsi_param param, char *buf); int (*get_session_param) (struct iscsi_cls_session *session, @@ -160,8 +162,9 @@ struct iscsi_cls_conn { void *dd_data; /* LLD private data */ struct iscsi_transport *transport; uint32_t cid; /* connection id */ + struct mutex ep_mutex; + struct iscsi_endpoint *ep; - int active; /* must be accessed with the connlock */ struct device dev; /* sysfs transport/container device */ }; @@ -222,6 +225,7 @@ struct iscsi_endpoint { void *dd_data; /* LLD private data */ struct device dev; uint64_t id; + struct iscsi_cls_conn *conn; }; /* diff --git a/include/trace/events/scsi.h b/include/trace/events/scsi.h index 25fbefdf2f2..db6c93510f7 100644 --- a/include/trace/events/scsi.h +++ b/include/trace/events/scsi.h @@ -184,6 +184,17 @@ scsi_statusbyte_name(SAM_STAT_ACA_ACTIVE), \ scsi_statusbyte_name(SAM_STAT_TASK_ABORTED)) +#define scsi_prot_op_name(result) { result, #result } +#define show_prot_op_name(val) \ + __print_symbolic(val, \ + scsi_prot_op_name(SCSI_PROT_NORMAL), \ + scsi_prot_op_name(SCSI_PROT_READ_INSERT), \ + scsi_prot_op_name(SCSI_PROT_WRITE_STRIP), \ + scsi_prot_op_name(SCSI_PROT_READ_STRIP), \ + scsi_prot_op_name(SCSI_PROT_WRITE_INSERT), \ + scsi_prot_op_name(SCSI_PROT_READ_PASS), \ + scsi_prot_op_name(SCSI_PROT_WRITE_PASS)) + const char *scsi_trace_parse_cdb(struct trace_seq*, unsigned char*, int); #define __parse_cdb(cdb, len) scsi_trace_parse_cdb(p, cdb, len) @@ -202,6 +213,7 @@ TRACE_EVENT(scsi_dispatch_cmd_start, __field( unsigned int, cmd_len ) __field( unsigned int, data_sglen ) __field( unsigned int, prot_sglen ) + __field( unsigned char, prot_op ) __dynamic_array(unsigned char, cmnd, cmd->cmd_len) ), @@ -214,13 +226,15 @@ TRACE_EVENT(scsi_dispatch_cmd_start, __entry->cmd_len = cmd->cmd_len; __entry->data_sglen = scsi_sg_count(cmd); __entry->prot_sglen = scsi_prot_sg_count(cmd); + __entry->prot_op = scsi_get_prot_op(cmd); memcpy(__get_dynamic_array(cmnd), cmd->cmnd, cmd->cmd_len); ), TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \ - " cmnd=(%s %s raw=%s)", + " prot_op=%s cmnd=(%s %s raw=%s)", __entry->host_no, __entry->channel, __entry->id, __entry->lun, __entry->data_sglen, __entry->prot_sglen, + show_prot_op_name(__entry->prot_op), show_opcode_name(__entry->opcode), __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len)) @@ -242,6 +256,7 @@ TRACE_EVENT(scsi_dispatch_cmd_error, __field( unsigned int, cmd_len ) __field( unsigned int, data_sglen ) __field( unsigned int, prot_sglen ) + __field( unsigned char, prot_op ) __dynamic_array(unsigned char, cmnd, cmd->cmd_len) ), @@ -255,13 +270,15 @@ TRACE_EVENT(scsi_dispatch_cmd_error, __entry->cmd_len = cmd->cmd_len; __entry->data_sglen = scsi_sg_count(cmd); __entry->prot_sglen = scsi_prot_sg_count(cmd); + __entry->prot_op = scsi_get_prot_op(cmd); memcpy(__get_dynamic_array(cmnd), cmd->cmnd, cmd->cmd_len); ), TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u prot_sgl=%u" \ - " cmnd=(%s %s raw=%s) rtn=%d", + " prot_op=%s cmnd=(%s %s raw=%s) rtn=%d", __entry->host_no, __entry->channel, __entry->id, __entry->lun, __entry->data_sglen, __entry->prot_sglen, + show_prot_op_name(__entry->prot_op), show_opcode_name(__entry->opcode), __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len), @@ -284,6 +301,7 @@ DECLARE_EVENT_CLASS(scsi_cmd_done_timeout_template, __field( unsigned int, cmd_len ) __field( unsigned int, data_sglen ) __field( unsigned int, prot_sglen ) + __field( unsigned char, prot_op ) __dynamic_array(unsigned char, cmnd, cmd->cmd_len) ), @@ -297,14 +315,16 @@ DECLARE_EVENT_CLASS(scsi_cmd_done_timeout_template, __entry->cmd_len = cmd->cmd_len; __entry->data_sglen = scsi_sg_count(cmd); __entry->prot_sglen = scsi_prot_sg_count(cmd); + __entry->prot_op = scsi_get_prot_op(cmd); memcpy(__get_dynamic_array(cmnd), cmd->cmnd, cmd->cmd_len); ), TP_printk("host_no=%u channel=%u id=%u lun=%u data_sgl=%u " \ - "prot_sgl=%u cmnd=(%s %s raw=%s) result=(driver=%s host=%s " \ - "message=%s status=%s)", + "prot_sgl=%u prot_op=%s cmnd=(%s %s raw=%s) result=(driver=" \ + "%s host=%s message=%s status=%s)", __entry->host_no, __entry->channel, __entry->id, __entry->lun, __entry->data_sglen, __entry->prot_sglen, + show_prot_op_name(__entry->prot_op), show_opcode_name(__entry->opcode), __parse_cdb(__get_dynamic_array(cmnd), __entry->cmd_len), __print_hex(__get_dynamic_array(cmnd), __entry->cmd_len), |