aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2006-04-06 22:13:36 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-04-14 15:03:41 -0400
commitfd7255f51a13ea915099c7e488001dfbbeb05104 (patch)
tree964624f68f000848dae1a9f4c396502849707826
parentb5c7a12dc29ae0990d9e867749bdd717a3160325 (diff)
[SCSI] iscsi: add sysfs attrs for uspace sync up
For iscsi boot when going from initramfs to the real root we need to stop the userpsace iscsi daemon. To later restart it iscsid needs to be able to rebuild itself and part of that process is matching a session running the kernel with the iscsid representation. To do this the attached patch adds several required iscsi values. If the LLD does not provide them becuase, login is done in userspace, then the transport class and userspace set ths up for the LLD. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-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 */