aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/iscsi_tcp.c68
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c262
-rw-r--r--include/scsi/iscsi_if.h64
-rw-r--r--include/scsi/scsi_transport_iscsi.h24
4 files changed, 342 insertions, 76 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 6ecb4baa37e2..6e510f3cfbf6 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -3536,7 +3536,7 @@ iscsi_session_get_param(struct iscsi_cls_session *cls_session,
3536 *value = session->ofmarker_en; 3536 *value = session->ofmarker_en;
3537 break; 3537 break;
3538 default: 3538 default:
3539 return ISCSI_ERR_PARAM_NOT_FOUND; 3539 return -EINVAL;
3540 } 3540 }
3541 3541
3542 return 0; 3542 return 0;
@@ -3547,6 +3547,7 @@ iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
3547 enum iscsi_param param, uint32_t *value) 3547 enum iscsi_param param, uint32_t *value)
3548{ 3548{
3549 struct iscsi_conn *conn = cls_conn->dd_data; 3549 struct iscsi_conn *conn = cls_conn->dd_data;
3550 struct inet_sock *inet;
3550 3551
3551 switch(param) { 3552 switch(param) {
3552 case ISCSI_PARAM_MAX_RECV_DLENGTH: 3553 case ISCSI_PARAM_MAX_RECV_DLENGTH:
@@ -3561,13 +3562,61 @@ iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
3561 case ISCSI_PARAM_DATADGST_EN: 3562 case ISCSI_PARAM_DATADGST_EN:
3562 *value = conn->datadgst_en; 3563 *value = conn->datadgst_en;
3563 break; 3564 break;
3565 case ISCSI_PARAM_CONN_PORT:
3566 mutex_lock(&conn->xmitmutex);
3567 if (!conn->sock) {
3568 mutex_unlock(&conn->xmitmutex);
3569 return -EINVAL;
3570 }
3571
3572 inet = inet_sk(conn->sock->sk);
3573 *value = be16_to_cpu(inet->dport);
3574 mutex_unlock(&conn->xmitmutex);
3564 default: 3575 default:
3565 return ISCSI_ERR_PARAM_NOT_FOUND; 3576 return -EINVAL;
3566 } 3577 }
3567 3578
3568 return 0; 3579 return 0;
3569} 3580}
3570 3581
3582static int
3583iscsi_conn_get_str_param(struct iscsi_cls_conn *cls_conn,
3584 enum iscsi_param param, char *buf)
3585{
3586 struct iscsi_conn *conn = cls_conn->dd_data;
3587 struct sock *sk;
3588 struct inet_sock *inet;
3589 struct ipv6_pinfo *np;
3590 int len = 0;
3591
3592 switch (param) {
3593 case ISCSI_PARAM_CONN_ADDRESS:
3594 mutex_lock(&conn->xmitmutex);
3595 if (!conn->sock) {
3596 mutex_unlock(&conn->xmitmutex);
3597 return -EINVAL;
3598 }
3599
3600 sk = conn->sock->sk;
3601 if (sk->sk_family == PF_INET) {
3602 inet = inet_sk(sk);
3603 len = sprintf(buf, "%u.%u.%u.%u\n",
3604 NIPQUAD(inet->daddr));
3605 } else {
3606 np = inet6_sk(sk);
3607 len = sprintf(buf,
3608 "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
3609 NIP6(np->daddr));
3610 }
3611 mutex_unlock(&conn->xmitmutex);
3612 break;
3613 default:
3614 return -EINVAL;
3615 }
3616
3617 return len;
3618}
3619
3571static void 3620static void
3572iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats) 3621iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats)
3573{ 3622{
@@ -3610,6 +3659,20 @@ static struct iscsi_transport iscsi_tcp_transport = {
3610 .name = "tcp", 3659 .name = "tcp",
3611 .caps = CAP_RECOVERY_L0 | CAP_MULTI_R2T | CAP_HDRDGST 3660 .caps = CAP_RECOVERY_L0 | CAP_MULTI_R2T | CAP_HDRDGST
3612 | CAP_DATADGST, 3661 | CAP_DATADGST,
3662 .param_mask = ISCSI_MAX_RECV_DLENGTH |
3663 ISCSI_MAX_XMIT_DLENGTH |
3664 ISCSI_HDRDGST_EN |
3665 ISCSI_DATADGST_EN |
3666 ISCSI_INITIAL_R2T_EN |
3667 ISCSI_MAX_R2T |
3668 ISCSI_IMM_DATA_EN |
3669 ISCSI_FIRST_BURST |
3670 ISCSI_MAX_BURST |
3671 ISCSI_PDU_INORDER_EN |
3672 ISCSI_DATASEQ_INORDER_EN |
3673 ISCSI_ERL |
3674 ISCSI_CONN_PORT |
3675 ISCSI_CONN_ADDRESS,
3613 .host_template = &iscsi_sht, 3676 .host_template = &iscsi_sht,
3614 .hostdata_size = sizeof(struct iscsi_session), 3677 .hostdata_size = sizeof(struct iscsi_session),
3615 .conndata_size = sizeof(struct iscsi_conn), 3678 .conndata_size = sizeof(struct iscsi_conn),
@@ -3622,6 +3685,7 @@ static struct iscsi_transport iscsi_tcp_transport = {
3622 .destroy_conn = iscsi_conn_destroy, 3685 .destroy_conn = iscsi_conn_destroy,
3623 .set_param = iscsi_conn_set_param, 3686 .set_param = iscsi_conn_set_param,
3624 .get_conn_param = iscsi_conn_get_param, 3687 .get_conn_param = iscsi_conn_get_param,
3688 .get_conn_str_param = iscsi_conn_get_str_param,
3625 .get_session_param = iscsi_session_get_param, 3689 .get_session_param = iscsi_session_get_param,
3626 .start_conn = iscsi_conn_start, 3690 .start_conn = iscsi_conn_start,
3627 .stop_conn = iscsi_conn_stop, 3691 .stop_conn = iscsi_conn_stop,
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 10ff0f0210ba..72a71ebc9d03 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -31,21 +31,13 @@
31#include <scsi/scsi_transport_iscsi.h> 31#include <scsi/scsi_transport_iscsi.h>
32#include <scsi/iscsi_if.h> 32#include <scsi/iscsi_if.h>
33 33
34#define ISCSI_SESSION_ATTRS 8 34#define ISCSI_SESSION_ATTRS 10
35#define ISCSI_CONN_ATTRS 6 35#define ISCSI_CONN_ATTRS 10
36 36
37struct iscsi_internal { 37struct iscsi_internal {
38 struct scsi_transport_template t; 38 struct scsi_transport_template t;
39 struct iscsi_transport *iscsi_transport; 39 struct iscsi_transport *iscsi_transport;
40 struct list_head list; 40 struct list_head list;
41 /*
42 * based on transport capabilities, at register time we set these
43 * bits to tell the transport class it wants attributes displayed
44 * in sysfs or that it can support different iSCSI Data-Path
45 * capabilities
46 */
47 uint32_t param_mask;
48
49 struct class_device cdev; 41 struct class_device cdev;
50 /* 42 /*
51 * We do not have any private or other attrs. 43 * We do not have any private or other attrs.
@@ -223,6 +215,7 @@ static void iscsi_session_release(struct device *dev)
223 215
224 shost = iscsi_session_to_shost(session); 216 shost = iscsi_session_to_shost(session);
225 scsi_host_put(shost); 217 scsi_host_put(shost);
218 kfree(session->targetname);
226 kfree(session); 219 kfree(session);
227 module_put(transport->owner); 220 module_put(transport->owner);
228} 221}
@@ -304,6 +297,7 @@ static void iscsi_conn_release(struct device *dev)
304 struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev); 297 struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev);
305 struct device *parent = conn->dev.parent; 298 struct device *parent = conn->dev.parent;
306 299
300 kfree(conn->persistent_address);
307 kfree(conn); 301 kfree(conn);
308 put_device(parent); 302 put_device(parent);
309} 303}
@@ -870,6 +864,67 @@ iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev
870 return 0; 864 return 0;
871} 865}
872 866
867static void
868iscsi_copy_param(struct iscsi_uevent *ev, uint32_t *value, char *data)
869{
870 if (ev->u.set_param.len != sizeof(uint32_t))
871 BUG();
872 memcpy(value, data, min_t(uint32_t, sizeof(uint32_t),
873 ev->u.set_param.len));
874}
875
876static int
877iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev)
878{
879 char *data = (char*)ev + sizeof(*ev);
880 struct iscsi_cls_conn *conn;
881 struct iscsi_cls_session *session;
882 int err = 0;
883 uint32_t value = 0;
884
885 session = iscsi_session_lookup(ev->u.set_param.sid);
886 conn = iscsi_conn_lookup(ev->u.set_param.sid, ev->u.set_param.cid);
887 if (!conn || !session)
888 return -EINVAL;
889
890 switch (ev->u.set_param.param) {
891 case ISCSI_PARAM_TARGET_NAME:
892 /* this should not change between logins */
893 if (session->targetname)
894 return 0;
895
896 session->targetname = kstrdup(data, GFP_KERNEL);
897 if (!session->targetname)
898 return -ENOMEM;
899 break;
900 case ISCSI_PARAM_TPGT:
901 iscsi_copy_param(ev, &value, data);
902 session->tpgt = value;
903 break;
904 case ISCSI_PARAM_PERSISTENT_PORT:
905 iscsi_copy_param(ev, &value, data);
906 conn->persistent_port = value;
907 break;
908 case ISCSI_PARAM_PERSISTENT_ADDRESS:
909 /*
910 * this is the address returned in discovery so it should
911 * not change between logins.
912 */
913 if (conn->persistent_address)
914 return 0;
915
916 conn->persistent_address = kstrdup(data, GFP_KERNEL);
917 if (!conn->persistent_address)
918 return -ENOMEM;
919 break;
920 default:
921 iscsi_copy_param(ev, &value, data);
922 err = transport->set_param(conn, ev->u.set_param.param, value);
923 }
924
925 return err;
926}
927
873static int 928static int
874iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) 929iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
875{ 930{
@@ -917,12 +972,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
917 err = -EINVAL; 972 err = -EINVAL;
918 break; 973 break;
919 case ISCSI_UEVENT_SET_PARAM: 974 case ISCSI_UEVENT_SET_PARAM:
920 conn = iscsi_conn_lookup(ev->u.set_param.sid, ev->u.set_param.cid); 975 err = iscsi_set_param(transport, ev);
921 if (conn)
922 ev->r.retcode = transport->set_param(conn,
923 ev->u.set_param.param, ev->u.set_param.value);
924 else
925 err = -EINVAL;
926 break; 976 break;
927 case ISCSI_UEVENT_START_CONN: 977 case ISCSI_UEVENT_START_CONN:
928 conn = iscsi_conn_lookup(ev->u.start_conn.sid, ev->u.start_conn.cid); 978 conn = iscsi_conn_lookup(ev->u.start_conn.sid, ev->u.start_conn.cid);
@@ -1028,6 +1078,10 @@ free_skb:
1028#define iscsi_cdev_to_conn(_cdev) \ 1078#define iscsi_cdev_to_conn(_cdev) \
1029 iscsi_dev_to_conn(_cdev->dev) 1079 iscsi_dev_to_conn(_cdev->dev)
1030 1080
1081#define ISCSI_CLASS_ATTR(_prefix,_name,_mode,_show,_store) \
1082struct class_device_attribute class_device_attr_##_prefix##_##_name = \
1083 __ATTR(_name,_mode,_show,_store)
1084
1031/* 1085/*
1032 * iSCSI connection attrs 1086 * iSCSI connection attrs
1033 */ 1087 */
@@ -1045,7 +1099,8 @@ show_conn_int_param_##param(struct class_device *cdev, char *buf) \
1045 1099
1046#define iscsi_conn_int_attr(field, param, format) \ 1100#define iscsi_conn_int_attr(field, param, format) \
1047 iscsi_conn_int_attr_show(param, format) \ 1101 iscsi_conn_int_attr_show(param, format) \
1048static CLASS_DEVICE_ATTR(field, S_IRUGO, show_conn_int_param_##param, NULL); 1102static ISCSI_CLASS_ATTR(conn, field, S_IRUGO, show_conn_int_param_##param, \
1103 NULL);
1049 1104
1050iscsi_conn_int_attr(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH, "%u"); 1105iscsi_conn_int_attr(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH, "%u");
1051iscsi_conn_int_attr(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH, "%u"); 1106iscsi_conn_int_attr(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH, "%u");
@@ -1053,6 +1108,25 @@ iscsi_conn_int_attr(header_digest, ISCSI_PARAM_HDRDGST_EN, "%d");
1053iscsi_conn_int_attr(data_digest, ISCSI_PARAM_DATADGST_EN, "%d"); 1108iscsi_conn_int_attr(data_digest, ISCSI_PARAM_DATADGST_EN, "%d");
1054iscsi_conn_int_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN, "%d"); 1109iscsi_conn_int_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN, "%d");
1055iscsi_conn_int_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN, "%d"); 1110iscsi_conn_int_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN, "%d");
1111iscsi_conn_int_attr(persistent_port, ISCSI_PARAM_PERSISTENT_PORT, "%d");
1112iscsi_conn_int_attr(port, ISCSI_PARAM_CONN_PORT, "%d");
1113
1114#define iscsi_conn_str_attr_show(param) \
1115static ssize_t \
1116show_conn_str_param_##param(struct class_device *cdev, char *buf) \
1117{ \
1118 struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \
1119 struct iscsi_transport *t = conn->transport; \
1120 return t->get_conn_str_param(conn, param, buf); \
1121}
1122
1123#define iscsi_conn_str_attr(field, param) \
1124 iscsi_conn_str_attr_show(param) \
1125static ISCSI_CLASS_ATTR(conn, field, S_IRUGO, show_conn_str_param_##param, \
1126 NULL);
1127
1128iscsi_conn_str_attr(persistent_address, ISCSI_PARAM_PERSISTENT_ADDRESS);
1129iscsi_conn_str_attr(address, ISCSI_PARAM_CONN_ADDRESS);
1056 1130
1057#define iscsi_cdev_to_session(_cdev) \ 1131#define iscsi_cdev_to_session(_cdev) \
1058 iscsi_dev_to_session(_cdev->dev) 1132 iscsi_dev_to_session(_cdev->dev)
@@ -1074,7 +1148,8 @@ show_session_int_param_##param(struct class_device *cdev, char *buf) \
1074 1148
1075#define iscsi_session_int_attr(field, param, format) \ 1149#define iscsi_session_int_attr(field, param, format) \
1076 iscsi_session_int_attr_show(param, format) \ 1150 iscsi_session_int_attr_show(param, format) \
1077static CLASS_DEVICE_ATTR(field, S_IRUGO, show_session_int_param_##param, NULL); 1151static ISCSI_CLASS_ATTR(sess, field, S_IRUGO, show_session_int_param_##param, \
1152 NULL);
1078 1153
1079iscsi_session_int_attr(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN, "%d"); 1154iscsi_session_int_attr(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN, "%d");
1080iscsi_session_int_attr(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T, "%hu"); 1155iscsi_session_int_attr(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T, "%hu");
@@ -1084,18 +1159,88 @@ iscsi_session_int_attr(max_burst_len, ISCSI_PARAM_MAX_BURST, "%u");
1084iscsi_session_int_attr(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN, "%d"); 1159iscsi_session_int_attr(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN, "%d");
1085iscsi_session_int_attr(data_seq_in_order, ISCSI_PARAM_DATASEQ_INORDER_EN, "%d"); 1160iscsi_session_int_attr(data_seq_in_order, ISCSI_PARAM_DATASEQ_INORDER_EN, "%d");
1086iscsi_session_int_attr(erl, ISCSI_PARAM_ERL, "%d"); 1161iscsi_session_int_attr(erl, ISCSI_PARAM_ERL, "%d");
1162iscsi_session_int_attr(tpgt, ISCSI_PARAM_TPGT, "%d");
1087 1163
1088#define SETUP_SESSION_RD_ATTR(field, param) \ 1164#define iscsi_session_str_attr_show(param) \
1089 if (priv->param_mask & (1 << param)) { \ 1165static ssize_t \
1090 priv->session_attrs[count] = &class_device_attr_##field;\ 1166show_session_str_param_##param(struct class_device *cdev, char *buf) \
1091 count++; \ 1167{ \
1092 } 1168 struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \
1169 struct iscsi_transport *t = session->transport; \
1170 return t->get_session_str_param(session, param, buf); \
1171}
1172
1173#define iscsi_session_str_attr(field, param) \
1174 iscsi_session_str_attr_show(param) \
1175static ISCSI_CLASS_ATTR(sess, field, S_IRUGO, show_session_str_param_##param, \
1176 NULL);
1177
1178iscsi_session_str_attr(targetname, ISCSI_PARAM_TARGET_NAME);
1093 1179
1094#define SETUP_CONN_RD_ATTR(field, param) \ 1180/*
1095 if (priv->param_mask & (1 << param)) { \ 1181 * Private session and conn attrs. userspace uses several iscsi values
1096 priv->conn_attrs[count] = &class_device_attr_##field; \ 1182 * to identify each session between reboots. Some of these values may not
1183 * be present in the iscsi_transport/LLD driver becuase userspace handles
1184 * login (and failback for login redirect) so for these type of drivers
1185 * the class manages the attrs and values for the iscsi_transport/LLD
1186 */
1187#define iscsi_priv_session_attr_show(field, format) \
1188static ssize_t \
1189show_priv_session_##field(struct class_device *cdev, char *buf) \
1190{ \
1191 struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \
1192 return sprintf(buf, format"\n", session->field); \
1193}
1194
1195#define iscsi_priv_session_attr(field, format) \
1196 iscsi_priv_session_attr_show(field, format) \
1197static ISCSI_CLASS_ATTR(priv_sess, field, S_IRUGO, show_priv_session_##field, \
1198 NULL)
1199iscsi_priv_session_attr(targetname, "%s");
1200iscsi_priv_session_attr(tpgt, "%d");
1201
1202#define iscsi_priv_conn_attr_show(field, format) \
1203static ssize_t \
1204show_priv_conn_##field(struct class_device *cdev, char *buf) \
1205{ \
1206 struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \
1207 return sprintf(buf, format"\n", conn->field); \
1208}
1209
1210#define iscsi_priv_conn_attr(field, format) \
1211 iscsi_priv_conn_attr_show(field, format) \
1212static ISCSI_CLASS_ATTR(priv_conn, field, S_IRUGO, show_priv_conn_##field, \
1213 NULL)
1214iscsi_priv_conn_attr(persistent_address, "%s");
1215iscsi_priv_conn_attr(persistent_port, "%d");
1216
1217#define SETUP_PRIV_SESSION_RD_ATTR(field) \
1218do { \
1219 priv->session_attrs[count] = &class_device_attr_priv_sess_##field; \
1220 count++; \
1221} while (0)
1222
1223#define SETUP_SESSION_RD_ATTR(field, param_flag) \
1224do { \
1225 if (tt->param_mask & param_flag) { \
1226 priv->session_attrs[count] = &class_device_attr_sess_##field; \
1097 count++; \ 1227 count++; \
1098 } 1228 } \
1229} while (0)
1230
1231#define SETUP_PRIV_CONN_RD_ATTR(field) \
1232do { \
1233 priv->conn_attrs[count] = &class_device_attr_priv_conn_##field; \
1234 count++; \
1235} while (0)
1236
1237#define SETUP_CONN_RD_ATTR(field, param_flag) \
1238do { \
1239 if (tt->param_mask & param_flag) { \
1240 priv->conn_attrs[count] = &class_device_attr_conn_##field; \
1241 count++; \
1242 } \
1243} while (0)
1099 1244
1100static int iscsi_session_match(struct attribute_container *cont, 1245static int iscsi_session_match(struct attribute_container *cont,
1101 struct device *dev) 1246 struct device *dev)
@@ -1173,31 +1318,30 @@ iscsi_register_transport(struct iscsi_transport *tt)
1173 if (err) 1318 if (err)
1174 goto unregister_cdev; 1319 goto unregister_cdev;
1175 1320
1176 /* setup parameters mask */
1177 priv->param_mask = 0xFFFFFFFF;
1178 if (!(tt->caps & CAP_MULTI_R2T))
1179 priv->param_mask &= ~(1 << ISCSI_PARAM_MAX_R2T);
1180 if (!(tt->caps & CAP_HDRDGST))
1181 priv->param_mask &= ~(1 << ISCSI_PARAM_HDRDGST_EN);
1182 if (!(tt->caps & CAP_DATADGST))
1183 priv->param_mask &= ~(1 << ISCSI_PARAM_DATADGST_EN);
1184 if (!(tt->caps & CAP_MARKERS)) {
1185 priv->param_mask &= ~(1 << ISCSI_PARAM_IFMARKER_EN);
1186 priv->param_mask &= ~(1 << ISCSI_PARAM_OFMARKER_EN);
1187 }
1188
1189 /* connection parameters */ 1321 /* connection parameters */
1190 priv->conn_cont.ac.attrs = &priv->conn_attrs[0]; 1322 priv->conn_cont.ac.attrs = &priv->conn_attrs[0];
1191 priv->conn_cont.ac.class = &iscsi_connection_class.class; 1323 priv->conn_cont.ac.class = &iscsi_connection_class.class;
1192 priv->conn_cont.ac.match = iscsi_conn_match; 1324 priv->conn_cont.ac.match = iscsi_conn_match;
1193 transport_container_register(&priv->conn_cont); 1325 transport_container_register(&priv->conn_cont);
1194 1326
1195 SETUP_CONN_RD_ATTR(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH); 1327 SETUP_CONN_RD_ATTR(max_recv_dlength, ISCSI_MAX_RECV_DLENGTH);
1196 SETUP_CONN_RD_ATTR(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH); 1328 SETUP_CONN_RD_ATTR(max_xmit_dlength, ISCSI_MAX_XMIT_DLENGTH);
1197 SETUP_CONN_RD_ATTR(header_digest, ISCSI_PARAM_HDRDGST_EN); 1329 SETUP_CONN_RD_ATTR(header_digest, ISCSI_HDRDGST_EN);
1198 SETUP_CONN_RD_ATTR(data_digest, ISCSI_PARAM_DATADGST_EN); 1330 SETUP_CONN_RD_ATTR(data_digest, ISCSI_DATADGST_EN);
1199 SETUP_CONN_RD_ATTR(ifmarker, ISCSI_PARAM_IFMARKER_EN); 1331 SETUP_CONN_RD_ATTR(ifmarker, ISCSI_IFMARKER_EN);
1200 SETUP_CONN_RD_ATTR(ofmarker, ISCSI_PARAM_OFMARKER_EN); 1332 SETUP_CONN_RD_ATTR(ofmarker, ISCSI_OFMARKER_EN);
1333 SETUP_CONN_RD_ATTR(address, ISCSI_CONN_ADDRESS);
1334 SETUP_CONN_RD_ATTR(port, ISCSI_CONN_PORT);
1335
1336 if (tt->param_mask & ISCSI_PERSISTENT_ADDRESS)
1337 SETUP_CONN_RD_ATTR(persistent_address, ISCSI_PERSISTENT_ADDRESS);
1338 else
1339 SETUP_PRIV_CONN_RD_ATTR(persistent_address);
1340
1341 if (tt->param_mask & ISCSI_PERSISTENT_PORT)
1342 SETUP_CONN_RD_ATTR(persistent_port, ISCSI_PERSISTENT_PORT);
1343 else
1344 SETUP_PRIV_CONN_RD_ATTR(persistent_port);
1201 1345
1202 BUG_ON(count > ISCSI_CONN_ATTRS); 1346 BUG_ON(count > ISCSI_CONN_ATTRS);
1203 priv->conn_attrs[count] = NULL; 1347 priv->conn_attrs[count] = NULL;
@@ -1209,14 +1353,24 @@ iscsi_register_transport(struct iscsi_transport *tt)
1209 priv->session_cont.ac.match = iscsi_session_match; 1353 priv->session_cont.ac.match = iscsi_session_match;
1210 transport_container_register(&priv->session_cont); 1354 transport_container_register(&priv->session_cont);
1211 1355
1212 SETUP_SESSION_RD_ATTR(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN); 1356 SETUP_SESSION_RD_ATTR(initial_r2t, ISCSI_INITIAL_R2T_EN);
1213 SETUP_SESSION_RD_ATTR(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T); 1357 SETUP_SESSION_RD_ATTR(max_outstanding_r2t, ISCSI_MAX_R2T);
1214 SETUP_SESSION_RD_ATTR(immediate_data, ISCSI_PARAM_IMM_DATA_EN); 1358 SETUP_SESSION_RD_ATTR(immediate_data, ISCSI_IMM_DATA_EN);
1215 SETUP_SESSION_RD_ATTR(first_burst_len, ISCSI_PARAM_FIRST_BURST); 1359 SETUP_SESSION_RD_ATTR(first_burst_len, ISCSI_FIRST_BURST);
1216 SETUP_SESSION_RD_ATTR(max_burst_len, ISCSI_PARAM_MAX_BURST); 1360 SETUP_SESSION_RD_ATTR(max_burst_len, ISCSI_MAX_BURST);
1217 SETUP_SESSION_RD_ATTR(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN); 1361 SETUP_SESSION_RD_ATTR(data_pdu_in_order, ISCSI_PDU_INORDER_EN);
1218 SETUP_SESSION_RD_ATTR(data_seq_in_order,ISCSI_PARAM_DATASEQ_INORDER_EN) 1362 SETUP_SESSION_RD_ATTR(data_seq_in_order, ISCSI_DATASEQ_INORDER_EN);
1219 SETUP_SESSION_RD_ATTR(erl, ISCSI_PARAM_ERL); 1363 SETUP_SESSION_RD_ATTR(erl, ISCSI_ERL);
1364
1365 if (tt->param_mask & ISCSI_TARGET_NAME)
1366 SETUP_SESSION_RD_ATTR(targetname, ISCSI_TARGET_NAME);
1367 else
1368 SETUP_PRIV_SESSION_RD_ATTR(targetname);
1369
1370 if (tt->param_mask & ISCSI_TPGT)
1371 SETUP_SESSION_RD_ATTR(tpgt, ISCSI_TPGT);
1372 else
1373 SETUP_PRIV_SESSION_RD_ATTR(tpgt);
1220 1374
1221 BUG_ON(count > ISCSI_SESSION_ATTRS); 1375 BUG_ON(count > ISCSI_SESSION_ATTRS);
1222 priv->session_attrs[count] = NULL; 1376 priv->session_attrs[count] = NULL;
diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h
index 933a91b1474e..2c3a89b64e71 100644
--- a/include/scsi/iscsi_if.h
+++ b/include/scsi/iscsi_if.h
@@ -86,7 +86,7 @@ struct iscsi_uevent {
86 uint32_t sid; 86 uint32_t sid;
87 uint32_t cid; 87 uint32_t cid;
88 uint32_t param; /* enum iscsi_param */ 88 uint32_t param; /* enum iscsi_param */
89 uint32_t value; 89 uint32_t len;
90 } set_param; 90 } set_param;
91 struct msg_start_conn { 91 struct msg_start_conn {
92 uint32_t sid; 92 uint32_t sid;
@@ -155,22 +155,54 @@ enum iscsi_err {
155 * iSCSI Parameters (RFC3720) 155 * iSCSI Parameters (RFC3720)
156 */ 156 */
157enum iscsi_param { 157enum iscsi_param {
158 ISCSI_PARAM_MAX_RECV_DLENGTH = 0, 158 /* passed in using netlink set param */
159 ISCSI_PARAM_MAX_XMIT_DLENGTH = 1, 159 ISCSI_PARAM_MAX_RECV_DLENGTH,
160 ISCSI_PARAM_HDRDGST_EN = 2, 160 ISCSI_PARAM_MAX_XMIT_DLENGTH,
161 ISCSI_PARAM_DATADGST_EN = 3, 161 ISCSI_PARAM_HDRDGST_EN,
162 ISCSI_PARAM_INITIAL_R2T_EN = 4, 162 ISCSI_PARAM_DATADGST_EN,
163 ISCSI_PARAM_MAX_R2T = 5, 163 ISCSI_PARAM_INITIAL_R2T_EN,
164 ISCSI_PARAM_IMM_DATA_EN = 6, 164 ISCSI_PARAM_MAX_R2T,
165 ISCSI_PARAM_FIRST_BURST = 7, 165 ISCSI_PARAM_IMM_DATA_EN,
166 ISCSI_PARAM_MAX_BURST = 8, 166 ISCSI_PARAM_FIRST_BURST,
167 ISCSI_PARAM_PDU_INORDER_EN = 9, 167 ISCSI_PARAM_MAX_BURST,
168 ISCSI_PARAM_DATASEQ_INORDER_EN = 10, 168 ISCSI_PARAM_PDU_INORDER_EN,
169 ISCSI_PARAM_ERL = 11, 169 ISCSI_PARAM_DATASEQ_INORDER_EN,
170 ISCSI_PARAM_IFMARKER_EN = 12, 170 ISCSI_PARAM_ERL,
171 ISCSI_PARAM_OFMARKER_EN = 13, 171 ISCSI_PARAM_IFMARKER_EN,
172 ISCSI_PARAM_OFMARKER_EN,
173 ISCSI_PARAM_TARGET_NAME,
174 ISCSI_PARAM_TPGT,
175 ISCSI_PARAM_PERSISTENT_ADDRESS,
176 ISCSI_PARAM_PERSISTENT_PORT,
177
178 /* pased in through bind conn using transport_fd */
179 ISCSI_PARAM_CONN_PORT,
180 ISCSI_PARAM_CONN_ADDRESS,
181
182 /* must always be last */
183 ISCSI_PARAM_MAX,
172}; 184};
173#define ISCSI_PARAM_MAX 14 185
186#define ISCSI_MAX_RECV_DLENGTH (1 << ISCSI_PARAM_MAX_RECV_DLENGTH)
187#define ISCSI_MAX_XMIT_DLENGTH (1 << ISCSI_PARAM_MAX_XMIT_DLENGTH)
188#define ISCSI_HDRDGST_EN (1 << ISCSI_PARAM_HDRDGST_EN)
189#define ISCSI_DATADGST_EN (1 << ISCSI_PARAM_DATADGST_EN)
190#define ISCSI_INITIAL_R2T_EN (1 << ISCSI_PARAM_INITIAL_R2T_EN)
191#define ISCSI_MAX_R2T (1 << ISCSI_PARAM_MAX_R2T)
192#define ISCSI_IMM_DATA_EN (1 << ISCSI_PARAM_IMM_DATA_EN)
193#define ISCSI_FIRST_BURST (1 << ISCSI_PARAM_FIRST_BURST)
194#define ISCSI_MAX_BURST (1 << ISCSI_PARAM_MAX_BURST)
195#define ISCSI_PDU_INORDER_EN (1 << ISCSI_PARAM_PDU_INORDER_EN)
196#define ISCSI_DATASEQ_INORDER_EN (1 << ISCSI_PARAM_DATASEQ_INORDER_EN)
197#define ISCSI_ERL (1 << ISCSI_PARAM_ERL)
198#define ISCSI_IFMARKER_EN (1 << ISCSI_PARAM_IFMARKER_EN)
199#define ISCSI_OFMARKER_EN (1 << ISCSI_PARAM_OFMARKER_EN)
200#define ISCSI_TARGET_NAME (1 << ISCSI_PARAM_TARGET_NAME)
201#define ISCSI_TPGT (1 << ISCSI_PARAM_TPGT)
202#define ISCSI_PERSISTENT_ADDRESS (1 << ISCSI_PARAM_PERSISTENT_ADDRESS)
203#define ISCSI_PERSISTENT_PORT (1 << ISCSI_PARAM_PERSISTENT_PORT)
204#define ISCSI_CONN_PORT (1 << ISCSI_PARAM_CONN_PORT)
205#define ISCSI_CONN_ADDRESS (1 << ISCSI_PARAM_CONN_ADDRESS)
174 206
175#define iscsi_ptr(_handle) ((void*)(unsigned long)_handle) 207#define iscsi_ptr(_handle) ((void*)(unsigned long)_handle)
176#define iscsi_handle(_ptr) ((uint64_t)(unsigned long)_ptr) 208#define iscsi_handle(_ptr) ((uint64_t)(unsigned long)_ptr)
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
index 631463cd4892..4b200645c84b 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -53,11 +53,11 @@ struct iscsi_transport {
53 struct module *owner; 53 struct module *owner;
54 char *name; 54 char *name;
55 unsigned int caps; 55 unsigned int caps;
56 /* LLD sets this to indicate what values it can export to sysfs */
57 unsigned int param_mask;
56 struct scsi_host_template *host_template; 58 struct scsi_host_template *host_template;
57 /* LLD session/scsi_host data size */ 59 /* LLD session/scsi_host data size */
58 int hostdata_size; 60 int hostdata_size;
59 /* LLD iscsi_host data size */
60 int ihostdata_size;
61 /* LLD connection data size */ 61 /* LLD connection data size */
62 int conndata_size; 62 int conndata_size;
63 /* LLD session data size */ 63 /* LLD session data size */
@@ -79,10 +79,13 @@ struct iscsi_transport {
79 int (*set_param) (struct iscsi_cls_conn *conn, enum iscsi_param param, 79 int (*set_param) (struct iscsi_cls_conn *conn, enum iscsi_param param,
80 uint32_t value); 80 uint32_t value);
81 int (*get_conn_param) (struct iscsi_cls_conn *conn, 81 int (*get_conn_param) (struct iscsi_cls_conn *conn,
82 enum iscsi_param param, 82 enum iscsi_param param, uint32_t *value);
83 uint32_t *value);
84 int (*get_session_param) (struct iscsi_cls_session *session, 83 int (*get_session_param) (struct iscsi_cls_session *session,
85 enum iscsi_param param, uint32_t *value); 84 enum iscsi_param param, uint32_t *value);
85 int (*get_conn_str_param) (struct iscsi_cls_conn *conn,
86 enum iscsi_param param, char *buf);
87 int (*get_session_str_param) (struct iscsi_cls_session *session,
88 enum iscsi_param param, char *buf);
86 int (*send_pdu) (struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, 89 int (*send_pdu) (struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
87 char *data, uint32_t data_size); 90 char *data, uint32_t data_size);
88 void (*get_stats) (struct iscsi_cls_conn *conn, 91 void (*get_stats) (struct iscsi_cls_conn *conn,
@@ -107,6 +110,14 @@ struct iscsi_cls_conn {
107 void *dd_data; /* LLD private data */ 110 void *dd_data; /* LLD private data */
108 struct iscsi_transport *transport; 111 struct iscsi_transport *transport;
109 uint32_t cid; /* connection id */ 112 uint32_t cid; /* connection id */
113
114 /* portal/group values we got during discovery */
115 char *persistent_address;
116 int persistent_port;
117 /* portal/group values we are currently using */
118 char *address;
119 int port;
120
110 int active; /* must be accessed with the connlock */ 121 int active; /* must be accessed with the connlock */
111 struct device dev; /* sysfs transport/container device */ 122 struct device dev; /* sysfs transport/container device */
112 struct mempool_zone *z_error; 123 struct mempool_zone *z_error;
@@ -120,6 +131,11 @@ struct iscsi_cls_conn {
120struct iscsi_cls_session { 131struct iscsi_cls_session {
121 struct list_head sess_list; /* item in session_list */ 132 struct list_head sess_list; /* item in session_list */
122 struct iscsi_transport *transport; 133 struct iscsi_transport *transport;
134
135 /* iSCSI values used as unique id by userspace. */
136 char *targetname;
137 int tpgt;
138
123 int sid; /* session id */ 139 int sid; /* session id */
124 void *dd_data; /* LLD private data */ 140 void *dd_data; /* LLD private data */
125 struct device dev; /* sysfs transport/container device */ 141 struct device dev; /* sysfs transport/container device */