aboutsummaryrefslogtreecommitdiff
path: root/include/scsi
diff options
context:
space:
mode:
Diffstat (limited to 'include/scsi')
-rw-r--r--include/scsi/iscsi_if.h230
-rw-r--r--include/scsi/libiscsi.h22
-rw-r--r--include/scsi/libiscsi_tcp.h2
-rw-r--r--include/scsi/libsas.h1
-rw-r--r--include/scsi/osd_ore.h1
-rw-r--r--include/scsi/osd_protocol.h10
-rw-r--r--include/scsi/scsi.h1
-rw-r--r--include/scsi/scsi_cmnd.h33
-rw-r--r--include/scsi/scsi_device.h27
-rw-r--r--include/scsi/scsi_driver.h11
-rw-r--r--include/scsi/scsi_host.h23
-rw-r--r--include/scsi/scsi_transport_fc.h1
-rw-r--r--include/scsi/scsi_transport_iscsi.h5
-rw-r--r--include/scsi/scsi_transport_srp.h35
14 files changed, 350 insertions, 52 deletions
diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h
index 5d6ed6cf12c..fd0421c6d40 100644
--- a/include/scsi/iscsi_if.h
+++ b/include/scsi/iscsi_if.h
@@ -70,6 +70,7 @@ enum iscsi_uevent_e {
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,
@@ -242,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 */
@@ -311,6 +315,7 @@ enum iscsi_param_type {
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 */
@@ -383,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 {
@@ -535,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,
};
@@ -766,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/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 546084964d5..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;
};
/*
@@ -677,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
*/
@@ -684,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 fe7c8f3e93f..2555ee5343f 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -166,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);
};
/*
@@ -478,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 4ebf6913b7b..cdb05dd1d44 100644
--- a/include/scsi/scsi_transport_srp.h
+++ b/include/scsi/scsi_transport_srp.h
@@ -19,7 +19,7 @@ struct srp_rport_identifiers {
* @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: Device loss timer has expired; port is being removed.
+ * @SRP_RPORT_LOST: Port is being removed.
*/
enum srp_rport_state {
SRP_RPORT_RUNNING,
@@ -29,10 +29,25 @@ enum srp_rport_state {
};
/**
- * struct srp_rport
- * @lld_data: LLD private data.
- * @mutex: Protects against concurrent rport reconnect / fast_io_fail /
- * dev_loss_tmo activity.
+ * 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 */
@@ -48,7 +63,6 @@ struct srp_rport {
struct mutex mutex;
enum srp_rport_state state;
- bool deleted;
int reconnect_delay;
int failed_reconnects;
struct delayed_work reconnect_work;
@@ -60,6 +74,8 @@ struct srp_rport {
/**
* 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
@@ -71,6 +87,11 @@ struct srp_rport {
* 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 */
@@ -101,9 +122,11 @@ extern int srp_tmo_valid(int reconnect_delay, int fast_io_fail_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