diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2006-04-06 22:13:36 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-04-14 15:03:41 -0400 |
commit | fd7255f51a13ea915099c7e488001dfbbeb05104 (patch) | |
tree | 964624f68f000848dae1a9f4c396502849707826 /drivers | |
parent | b5c7a12dc29ae0990d9e867749bdd717a3160325 (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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/iscsi_tcp.c | 68 | ||||
-rw-r--r-- | drivers/scsi/scsi_transport_iscsi.c | 262 |
2 files changed, 274 insertions, 56 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 | ||
3582 | static int | ||
3583 | iscsi_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 | |||
3571 | static void | 3620 | static void |
3572 | iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats) | 3621 | iscsi_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 | ||
37 | struct iscsi_internal { | 37 | struct 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 | ||
867 | static void | ||
868 | iscsi_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 | |||
876 | static int | ||
877 | iscsi_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 | |||
873 | static int | 928 | static int |
874 | iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | 929 | iscsi_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) \ | ||
1082 | struct 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) \ |
1048 | static CLASS_DEVICE_ATTR(field, S_IRUGO, show_conn_int_param_##param, NULL); | 1102 | static ISCSI_CLASS_ATTR(conn, field, S_IRUGO, show_conn_int_param_##param, \ |
1103 | NULL); | ||
1049 | 1104 | ||
1050 | iscsi_conn_int_attr(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH, "%u"); | 1105 | iscsi_conn_int_attr(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH, "%u"); |
1051 | iscsi_conn_int_attr(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH, "%u"); | 1106 | iscsi_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"); | |||
1053 | iscsi_conn_int_attr(data_digest, ISCSI_PARAM_DATADGST_EN, "%d"); | 1108 | iscsi_conn_int_attr(data_digest, ISCSI_PARAM_DATADGST_EN, "%d"); |
1054 | iscsi_conn_int_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN, "%d"); | 1109 | iscsi_conn_int_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN, "%d"); |
1055 | iscsi_conn_int_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN, "%d"); | 1110 | iscsi_conn_int_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN, "%d"); |
1111 | iscsi_conn_int_attr(persistent_port, ISCSI_PARAM_PERSISTENT_PORT, "%d"); | ||
1112 | iscsi_conn_int_attr(port, ISCSI_PARAM_CONN_PORT, "%d"); | ||
1113 | |||
1114 | #define iscsi_conn_str_attr_show(param) \ | ||
1115 | static ssize_t \ | ||
1116 | show_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) \ | ||
1125 | static ISCSI_CLASS_ATTR(conn, field, S_IRUGO, show_conn_str_param_##param, \ | ||
1126 | NULL); | ||
1127 | |||
1128 | iscsi_conn_str_attr(persistent_address, ISCSI_PARAM_PERSISTENT_ADDRESS); | ||
1129 | iscsi_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) \ |
1077 | static CLASS_DEVICE_ATTR(field, S_IRUGO, show_session_int_param_##param, NULL); | 1151 | static ISCSI_CLASS_ATTR(sess, field, S_IRUGO, show_session_int_param_##param, \ |
1152 | NULL); | ||
1078 | 1153 | ||
1079 | iscsi_session_int_attr(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN, "%d"); | 1154 | iscsi_session_int_attr(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN, "%d"); |
1080 | iscsi_session_int_attr(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T, "%hu"); | 1155 | iscsi_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"); | |||
1084 | iscsi_session_int_attr(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN, "%d"); | 1159 | iscsi_session_int_attr(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN, "%d"); |
1085 | iscsi_session_int_attr(data_seq_in_order, ISCSI_PARAM_DATASEQ_INORDER_EN, "%d"); | 1160 | iscsi_session_int_attr(data_seq_in_order, ISCSI_PARAM_DATASEQ_INORDER_EN, "%d"); |
1086 | iscsi_session_int_attr(erl, ISCSI_PARAM_ERL, "%d"); | 1161 | iscsi_session_int_attr(erl, ISCSI_PARAM_ERL, "%d"); |
1162 | iscsi_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)) { \ | 1165 | static ssize_t \ |
1090 | priv->session_attrs[count] = &class_device_attr_##field;\ | 1166 | show_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) \ | ||
1175 | static ISCSI_CLASS_ATTR(sess, field, S_IRUGO, show_session_str_param_##param, \ | ||
1176 | NULL); | ||
1177 | |||
1178 | iscsi_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) \ | ||
1188 | static ssize_t \ | ||
1189 | show_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) \ | ||
1197 | static ISCSI_CLASS_ATTR(priv_sess, field, S_IRUGO, show_priv_session_##field, \ | ||
1198 | NULL) | ||
1199 | iscsi_priv_session_attr(targetname, "%s"); | ||
1200 | iscsi_priv_session_attr(tpgt, "%d"); | ||
1201 | |||
1202 | #define iscsi_priv_conn_attr_show(field, format) \ | ||
1203 | static ssize_t \ | ||
1204 | show_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) \ | ||
1212 | static ISCSI_CLASS_ATTR(priv_conn, field, S_IRUGO, show_priv_conn_##field, \ | ||
1213 | NULL) | ||
1214 | iscsi_priv_conn_attr(persistent_address, "%s"); | ||
1215 | iscsi_priv_conn_attr(persistent_port, "%d"); | ||
1216 | |||
1217 | #define SETUP_PRIV_SESSION_RD_ATTR(field) \ | ||
1218 | do { \ | ||
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) \ | ||
1224 | do { \ | ||
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) \ | ||
1232 | do { \ | ||
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) \ | ||
1238 | do { \ | ||
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 | ||
1100 | static int iscsi_session_match(struct attribute_container *cont, | 1245 | static 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; |