From c6a4bb2ef596d0bfe0d885ef6807b263ac83e47a Mon Sep 17 00:00:00 2001 From: Adheer Chandravanshi Date: Fri, 22 Mar 2013 07:41:29 -0400 Subject: [SCSI] scsi_transport_iscsi: Add flash node mgmt support This patch allows iscsiadm to manage iSCSI target information stored on adapter flash on per host basis. The sysfs entries will look as cited below: /sys/bus/iscsi_flashnode/devices/flashnode_sess-:/ /sys/bus/iscsi_flashnode/devices/flashnode_conn-::/ Signed-off-by: Adheer Chandravanshi Signed-off-by: Manish Rangankar Signed-off-by: Vikas Chaudhary Signed-off-by: James Bottomley --- include/scsi/iscsi_if.h | 113 +++++++++++++++++++++++++++ include/scsi/scsi_transport_iscsi.h | 151 ++++++++++++++++++++++++++++++++++++ 2 files changed, 264 insertions(+) (limited to 'include/scsi') diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h index 917741bb8e11..f1b01839490c 100644 --- a/include/scsi/iscsi_if.h +++ b/include/scsi/iscsi_if.h @@ -63,6 +63,12 @@ enum iscsi_uevent_e { ISCSI_UEVENT_PING = UEVENT_BASE + 22, ISCSI_UEVENT_GET_CHAP = UEVENT_BASE + 23, ISCSI_UEVENT_DELETE_CHAP = UEVENT_BASE + 24, + ISCSI_UEVENT_SET_FLASHNODE_PARAMS = UEVENT_BASE + 25, + ISCSI_UEVENT_NEW_FLASHNODE = UEVENT_BASE + 26, + ISCSI_UEVENT_DEL_FLASHNODE = UEVENT_BASE + 27, + ISCSI_UEVENT_LOGIN_FLASHNODE = UEVENT_BASE + 28, + ISCSI_UEVENT_LOGOUT_FLASHNODE = UEVENT_BASE + 29, + ISCSI_UEVENT_LOGOUT_FLASHNODE_SID = UEVENT_BASE + 30, /* up events */ ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1, @@ -210,6 +216,31 @@ struct iscsi_uevent { uint32_t host_no; uint16_t chap_tbl_idx; } delete_chap; + struct msg_set_flashnode_param { + uint32_t host_no; + uint32_t flashnode_idx; + uint32_t count; + } set_flashnode; + struct msg_new_flashnode { + uint32_t host_no; + uint32_t len; + } new_flashnode; + struct msg_del_flashnode { + uint32_t host_no; + uint32_t flashnode_idx; + } del_flashnode; + struct msg_login_flashnode { + uint32_t host_no; + uint32_t flashnode_idx; + } login_flashnode; + struct msg_logout_flashnode { + uint32_t host_no; + uint32_t flashnode_idx; + } logout_flashnode; + struct msg_logout_flashnode_sid { + uint32_t host_no; + uint32_t sid; + } logout_flashnode_sid; } u; union { /* messages k -> u */ @@ -267,6 +298,9 @@ struct iscsi_uevent { with each ping request */ uint32_t data_size; } ping_comp; + struct msg_new_flashnode_ret { + uint32_t flashnode_idx; + } new_flashnode_ret; } r; } __attribute__ ((aligned (sizeof(uint64_t)))); @@ -274,6 +308,7 @@ enum iscsi_param_type { ISCSI_PARAM, /* iscsi_param (session, conn, target, LU) */ ISCSI_HOST_PARAM, /* iscsi_host_param */ ISCSI_NET_PARAM, /* iscsi_net_param */ + ISCSI_FLASHNODE_PARAM, /* iscsi_flashnode_param */ }; struct iscsi_iface_param_info { @@ -469,6 +504,84 @@ enum iscsi_host_param { ISCSI_HOST_PARAM_MAX, }; +/* iSCSI Flash Target params */ +enum iscsi_flashnode_param { + ISCSI_FLASHNODE_IS_FW_ASSIGNED_IPV6, + ISCSI_FLASHNODE_PORTAL_TYPE, + ISCSI_FLASHNODE_AUTO_SND_TGT_DISABLE, + ISCSI_FLASHNODE_DISCOVERY_SESS, + ISCSI_FLASHNODE_ENTRY_EN, + ISCSI_FLASHNODE_HDR_DGST_EN, + ISCSI_FLASHNODE_DATA_DGST_EN, + ISCSI_FLASHNODE_IMM_DATA_EN, + ISCSI_FLASHNODE_INITIAL_R2T_EN, + ISCSI_FLASHNODE_DATASEQ_INORDER, + ISCSI_FLASHNODE_PDU_INORDER, + ISCSI_FLASHNODE_CHAP_AUTH_EN, + ISCSI_FLASHNODE_SNACK_REQ_EN, + ISCSI_FLASHNODE_DISCOVERY_LOGOUT_EN, + ISCSI_FLASHNODE_BIDI_CHAP_EN, + /* make authentication for discovery sessions optional */ + ISCSI_FLASHNODE_DISCOVERY_AUTH_OPTIONAL, + ISCSI_FLASHNODE_ERL, + ISCSI_FLASHNODE_TCP_TIMESTAMP_STAT, + ISCSI_FLASHNODE_TCP_NAGLE_DISABLE, + ISCSI_FLASHNODE_TCP_WSF_DISABLE, + ISCSI_FLASHNODE_TCP_TIMER_SCALE, + ISCSI_FLASHNODE_TCP_TIMESTAMP_EN, + ISCSI_FLASHNODE_IP_FRAG_DISABLE, + ISCSI_FLASHNODE_MAX_RECV_DLENGTH, + ISCSI_FLASHNODE_MAX_XMIT_DLENGTH, + ISCSI_FLASHNODE_FIRST_BURST, + ISCSI_FLASHNODE_DEF_TIME2WAIT, + ISCSI_FLASHNODE_DEF_TIME2RETAIN, + ISCSI_FLASHNODE_MAX_R2T, + ISCSI_FLASHNODE_KEEPALIVE_TMO, + ISCSI_FLASHNODE_ISID, + ISCSI_FLASHNODE_TSID, + ISCSI_FLASHNODE_PORT, + ISCSI_FLASHNODE_MAX_BURST, + ISCSI_FLASHNODE_DEF_TASKMGMT_TMO, + ISCSI_FLASHNODE_IPADDR, + ISCSI_FLASHNODE_ALIAS, + ISCSI_FLASHNODE_REDIRECT_IPADDR, + ISCSI_FLASHNODE_MAX_SEGMENT_SIZE, + ISCSI_FLASHNODE_LOCAL_PORT, + ISCSI_FLASHNODE_IPV4_TOS, + ISCSI_FLASHNODE_IPV6_TC, + ISCSI_FLASHNODE_IPV6_FLOW_LABEL, + ISCSI_FLASHNODE_NAME, + ISCSI_FLASHNODE_TPGT, + ISCSI_FLASHNODE_LINK_LOCAL_IPV6, + ISCSI_FLASHNODE_DISCOVERY_PARENT_IDX, + ISCSI_FLASHNODE_DISCOVERY_PARENT_TYPE, + ISCSI_FLASHNODE_TCP_XMIT_WSF, + ISCSI_FLASHNODE_TCP_RECV_WSF, + ISCSI_FLASHNODE_CHAP_IN_IDX, + ISCSI_FLASHNODE_CHAP_OUT_IDX, + ISCSI_FLASHNODE_USERNAME, + ISCSI_FLASHNODE_USERNAME_IN, + ISCSI_FLASHNODE_PASSWORD, + ISCSI_FLASHNODE_PASSWORD_IN, + ISCSI_FLASHNODE_STATSN, + ISCSI_FLASHNODE_EXP_STATSN, + ISCSI_FLASHNODE_IS_BOOT_TGT, + + ISCSI_FLASHNODE_MAX, +}; + +struct iscsi_flashnode_param_info { + uint32_t len; /* Actual length of the param */ + uint16_t param; /* iscsi param value */ + uint8_t value[0]; /* length sized value follows */ +} __packed; + +enum iscsi_discovery_parent_type { + ISCSI_DISC_PARENT_UNKNOWN = 0x1, + ISCSI_DISC_PARENT_SENDTGT = 0x2, + ISCSI_DISC_PARENT_ISNS = 0x3, +}; + /* iSCSI port Speed */ enum iscsi_port_speed { ISCSI_PORT_SPEED_UNKNOWN = 0x1, diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index 53f0b361d668..4a58cca2ecc1 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -39,6 +39,8 @@ struct iscsi_task; struct sockaddr; struct iscsi_iface; struct bsg_job; +struct iscsi_bus_flash_session; +struct iscsi_bus_flash_conn; /** * struct iscsi_transport - iSCSI Transport template @@ -150,6 +152,19 @@ 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 (*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, + struct iscsi_bus_flash_conn *fnode_conn, + void *data, int len); + int (*new_flashnode) (struct Scsi_Host *shost, const char *buf, + int len); + int (*del_flashnode) (struct iscsi_bus_flash_session *fnode_sess); + int (*login_flashnode) (struct iscsi_bus_flash_session *fnode_sess, + struct iscsi_bus_flash_conn *fnode_conn); + 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); }; /* @@ -286,6 +301,112 @@ struct iscsi_iface { #define iscsi_iface_to_shost(_iface) \ dev_to_shost(_iface->dev.parent) + +struct iscsi_bus_flash_conn { + struct list_head conn_list; /* item in connlist */ + void *dd_data; /* LLD private data */ + struct iscsi_transport *transport; + struct device dev; /* sysfs transport/container device */ + /* iscsi connection parameters */ + uint32_t exp_statsn; + uint32_t statsn; + unsigned max_recv_dlength; /* initiator_max_recv_dsl*/ + unsigned max_xmit_dlength; /* target_max_recv_dsl */ + unsigned max_segment_size; + unsigned tcp_xmit_wsf; + unsigned tcp_recv_wsf; + int hdrdgst_en; + int datadgst_en; + int port; + char *ipaddress; + char *link_local_ipv6_addr; + char *redirect_ipaddr; + uint16_t keepalive_timeout; + uint16_t local_port; + uint8_t snack_req_en; + /* tcp timestamp negotiation status */ + uint8_t tcp_timestamp_stat; + uint8_t tcp_nagle_disable; + /* tcp window scale factor */ + uint8_t tcp_wsf_disable; + uint8_t tcp_timer_scale; + uint8_t tcp_timestamp_en; + uint8_t ipv4_tos; + uint8_t ipv6_traffic_class; + uint8_t ipv6_flow_label; + uint8_t fragment_disable; + /* Link local IPv6 address is assigned by firmware or driver */ + uint8_t is_fw_assigned_ipv6; +}; + +#define iscsi_dev_to_flash_conn(_dev) \ + container_of(_dev, struct iscsi_bus_flash_conn, dev) + +#define iscsi_flash_conn_to_flash_session(_conn) \ + iscsi_dev_to_flash_session(_conn->dev.parent) + +#define ISID_SIZE 6 + +struct iscsi_bus_flash_session { + struct list_head sess_list; /* item in session_list */ + struct iscsi_transport *transport; + unsigned int target_id; + int flash_state; /* persistent or non-persistent */ + void *dd_data; /* LLD private data */ + struct device dev; /* sysfs transport/container device */ + /* iscsi session parameters */ + unsigned first_burst; + unsigned max_burst; + unsigned short max_r2t; + int default_taskmgmt_timeout; + int initial_r2t_en; + int imm_data_en; + int time2wait; + int time2retain; + int pdu_inorder_en; + int dataseq_inorder_en; + int erl; + int tpgt; + char *username; + char *username_in; + char *password; + char *password_in; + char *targetname; + char *targetalias; + char *portal_type; + uint16_t tsid; + uint16_t chap_in_idx; + uint16_t chap_out_idx; + /* index of iSCSI discovery session if the entry is + * discovered by iSCSI discovery session + */ + uint16_t discovery_parent_idx; + /* indicates if discovery was done through iSNS discovery service + * or through sendTarget */ + uint16_t discovery_parent_type; + /* Firmware auto sendtarget discovery disable */ + uint8_t auto_snd_tgt_disable; + uint8_t discovery_sess; + /* indicates if this flashnode entry is enabled or disabled */ + uint8_t entry_state; + uint8_t chap_auth_en; + /* enables firmware to auto logout the discovery session on discovery + * completion + */ + uint8_t discovery_logout_en; + uint8_t bidi_chap_en; + /* makes authentication for discovery session optional */ + uint8_t discovery_auth_optional; + uint8_t isid[ISID_SIZE]; + uint8_t is_boot_target; +}; + +#define iscsi_dev_to_flash_session(_dev) \ + container_of(_dev, struct iscsi_bus_flash_session, dev) + +#define iscsi_flash_session_to_shost(_session) \ + dev_to_shost(_session->dev.parent) + /* * session and connection functions that can be used by HW iSCSI LLDs */ @@ -330,4 +451,34 @@ extern char *iscsi_get_port_speed_name(struct Scsi_Host *shost); extern char *iscsi_get_port_state_name(struct Scsi_Host *shost); extern int iscsi_is_session_dev(const struct device *dev); +extern char *iscsi_get_discovery_parent_name(int parent_type); +extern struct device * +iscsi_find_flashnode(struct Scsi_Host *shost, void *data, + int (*fn)(struct device *dev, void *data)); + +extern struct iscsi_bus_flash_session * +iscsi_create_flashnode_sess(struct Scsi_Host *shost, int index, + struct iscsi_transport *transport, int dd_size); + +extern struct iscsi_bus_flash_conn * +iscsi_create_flashnode_conn(struct Scsi_Host *shost, + struct iscsi_bus_flash_session *fnode_sess, + struct iscsi_transport *transport, int dd_size); + +extern void +iscsi_destroy_flashnode_sess(struct iscsi_bus_flash_session *fnode_sess); + +extern void iscsi_destroy_all_flashnode(struct Scsi_Host *shost); +extern int iscsi_flashnode_bus_match(struct device *dev, + struct device_driver *drv); +extern int iscsi_is_flashnode_conn_dev(struct device *dev, void *data); + +extern struct device * +iscsi_find_flashnode_sess(struct Scsi_Host *shost, void *data, + int (*fn)(struct device *dev, void *data)); + +extern struct device * +iscsi_find_flashnode_conn(struct iscsi_bus_flash_session *fnode_sess, + void *data, + int (*fn)(struct device *dev, void *data)); #endif -- cgit v1.2.3