diff options
Diffstat (limited to 'include/scsi')
| -rw-r--r-- | include/scsi/fc/fc_fc2.h | 2 | ||||
| -rw-r--r-- | include/scsi/iscsi_if.h | 247 | ||||
| -rw-r--r-- | include/scsi/libfc.h | 9 | ||||
| -rw-r--r-- | include/scsi/libfcoe.h | 7 | ||||
| -rw-r--r-- | include/scsi/libiscsi.h | 22 | ||||
| -rw-r--r-- | include/scsi/libiscsi_tcp.h | 2 | ||||
| -rw-r--r-- | include/scsi/libsas.h | 1 | ||||
| -rw-r--r-- | include/scsi/osd_ore.h | 1 | ||||
| -rw-r--r-- | include/scsi/osd_protocol.h | 10 | ||||
| -rw-r--r-- | include/scsi/scsi.h | 1 | ||||
| -rw-r--r-- | include/scsi/scsi_cmnd.h | 33 | ||||
| -rw-r--r-- | include/scsi/scsi_device.h | 27 | ||||
| -rw-r--r-- | include/scsi/scsi_driver.h | 11 | ||||
| -rw-r--r-- | include/scsi/scsi_host.h | 28 | ||||
| -rw-r--r-- | include/scsi/scsi_transport_fc.h | 1 | ||||
| -rw-r--r-- | include/scsi/scsi_transport_iscsi.h | 6 | ||||
| -rw-r--r-- | include/scsi/scsi_transport_srp.h | 106 | 
17 files changed, 463 insertions, 51 deletions
diff --git a/include/scsi/fc/fc_fc2.h b/include/scsi/fc/fc_fc2.h index f87777d0d5b..0b267143130 100644 --- a/include/scsi/fc/fc_fc2.h +++ b/include/scsi/fc/fc_fc2.h @@ -104,7 +104,7 @@ struct fc_esb {   * esb_e_stat - flags from FC-FS-2 T11/1619-D Rev 0.90.   */  #define ESB_ST_RESP         (1 << 31)   /* responder to exchange */ -#define ESB_ST_SEQ_INIT     (1 << 30)   /* port holds sequence initiaive */ +#define ESB_ST_SEQ_INIT     (1 << 30)   /* port holds sequence initiative */  #define ESB_ST_COMPLETE     (1 << 29)   /* exchange is complete */  #define ESB_ST_ABNORMAL     (1 << 28)   /* abnormal ending condition */  #define ESB_ST_REC_QUAL     (1 << 26)   /* recovery qualifier active */ diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h index 13d81c5c4eb..fd0421c6d40 100644 --- a/include/scsi/iscsi_if.h +++ b/include/scsi/iscsi_if.h @@ -69,6 +69,8 @@ enum iscsi_uevent_e {  	ISCSI_UEVENT_LOGIN_FLASHNODE	= UEVENT_BASE + 28,  	ISCSI_UEVENT_LOGOUT_FLASHNODE	= UEVENT_BASE + 29,  	ISCSI_UEVENT_LOGOUT_FLASHNODE_SID	= UEVENT_BASE + 30, +	ISCSI_UEVENT_SET_CHAP		= UEVENT_BASE + 31, +	ISCSI_UEVENT_GET_HOST_STATS	= UEVENT_BASE + 32,  	/* up events */  	ISCSI_KEVENT_RECV_PDU		= KEVENT_BASE + 1, @@ -241,6 +243,9 @@ struct iscsi_uevent {  			uint32_t	host_no;  			uint32_t	sid;  		} logout_flashnode_sid; +		struct msg_get_host_stats { +			uint32_t host_no; +		} get_host_stats;  	} u;  	union {  		/* messages k -> u */ @@ -309,8 +314,17 @@ enum iscsi_param_type {  	ISCSI_HOST_PARAM,	/* iscsi_host_param */  	ISCSI_NET_PARAM,	/* iscsi_net_param */  	ISCSI_FLASHNODE_PARAM,	/* iscsi_flashnode_param */ +	ISCSI_CHAP_PARAM,	/* iscsi_chap_param */ +	ISCSI_IFACE_PARAM,	/* iscsi_iface_param */  }; +/* structure for minimalist usecase */ +struct iscsi_param_info { +	uint32_t len;		/* Actual length of the param value */ +	uint16_t param;		/* iscsi param */ +	uint8_t value[0];	/* length sized value follows */ +} __packed; +  struct iscsi_iface_param_info {  	uint32_t iface_num;	/* iface number, 0 - n */  	uint32_t len;		/* Actual length of the param */ @@ -374,28 +388,106 @@ struct iscsi_path {  #define ISCSI_VLAN_DISABLE	0x01  #define ISCSI_VLAN_ENABLE	0x02 +/* iscsi generic enable/disabled setting for various features */ +#define ISCSI_NET_PARAM_DISABLE		0x01 +#define ISCSI_NET_PARAM_ENABLE		0x02 +  /* iSCSI network params */  enum iscsi_net_param {  	ISCSI_NET_PARAM_IPV4_ADDR		= 1, -	ISCSI_NET_PARAM_IPV4_SUBNET		= 2, -	ISCSI_NET_PARAM_IPV4_GW			= 3, -	ISCSI_NET_PARAM_IPV4_BOOTPROTO		= 4, -	ISCSI_NET_PARAM_MAC			= 5, -	ISCSI_NET_PARAM_IPV6_LINKLOCAL		= 6, -	ISCSI_NET_PARAM_IPV6_ADDR		= 7, -	ISCSI_NET_PARAM_IPV6_ROUTER		= 8, -	ISCSI_NET_PARAM_IPV6_ADDR_AUTOCFG	= 9, -	ISCSI_NET_PARAM_IPV6_LINKLOCAL_AUTOCFG	= 10, -	ISCSI_NET_PARAM_IPV6_ROUTER_AUTOCFG	= 11, -	ISCSI_NET_PARAM_IFACE_ENABLE		= 12, -	ISCSI_NET_PARAM_VLAN_ID			= 13, -	ISCSI_NET_PARAM_VLAN_PRIORITY		= 14, -	ISCSI_NET_PARAM_VLAN_ENABLED		= 15, -	ISCSI_NET_PARAM_VLAN_TAG		= 16, -	ISCSI_NET_PARAM_IFACE_TYPE		= 17, -	ISCSI_NET_PARAM_IFACE_NAME		= 18, -	ISCSI_NET_PARAM_MTU			= 19, -	ISCSI_NET_PARAM_PORT			= 20, +	ISCSI_NET_PARAM_IPV4_SUBNET, +	ISCSI_NET_PARAM_IPV4_GW, +	ISCSI_NET_PARAM_IPV4_BOOTPROTO, +	ISCSI_NET_PARAM_MAC, +	ISCSI_NET_PARAM_IPV6_LINKLOCAL, +	ISCSI_NET_PARAM_IPV6_ADDR, +	ISCSI_NET_PARAM_IPV6_ROUTER, +	ISCSI_NET_PARAM_IPV6_ADDR_AUTOCFG, +	ISCSI_NET_PARAM_IPV6_LINKLOCAL_AUTOCFG, +	ISCSI_NET_PARAM_IPV6_ROUTER_AUTOCFG, +	ISCSI_NET_PARAM_IFACE_ENABLE, +	ISCSI_NET_PARAM_VLAN_ID, +	ISCSI_NET_PARAM_VLAN_PRIORITY, +	ISCSI_NET_PARAM_VLAN_ENABLED, +	ISCSI_NET_PARAM_VLAN_TAG, +	ISCSI_NET_PARAM_IFACE_TYPE, +	ISCSI_NET_PARAM_IFACE_NAME, +	ISCSI_NET_PARAM_MTU, +	ISCSI_NET_PARAM_PORT, +	ISCSI_NET_PARAM_IPADDR_STATE, +	ISCSI_NET_PARAM_IPV6_LINKLOCAL_STATE, +	ISCSI_NET_PARAM_IPV6_ROUTER_STATE, +	ISCSI_NET_PARAM_DELAYED_ACK_EN, +	ISCSI_NET_PARAM_TCP_NAGLE_DISABLE, +	ISCSI_NET_PARAM_TCP_WSF_DISABLE, +	ISCSI_NET_PARAM_TCP_WSF, +	ISCSI_NET_PARAM_TCP_TIMER_SCALE, +	ISCSI_NET_PARAM_TCP_TIMESTAMP_EN, +	ISCSI_NET_PARAM_CACHE_ID, +	ISCSI_NET_PARAM_IPV4_DHCP_DNS_ADDR_EN, +	ISCSI_NET_PARAM_IPV4_DHCP_SLP_DA_EN, +	ISCSI_NET_PARAM_IPV4_TOS_EN, +	ISCSI_NET_PARAM_IPV4_TOS, +	ISCSI_NET_PARAM_IPV4_GRAT_ARP_EN, +	ISCSI_NET_PARAM_IPV4_DHCP_ALT_CLIENT_ID_EN, +	ISCSI_NET_PARAM_IPV4_DHCP_ALT_CLIENT_ID, +	ISCSI_NET_PARAM_IPV4_DHCP_REQ_VENDOR_ID_EN, +	ISCSI_NET_PARAM_IPV4_DHCP_USE_VENDOR_ID_EN, +	ISCSI_NET_PARAM_IPV4_DHCP_VENDOR_ID, +	ISCSI_NET_PARAM_IPV4_DHCP_LEARN_IQN_EN, +	ISCSI_NET_PARAM_IPV4_FRAGMENT_DISABLE, +	ISCSI_NET_PARAM_IPV4_IN_FORWARD_EN, +	ISCSI_NET_PARAM_IPV4_TTL, +	ISCSI_NET_PARAM_IPV6_GRAT_NEIGHBOR_ADV_EN, +	ISCSI_NET_PARAM_IPV6_MLD_EN, +	ISCSI_NET_PARAM_IPV6_FLOW_LABEL, +	ISCSI_NET_PARAM_IPV6_TRAFFIC_CLASS, +	ISCSI_NET_PARAM_IPV6_HOP_LIMIT, +	ISCSI_NET_PARAM_IPV6_ND_REACHABLE_TMO, +	ISCSI_NET_PARAM_IPV6_ND_REXMIT_TIME, +	ISCSI_NET_PARAM_IPV6_ND_STALE_TMO, +	ISCSI_NET_PARAM_IPV6_DUP_ADDR_DETECT_CNT, +	ISCSI_NET_PARAM_IPV6_RTR_ADV_LINK_MTU, +	ISCSI_NET_PARAM_REDIRECT_EN, +}; + +enum iscsi_ipaddress_state { +	ISCSI_IPDDRESS_STATE_UNCONFIGURED, +	ISCSI_IPDDRESS_STATE_ACQUIRING, +	ISCSI_IPDDRESS_STATE_TENTATIVE, +	ISCSI_IPDDRESS_STATE_VALID, +	ISCSI_IPDDRESS_STATE_DISABLING, +	ISCSI_IPDDRESS_STATE_INVALID, +	ISCSI_IPDDRESS_STATE_DEPRECATED, +}; + +enum iscsi_router_state { +	ISCSI_ROUTER_STATE_UNKNOWN, +	ISCSI_ROUTER_STATE_ADVERTISED, +	ISCSI_ROUTER_STATE_MANUAL, +	ISCSI_ROUTER_STATE_STALE, +}; + +/* iSCSI specific settings params for iface */ +enum iscsi_iface_param { +	ISCSI_IFACE_PARAM_DEF_TASKMGMT_TMO, +	ISCSI_IFACE_PARAM_HDRDGST_EN, +	ISCSI_IFACE_PARAM_DATADGST_EN, +	ISCSI_IFACE_PARAM_IMM_DATA_EN, +	ISCSI_IFACE_PARAM_INITIAL_R2T_EN, +	ISCSI_IFACE_PARAM_DATASEQ_INORDER_EN, +	ISCSI_IFACE_PARAM_PDU_INORDER_EN, +	ISCSI_IFACE_PARAM_ERL, +	ISCSI_IFACE_PARAM_MAX_RECV_DLENGTH, +	ISCSI_IFACE_PARAM_FIRST_BURST, +	ISCSI_IFACE_PARAM_MAX_R2T, +	ISCSI_IFACE_PARAM_MAX_BURST, +	ISCSI_IFACE_PARAM_CHAP_AUTH_EN, +	ISCSI_IFACE_PARAM_BIDI_CHAP_EN, +	ISCSI_IFACE_PARAM_DISCOVERY_AUTH_OPTIONAL, +	ISCSI_IFACE_PARAM_DISCOVERY_LOGOUT_EN, +	ISCSI_IFACE_PARAM_STRICT_LOGIN_COMP_EN, +	ISCSI_IFACE_PARAM_INITIATOR_NAME,  };  enum iscsi_conn_state { @@ -526,6 +618,7 @@ enum iscsi_param {  	ISCSI_PARAM_DISCOVERY_PARENT_IDX,  	ISCSI_PARAM_DISCOVERY_PARENT_TYPE, +	ISCSI_PARAM_LOCAL_IPADDR,  	/* must always be last */  	ISCSI_PARAM_MAX,  }; @@ -739,6 +832,14 @@ enum chap_type_e {  	CHAP_TYPE_IN,  }; +enum iscsi_chap_param { +	ISCSI_CHAP_PARAM_INDEX, +	ISCSI_CHAP_PARAM_CHAP_TYPE, +	ISCSI_CHAP_PARAM_USERNAME, +	ISCSI_CHAP_PARAM_PASSWORD, +	ISCSI_CHAP_PARAM_PASSWORD_LEN +}; +  #define ISCSI_CHAP_AUTH_NAME_MAX_LEN	256  #define ISCSI_CHAP_AUTH_SECRET_MAX_LEN	256  struct iscsi_chap_rec { @@ -749,4 +850,112 @@ struct iscsi_chap_rec {  	uint8_t password_length;  }; +#define ISCSI_HOST_STATS_CUSTOM_MAX             32 +#define ISCSI_HOST_STATS_CUSTOM_DESC_MAX        64 +struct iscsi_host_stats_custom { +	char desc[ISCSI_HOST_STATS_CUSTOM_DESC_MAX]; +	uint64_t value; +}; + +/* struct iscsi_offload_host_stats: Host statistics, + * Include statistics for MAC, IP, TCP & iSCSI. + */ +struct iscsi_offload_host_stats { +	/* MAC */ +	uint64_t mactx_frames; +	uint64_t mactx_bytes; +	uint64_t mactx_multicast_frames; +	uint64_t mactx_broadcast_frames; +	uint64_t mactx_pause_frames; +	uint64_t mactx_control_frames; +	uint64_t mactx_deferral; +	uint64_t mactx_excess_deferral; +	uint64_t mactx_late_collision; +	uint64_t mactx_abort; +	uint64_t mactx_single_collision; +	uint64_t mactx_multiple_collision; +	uint64_t mactx_collision; +	uint64_t mactx_frames_dropped; +	uint64_t mactx_jumbo_frames; +	uint64_t macrx_frames; +	uint64_t macrx_bytes; +	uint64_t macrx_unknown_control_frames; +	uint64_t macrx_pause_frames; +	uint64_t macrx_control_frames; +	uint64_t macrx_dribble; +	uint64_t macrx_frame_length_error; +	uint64_t macrx_jabber; +	uint64_t macrx_carrier_sense_error; +	uint64_t macrx_frame_discarded; +	uint64_t macrx_frames_dropped; +	uint64_t mac_crc_error; +	uint64_t mac_encoding_error; +	uint64_t macrx_length_error_large; +	uint64_t macrx_length_error_small; +	uint64_t macrx_multicast_frames; +	uint64_t macrx_broadcast_frames; +	/* IP */ +	uint64_t iptx_packets; +	uint64_t iptx_bytes; +	uint64_t iptx_fragments; +	uint64_t iprx_packets; +	uint64_t iprx_bytes; +	uint64_t iprx_fragments; +	uint64_t ip_datagram_reassembly; +	uint64_t ip_invalid_address_error; +	uint64_t ip_error_packets; +	uint64_t ip_fragrx_overlap; +	uint64_t ip_fragrx_outoforder; +	uint64_t ip_datagram_reassembly_timeout; +	uint64_t ipv6tx_packets; +	uint64_t ipv6tx_bytes; +	uint64_t ipv6tx_fragments; +	uint64_t ipv6rx_packets; +	uint64_t ipv6rx_bytes; +	uint64_t ipv6rx_fragments; +	uint64_t ipv6_datagram_reassembly; +	uint64_t ipv6_invalid_address_error; +	uint64_t ipv6_error_packets; +	uint64_t ipv6_fragrx_overlap; +	uint64_t ipv6_fragrx_outoforder; +	uint64_t ipv6_datagram_reassembly_timeout; +	/* TCP */ +	uint64_t tcptx_segments; +	uint64_t tcptx_bytes; +	uint64_t tcprx_segments; +	uint64_t tcprx_byte; +	uint64_t tcp_duplicate_ack_retx; +	uint64_t tcp_retx_timer_expired; +	uint64_t tcprx_duplicate_ack; +	uint64_t tcprx_pure_ackr; +	uint64_t tcptx_delayed_ack; +	uint64_t tcptx_pure_ack; +	uint64_t tcprx_segment_error; +	uint64_t tcprx_segment_outoforder; +	uint64_t tcprx_window_probe; +	uint64_t tcprx_window_update; +	uint64_t tcptx_window_probe_persist; +	/* ECC */ +	uint64_t ecc_error_correction; +	/* iSCSI */ +	uint64_t iscsi_pdu_tx; +	uint64_t iscsi_data_bytes_tx; +	uint64_t iscsi_pdu_rx; +	uint64_t iscsi_data_bytes_rx; +	uint64_t iscsi_io_completed; +	uint64_t iscsi_unexpected_io_rx; +	uint64_t iscsi_format_error; +	uint64_t iscsi_hdr_digest_error; +	uint64_t iscsi_data_digest_error; +	uint64_t iscsi_sequence_error; +	/* +	 * iSCSI Custom Host Statistics support, i.e. Transport could +	 * extend existing host statistics with its own specific statistics +	 * up to ISCSI_HOST_STATS_CUSTOM_MAX +	 */ +	uint32_t custom_length; +	struct iscsi_host_stats_custom custom[0] +		__aligned(sizeof(uint64_t)); +}; +  #endif diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h index e1379b4e8fa..52beadf9a29 100644 --- a/include/scsi/libfc.h +++ b/include/scsi/libfc.h @@ -410,6 +410,12 @@ struct fc_seq {   * @fh_type:      The frame type   * @class:        The class of service   * @seq:          The sequence in use on this exchange + * @resp_active:  Number of tasks that are concurrently executing @resp(). + * @resp_task:    If @resp_active > 0, either the task executing @resp(), the + *                task that has been interrupted to execute the soft-IRQ + *                executing @resp() or NULL if more than one task is executing + *                @resp concurrently. + * @resp_wq:      Waitqueue for the tasks waiting on @resp_active.   * @resp:         Callback for responses on this exchange   * @destructor:   Called when destroying the exchange   * @arg:          Passed as a void pointer to the resp() callback @@ -441,6 +447,9 @@ struct fc_exch {  	u32		    r_a_tov;  	u32		    f_ctl;  	struct fc_seq       seq; +	int		    resp_active; +	struct task_struct  *resp_task; +	wait_queue_head_t   resp_wq;  	void		    (*resp)(struct fc_seq *, struct fc_frame *, void *);  	void		    *arg;  	void		    (*destructor)(struct fc_seq *, void *); diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h index 4427393115e..de7e3ee60f0 100644 --- a/include/scsi/libfcoe.h +++ b/include/scsi/libfcoe.h @@ -90,6 +90,7 @@ enum fip_state {   * @lp:		   &fc_lport: libfc local port.   * @sel_fcf:	   currently selected FCF, or NULL.   * @fcfs:	   list of discovered FCFs. + * @cdev:          (Optional) pointer to sysfs fcoe_ctlr_device.   * @fcf_count:	   number of discovered FCF entries.   * @sol_time:	   time when a multicast solicitation was last sent.   * @sel_time:	   time after which to select an FCF. @@ -127,6 +128,7 @@ struct fcoe_ctlr {  	struct fc_lport *lp;  	struct fcoe_fcf *sel_fcf;  	struct list_head fcfs; +	struct fcoe_ctlr_device *cdev;  	u16 fcf_count;  	unsigned long sol_time;  	unsigned long sel_time; @@ -168,8 +170,11 @@ static inline void *fcoe_ctlr_priv(const struct fcoe_ctlr *ctlr)  	return (void *)(ctlr + 1);  } +/* + * This assumes that the fcoe_ctlr (x) is allocated with the fcoe_ctlr_device. + */  #define fcoe_ctlr_to_ctlr_dev(x)					\ -	(struct fcoe_ctlr_device *)(((struct fcoe_ctlr_device *)(x)) - 1) +	(x)->cdev  /**   * struct fcoe_fcf - Fibre-Channel Forwarder diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 6ac9e17acdc..728c9ad9feb 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -133,6 +133,10 @@ struct iscsi_task {  	unsigned long		last_xfer;  	unsigned long		last_timeout;  	bool			have_checked_conn; + +	/* T10 protection information */ +	bool			protected; +  	/* state set/tested under session->lock */  	int			state;  	atomic_t		refcount; @@ -231,6 +235,7 @@ struct iscsi_conn {  	uint8_t			ipv6_traffic_class;  	uint8_t			ipv6_flow_label;  	uint8_t			is_fw_assigned_ipv6; +	char			*local_ipaddr;  	/* MIB-statistics */  	uint64_t		txdata_octets; @@ -326,12 +331,19 @@ struct iscsi_session {  	struct iscsi_transport	*tt;  	struct Scsi_Host	*host;  	struct iscsi_conn	*leadconn;	/* leading connection */ -	spinlock_t		lock;		/* protects session state, * -						 * sequence numbers,       * +	/* Between the forward and the backward locks exists a strict locking +	 * hierarchy. The mutual exclusion zone protected by the forward lock +	 * can enclose the mutual exclusion zone protected by the backward lock +	 * but not vice versa. +	 */ +	spinlock_t		frwd_lock;	/* protects session state, * +						 * cmdsn, queued_cmdsn     *  						 * session resources:      * -						 * - cmdpool,		   * -						 * - mgmtpool,		   * -						 * - r2tpool		   */ +						 * - cmdpool kfifo_out ,   * +						 * - mgmtpool,		   */ +	spinlock_t		back_lock;	/* protects cmdsn_exp      * +						 * cmdsn_max,              * +						 * cmdpool kfifo_in        */  	int			state;		/* session state           */  	int			age;		/* counts session re-opens */ diff --git a/include/scsi/libiscsi_tcp.h b/include/scsi/libiscsi_tcp.h index 215469a9b80..2a7aa75dd00 100644 --- a/include/scsi/libiscsi_tcp.h +++ b/include/scsi/libiscsi_tcp.h @@ -83,6 +83,8 @@ struct iscsi_tcp_task {  	struct iscsi_pool	r2tpool;  	struct kfifo		r2tqueue;  	void			*dd_data; +	spinlock_t		pool2queue; +	spinlock_t		queue2pool;  };  enum { diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index f843dd8722a..ef7872c20da 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h @@ -172,7 +172,6 @@ struct sata_device {          enum   ata_command_set command_set;          struct smp_resp        rps_resp; /* report_phy_sata_resp */          u8     port_no;        /* port number, if this is a PM (Port) */ -	int    pm_result;  	struct ata_port *ap;  	struct ata_host ata_host; diff --git a/include/scsi/osd_ore.h b/include/scsi/osd_ore.h index a5f9b960dfc..6ca3265a4dc 100644 --- a/include/scsi/osd_ore.h +++ b/include/scsi/osd_ore.h @@ -102,6 +102,7 @@ struct ore_striping_info {  	unsigned unit_off;  	unsigned cur_pg;  	unsigned cur_comp; +	unsigned maxdevUnits;  };  struct ore_io_state; diff --git a/include/scsi/osd_protocol.h b/include/scsi/osd_protocol.h index 25ac6283b9c..a2594afe05c 100644 --- a/include/scsi/osd_protocol.h +++ b/include/scsi/osd_protocol.h @@ -263,16 +263,16 @@ static inline struct osd_cdb_head *osd_cdb_head(struct osd_cdb *ocdb)   * Ex name = FORMAT_OSD we have OSD_ACT_FORMAT_OSD && OSDv1_ACT_FORMAT_OSD   */  #define OSD_ACT___(Name, Num) \ -	OSD_ACT_##Name = __constant_cpu_to_be16(0x8880 + Num), \ -	OSDv1_ACT_##Name = __constant_cpu_to_be16(0x8800 + Num), +	OSD_ACT_##Name = cpu_to_be16(0x8880 + Num), \ +	OSDv1_ACT_##Name = cpu_to_be16(0x8800 + Num),  /* V2 only actions */  #define OSD_ACT_V2(Name, Num) \ -	OSD_ACT_##Name = __constant_cpu_to_be16(0x8880 + Num), +	OSD_ACT_##Name = cpu_to_be16(0x8880 + Num),  #define OSD_ACT_V1_V2(Name, Num1, Num2) \ -	OSD_ACT_##Name = __constant_cpu_to_be16(Num2), \ -	OSDv1_ACT_##Name = __constant_cpu_to_be16(Num1), +	OSD_ACT_##Name = cpu_to_be16(Num2), \ +	OSDv1_ACT_##Name = cpu_to_be16(Num1),  enum osd_service_actions {  	OSD_ACT_V2(OBJECT_STRUCTURE_CHECK,	0x00) diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h index 66d42edfb3f..0a4edfe8af5 100644 --- a/include/scsi/scsi.h +++ b/include/scsi/scsi.h @@ -155,6 +155,7 @@ enum scsi_timeouts {  /* values for service action in */  #define	SAI_READ_CAPACITY_16  0x10  #define SAI_GET_LBA_STATUS    0x12 +#define SAI_REPORT_REFERRALS  0x13  /* values for VARIABLE_LENGTH_CMD service action codes   * see spc4r17 Section D.3.5, table D.7 and D.8 */  #define VLC_SA_RECEIVE_CREDENTIAL 0x1800 diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index de5f5d8f1f8..e0ae7109814 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -7,6 +7,7 @@  #include <linux/types.h>  #include <linux/timer.h>  #include <linux/scatterlist.h> +#include <scsi/scsi_device.h>  struct Scsi_Host;  struct scsi_device; @@ -55,6 +56,7 @@ struct scsi_cmnd {  	struct scsi_device *device;  	struct list_head list;  /* scsi_cmnd participates in queue lists */  	struct list_head eh_entry; /* entry for the host eh_cmd_q */ +	struct delayed_work abort_work;  	int eh_eflags;		/* Used by error handlr */  	/* @@ -132,6 +134,15 @@ struct scsi_cmnd {  	unsigned char tag;	/* SCSI-II queued command tag */  }; +/* + * Return the driver private allocation behind the command. + * Only works if cmd_size is set in the host template. + */ +static inline void *scsi_cmd_priv(struct scsi_cmnd *cmd) +{ +	return cmd + 1; +} +  /* make sure not to use it with REQ_TYPE_BLOCK_PC commands */  static inline struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd)  { @@ -141,8 +152,7 @@ static inline struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd)  extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, gfp_t);  extern struct scsi_cmnd *__scsi_get_command(struct Scsi_Host *, gfp_t);  extern void scsi_put_command(struct scsi_cmnd *); -extern void __scsi_put_command(struct Scsi_Host *, struct scsi_cmnd *, -			       struct device *); +extern void __scsi_put_command(struct Scsi_Host *, struct scsi_cmnd *);  extern void scsi_finish_command(struct scsi_cmnd *cmd);  extern void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count, @@ -155,9 +165,6 @@ extern void scsi_release_buffers(struct scsi_cmnd *cmd);  extern int scsi_dma_map(struct scsi_cmnd *cmd);  extern void scsi_dma_unmap(struct scsi_cmnd *cmd); -struct scsi_cmnd *scsi_allocate_command(gfp_t gfp_mask); -void scsi_free_command(gfp_t gfp_mask, struct scsi_cmnd *cmd); -  static inline unsigned scsi_sg_count(struct scsi_cmnd *cmd)  {  	return cmd->sdb.table.nents; @@ -309,4 +316,20 @@ static inline void set_driver_byte(struct scsi_cmnd *cmd, char status)  	cmd->result = (cmd->result & 0x00ffffff) | (status << 24);  } +static inline unsigned scsi_transfer_length(struct scsi_cmnd *scmd) +{ +	unsigned int xfer_len = scsi_out(scmd)->length; +	unsigned int prot_op = scsi_get_prot_op(scmd); +	unsigned int sector_size = scmd->device->sector_size; + +	switch (prot_op) { +	case SCSI_PROT_NORMAL: +	case SCSI_PROT_WRITE_STRIP: +	case SCSI_PROT_READ_INSERT: +		return xfer_len; +	} + +	return xfer_len + (xfer_len >> ilog2(sector_size)) * 8; +} +  #endif /* _SCSI_SCSI_CMND_H */ diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index d65fbec2533..27ab31017f0 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -113,6 +113,12 @@ struct scsi_device {  	const char * vendor;		/* [back_compat] point into 'inquiry' ... */  	const char * model;		/* ... after scan; point to static string */  	const char * rev;		/* ... "nullnullnullnull" before scan */ + +#define SCSI_VPD_PG_LEN                255 +	int vpd_pg83_len; +	unsigned char *vpd_pg83; +	int vpd_pg80_len; +	unsigned char *vpd_pg80;  	unsigned char current_tag;	/* current tag */  	struct scsi_target      *sdev_target;   /* used only for single_lun */ @@ -167,6 +173,7 @@ struct scsi_device {  	unsigned is_visible:1;	/* is the device visible in sysfs */  	unsigned wce_default_on:1;	/* Cache is ON by default */  	unsigned no_dif:1;	/* T10 PI (DIF) should be disabled */ +	unsigned broken_fua:1;		/* Don't set FUA bit */  	atomic_t disk_events_disable_depth; /* disable depth for disk events */ @@ -235,12 +242,24 @@ struct scsi_dh_data {  #define sdev_printk(prefix, sdev, fmt, a...)	\  	dev_printk(prefix, &(sdev)->sdev_gendev, fmt, ##a) +#define sdev_dbg(sdev, fmt, a...) \ +	dev_dbg(&(sdev)->sdev_gendev, fmt, ##a) +  #define scmd_printk(prefix, scmd, fmt, a...)				\          (scmd)->request->rq_disk ?					\  	sdev_printk(prefix, (scmd)->device, "[%s] " fmt,		\  		    (scmd)->request->rq_disk->disk_name, ##a) :		\  	sdev_printk(prefix, (scmd)->device, fmt, ##a) +#define scmd_dbg(scmd, fmt, a...)					   \ +	do {								   \ +		if ((scmd)->request->rq_disk)				   \ +			sdev_dbg((scmd)->device, "[%s] " fmt,		   \ +				 (scmd)->request->rq_disk->disk_name, ##a);\ +		else							   \ +			sdev_dbg((scmd)->device, fmt, ##a);		   \ +	} while (0) +  enum scsi_target_state {  	STARGET_CREATED = 1,  	STARGET_RUNNING, @@ -257,7 +276,7 @@ struct scsi_target {  	struct list_head	siblings;  	struct list_head	devices;  	struct device		dev; -	unsigned int		reap_ref; /* protected by the host lock */ +	struct kref		reap_ref; /* last put renders target invisible */  	unsigned int		channel;  	unsigned int		id; /* target id ... replace  				     * scsi_device.id eventually */ @@ -284,7 +303,6 @@ struct scsi_target {  #define SCSI_DEFAULT_TARGET_BLOCKED	3  	char			scsi_level; -	struct execute_work	ew;  	enum scsi_target_state	state;  	void 			*hostdata; /* available to low-level driver */  	unsigned long		starget_data[0]; /* for the transport */ @@ -309,6 +327,7 @@ extern int scsi_add_device(struct Scsi_Host *host, uint channel,  extern int scsi_register_device_handler(struct scsi_device_handler *scsi_dh);  extern void scsi_remove_device(struct scsi_device *);  extern int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh); +void scsi_attach_vpd(struct scsi_device *sdev);  extern int scsi_device_get(struct scsi_device *);  extern void scsi_device_put(struct scsi_device *); @@ -405,11 +424,11 @@ extern int scsi_is_target_device(const struct device *);  extern int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,  			int data_direction, void *buffer, unsigned bufflen,  			unsigned char *sense, int timeout, int retries, -			int flag, int *resid); +			u64 flags, int *resid);  extern int scsi_execute_req_flags(struct scsi_device *sdev,  	const unsigned char *cmd, int data_direction, void *buffer,  	unsigned bufflen, struct scsi_sense_hdr *sshdr, int timeout, -	int retries, int *resid, int flags); +	int retries, int *resid, u64 flags);  static inline int scsi_execute_req(struct scsi_device *sdev,  	const unsigned char *cmd, int data_direction, void *buffer,  	unsigned bufflen, struct scsi_sense_hdr *sshdr, int timeout, diff --git a/include/scsi/scsi_driver.h b/include/scsi/scsi_driver.h index d443aa06a72..36c4114ed9b 100644 --- a/include/scsi/scsi_driver.h +++ b/include/scsi/scsi_driver.h @@ -4,19 +4,19 @@  #include <linux/device.h>  struct module; +struct request;  struct scsi_cmnd;  struct scsi_device; -struct request; -struct request_queue; -  struct scsi_driver {  	struct module		*owner;  	struct device_driver	gendrv;  	void (*rescan)(struct device *); +	int (*init_command)(struct scsi_cmnd *); +	void (*uninit_command)(struct scsi_cmnd *);  	int (*done)(struct scsi_cmnd *); -	int (*eh_action)(struct scsi_cmnd *, unsigned char *, int, int); +	int (*eh_action)(struct scsi_cmnd *, int);  };  #define to_scsi_driver(drv) \  	container_of((drv), struct scsi_driver, gendrv) @@ -31,8 +31,5 @@ extern int scsi_register_interface(struct class_interface *);  int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req);  int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req); -int scsi_prep_state_check(struct scsi_device *sdev, struct request *req); -int scsi_prep_return(struct request_queue *q, struct request *req, int ret); -int scsi_prep_fn(struct request_queue *, struct request *);  #endif /* _SCSI_SCSI_DRIVER_H */ diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 75524357221..94844fc77b9 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -15,6 +15,7 @@ struct completion;  struct module;  struct scsi_cmnd;  struct scsi_device; +struct scsi_host_cmd_pool;  struct scsi_target;  struct Scsi_Host;  struct scsi_host_cmd_pool; @@ -475,6 +476,14 @@ struct scsi_host_template {  	 */  	unsigned ordered_tag:1; +	/* True if the controller does not support WRITE SAME */ +	unsigned no_write_same:1; + +	/* +	 * True if asynchronous aborts are not supported +	 */ +	unsigned no_async_abort:1; +  	/*  	 * Countdown for host blocking with no commands outstanding.  	 */ @@ -516,6 +525,12 @@ struct scsi_host_template {  	 *   scsi_netlink.h  	 */  	u64 vendor_id; + +	/* +	 * Additional per-command data allocated for the driver. +	 */ +	unsigned int cmd_size; +	struct scsi_host_cmd_pool *cmd_pool;  };  /* @@ -598,9 +613,12 @@ struct Scsi_Host {  	unsigned int host_eh_scheduled;    /* EH scheduled without command */  	unsigned int host_no;  /* Used for IOCTL_GET_IDLUN, /proc/scsi et al. */ -	int resetting; /* if set, it means that last_reset is a valid value */ + +	/* next two fields are used to bound the time spent in error handling */ +	int eh_deadline;  	unsigned long last_reset; +  	/*  	 * These three parameters can be used to allow for wide scsi,  	 * and for host adapters that support multiple busses @@ -674,6 +692,9 @@ struct Scsi_Host {  	/* Don't resume host in EH */  	unsigned eh_noresume:1; +	/* The controller does not support WRITE SAME */ +	unsigned no_write_same:1; +  	/*  	 * Optional work queue to be utilized by the transport  	 */ @@ -681,6 +702,11 @@ struct Scsi_Host {  	struct workqueue_struct *work_q;  	/* +	 * Task management function work queue +	 */ +	struct workqueue_struct *tmf_work_q; + +	/*  	 * Host has rejected a command because it was busy.  	 */  	unsigned int host_blocked; diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h index b797e8fad66..8c79980dc8f 100644 --- a/include/scsi/scsi_transport_fc.h +++ b/include/scsi/scsi_transport_fc.h @@ -130,6 +130,7 @@ enum fc_vport_state {  #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 */  /* diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index d0f1602985e..2555ee5343f 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -152,6 +152,7 @@ struct iscsi_transport {  	int (*get_chap) (struct Scsi_Host *shost, uint16_t chap_tbl_idx,  			 uint32_t *num_entries, char *buf);  	int (*delete_chap) (struct Scsi_Host *shost, uint16_t chap_tbl_idx); +	int (*set_chap) (struct Scsi_Host *shost, void *data, int len);  	int (*get_flashnode_param) (struct iscsi_bus_flash_session *fnode_sess,  				    int param, char *buf);  	int (*set_flashnode_param) (struct iscsi_bus_flash_session *fnode_sess, @@ -165,6 +166,8 @@ struct iscsi_transport {  	int (*logout_flashnode) (struct iscsi_bus_flash_session *fnode_sess,  				 struct iscsi_bus_flash_conn *fnode_conn);  	int (*logout_flashnode_sid) (struct iscsi_cls_session *cls_sess); +	int (*get_host_stats) (struct Scsi_Host *shost, char *buf, int len); +	u8 (*check_protection)(struct iscsi_task *task, sector_t *sector);  };  /* @@ -477,4 +480,7 @@ iscsi_find_flashnode_sess(struct Scsi_Host *shost, void *data,  extern struct device *  iscsi_find_flashnode_conn(struct iscsi_bus_flash_session *fnode_sess); +extern char * +iscsi_get_ipaddress_state_name(enum iscsi_ipaddress_state port_state); +extern char *iscsi_get_router_state_name(enum iscsi_router_state router_state);  #endif diff --git a/include/scsi/scsi_transport_srp.h b/include/scsi/scsi_transport_srp.h index ff0f04ac91a..cdb05dd1d44 100644 --- a/include/scsi/scsi_transport_srp.h +++ b/include/scsi/scsi_transport_srp.h @@ -13,6 +13,42 @@ struct srp_rport_identifiers {  	u8 roles;  }; +/** + * enum srp_rport_state - SRP transport layer state + * @SRP_RPORT_RUNNING:   Transport layer operational. + * @SRP_RPORT_BLOCKED:   Transport layer not operational; fast I/O fail timer + *                       is running and I/O has been blocked. + * @SRP_RPORT_FAIL_FAST: Fast I/O fail timer has expired; fail I/O fast. + * @SRP_RPORT_LOST:      Port is being removed. + */ +enum srp_rport_state { +	SRP_RPORT_RUNNING, +	SRP_RPORT_BLOCKED, +	SRP_RPORT_FAIL_FAST, +	SRP_RPORT_LOST, +}; + +/** + * struct srp_rport - SRP initiator or target port + * + * Fields that are relevant for SRP initiator and SRP target drivers: + * @dev:               Device associated with this rport. + * @port_id:           16-byte port identifier. + * @roles:             Role of this port - initiator or target. + * + * Fields that are only relevant for SRP initiator drivers: + * @lld_data:          LLD private data. + * @mutex:             Protects against concurrent rport reconnect / + *                     fast_io_fail / dev_loss_tmo activity. + * @state:             rport state. + * @reconnect_delay:   Reconnect delay in seconds. + * @failed_reconnects: Number of failed reconnect attempts. + * @reconnect_work:    Work structure used for scheduling reconnect attempts. + * @fast_io_fail_tmo:  Fast I/O fail timeout in seconds. + * @dev_loss_tmo:      Device loss timeout in seconds. + * @fast_io_fail_work: Work structure used for scheduling fast I/O fail work. + * @dev_loss_work:     Work structure used for scheduling device loss work. + */  struct srp_rport {  	/* for initiator and target drivers */ @@ -23,11 +59,49 @@ struct srp_rport {  	/* for initiator drivers */ -	void *lld_data;	/* LLD private data */ +	void			*lld_data; + +	struct mutex		mutex; +	enum srp_rport_state	state; +	int			reconnect_delay; +	int			failed_reconnects; +	struct delayed_work	reconnect_work; +	int			fast_io_fail_tmo; +	int			dev_loss_tmo; +	struct delayed_work	fast_io_fail_work; +	struct delayed_work	dev_loss_work;  }; +/** + * struct srp_function_template + * + * Fields that are only relevant for SRP initiator drivers: + * @has_rport_state: Whether or not to create the state, fast_io_fail_tmo and + *     dev_loss_tmo sysfs attribute for an rport. + * @reset_timer_if_blocked: Whether or srp_timed_out() should reset the command + *     timer if the device on which it has been queued is blocked. + * @reconnect_delay: If not NULL, points to the default reconnect_delay value. + * @fast_io_fail_tmo: If not NULL, points to the default fast_io_fail_tmo value. + * @dev_loss_tmo: If not NULL, points to the default dev_loss_tmo value. + * @reconnect: Callback function for reconnecting to the target. See also + *     srp_reconnect_rport(). + * @terminate_rport_io: Callback function for terminating all outstanding I/O + *     requests for an rport. + * @rport_delete: Callback function that deletes an rport. + * + * Fields that are only relevant for SRP target drivers: + * @tsk_mgmt_response: Callback function for sending a task management response. + * @it_nexus_response: Callback function for processing an IT nexus response. + */  struct srp_function_template {  	/* for initiator drivers */ +	bool has_rport_state; +	bool reset_timer_if_blocked; +	int *reconnect_delay; +	int *fast_io_fail_tmo; +	int *dev_loss_tmo; +	int (*reconnect)(struct srp_rport *rport); +	void (*terminate_rport_io)(struct srp_rport *rport);  	void (*rport_delete)(struct srp_rport *rport);  	/* for target drivers */  	int (* tsk_mgmt_response)(struct Scsi_Host *, u64, u64, int); @@ -38,10 +112,38 @@ extern struct scsi_transport_template *  srp_attach_transport(struct srp_function_template *);  extern void srp_release_transport(struct scsi_transport_template *); +extern void srp_rport_get(struct srp_rport *rport); +extern void srp_rport_put(struct srp_rport *rport);  extern struct srp_rport *srp_rport_add(struct Scsi_Host *,  				       struct srp_rport_identifiers *);  extern void srp_rport_del(struct srp_rport *); - +extern int srp_tmo_valid(int reconnect_delay, int fast_io_fail_tmo, +			 int dev_loss_tmo); +extern int srp_reconnect_rport(struct srp_rport *rport); +extern void srp_start_tl_fail_timers(struct srp_rport *rport);  extern void srp_remove_host(struct Scsi_Host *); +extern void srp_stop_rport_timers(struct srp_rport *rport); + +/** + * srp_chkready() - evaluate the transport layer state before I/O + * @rport: SRP target port pointer. + * + * Returns a SCSI result code that can be returned by the LLD queuecommand() + * implementation. The role of this function is similar to that of + * fc_remote_port_chkready(). + */ +static inline int srp_chkready(struct srp_rport *rport) +{ +	switch (rport->state) { +	case SRP_RPORT_RUNNING: +	case SRP_RPORT_BLOCKED: +	default: +		return 0; +	case SRP_RPORT_FAIL_FAST: +		return DID_TRANSPORT_FAILFAST << 16; +	case SRP_RPORT_LOST: +		return DID_NO_CONNECT << 16; +	} +}  #endif  | 
