Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c6a4bb2e authored by Adheer Chandravanshi's avatar Adheer Chandravanshi Committed by James Bottomley
Browse files

[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-<host_no>:<flashnode_id>/<session attrs>
	/sys/bus/iscsi_flashnode/devices/flashnode_conn-<host_no>:<flashnode_id>:<conn_id>/<conn attrs>

Signed-off-by: default avatarAdheer Chandravanshi <adheer.chandravanshi@qlogic.com>
Signed-off-by: default avatarManish Rangankar <manish.rangankar@qlogic.com>
Signed-off-by: default avatarVikas Chaudhary <vikas.chaudhary@qlogic.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 9060f6bf
Loading
Loading
Loading
Loading
+1001 −1

File changed.

Preview size limit exceeded, changes collapsed.

+113 −0
Original line number Diff line number Diff line
@@ -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,
+151 −0
Original line number Diff line number Diff line
@@ -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