From: Adheer Chandravanshi <[email protected]>
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/class/iscsi_flash_tgt/tgt-<host_no>-<target_no>/
Eg:
/sys/class/iscsi_flash_tgt/tgt-1-0/apply
/sys/class/iscsi_flash_tgt/tgt-1-0/login
/sys/class/iscsi_flash_tgt/tgt-1-0/logout
/sys/class/iscsi_flash_tgt/tgt-1-0/<Target attributes>
Here: apply, login and logout are the operations which iscsiadm can
perform on each flash target entry.
Operation to add a new flast target or delete a flash target can be performed
using two new sysfs attributes as given below:
/sys/class/iscsi_host/host1/add_flash_tgt
/sys/class/iscsi_host/host1/del_flash_tgt
Signed-off-by: Adheer Chandravanshi <[email protected]>
Signed-off-by: Vikas Chaudhary <[email protected]>
---
drivers/scsi/scsi_transport_iscsi.c | 469 ++++++++++++++++++++++++++++++++++-
include/scsi/iscsi_if.h | 67 +++++
include/scsi/scsi_transport_iscsi.h | 28 ++
3 files changed, 551 insertions(+), 13 deletions(-)
diff --git a/drivers/scsi/scsi_transport_iscsi.c
b/drivers/scsi/scsi_transport_iscsi.c
index 31969f2..6d92331 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -25,6 +25,7 @@
#include <linux/slab.h>
#include <linux/bsg-lib.h>
#include <linux/idr.h>
+#include <linux/list.h>
#include <net/tcp.h>
#include <scsi/scsi.h>
#include <scsi/scsi_host.h>
@@ -460,6 +461,417 @@ void iscsi_destroy_iface(struct iscsi_iface *iface)
EXPORT_SYMBOL_GPL(iscsi_destroy_iface);
/*
+ * Interface to display flash tgt params to sysfs
+ */
+
+static void iscsi_flash_tgt_release(struct device *dev)
+{
+ struct iscsi_flash_tgt *tgt = iscsi_dev_to_flash_tgt(dev);
+ struct device *parent = tgt->dev.parent;
+
+ kfree(tgt);
+ put_device(parent);
+}
+
+
+static struct class iscsi_flash_tgt_class = {
+ .name = "iscsi_flash_tgt",
+ .dev_release = iscsi_flash_tgt_release,
+};
+
+#define ISCSI_FLASH_TGT_ATTR(_prefix, _name, _mode, _show, _store) \
+struct device_attribute dev_attr_##_prefix##_##_name = \
+ __ATTR(_name, _mode, _show, _store)
+
+/* flash tgt attrs show */
+#define iscsi_flash_tgt_attr_show(type, name, param) \
+static ssize_t \
+show_##type##_##name(struct device *dev, struct device_attribute *attr,
\
+ char *buf) \
+{ \
+ struct iscsi_flash_tgt *tgt = iscsi_dev_to_flash_tgt(dev); \
+ struct iscsi_transport *t = tgt->transport; \
+ return t->get_flash_tgt_param(tgt, param, buf); \
+} \
+
+/* flash tgt attrs store */
+#define iscsi_flash_tgt_attr_store(type, name, param) \
+static ssize_t \
+store_##type##_##name(struct device *dev, struct device_attribute *attr,\
+ const char *buf, size_t len) \
+{ \
+ struct iscsi_flash_tgt *tgt = iscsi_dev_to_flash_tgt(dev); \
+ struct iscsi_transport *t = tgt->transport; \
+ return t->set_flash_tgt_param(tgt, param, buf, len); \
+} \
+
+#define iscsi_flash_tgt_attr(type, name, param)
\
+ iscsi_flash_tgt_attr_show(type, name, param) \
+ iscsi_flash_tgt_attr_store(type, name, param) \
+static ISCSI_FLASH_TGT_ATTR(type, name, S_IRUGO | S_IWUSR, \
+ show_##type##_##name, store_##type##_##name);
+
+/* Target attributes */
+
+iscsi_flash_tgt_attr(tgt, ipaddress, ISCSI_FLASH_TGT_IP_ADDR);
+iscsi_flash_tgt_attr(tgt, port, ISCSI_FLASH_TGT_PORT);
+iscsi_flash_tgt_attr(tgt, opt_auto_send_tgt_disable,
+ ISCSI_FLASH_TGT_OPT_AUTO_SND_TGT_DISABLE);
+iscsi_flash_tgt_attr(tgt, opt_discovery_session,
+ ISCSI_FLASH_TGT_OPT_DISCOVERY_SESS);
+iscsi_flash_tgt_attr(tgt, opt_entry_enable, ISCSI_FLASH_TGT_OPT_ENTRY_ENABLE);
+iscsi_flash_tgt_attr(tgt, opt_dev_assoc_target,
+ ISCSI_FLASH_TGT_OPT_DEV_ASSOC_TARGET);
+iscsi_flash_tgt_attr(tgt, opt_dev_assoc_initiator,
+ ISCSI_FLASH_TGT_OPT_DEV_ASSOC_INITIATOR);
+iscsi_flash_tgt_attr(tgt, exec_throttle, ISCSI_FLASH_TGT_EXEC_THROTTLE);
+iscsi_flash_tgt_attr(tgt, exec_count, ISCSI_FLASH_TGT_EXEC_COUNT);
+iscsi_flash_tgt_attr(tgt, retry_count, ISCSI_FLASH_TGT_RETRY_COUNT);
+iscsi_flash_tgt_attr(tgt, retry_delay, ISCSI_FLASH_TGT_RETRY_DELAY);
+iscsi_flash_tgt_attr(tgt, iscsiopt_enable_hdr_digest,
+ ISCSI_FLASH_TGT_ISCSIOPT_ENABLE_HDR_DIGEST);
+iscsi_flash_tgt_attr(tgt, iscsiopt_enable_data_digest,
+ ISCSI_FLASH_TGT_ISCSIOPT_ENABLE_DATA_DIGEST);
+iscsi_flash_tgt_attr(tgt, iscsiopt_enable_immediate_data,
+ ISCSI_FLASH_TGT_ISCSIOPT_ENABLE_IMMEDIATE_DATA);
+iscsi_flash_tgt_attr(tgt, iscsiopt_enable_initial_r2t,
+ ISCSI_FLASH_TGT_ISCSIOPT_ENABLE_INITIAL_R2T);
+iscsi_flash_tgt_attr(tgt, iscsiopt_data_seq_in_order,
+ ISCSI_FLASH_TGT_ISCSIOPT_DATA_SEQ_IN_ORDER);
+iscsi_flash_tgt_attr(tgt, iscsiopt_data_pdu_in_order,
+ ISCSI_FLASH_TGT_ISCSIOPT_DATA_PDU_IN_ORDER);
+iscsi_flash_tgt_attr(tgt, iscsiopt_chap_auth_enable,
+ ISCSI_FLASH_TGT_ISCSIOPT_CHAP_AUTH_ENABLE);
+iscsi_flash_tgt_attr(tgt, iscsiopt_snack_req_enable,
+ ISCSI_FLASH_TGT_ISCSIOPT_SNACK_REQ_ENABLE);
+iscsi_flash_tgt_attr(tgt, iscsiopt_discovery_logout_enable,
+ ISCSI_FLASH_TGT_ISCSIOPT_DISCOVERY_LOGOUT_ENABLE);
+iscsi_flash_tgt_attr(tgt, iscsiopt_bidi_chap_challenge_enable,
+ ISCSI_FLASH_TGT_ISCSIOPT_BIDI_CHAP_CHALLENGE_ENABLE);
+iscsi_flash_tgt_attr(tgt, iscsiopt_discovery_auth_optional,
+ ISCSI_FLASH_TGT_ISCSIOPT_DISCOVERY_AUTH_OPTIONAL);
+iscsi_flash_tgt_attr(tgt, tcpopt_nagle_disable,
+ ISCSI_FLASH_TGT_TCPOPT_NAGLE_DISABLE);
+iscsi_flash_tgt_attr(tgt, tcpopt_timer_scale,
+ ISCSI_FLASH_TGT_TCPOPT_TIMER_SCALE);
+iscsi_flash_tgt_attr(tgt, tcpopt_timestamp_enable,
+ ISCSI_FLASH_TGT_TCPOPT_TIMESTAMP_ENABLE);
+iscsi_flash_tgt_attr(tgt, ipopt_frag_disable,
+ ISCSI_FLASH_TGT_IPOPT_FRAG_DISABLE);
+iscsi_flash_tgt_attr(tgt, max_recv_data_segment_length,
+ ISCSI_FLASH_TGT_MAX_RECV_DATA_SEGMENT_LEN);
+iscsi_flash_tgt_attr(tgt, max_xmit_data_segment_length,
+ ISCSI_FLASH_TGT_MAX_XMIT_DATA_SEGMENT_LEN);
+iscsi_flash_tgt_attr(tgt, first_burst_length,
+ ISCSI_FLASH_TGT_FIRST_BURST_LEN);
+iscsi_flash_tgt_attr(tgt, default_time2wait,
+ ISCSI_FLASH_TGT_DEF_TIME2WAIT);
+iscsi_flash_tgt_attr(tgt, default_time2retain,
+ ISCSI_FLASH_TGT_DEF_TIME2RETAIN);
+iscsi_flash_tgt_attr(tgt, max_outstanding_r2t,
+ ISCSI_FLASH_TGT_MAX_OUTSTANDING_R2T);
+iscsi_flash_tgt_attr(tgt, noop_out_interval,
+ ISCSI_FLASH_TGT_NOOP_OUT_INTERVAL);
+iscsi_flash_tgt_attr(tgt, isid, ISCSI_FLASH_TGT_ISID);
+iscsi_flash_tgt_attr(tgt, tsid, ISCSI_FLASH_TGT_TSID);
+iscsi_flash_tgt_attr(tgt, max_burst_length,
+ ISCSI_FLASH_TGT_MAX_BURST_LEN);
+iscsi_flash_tgt_attr(tgt, firmware_cmd_timeout,
+ ISCSI_FLASH_TGT_FW_CMD_TIMEOUT);
+iscsi_flash_tgt_attr(tgt, iscsi_alias, ISCSI_FLASH_TGT_ISCSI_ALIAS);
+iscsi_flash_tgt_attr(tgt, target_address, ISCSI_FLASH_TGT_ADDRESS);
+iscsi_flash_tgt_attr(tgt, max_segment_size, ISCSI_FLASH_TGT_MAX_SEGMENT_SIZE);
+iscsi_flash_tgt_attr(tgt, local_port, ISCSI_FLASH_TGT_LOCAL_PORT);
+iscsi_flash_tgt_attr(tgt, ipv4_tos, ISCSI_FLASH_TGT_IPV4_TOS);
+iscsi_flash_tgt_attr(tgt, ipv6_flow_label, ISCSI_FLASH_TGT_IPV6_FLOW_LABEL);
+iscsi_flash_tgt_attr(tgt, name, ISCSI_FLASH_TGT_NAME);
+iscsi_flash_tgt_attr(tgt, tpgt, ISCSI_FLASH_TGT_TPGT);
+iscsi_flash_tgt_attr(tgt, tcp_xmit_wsf, ISCSI_FLASH_TGT_TCP_XMIT_WIN_SCALE);
+iscsi_flash_tgt_attr(tgt, tcp_recv_wsf, ISCSI_FLASH_TGT_TCP_RECV_WIN_SCALE);
+iscsi_flash_tgt_attr(tgt, chap_user, ISCSI_FLASH_TGT_CHAP_USER);
+iscsi_flash_tgt_attr(tgt, chap_passwd, ISCSI_FLASH_TGT_CHAP_PASSWD);
+iscsi_flash_tgt_attr(tgt, chap_user_in, ISCSI_FLASH_TGT_CHAP_USER_IN);
+iscsi_flash_tgt_attr(tgt, chap_passwd_in, ISCSI_FLASH_TGT_CHAP_PASSWD_IN);
+iscsi_flash_tgt_attr(tgt, login, ISCSI_FLASH_TGT_LOGIN);
+iscsi_flash_tgt_attr(tgt, logout, ISCSI_FLASH_TGT_LOGOUT);
+iscsi_flash_tgt_attr(tgt, apply, ISCSI_FLASH_TGT_APPLY);
+
+static umode_t iscsi_flash_tgt_attr_is_visible(struct kobject *kobj,
+ struct attribute *attr, int i)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct iscsi_flash_tgt *tgt = iscsi_dev_to_flash_tgt(dev);
+ struct iscsi_transport *t = tgt->transport;
+ int param;
+
+ if (attr == &dev_attr_tgt_ipaddress.attr) {
+ param = ISCSI_FLASH_TGT_IP_ADDR;
+ } else if (attr == &dev_attr_tgt_port.attr) {
+ param = ISCSI_FLASH_TGT_PORT;
+ } else if (attr == &dev_attr_tgt_opt_auto_send_tgt_disable.attr) {
+ param = ISCSI_FLASH_TGT_OPT_AUTO_SND_TGT_DISABLE;
+ } else if (attr == &dev_attr_tgt_opt_discovery_session.attr) {
+ param = ISCSI_FLASH_TGT_OPT_DISCOVERY_SESS;
+ } else if (attr == &dev_attr_tgt_opt_entry_enable.attr) {
+ param = ISCSI_FLASH_TGT_OPT_ENTRY_ENABLE;
+ } else if (attr == &dev_attr_tgt_opt_dev_assoc_target.attr) {
+ param = ISCSI_FLASH_TGT_OPT_DEV_ASSOC_TARGET;
+ } else if (attr == &dev_attr_tgt_opt_dev_assoc_initiator.attr) {
+ param = ISCSI_FLASH_TGT_OPT_DEV_ASSOC_INITIATOR;
+ } else if (attr == &dev_attr_tgt_exec_throttle.attr) {
+ param = ISCSI_FLASH_TGT_EXEC_THROTTLE;
+ } else if (attr == &dev_attr_tgt_exec_count.attr) {
+ param = ISCSI_FLASH_TGT_EXEC_COUNT;
+ } else if (attr == &dev_attr_tgt_retry_count.attr) {
+ param = ISCSI_FLASH_TGT_RETRY_COUNT;
+ } else if (attr == &dev_attr_tgt_retry_delay.attr) {
+ param = ISCSI_FLASH_TGT_RETRY_DELAY;
+ } else if (attr == &dev_attr_tgt_iscsiopt_enable_hdr_digest.attr) {
+ param = ISCSI_FLASH_TGT_ISCSIOPT_ENABLE_HDR_DIGEST;
+ } else if (attr == &dev_attr_tgt_iscsiopt_enable_data_digest.attr) {
+ param = ISCSI_FLASH_TGT_ISCSIOPT_ENABLE_DATA_DIGEST;
+ } else if (attr == &dev_attr_tgt_iscsiopt_enable_immediate_data.attr) {
+ param = ISCSI_FLASH_TGT_ISCSIOPT_ENABLE_IMMEDIATE_DATA;
+ } else if (attr == &dev_attr_tgt_iscsiopt_enable_initial_r2t.attr) {
+ param = ISCSI_FLASH_TGT_ISCSIOPT_ENABLE_INITIAL_R2T;
+ } else if (attr == &dev_attr_tgt_iscsiopt_data_seq_in_order.attr) {
+ param = ISCSI_FLASH_TGT_ISCSIOPT_DATA_SEQ_IN_ORDER;
+ } else if (attr == &dev_attr_tgt_iscsiopt_data_pdu_in_order.attr) {
+ param = ISCSI_FLASH_TGT_ISCSIOPT_DATA_PDU_IN_ORDER;
+ } else if (attr == &dev_attr_tgt_iscsiopt_chap_auth_enable.attr) {
+ param = ISCSI_FLASH_TGT_ISCSIOPT_CHAP_AUTH_ENABLE;
+ } else if (attr == &dev_attr_tgt_iscsiopt_snack_req_enable.attr) {
+ param = ISCSI_FLASH_TGT_ISCSIOPT_SNACK_REQ_ENABLE;
+ } else if (attr ==
+ &dev_attr_tgt_iscsiopt_discovery_logout_enable.attr) {
+ param = ISCSI_FLASH_TGT_ISCSIOPT_DISCOVERY_LOGOUT_ENABLE;
+ } else if (attr ==
+ &dev_attr_tgt_iscsiopt_bidi_chap_challenge_enable.attr) {
+ param = ISCSI_FLASH_TGT_ISCSIOPT_BIDI_CHAP_CHALLENGE_ENABLE;
+ } else if (attr ==
+ &dev_attr_tgt_iscsiopt_discovery_auth_optional.attr) {
+ param = ISCSI_FLASH_TGT_ISCSIOPT_DISCOVERY_AUTH_OPTIONAL;
+ } else if (attr == &dev_attr_tgt_tcpopt_nagle_disable.attr) {
+ param = ISCSI_FLASH_TGT_TCPOPT_NAGLE_DISABLE;
+ } else if (attr == &dev_attr_tgt_tcpopt_timer_scale.attr) {
+ param = ISCSI_FLASH_TGT_TCPOPT_TIMER_SCALE;
+ } else if (attr == &dev_attr_tgt_tcpopt_timestamp_enable.attr) {
+ param = ISCSI_FLASH_TGT_TCPOPT_TIMESTAMP_ENABLE;
+ } else if (attr == &dev_attr_tgt_ipopt_frag_disable.attr) {
+ param = ISCSI_FLASH_TGT_IPOPT_FRAG_DISABLE;
+ } else if (attr == &dev_attr_tgt_max_recv_data_segment_length.attr) {
+ param = ISCSI_FLASH_TGT_MAX_RECV_DATA_SEGMENT_LEN;
+ } else if (attr == &dev_attr_tgt_max_xmit_data_segment_length.attr) {
+ param = ISCSI_FLASH_TGT_MAX_XMIT_DATA_SEGMENT_LEN;
+ } else if (attr == &dev_attr_tgt_first_burst_length.attr) {
+ param = ISCSI_FLASH_TGT_FIRST_BURST_LEN;
+ } else if (attr == &dev_attr_tgt_default_time2wait.attr) {
+ param = ISCSI_FLASH_TGT_DEF_TIME2WAIT;
+ } else if (attr == &dev_attr_tgt_default_time2retain.attr) {
+ param = ISCSI_FLASH_TGT_DEF_TIME2RETAIN;
+ } else if (attr == &dev_attr_tgt_max_outstanding_r2t.attr) {
+ param = ISCSI_FLASH_TGT_MAX_OUTSTANDING_R2T;
+ } else if (attr == &dev_attr_tgt_noop_out_interval.attr) {
+ param = ISCSI_FLASH_TGT_NOOP_OUT_INTERVAL;
+ } else if (attr == &dev_attr_tgt_isid.attr) {
+ param = ISCSI_FLASH_TGT_ISID;
+ } else if (attr == &dev_attr_tgt_tsid.attr) {
+ param = ISCSI_FLASH_TGT_TSID;
+ } else if (attr == &dev_attr_tgt_max_burst_length.attr) {
+ param = ISCSI_FLASH_TGT_MAX_BURST_LEN;
+ } else if (attr == &dev_attr_tgt_firmware_cmd_timeout.attr) {
+ param = ISCSI_FLASH_TGT_FW_CMD_TIMEOUT;
+ } else if (attr == &dev_attr_tgt_iscsi_alias.attr) {
+ param = ISCSI_FLASH_TGT_ISCSI_ALIAS;
+ } else if (attr == &dev_attr_tgt_target_address.attr) {
+ param = ISCSI_FLASH_TGT_ADDRESS;
+ } else if (attr == &dev_attr_tgt_max_segment_size.attr) {
+ param = ISCSI_FLASH_TGT_MAX_SEGMENT_SIZE;
+ } else if (attr == &dev_attr_tgt_local_port.attr) {
+ param = ISCSI_FLASH_TGT_LOCAL_PORT;
+ } else if (attr == &dev_attr_tgt_ipv4_tos.attr) {
+ param = ISCSI_FLASH_TGT_IPV4_TOS;
+ } else if (attr == &dev_attr_tgt_ipv6_flow_label.attr) {
+ param = ISCSI_FLASH_TGT_IPV6_FLOW_LABEL;
+ } else if (attr == &dev_attr_tgt_name.attr) {
+ param = ISCSI_FLASH_TGT_NAME;
+ } else if (attr == &dev_attr_tgt_tpgt.attr) {
+ param = ISCSI_FLASH_TGT_TPGT;
+ } else if (attr == &dev_attr_tgt_tcp_xmit_wsf.attr) {
+ param = ISCSI_FLASH_TGT_TCP_XMIT_WIN_SCALE;
+ } else if (attr == &dev_attr_tgt_tcp_recv_wsf.attr) {
+ param = ISCSI_FLASH_TGT_TCP_RECV_WIN_SCALE;
+ } else if (attr == &dev_attr_tgt_chap_user.attr) {
+ param = ISCSI_FLASH_TGT_CHAP_USER;
+ } else if (attr == &dev_attr_tgt_chap_passwd.attr) {
+ param = ISCSI_FLASH_TGT_CHAP_PASSWD;
+ } else if (attr == &dev_attr_tgt_chap_user_in.attr) {
+ param = ISCSI_FLASH_TGT_CHAP_USER_IN;
+ } else if (attr == &dev_attr_tgt_chap_passwd_in.attr) {
+ param = ISCSI_FLASH_TGT_CHAP_PASSWD_IN;
+ } else if (attr == &dev_attr_tgt_login.attr) {
+ param = ISCSI_FLASH_TGT_LOGIN;
+ } else if (attr == &dev_attr_tgt_logout.attr) {
+ param = ISCSI_FLASH_TGT_LOGOUT;
+ } else if (attr == &dev_attr_tgt_apply.attr) {
+ param = ISCSI_FLASH_TGT_APPLY;
+ } else {
+ WARN_ONCE(1, "Invalid flash tgt attr");
+ return 0;
+ }
+
+ return t->attr_is_visible(ISCSI_FLASH_TGT_PARAM, param);
+}
+
+static struct attribute *iscsi_flash_tgt_attrs[] = {
+ &dev_attr_tgt_ipaddress.attr,
+ &dev_attr_tgt_port.attr,
+ &dev_attr_tgt_opt_auto_send_tgt_disable.attr,
+ &dev_attr_tgt_opt_discovery_session.attr,
+ &dev_attr_tgt_opt_entry_enable.attr,
+ &dev_attr_tgt_opt_dev_assoc_target.attr,
+ &dev_attr_tgt_opt_dev_assoc_initiator.attr,
+ &dev_attr_tgt_exec_throttle.attr,
+ &dev_attr_tgt_exec_count.attr,
+ &dev_attr_tgt_retry_count.attr,
+ &dev_attr_tgt_retry_delay.attr,
+ &dev_attr_tgt_iscsiopt_enable_hdr_digest.attr,
+ &dev_attr_tgt_iscsiopt_enable_data_digest.attr,
+ &dev_attr_tgt_iscsiopt_enable_immediate_data.attr,
+ &dev_attr_tgt_iscsiopt_enable_initial_r2t.attr,
+ &dev_attr_tgt_iscsiopt_data_seq_in_order.attr,
+ &dev_attr_tgt_iscsiopt_data_pdu_in_order.attr,
+ &dev_attr_tgt_iscsiopt_chap_auth_enable.attr,
+ &dev_attr_tgt_iscsiopt_snack_req_enable.attr,
+ &dev_attr_tgt_iscsiopt_discovery_logout_enable.attr,
+ &dev_attr_tgt_iscsiopt_bidi_chap_challenge_enable.attr,
+ &dev_attr_tgt_iscsiopt_discovery_auth_optional.attr,
+ &dev_attr_tgt_tcpopt_nagle_disable.attr,
+ &dev_attr_tgt_tcpopt_timer_scale.attr,
+ &dev_attr_tgt_tcpopt_timestamp_enable.attr,
+ &dev_attr_tgt_ipopt_frag_disable.attr,
+ &dev_attr_tgt_max_recv_data_segment_length.attr,
+ &dev_attr_tgt_max_xmit_data_segment_length.attr,
+ &dev_attr_tgt_first_burst_length.attr,
+ &dev_attr_tgt_default_time2wait.attr,
+ &dev_attr_tgt_default_time2retain.attr,
+ &dev_attr_tgt_max_outstanding_r2t.attr,
+ &dev_attr_tgt_noop_out_interval.attr,
+ &dev_attr_tgt_isid.attr,
+ &dev_attr_tgt_tsid.attr,
+ &dev_attr_tgt_max_burst_length.attr,
+ &dev_attr_tgt_firmware_cmd_timeout.attr,
+ &dev_attr_tgt_iscsi_alias.attr,
+ &dev_attr_tgt_target_address.attr,
+ &dev_attr_tgt_max_segment_size.attr,
+ &dev_attr_tgt_local_port.attr,
+ &dev_attr_tgt_ipv4_tos.attr,
+ &dev_attr_tgt_ipv6_flow_label.attr,
+ &dev_attr_tgt_name.attr,
+ &dev_attr_tgt_tpgt.attr,
+ &dev_attr_tgt_tcp_xmit_wsf.attr,
+ &dev_attr_tgt_tcp_recv_wsf.attr,
+ &dev_attr_tgt_chap_user.attr,
+ &dev_attr_tgt_chap_passwd.attr,
+ &dev_attr_tgt_chap_user_in.attr,
+ &dev_attr_tgt_chap_passwd_in.attr,
+ &dev_attr_tgt_login.attr,
+ &dev_attr_tgt_logout.attr,
+ &dev_attr_tgt_apply.attr,
+ NULL,
+};
+
+static struct attribute_group iscsi_flash_tgt_group = {
+ .attrs = iscsi_flash_tgt_attrs,
+ .is_visible = iscsi_flash_tgt_attr_is_visible,
+};
+
+struct iscsi_flash_tgt *
+iscsi_create_flash_tgt(struct Scsi_Host *shost, int index,
+ struct iscsi_transport *transport,
+ int dd_size)
+{
+ struct iscsi_flash_tgt *tgt;
+ int err;
+
+ tgt = kzalloc(sizeof(*tgt) + dd_size, GFP_KERNEL);
+ if (!tgt)
+ return NULL;
+
+ INIT_LIST_HEAD(&tgt->list);
+ tgt->transport = transport;
+ tgt->dev.release = iscsi_flash_tgt_release;
+ tgt->dev.class = &iscsi_flash_tgt_class;
+ /* parent reference released in iscsi_flash_tgt_release */
+ tgt->dev.parent = get_device(&shost->shost_gendev);
+ dev_set_name(&tgt->dev, "tgt-%u-%u", shost->host_no, index);
+
+ err = device_register(&tgt->dev);
+ if (err)
+ goto free_tgt;
+
+ err = sysfs_create_group(&tgt->dev.kobj, &iscsi_flash_tgt_group);
+ if (err)
+ goto unreg_tgt;
+
+ if (dd_size)
+ tgt->dd_data = &tgt[1];
+
+ return tgt;
+
+unreg_tgt:
+ device_unregister(&tgt->dev);
+ return NULL;
+
+free_tgt:
+ put_device(tgt->dev.parent);
+ kfree(tgt);
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(iscsi_create_flash_tgt);
+
+int iscsi_is_flash_tgt_dev(const struct device *dev)
+{
+ return dev->release == iscsi_flash_tgt_release;
+}
+EXPORT_SYMBOL_GPL(iscsi_is_flash_tgt_dev);
+
+struct device *iscsi_find_flash_tgt(struct Scsi_Host *shost, void *data,
+ int (*fn)(struct device *dev, void *data))
+{
+ struct device *dev;
+
+ dev = device_find_child(&shost->shost_gendev, data, fn);
+ return dev;
+}
+EXPORT_SYMBOL_GPL(iscsi_find_flash_tgt);
+
+void iscsi_destroy_flash_tgt(struct iscsi_flash_tgt *tgt)
+{
+ list_del(&tgt->list);
+ sysfs_remove_group(&tgt->dev.kobj, &iscsi_flash_tgt_group);
+ device_unregister(&tgt->dev);
+}
+EXPORT_SYMBOL_GPL(iscsi_destroy_flash_tgt);
+
+static int iscsi_iter_destroy_flash_tgt_fn(struct device *dev, void *data)
+{
+ if (!iscsi_is_flash_tgt_dev(dev))
+ return 0;
+
+ iscsi_destroy_flash_tgt(iscsi_dev_to_flash_tgt(dev));
+ return 0;
+}
+
+void iscsi_destroy_all_flash_tgt(struct Scsi_Host *shost)
+{
+
+ device_for_each_child(&shost->shost_gendev, NULL,
+ iscsi_iter_destroy_flash_tgt_fn);
+}
+EXPORT_SYMBOL_GPL(iscsi_destroy_all_flash_tgt);
+
+/*
* BSG support
*/
/**
@@ -2654,20 +3066,36 @@ static struct attribute_group iscsi_session_group = {
/*
* iSCSI host attrs
*/
-#define iscsi_host_attr_show(param) \
-static ssize_t \
-show_host_param_##param(struct device *dev, \
- struct device_attribute *attr, char *buf) \
-{ \
- struct Scsi_Host *shost = transport_class_to_shost(dev); \
+#define iscsi_host_attr_show(param) \
+static ssize_t \
+show_host_param_##param(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+{ \
+ struct Scsi_Host *shost = transport_class_to_shost(dev); \
struct iscsi_internal *priv = to_iscsi_internal(shost->transportt); \
- return priv->iscsi_transport->get_host_param(shost, param, buf); \
-}
+ return priv->iscsi_transport->get_host_param(shost, param, buf); \
+} \
+
+#define iscsi_host_flash_tgt_attr_store(param) \
+static ssize_t \
+store_host_flash_tgt_param_##param(struct device *dev, \
+ struct device_attribute *attr, \
+ const char *buf, size_t len) \
+{ \
+ struct Scsi_Host *shost = transport_class_to_shost(dev); \
+ struct iscsi_internal *priv = to_iscsi_internal(shost->transportt); \
+ return priv->iscsi_transport->set_host_flash_tgt_param(shost, param,\
+ buf, len); \
+} \
-#define iscsi_host_attr(field, param) \
- iscsi_host_attr_show(param) \
-static ISCSI_CLASS_ATTR(host, field, S_IRUGO, show_host_param_##param, \
- NULL);
+#define iscsi_host_attr(field, param) \
+ iscsi_host_attr_show(param) \
+static ISCSI_CLASS_ATTR(host, field, S_IRUGO, show_host_param_##param, NULL);
+
+#define iscsi_host_flash_tgt_attr(field, param) \
+ iscsi_host_flash_tgt_attr_store(param) \
+static ISCSI_CLASS_ATTR(host, field, S_IWUSR, NULL, \
+ store_host_flash_tgt_param_##param);
iscsi_host_attr(netdev, ISCSI_HOST_PARAM_NETDEV_NAME);
iscsi_host_attr(hwaddress, ISCSI_HOST_PARAM_HWADDRESS);
@@ -2675,6 +3103,8 @@ iscsi_host_attr(ipaddress, ISCSI_HOST_PARAM_IPADDRESS);
iscsi_host_attr(initiatorname, ISCSI_HOST_PARAM_INITIATOR_NAME);
iscsi_host_attr(port_state, ISCSI_HOST_PARAM_PORT_STATE);
iscsi_host_attr(port_speed, ISCSI_HOST_PARAM_PORT_SPEED);
+iscsi_host_flash_tgt_attr(add_flash_tgt, ISCSI_HOST_PARAM_ADD_FLASH_TGT);
+iscsi_host_flash_tgt_attr(del_flash_tgt, ISCSI_HOST_PARAM_DEL_FLASH_TGT);
static struct attribute *iscsi_host_attrs[] = {
&dev_attr_host_netdev.attr,
@@ -2683,6 +3113,8 @@ static struct attribute *iscsi_host_attrs[] = {
&dev_attr_host_initiatorname.attr,
&dev_attr_host_port_state.attr,
&dev_attr_host_port_speed.attr,
+ &dev_attr_host_add_flash_tgt.attr,
+ &dev_attr_host_del_flash_tgt.attr,
NULL,
};
@@ -2706,6 +3138,10 @@ static umode_t iscsi_host_attr_is_visible(struct kobject
*kobj,
param = ISCSI_HOST_PARAM_PORT_STATE;
else if (attr == &dev_attr_host_port_speed.attr)
param = ISCSI_HOST_PARAM_PORT_SPEED;
+ else if (attr == &dev_attr_host_add_flash_tgt.attr)
+ param = ISCSI_HOST_PARAM_ADD_FLASH_TGT;
+ else if (attr == &dev_attr_host_del_flash_tgt.attr)
+ param = ISCSI_HOST_PARAM_DEL_FLASH_TGT;
else {
WARN_ONCE(1, "Invalid host attr");
return 0;
@@ -2953,10 +3389,14 @@ static __init int iscsi_transport_init(void)
if (err)
goto unregister_transport_class;
- err = class_register(&iscsi_iface_class);
+ err = class_register(&iscsi_flash_tgt_class);
if (err)
goto unregister_endpoint_class;
+ err = class_register(&iscsi_iface_class);
+ if (err)
+ goto unregister_flash_tgt_class;
+
err = transport_class_register(&iscsi_host_class);
if (err)
goto unregister_iface_class;
@@ -2991,6 +3431,8 @@ unregister_host_class:
transport_class_unregister(&iscsi_host_class);
unregister_iface_class:
class_unregister(&iscsi_iface_class);
+unregister_flash_tgt_class:
+ class_unregister(&iscsi_flash_tgt_class);
unregister_endpoint_class:
class_unregister(&iscsi_endpoint_class);
unregister_transport_class:
@@ -3007,6 +3449,7 @@ static void __exit iscsi_transport_exit(void)
transport_class_unregister(&iscsi_host_class);
class_unregister(&iscsi_endpoint_class);
class_unregister(&iscsi_iface_class);
+ class_unregister(&iscsi_flash_tgt_class);
class_unregister(&iscsi_transport_class);
}
diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h
index 917741b..2ab7eb2 100644
--- a/include/scsi/iscsi_if.h
+++ b/include/scsi/iscsi_if.h
@@ -274,6 +274,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_FLASH_TGT_PARAM, /* iscsi_flash_tgt_param */
};
struct iscsi_iface_param_info {
@@ -466,9 +467,75 @@ enum iscsi_host_param {
ISCSI_HOST_PARAM_IPADDRESS,
ISCSI_HOST_PARAM_PORT_STATE,
ISCSI_HOST_PARAM_PORT_SPEED,
+ ISCSI_HOST_PARAM_ADD_FLASH_TGT,
+ ISCSI_HOST_PARAM_DEL_FLASH_TGT,
ISCSI_HOST_PARAM_MAX,
};
+/* iSCSI Flash Target params */
+enum iscsi_flash_tgt_param {
+ ISCSI_FLASH_TGT_OPT_AUTO_SND_TGT_DISABLE,
+ ISCSI_FLASH_TGT_OPT_DISCOVERY_SESS,
+ ISCSI_FLASH_TGT_OPT_ENTRY_ENABLE,
+ ISCSI_FLASH_TGT_OPT_DEV_ASSOC_TARGET,
+ ISCSI_FLASH_TGT_OPT_DEV_ASSOC_INITIATOR,
+ /* number of commands that can execute concurrently */
+ ISCSI_FLASH_TGT_EXEC_THROTTLE,
+ /* number of commands that are executing */
+ ISCSI_FLASH_TGT_EXEC_COUNT,
+ /* number of retry attempts for retryable events */
+ ISCSI_FLASH_TGT_RETRY_COUNT,
+ /* interval between attempts for retryable events */
+ ISCSI_FLASH_TGT_RETRY_DELAY,
+ ISCSI_FLASH_TGT_ISCSIOPT_ENABLE_HDR_DIGEST,
+ ISCSI_FLASH_TGT_ISCSIOPT_ENABLE_DATA_DIGEST,
+ ISCSI_FLASH_TGT_ISCSIOPT_ENABLE_IMMEDIATE_DATA,
+ ISCSI_FLASH_TGT_ISCSIOPT_ENABLE_INITIAL_R2T,
+ ISCSI_FLASH_TGT_ISCSIOPT_DATA_SEQ_IN_ORDER,
+ ISCSI_FLASH_TGT_ISCSIOPT_DATA_PDU_IN_ORDER,
+ ISCSI_FLASH_TGT_ISCSIOPT_CHAP_AUTH_ENABLE,
+ ISCSI_FLASH_TGT_ISCSIOPT_SNACK_REQ_ENABLE,
+ ISCSI_FLASH_TGT_ISCSIOPT_DISCOVERY_LOGOUT_ENABLE,
+ ISCSI_FLASH_TGT_ISCSIOPT_BIDI_CHAP_CHALLENGE_ENABLE,
+ /* make authentication for discovery sessions optional */
+ ISCSI_FLASH_TGT_ISCSIOPT_DISCOVERY_AUTH_OPTIONAL,
+ ISCSI_FLASH_TGT_TCPOPT_NAGLE_DISABLE,
+ ISCSI_FLASH_TGT_TCPOPT_TIMER_SCALE,
+ ISCSI_FLASH_TGT_TCPOPT_TIMESTAMP_ENABLE,
+ ISCSI_FLASH_TGT_IPOPT_FRAG_DISABLE,
+ ISCSI_FLASH_TGT_MAX_RECV_DATA_SEGMENT_LEN,
+ ISCSI_FLASH_TGT_MAX_XMIT_DATA_SEGMENT_LEN,
+ ISCSI_FLASH_TGT_FIRST_BURST_LEN,
+ ISCSI_FLASH_TGT_DEF_TIME2WAIT,
+ ISCSI_FLASH_TGT_DEF_TIME2RETAIN,
+ ISCSI_FLASH_TGT_MAX_OUTSTANDING_R2T,
+ ISCSI_FLASH_TGT_NOOP_OUT_INTERVAL,
+ ISCSI_FLASH_TGT_ISID,
+ ISCSI_FLASH_TGT_TSID,
+ ISCSI_FLASH_TGT_PORT,
+ ISCSI_FLASH_TGT_MAX_BURST_LEN,
+ ISCSI_FLASH_TGT_FW_CMD_TIMEOUT,
+ ISCSI_FLASH_TGT_IP_ADDR,
+ ISCSI_FLASH_TGT_ISCSI_ALIAS,
+ ISCSI_FLASH_TGT_ADDRESS,
+ ISCSI_FLASH_TGT_MAX_SEGMENT_SIZE,
+ ISCSI_FLASH_TGT_LOCAL_PORT,
+ ISCSI_FLASH_TGT_IPV4_TOS,
+ ISCSI_FLASH_TGT_IPV6_FLOW_LABEL,
+ ISCSI_FLASH_TGT_NAME,
+ ISCSI_FLASH_TGT_TPGT,
+ ISCSI_FLASH_TGT_TCP_XMIT_WIN_SCALE,
+ ISCSI_FLASH_TGT_TCP_RECV_WIN_SCALE,
+ ISCSI_FLASH_TGT_CHAP_USER,
+ ISCSI_FLASH_TGT_CHAP_PASSWD,
+ ISCSI_FLASH_TGT_CHAP_USER_IN,
+ ISCSI_FLASH_TGT_CHAP_PASSWD_IN,
+ ISCSI_FLASH_TGT_LOGIN,
+ ISCSI_FLASH_TGT_LOGOUT,
+ ISCSI_FLASH_TGT_APPLY,
+ ISCSI_FLASH_TGT_MAX,
+};
+
/* 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 53f0b36..630abf8 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -39,6 +39,7 @@ struct iscsi_task;
struct sockaddr;
struct iscsi_iface;
struct bsg_job;
+struct iscsi_flash_tgt;
/**
* struct iscsi_transport - iSCSI Transport template
@@ -112,6 +113,9 @@ struct iscsi_transport {
int (*set_host_param) (struct Scsi_Host *shost,
enum iscsi_host_param param, char *buf,
int buflen);
+ int (*set_host_flash_tgt_param) (struct Scsi_Host *shost,
+ enum iscsi_host_param param,
+ const char *buf, int buflen);
int (*send_pdu) (struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
char *data, uint32_t data_size);
void (*get_stats) (struct iscsi_cls_conn *conn,
@@ -150,6 +154,10 @@ 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_flash_tgt_param) (struct iscsi_flash_tgt *tgt, int param,
+ char *buf);
+ int (*set_flash_tgt_param) (struct iscsi_flash_tgt *tgt, int param,
+ const char *buf, int len);
};
/*
@@ -286,6 +294,16 @@ struct iscsi_iface {
#define iscsi_iface_to_shost(_iface) \
dev_to_shost(_iface->dev.parent)
+struct iscsi_flash_tgt {
+ struct list_head list;
+ struct device dev;
+ struct iscsi_transport *transport;
+ void *dd_data; /* LLD private data */
+};
+
+#define iscsi_dev_to_flash_tgt(_dev) \
+ container_of(_dev, struct iscsi_flash_tgt, dev)
+
/*
* session and connection functions that can be used by HW iSCSI LLDs
*/
@@ -330,4 +348,14 @@ 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 struct device *
+iscsi_find_flash_tgt(struct Scsi_Host *shost, void *data,
+ int (*fn)(struct device *dev, void *data));
+extern struct iscsi_flash_tgt *iscsi_create_flash_tgt(struct Scsi_Host *shost,
+ int index,
+ struct iscsi_transport *t,
+ int dd_size);
+extern void iscsi_destroy_flash_tgt(struct iscsi_flash_tgt *tgt);
+extern void iscsi_destroy_all_flash_tgt(struct Scsi_Host *shost);
+extern int iscsi_is_flash_tgt_dev(const struct device *dev);
#endif
--
1.7.1
--
You received this message because you are subscribed to the Google Groups
"open-iscsi" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/open-iscsi?hl=en.