diff options
| author | Mike Christie <michaelc@cs.wisc.edu> | 2006-06-28 13:00:23 -0400 |
|---|---|---|
| committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-06-29 11:07:14 -0400 |
| commit | a54a52caad4bd6166cb7fa64e4e93031fa2fda5d (patch) | |
| tree | 728672fae35fd344619129e78213043dabacf099 | |
| parent | 01cb225dad8da2e717356fab03240e2f4a8d01bf (diff) | |
[SCSI] iscsi: fixup set/get param functions
Reduce duplication in the software iscsi_transport modules by
adding a libiscsi function to handle the common grunt work.
This also has the drivers return specifc -EXXX values for different
errors so userspace can finally handle them in a sane way.
Also just pass the sysfs buffers to the drivers so HW iscsi can
get/set its string values, like targetname, and initiatorname.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
| -rw-r--r-- | drivers/scsi/libiscsi.c | 179 | ||||
| -rw-r--r-- | drivers/scsi/scsi_transport_iscsi.c | 210 | ||||
| -rw-r--r-- | include/scsi/libiscsi.h | 15 | ||||
| -rw-r--r-- | include/scsi/scsi_transport_iscsi.h | 29 |
4 files changed, 246 insertions, 187 deletions
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 2673a11a9495..7c76a989b218 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
| @@ -1697,6 +1697,185 @@ int iscsi_conn_bind(struct iscsi_cls_session *cls_session, | |||
| 1697 | } | 1697 | } |
| 1698 | EXPORT_SYMBOL_GPL(iscsi_conn_bind); | 1698 | EXPORT_SYMBOL_GPL(iscsi_conn_bind); |
| 1699 | 1699 | ||
| 1700 | |||
| 1701 | int iscsi_set_param(struct iscsi_cls_conn *cls_conn, | ||
| 1702 | enum iscsi_param param, char *buf, int buflen) | ||
| 1703 | { | ||
| 1704 | struct iscsi_conn *conn = cls_conn->dd_data; | ||
| 1705 | struct iscsi_session *session = conn->session; | ||
| 1706 | uint32_t value; | ||
| 1707 | |||
| 1708 | switch(param) { | ||
| 1709 | case ISCSI_PARAM_MAX_RECV_DLENGTH: | ||
| 1710 | sscanf(buf, "%d", &conn->max_recv_dlength); | ||
| 1711 | break; | ||
| 1712 | case ISCSI_PARAM_MAX_XMIT_DLENGTH: | ||
| 1713 | sscanf(buf, "%d", &conn->max_xmit_dlength); | ||
| 1714 | break; | ||
| 1715 | case ISCSI_PARAM_HDRDGST_EN: | ||
| 1716 | sscanf(buf, "%d", &conn->hdrdgst_en); | ||
| 1717 | break; | ||
| 1718 | case ISCSI_PARAM_DATADGST_EN: | ||
| 1719 | sscanf(buf, "%d", &conn->datadgst_en); | ||
| 1720 | break; | ||
| 1721 | case ISCSI_PARAM_INITIAL_R2T_EN: | ||
| 1722 | sscanf(buf, "%d", &session->initial_r2t_en); | ||
| 1723 | break; | ||
| 1724 | case ISCSI_PARAM_MAX_R2T: | ||
| 1725 | sscanf(buf, "%d", &session->max_r2t); | ||
| 1726 | break; | ||
| 1727 | case ISCSI_PARAM_IMM_DATA_EN: | ||
| 1728 | sscanf(buf, "%d", &session->imm_data_en); | ||
| 1729 | break; | ||
| 1730 | case ISCSI_PARAM_FIRST_BURST: | ||
| 1731 | sscanf(buf, "%d", &session->first_burst); | ||
| 1732 | break; | ||
| 1733 | case ISCSI_PARAM_MAX_BURST: | ||
| 1734 | sscanf(buf, "%d", &session->max_burst); | ||
| 1735 | break; | ||
| 1736 | case ISCSI_PARAM_PDU_INORDER_EN: | ||
| 1737 | sscanf(buf, "%d", &session->pdu_inorder_en); | ||
| 1738 | break; | ||
| 1739 | case ISCSI_PARAM_DATASEQ_INORDER_EN: | ||
| 1740 | sscanf(buf, "%d", &session->dataseq_inorder_en); | ||
| 1741 | break; | ||
| 1742 | case ISCSI_PARAM_ERL: | ||
| 1743 | sscanf(buf, "%d", &session->erl); | ||
| 1744 | break; | ||
| 1745 | case ISCSI_PARAM_IFMARKER_EN: | ||
| 1746 | sscanf(buf, "%d", &value); | ||
| 1747 | BUG_ON(value); | ||
| 1748 | break; | ||
| 1749 | case ISCSI_PARAM_OFMARKER_EN: | ||
| 1750 | sscanf(buf, "%d", &value); | ||
| 1751 | BUG_ON(value); | ||
| 1752 | break; | ||
| 1753 | case ISCSI_PARAM_EXP_STATSN: | ||
| 1754 | sscanf(buf, "%u", &conn->exp_statsn); | ||
| 1755 | break; | ||
| 1756 | case ISCSI_PARAM_TARGET_NAME: | ||
| 1757 | /* this should not change between logins */ | ||
| 1758 | if (session->targetname) | ||
| 1759 | break; | ||
| 1760 | |||
| 1761 | session->targetname = kstrdup(buf, GFP_KERNEL); | ||
| 1762 | if (!session->targetname) | ||
| 1763 | return -ENOMEM; | ||
| 1764 | break; | ||
| 1765 | case ISCSI_PARAM_TPGT: | ||
| 1766 | sscanf(buf, "%d", &session->tpgt); | ||
| 1767 | break; | ||
| 1768 | case ISCSI_PARAM_PERSISTENT_PORT: | ||
| 1769 | sscanf(buf, "%d", &conn->persistent_port); | ||
| 1770 | break; | ||
| 1771 | case ISCSI_PARAM_PERSISTENT_ADDRESS: | ||
| 1772 | /* | ||
| 1773 | * this is the address returned in discovery so it should | ||
| 1774 | * not change between logins. | ||
| 1775 | */ | ||
| 1776 | if (conn->persistent_address) | ||
| 1777 | break; | ||
| 1778 | |||
| 1779 | conn->persistent_address = kstrdup(buf, GFP_KERNEL); | ||
| 1780 | if (!conn->persistent_address) | ||
| 1781 | return -ENOMEM; | ||
| 1782 | break; | ||
| 1783 | default: | ||
| 1784 | return -ENOSYS; | ||
| 1785 | } | ||
| 1786 | |||
| 1787 | return 0; | ||
| 1788 | } | ||
| 1789 | EXPORT_SYMBOL_GPL(iscsi_set_param); | ||
| 1790 | |||
| 1791 | int iscsi_session_get_param(struct iscsi_cls_session *cls_session, | ||
| 1792 | enum iscsi_param param, char *buf) | ||
| 1793 | { | ||
| 1794 | struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); | ||
| 1795 | struct iscsi_session *session = iscsi_hostdata(shost->hostdata); | ||
| 1796 | int len; | ||
| 1797 | |||
| 1798 | switch(param) { | ||
| 1799 | case ISCSI_PARAM_INITIAL_R2T_EN: | ||
| 1800 | len = sprintf(buf, "%d\n", session->initial_r2t_en); | ||
| 1801 | break; | ||
| 1802 | case ISCSI_PARAM_MAX_R2T: | ||
| 1803 | len = sprintf(buf, "%hu\n", session->max_r2t); | ||
| 1804 | break; | ||
| 1805 | case ISCSI_PARAM_IMM_DATA_EN: | ||
| 1806 | len = sprintf(buf, "%d\n", session->imm_data_en); | ||
| 1807 | break; | ||
| 1808 | case ISCSI_PARAM_FIRST_BURST: | ||
| 1809 | len = sprintf(buf, "%u\n", session->first_burst); | ||
| 1810 | break; | ||
| 1811 | case ISCSI_PARAM_MAX_BURST: | ||
| 1812 | len = sprintf(buf, "%u\n", session->max_burst); | ||
| 1813 | break; | ||
| 1814 | case ISCSI_PARAM_PDU_INORDER_EN: | ||
| 1815 | len = sprintf(buf, "%d\n", session->pdu_inorder_en); | ||
| 1816 | break; | ||
| 1817 | case ISCSI_PARAM_DATASEQ_INORDER_EN: | ||
| 1818 | len = sprintf(buf, "%d\n", session->dataseq_inorder_en); | ||
| 1819 | break; | ||
| 1820 | case ISCSI_PARAM_ERL: | ||
| 1821 | len = sprintf(buf, "%d\n", session->erl); | ||
| 1822 | break; | ||
| 1823 | case ISCSI_PARAM_TARGET_NAME: | ||
| 1824 | len = sprintf(buf, "%s\n", session->targetname); | ||
| 1825 | break; | ||
| 1826 | case ISCSI_PARAM_TPGT: | ||
| 1827 | len = sprintf(buf, "%d\n", session->tpgt); | ||
| 1828 | break; | ||
| 1829 | default: | ||
| 1830 | return -ENOSYS; | ||
| 1831 | } | ||
| 1832 | |||
| 1833 | return len; | ||
| 1834 | } | ||
| 1835 | EXPORT_SYMBOL_GPL(iscsi_session_get_param); | ||
| 1836 | |||
| 1837 | int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, | ||
| 1838 | enum iscsi_param param, char *buf) | ||
| 1839 | { | ||
| 1840 | struct iscsi_conn *conn = cls_conn->dd_data; | ||
| 1841 | int len; | ||
| 1842 | |||
| 1843 | switch(param) { | ||
| 1844 | case ISCSI_PARAM_MAX_RECV_DLENGTH: | ||
| 1845 | len = sprintf(buf, "%u\n", conn->max_recv_dlength); | ||
| 1846 | break; | ||
| 1847 | case ISCSI_PARAM_MAX_XMIT_DLENGTH: | ||
| 1848 | len = sprintf(buf, "%u\n", conn->max_xmit_dlength); | ||
| 1849 | break; | ||
| 1850 | case ISCSI_PARAM_HDRDGST_EN: | ||
| 1851 | len = sprintf(buf, "%d\n", conn->hdrdgst_en); | ||
| 1852 | break; | ||
| 1853 | case ISCSI_PARAM_DATADGST_EN: | ||
| 1854 | len = sprintf(buf, "%d\n", conn->datadgst_en); | ||
| 1855 | break; | ||
| 1856 | case ISCSI_PARAM_IFMARKER_EN: | ||
| 1857 | len = sprintf(buf, "%d\n", conn->ifmarker_en); | ||
| 1858 | break; | ||
| 1859 | case ISCSI_PARAM_OFMARKER_EN: | ||
| 1860 | len = sprintf(buf, "%d\n", conn->ofmarker_en); | ||
| 1861 | break; | ||
| 1862 | case ISCSI_PARAM_EXP_STATSN: | ||
| 1863 | len = sprintf(buf, "%u\n", conn->exp_statsn); | ||
| 1864 | break; | ||
| 1865 | case ISCSI_PARAM_PERSISTENT_PORT: | ||
| 1866 | len = sprintf(buf, "%d\n", conn->persistent_port); | ||
| 1867 | break; | ||
| 1868 | case ISCSI_PARAM_PERSISTENT_ADDRESS: | ||
| 1869 | len = sprintf(buf, "%s\n", conn->persistent_address); | ||
| 1870 | break; | ||
| 1871 | default: | ||
| 1872 | return -ENOSYS; | ||
| 1873 | } | ||
| 1874 | |||
| 1875 | return len; | ||
| 1876 | } | ||
| 1877 | EXPORT_SYMBOL_GPL(iscsi_conn_get_param); | ||
| 1878 | |||
| 1700 | MODULE_AUTHOR("Mike Christie"); | 1879 | MODULE_AUTHOR("Mike Christie"); |
| 1701 | MODULE_DESCRIPTION("iSCSI library functions"); | 1880 | MODULE_DESCRIPTION("iSCSI library functions"); |
| 1702 | MODULE_LICENSE("GPL"); | 1881 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 99e76d458290..147c854e1d4d 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c | |||
| @@ -233,7 +233,6 @@ static void iscsi_session_release(struct device *dev) | |||
| 233 | 233 | ||
| 234 | shost = iscsi_session_to_shost(session); | 234 | shost = iscsi_session_to_shost(session); |
| 235 | scsi_host_put(shost); | 235 | scsi_host_put(shost); |
| 236 | kfree(session->targetname); | ||
| 237 | kfree(session); | 236 | kfree(session); |
| 238 | module_put(transport->owner); | 237 | module_put(transport->owner); |
| 239 | } | 238 | } |
| @@ -388,7 +387,6 @@ static void iscsi_conn_release(struct device *dev) | |||
| 388 | struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev); | 387 | struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev); |
| 389 | struct device *parent = conn->dev.parent; | 388 | struct device *parent = conn->dev.parent; |
| 390 | 389 | ||
| 391 | kfree(conn->persistent_address); | ||
| 392 | kfree(conn); | 390 | kfree(conn); |
| 393 | put_device(parent); | 391 | put_device(parent); |
| 394 | } | 392 | } |
| @@ -877,23 +875,13 @@ iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev | |||
| 877 | return 0; | 875 | return 0; |
| 878 | } | 876 | } |
| 879 | 877 | ||
| 880 | static void | ||
| 881 | iscsi_copy_param(struct iscsi_uevent *ev, uint32_t *value, char *data) | ||
| 882 | { | ||
| 883 | if (ev->u.set_param.len != sizeof(uint32_t)) | ||
| 884 | BUG(); | ||
| 885 | memcpy(value, data, min_t(uint32_t, sizeof(uint32_t), | ||
| 886 | ev->u.set_param.len)); | ||
| 887 | } | ||
| 888 | |||
| 889 | static int | 878 | static int |
| 890 | iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev) | 879 | iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev) |
| 891 | { | 880 | { |
| 892 | char *data = (char*)ev + sizeof(*ev); | 881 | char *data = (char*)ev + sizeof(*ev); |
| 893 | struct iscsi_cls_conn *conn; | 882 | struct iscsi_cls_conn *conn; |
| 894 | struct iscsi_cls_session *session; | 883 | struct iscsi_cls_session *session; |
| 895 | int err = 0; | 884 | int err = 0, value = 0; |
| 896 | uint32_t value = 0; | ||
| 897 | 885 | ||
| 898 | session = iscsi_session_lookup(ev->u.set_param.sid); | 886 | session = iscsi_session_lookup(ev->u.set_param.sid); |
| 899 | conn = iscsi_conn_lookup(ev->u.set_param.sid, ev->u.set_param.cid); | 887 | conn = iscsi_conn_lookup(ev->u.set_param.sid, ev->u.set_param.cid); |
| @@ -902,42 +890,13 @@ iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev) | |||
| 902 | 890 | ||
| 903 | switch (ev->u.set_param.param) { | 891 | switch (ev->u.set_param.param) { |
| 904 | case ISCSI_PARAM_SESS_RECOVERY_TMO: | 892 | case ISCSI_PARAM_SESS_RECOVERY_TMO: |
| 905 | iscsi_copy_param(ev, &value, data); | 893 | sscanf(data, "%d", &value); |
| 906 | if (value != 0) | 894 | if (value != 0) |
| 907 | session->recovery_tmo = value; | 895 | session->recovery_tmo = value; |
| 908 | break; | 896 | break; |
| 909 | case ISCSI_PARAM_TARGET_NAME: | ||
| 910 | /* this should not change between logins */ | ||
| 911 | if (session->targetname) | ||
| 912 | return 0; | ||
| 913 | |||
| 914 | session->targetname = kstrdup(data, GFP_KERNEL); | ||
| 915 | if (!session->targetname) | ||
| 916 | return -ENOMEM; | ||
| 917 | break; | ||
| 918 | case ISCSI_PARAM_TPGT: | ||
| 919 | iscsi_copy_param(ev, &value, data); | ||
| 920 | session->tpgt = value; | ||
| 921 | break; | ||
| 922 | case ISCSI_PARAM_PERSISTENT_PORT: | ||
| 923 | iscsi_copy_param(ev, &value, data); | ||
| 924 | conn->persistent_port = value; | ||
| 925 | break; | ||
| 926 | case ISCSI_PARAM_PERSISTENT_ADDRESS: | ||
| 927 | /* | ||
| 928 | * this is the address returned in discovery so it should | ||
| 929 | * not change between logins. | ||
| 930 | */ | ||
| 931 | if (conn->persistent_address) | ||
| 932 | return 0; | ||
| 933 | |||
| 934 | conn->persistent_address = kstrdup(data, GFP_KERNEL); | ||
| 935 | if (!conn->persistent_address) | ||
| 936 | return -ENOMEM; | ||
| 937 | break; | ||
| 938 | default: | 897 | default: |
| 939 | iscsi_copy_param(ev, &value, data); | 898 | err = transport->set_param(conn, ev->u.set_param.param, |
| 940 | err = transport->set_param(conn, ev->u.set_param.param, value); | 899 | data, ev->u.set_param.len); |
| 941 | } | 900 | } |
| 942 | 901 | ||
| 943 | return err; | 902 | return err; |
| @@ -1165,49 +1124,31 @@ struct class_device_attribute class_device_attr_##_prefix##_##_name = \ | |||
| 1165 | /* | 1124 | /* |
| 1166 | * iSCSI connection attrs | 1125 | * iSCSI connection attrs |
| 1167 | */ | 1126 | */ |
| 1168 | #define iscsi_conn_int_attr_show(param, format) \ | 1127 | #define iscsi_conn_attr_show(param) \ |
| 1169 | static ssize_t \ | 1128 | static ssize_t \ |
| 1170 | show_conn_int_param_##param(struct class_device *cdev, char *buf) \ | 1129 | show_conn_param_##param(struct class_device *cdev, char *buf) \ |
| 1171 | { \ | 1130 | { \ |
| 1172 | uint32_t value = 0; \ | ||
| 1173 | struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \ | 1131 | struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \ |
| 1174 | struct iscsi_transport *t = conn->transport; \ | 1132 | struct iscsi_transport *t = conn->transport; \ |
| 1175 | \ | 1133 | return t->get_conn_param(conn, param, buf); \ |
| 1176 | t->get_conn_param(conn, param, &value); \ | ||
| 1177 | return snprintf(buf, 20, format"\n", value); \ | ||
| 1178 | } | 1134 | } |
| 1179 | 1135 | ||
| 1180 | #define iscsi_conn_int_attr(field, param, format) \ | 1136 | #define iscsi_conn_attr(field, param) \ |
| 1181 | iscsi_conn_int_attr_show(param, format) \ | 1137 | iscsi_conn_attr_show(param) \ |
| 1182 | static ISCSI_CLASS_ATTR(conn, field, S_IRUGO, show_conn_int_param_##param, \ | 1138 | static ISCSI_CLASS_ATTR(conn, field, S_IRUGO, show_conn_param_##param, \ |
| 1183 | NULL); | 1139 | NULL); |
| 1184 | 1140 | ||
| 1185 | iscsi_conn_int_attr(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH, "%u"); | 1141 | iscsi_conn_attr(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH); |
| 1186 | iscsi_conn_int_attr(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH, "%u"); | 1142 | iscsi_conn_attr(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH); |
| 1187 | iscsi_conn_int_attr(header_digest, ISCSI_PARAM_HDRDGST_EN, "%d"); | 1143 | iscsi_conn_attr(header_digest, ISCSI_PARAM_HDRDGST_EN); |
| 1188 | iscsi_conn_int_attr(data_digest, ISCSI_PARAM_DATADGST_EN, "%d"); | 1144 | iscsi_conn_attr(data_digest, ISCSI_PARAM_DATADGST_EN); |
| 1189 | iscsi_conn_int_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN, "%d"); | 1145 | iscsi_conn_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN); |
| 1190 | iscsi_conn_int_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN, "%d"); | 1146 | iscsi_conn_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN); |
| 1191 | iscsi_conn_int_attr(persistent_port, ISCSI_PARAM_PERSISTENT_PORT, "%d"); | 1147 | iscsi_conn_attr(persistent_port, ISCSI_PARAM_PERSISTENT_PORT); |
| 1192 | iscsi_conn_int_attr(port, ISCSI_PARAM_CONN_PORT, "%d"); | 1148 | iscsi_conn_attr(port, ISCSI_PARAM_CONN_PORT); |
| 1193 | iscsi_conn_int_attr(exp_statsn, ISCSI_PARAM_EXP_STATSN, "%u"); | 1149 | iscsi_conn_attr(exp_statsn, ISCSI_PARAM_EXP_STATSN); |
| 1194 | 1150 | iscsi_conn_attr(persistent_address, ISCSI_PARAM_PERSISTENT_ADDRESS); | |
| 1195 | #define iscsi_conn_str_attr_show(param) \ | 1151 | iscsi_conn_attr(address, ISCSI_PARAM_CONN_ADDRESS); |
| 1196 | static ssize_t \ | ||
| 1197 | show_conn_str_param_##param(struct class_device *cdev, char *buf) \ | ||
| 1198 | { \ | ||
| 1199 | struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \ | ||
| 1200 | struct iscsi_transport *t = conn->transport; \ | ||
| 1201 | return t->get_conn_str_param(conn, param, buf); \ | ||
| 1202 | } | ||
| 1203 | |||
| 1204 | #define iscsi_conn_str_attr(field, param) \ | ||
| 1205 | iscsi_conn_str_attr_show(param) \ | ||
| 1206 | static ISCSI_CLASS_ATTR(conn, field, S_IRUGO, show_conn_str_param_##param, \ | ||
| 1207 | NULL); | ||
| 1208 | |||
| 1209 | iscsi_conn_str_attr(persistent_address, ISCSI_PARAM_PERSISTENT_ADDRESS); | ||
| 1210 | iscsi_conn_str_attr(address, ISCSI_PARAM_CONN_ADDRESS); | ||
| 1211 | 1152 | ||
| 1212 | #define iscsi_cdev_to_session(_cdev) \ | 1153 | #define iscsi_cdev_to_session(_cdev) \ |
| 1213 | iscsi_dev_to_session(_cdev->dev) | 1154 | iscsi_dev_to_session(_cdev->dev) |
| @@ -1215,61 +1156,36 @@ iscsi_conn_str_attr(address, ISCSI_PARAM_CONN_ADDRESS); | |||
| 1215 | /* | 1156 | /* |
| 1216 | * iSCSI session attrs | 1157 | * iSCSI session attrs |
| 1217 | */ | 1158 | */ |
| 1218 | #define iscsi_session_int_attr_show(param, format) \ | 1159 | #define iscsi_session_attr_show(param) \ |
| 1219 | static ssize_t \ | ||
| 1220 | show_session_int_param_##param(struct class_device *cdev, char *buf) \ | ||
| 1221 | { \ | ||
| 1222 | uint32_t value = 0; \ | ||
| 1223 | struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \ | ||
| 1224 | struct iscsi_transport *t = session->transport; \ | ||
| 1225 | \ | ||
| 1226 | t->get_session_param(session, param, &value); \ | ||
| 1227 | return snprintf(buf, 20, format"\n", value); \ | ||
| 1228 | } | ||
| 1229 | |||
| 1230 | #define iscsi_session_int_attr(field, param, format) \ | ||
| 1231 | iscsi_session_int_attr_show(param, format) \ | ||
| 1232 | static ISCSI_CLASS_ATTR(sess, field, S_IRUGO, show_session_int_param_##param, \ | ||
| 1233 | NULL); | ||
| 1234 | |||
| 1235 | iscsi_session_int_attr(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN, "%d"); | ||
| 1236 | iscsi_session_int_attr(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T, "%hu"); | ||
| 1237 | iscsi_session_int_attr(immediate_data, ISCSI_PARAM_IMM_DATA_EN, "%d"); | ||
| 1238 | iscsi_session_int_attr(first_burst_len, ISCSI_PARAM_FIRST_BURST, "%u"); | ||
| 1239 | iscsi_session_int_attr(max_burst_len, ISCSI_PARAM_MAX_BURST, "%u"); | ||
| 1240 | iscsi_session_int_attr(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN, "%d"); | ||
| 1241 | iscsi_session_int_attr(data_seq_in_order, ISCSI_PARAM_DATASEQ_INORDER_EN, "%d"); | ||
| 1242 | iscsi_session_int_attr(erl, ISCSI_PARAM_ERL, "%d"); | ||
| 1243 | iscsi_session_int_attr(tpgt, ISCSI_PARAM_TPGT, "%d"); | ||
| 1244 | |||
| 1245 | #define iscsi_session_str_attr_show(param) \ | ||
| 1246 | static ssize_t \ | 1160 | static ssize_t \ |
| 1247 | show_session_str_param_##param(struct class_device *cdev, char *buf) \ | 1161 | show_session_param_##param(struct class_device *cdev, char *buf) \ |
| 1248 | { \ | 1162 | { \ |
| 1249 | struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \ | 1163 | struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \ |
| 1250 | struct iscsi_transport *t = session->transport; \ | 1164 | struct iscsi_transport *t = session->transport; \ |
| 1251 | return t->get_session_str_param(session, param, buf); \ | 1165 | return t->get_session_param(session, param, buf); \ |
| 1252 | } | 1166 | } |
| 1253 | 1167 | ||
| 1254 | #define iscsi_session_str_attr(field, param) \ | 1168 | #define iscsi_session_attr(field, param) \ |
| 1255 | iscsi_session_str_attr_show(param) \ | 1169 | iscsi_session_attr_show(param) \ |
| 1256 | static ISCSI_CLASS_ATTR(sess, field, S_IRUGO, show_session_str_param_##param, \ | 1170 | static ISCSI_CLASS_ATTR(sess, field, S_IRUGO, show_session_param_##param, \ |
| 1257 | NULL); | 1171 | NULL); |
| 1258 | 1172 | ||
| 1259 | iscsi_session_str_attr(targetname, ISCSI_PARAM_TARGET_NAME); | 1173 | iscsi_session_attr(targetname, ISCSI_PARAM_TARGET_NAME); |
| 1174 | iscsi_session_attr(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN); | ||
| 1175 | iscsi_session_attr(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T); | ||
| 1176 | iscsi_session_attr(immediate_data, ISCSI_PARAM_IMM_DATA_EN); | ||
| 1177 | iscsi_session_attr(first_burst_len, ISCSI_PARAM_FIRST_BURST); | ||
| 1178 | iscsi_session_attr(max_burst_len, ISCSI_PARAM_MAX_BURST); | ||
| 1179 | iscsi_session_attr(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN); | ||
| 1180 | iscsi_session_attr(data_seq_in_order, ISCSI_PARAM_DATASEQ_INORDER_EN); | ||
| 1181 | iscsi_session_attr(erl, ISCSI_PARAM_ERL); | ||
| 1182 | iscsi_session_attr(tpgt, ISCSI_PARAM_TPGT); | ||
| 1260 | 1183 | ||
| 1261 | /* | ||
| 1262 | * Private session and conn attrs. userspace uses several iscsi values | ||
| 1263 | * to identify each session between reboots. Some of these values may not | ||
| 1264 | * be present in the iscsi_transport/LLD driver becuase userspace handles | ||
| 1265 | * login (and failback for login redirect) so for these type of drivers | ||
| 1266 | * the class manages the attrs and values for the iscsi_transport/LLD | ||
| 1267 | */ | ||
| 1268 | #define iscsi_priv_session_attr_show(field, format) \ | 1184 | #define iscsi_priv_session_attr_show(field, format) \ |
| 1269 | static ssize_t \ | 1185 | static ssize_t \ |
| 1270 | show_priv_session_##field(struct class_device *cdev, char *buf) \ | 1186 | show_priv_session_##field(struct class_device *cdev, char *buf) \ |
| 1271 | { \ | 1187 | { \ |
| 1272 | struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev); \ | 1188 | struct iscsi_cls_session *session = iscsi_cdev_to_session(cdev);\ |
| 1273 | return sprintf(buf, format"\n", session->field); \ | 1189 | return sprintf(buf, format"\n", session->field); \ |
| 1274 | } | 1190 | } |
| 1275 | 1191 | ||
| @@ -1277,31 +1193,15 @@ show_priv_session_##field(struct class_device *cdev, char *buf) \ | |||
| 1277 | iscsi_priv_session_attr_show(field, format) \ | 1193 | iscsi_priv_session_attr_show(field, format) \ |
| 1278 | static ISCSI_CLASS_ATTR(priv_sess, field, S_IRUGO, show_priv_session_##field, \ | 1194 | static ISCSI_CLASS_ATTR(priv_sess, field, S_IRUGO, show_priv_session_##field, \ |
| 1279 | NULL) | 1195 | NULL) |
| 1280 | iscsi_priv_session_attr(targetname, "%s"); | ||
| 1281 | iscsi_priv_session_attr(tpgt, "%d"); | ||
| 1282 | iscsi_priv_session_attr(recovery_tmo, "%d"); | 1196 | iscsi_priv_session_attr(recovery_tmo, "%d"); |
| 1283 | 1197 | ||
| 1284 | #define iscsi_priv_conn_attr_show(field, format) \ | ||
| 1285 | static ssize_t \ | ||
| 1286 | show_priv_conn_##field(struct class_device *cdev, char *buf) \ | ||
| 1287 | { \ | ||
| 1288 | struct iscsi_cls_conn *conn = iscsi_cdev_to_conn(cdev); \ | ||
| 1289 | return sprintf(buf, format"\n", conn->field); \ | ||
| 1290 | } | ||
| 1291 | |||
| 1292 | #define iscsi_priv_conn_attr(field, format) \ | ||
| 1293 | iscsi_priv_conn_attr_show(field, format) \ | ||
| 1294 | static ISCSI_CLASS_ATTR(priv_conn, field, S_IRUGO, show_priv_conn_##field, \ | ||
| 1295 | NULL) | ||
| 1296 | iscsi_priv_conn_attr(persistent_address, "%s"); | ||
| 1297 | iscsi_priv_conn_attr(persistent_port, "%d"); | ||
| 1298 | |||
| 1299 | #define SETUP_PRIV_SESSION_RD_ATTR(field) \ | 1198 | #define SETUP_PRIV_SESSION_RD_ATTR(field) \ |
| 1300 | do { \ | 1199 | do { \ |
| 1301 | priv->session_attrs[count] = &class_device_attr_priv_sess_##field; \ | 1200 | priv->session_attrs[count] = &class_device_attr_priv_sess_##field; \ |
| 1302 | count++; \ | 1201 | count++; \ |
| 1303 | } while (0) | 1202 | } while (0) |
| 1304 | 1203 | ||
| 1204 | |||
| 1305 | #define SETUP_SESSION_RD_ATTR(field, param_flag) \ | 1205 | #define SETUP_SESSION_RD_ATTR(field, param_flag) \ |
| 1306 | do { \ | 1206 | do { \ |
| 1307 | if (tt->param_mask & param_flag) { \ | 1207 | if (tt->param_mask & param_flag) { \ |
| @@ -1310,12 +1210,6 @@ do { \ | |||
| 1310 | } \ | 1210 | } \ |
| 1311 | } while (0) | 1211 | } while (0) |
| 1312 | 1212 | ||
| 1313 | #define SETUP_PRIV_CONN_RD_ATTR(field) \ | ||
| 1314 | do { \ | ||
| 1315 | priv->conn_attrs[count] = &class_device_attr_priv_conn_##field; \ | ||
| 1316 | count++; \ | ||
| 1317 | } while (0) | ||
| 1318 | |||
| 1319 | #define SETUP_CONN_RD_ATTR(field, param_flag) \ | 1213 | #define SETUP_CONN_RD_ATTR(field, param_flag) \ |
| 1320 | do { \ | 1214 | do { \ |
| 1321 | if (tt->param_mask & param_flag) { \ | 1215 | if (tt->param_mask & param_flag) { \ |
| @@ -1442,16 +1336,8 @@ iscsi_register_transport(struct iscsi_transport *tt) | |||
| 1442 | SETUP_CONN_RD_ATTR(address, ISCSI_CONN_ADDRESS); | 1336 | SETUP_CONN_RD_ATTR(address, ISCSI_CONN_ADDRESS); |
| 1443 | SETUP_CONN_RD_ATTR(port, ISCSI_CONN_PORT); | 1337 | SETUP_CONN_RD_ATTR(port, ISCSI_CONN_PORT); |
| 1444 | SETUP_CONN_RD_ATTR(exp_statsn, ISCSI_EXP_STATSN); | 1338 | SETUP_CONN_RD_ATTR(exp_statsn, ISCSI_EXP_STATSN); |
| 1445 | 1339 | SETUP_CONN_RD_ATTR(persistent_address, ISCSI_PERSISTENT_ADDRESS); | |
| 1446 | if (tt->param_mask & ISCSI_PERSISTENT_ADDRESS) | 1340 | SETUP_CONN_RD_ATTR(persistent_port, ISCSI_PERSISTENT_PORT); |
| 1447 | SETUP_CONN_RD_ATTR(persistent_address, ISCSI_PERSISTENT_ADDRESS); | ||
| 1448 | else | ||
| 1449 | SETUP_PRIV_CONN_RD_ATTR(persistent_address); | ||
| 1450 | |||
| 1451 | if (tt->param_mask & ISCSI_PERSISTENT_PORT) | ||
| 1452 | SETUP_CONN_RD_ATTR(persistent_port, ISCSI_PERSISTENT_PORT); | ||
| 1453 | else | ||
| 1454 | SETUP_PRIV_CONN_RD_ATTR(persistent_port); | ||
| 1455 | 1341 | ||
| 1456 | BUG_ON(count > ISCSI_CONN_ATTRS); | 1342 | BUG_ON(count > ISCSI_CONN_ATTRS); |
| 1457 | priv->conn_attrs[count] = NULL; | 1343 | priv->conn_attrs[count] = NULL; |
| @@ -1471,18 +1357,10 @@ iscsi_register_transport(struct iscsi_transport *tt) | |||
| 1471 | SETUP_SESSION_RD_ATTR(data_pdu_in_order, ISCSI_PDU_INORDER_EN); | 1357 | SETUP_SESSION_RD_ATTR(data_pdu_in_order, ISCSI_PDU_INORDER_EN); |
| 1472 | SETUP_SESSION_RD_ATTR(data_seq_in_order, ISCSI_DATASEQ_INORDER_EN); | 1358 | SETUP_SESSION_RD_ATTR(data_seq_in_order, ISCSI_DATASEQ_INORDER_EN); |
| 1473 | SETUP_SESSION_RD_ATTR(erl, ISCSI_ERL); | 1359 | SETUP_SESSION_RD_ATTR(erl, ISCSI_ERL); |
| 1360 | SETUP_SESSION_RD_ATTR(targetname, ISCSI_TARGET_NAME); | ||
| 1361 | SETUP_SESSION_RD_ATTR(tpgt, ISCSI_TPGT); | ||
| 1474 | SETUP_PRIV_SESSION_RD_ATTR(recovery_tmo); | 1362 | SETUP_PRIV_SESSION_RD_ATTR(recovery_tmo); |
| 1475 | 1363 | ||
| 1476 | if (tt->param_mask & ISCSI_TARGET_NAME) | ||
| 1477 | SETUP_SESSION_RD_ATTR(targetname, ISCSI_TARGET_NAME); | ||
| 1478 | else | ||
| 1479 | SETUP_PRIV_SESSION_RD_ATTR(targetname); | ||
| 1480 | |||
| 1481 | if (tt->param_mask & ISCSI_TPGT) | ||
| 1482 | SETUP_SESSION_RD_ATTR(tpgt, ISCSI_TPGT); | ||
| 1483 | else | ||
| 1484 | SETUP_PRIV_SESSION_RD_ATTR(tpgt); | ||
| 1485 | |||
| 1486 | BUG_ON(count > ISCSI_SESSION_ATTRS); | 1364 | BUG_ON(count > ISCSI_SESSION_ATTRS); |
| 1487 | priv->session_attrs[count] = NULL; | 1365 | priv->session_attrs[count] = NULL; |
| 1488 | 1366 | ||
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index cbf7e58bd6f9..ba2760802ded 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h | |||
| @@ -157,6 +157,11 @@ struct iscsi_conn { | |||
| 157 | int max_xmit_dlength; /* target_max_recv_dsl */ | 157 | int max_xmit_dlength; /* target_max_recv_dsl */ |
| 158 | int hdrdgst_en; | 158 | int hdrdgst_en; |
| 159 | int datadgst_en; | 159 | int datadgst_en; |
| 160 | int ifmarker_en; | ||
| 161 | int ofmarker_en; | ||
| 162 | /* values userspace uses to id a conn */ | ||
| 163 | int persistent_port; | ||
| 164 | char *persistent_address; | ||
| 160 | 165 | ||
| 161 | /* MIB-statistics */ | 166 | /* MIB-statistics */ |
| 162 | uint64_t txdata_octets; | 167 | uint64_t txdata_octets; |
| @@ -196,8 +201,8 @@ struct iscsi_session { | |||
| 196 | int pdu_inorder_en; | 201 | int pdu_inorder_en; |
| 197 | int dataseq_inorder_en; | 202 | int dataseq_inorder_en; |
| 198 | int erl; | 203 | int erl; |
| 199 | int ifmarker_en; | 204 | int tpgt; |
| 200 | int ofmarker_en; | 205 | char *targetname; |
| 201 | 206 | ||
| 202 | /* control data */ | 207 | /* control data */ |
| 203 | struct iscsi_transport *tt; | 208 | struct iscsi_transport *tt; |
| @@ -240,6 +245,10 @@ iscsi_session_setup(struct iscsi_transport *, struct scsi_transport_template *, | |||
| 240 | extern void iscsi_session_teardown(struct iscsi_cls_session *); | 245 | extern void iscsi_session_teardown(struct iscsi_cls_session *); |
| 241 | extern struct iscsi_session *class_to_transport_session(struct iscsi_cls_session *); | 246 | extern struct iscsi_session *class_to_transport_session(struct iscsi_cls_session *); |
| 242 | extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *); | 247 | extern void iscsi_session_recovery_timedout(struct iscsi_cls_session *); |
| 248 | extern int iscsi_set_param(struct iscsi_cls_conn *cls_conn, | ||
| 249 | enum iscsi_param param, char *buf, int buflen); | ||
| 250 | extern int iscsi_session_get_param(struct iscsi_cls_session *cls_session, | ||
| 251 | enum iscsi_param param, char *buf); | ||
| 243 | 252 | ||
| 244 | #define session_to_cls(_sess) \ | 253 | #define session_to_cls(_sess) \ |
| 245 | hostdata_session(_sess->host->hostdata) | 254 | hostdata_session(_sess->host->hostdata) |
| @@ -255,6 +264,8 @@ extern void iscsi_conn_stop(struct iscsi_cls_conn *, int); | |||
| 255 | extern int iscsi_conn_bind(struct iscsi_cls_session *, struct iscsi_cls_conn *, | 264 | extern int iscsi_conn_bind(struct iscsi_cls_session *, struct iscsi_cls_conn *, |
| 256 | int); | 265 | int); |
| 257 | extern void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err); | 266 | extern void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err); |
| 267 | extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, | ||
| 268 | enum iscsi_param param, char *buf); | ||
| 258 | 269 | ||
| 259 | /* | 270 | /* |
| 260 | * pdu and task processing | 271 | * pdu and task processing |
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index b95151aec602..05397058a9b8 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h | |||
| @@ -34,6 +34,7 @@ struct iscsi_cls_conn; | |||
| 34 | struct iscsi_conn; | 34 | struct iscsi_conn; |
| 35 | struct iscsi_cmd_task; | 35 | struct iscsi_cmd_task; |
| 36 | struct iscsi_mgmt_task; | 36 | struct iscsi_mgmt_task; |
| 37 | struct sockaddr; | ||
| 37 | 38 | ||
| 38 | /** | 39 | /** |
| 39 | * struct iscsi_transport - iSCSI Transport template | 40 | * struct iscsi_transport - iSCSI Transport template |
| @@ -46,7 +47,12 @@ struct iscsi_mgmt_task; | |||
| 46 | * @bind_conn: associate this connection with existing iSCSI session | 47 | * @bind_conn: associate this connection with existing iSCSI session |
| 47 | * and specified transport descriptor | 48 | * and specified transport descriptor |
| 48 | * @destroy_conn: destroy inactive iSCSI connection | 49 | * @destroy_conn: destroy inactive iSCSI connection |
| 49 | * @set_param: set iSCSI Data-Path operational parameter | 50 | * @set_param: set iSCSI parameter. Return 0 on success, -ENODATA |
| 51 | * when param is not supported, and a -Exx value on other | ||
| 52 | * error. | ||
| 53 | * @get_param get iSCSI parameter. Must return number of bytes | ||
| 54 | * copied to buffer on success, -ENODATA when param | ||
| 55 | * is not supported, and a -Exx value on other error | ||
| 50 | * @start_conn: set connection to be operational | 56 | * @start_conn: set connection to be operational |
| 51 | * @stop_conn: suspend/recover/terminate connection | 57 | * @stop_conn: suspend/recover/terminate connection |
| 52 | * @send_pdu: send iSCSI PDU, Login, Logout, NOP-Out, Reject, Text. | 58 | * @send_pdu: send iSCSI PDU, Login, Logout, NOP-Out, Reject, Text. |
| @@ -97,15 +103,11 @@ struct iscsi_transport { | |||
| 97 | void (*stop_conn) (struct iscsi_cls_conn *conn, int flag); | 103 | void (*stop_conn) (struct iscsi_cls_conn *conn, int flag); |
| 98 | void (*destroy_conn) (struct iscsi_cls_conn *conn); | 104 | void (*destroy_conn) (struct iscsi_cls_conn *conn); |
| 99 | int (*set_param) (struct iscsi_cls_conn *conn, enum iscsi_param param, | 105 | int (*set_param) (struct iscsi_cls_conn *conn, enum iscsi_param param, |
| 100 | uint32_t value); | 106 | char *buf, int buflen); |
| 101 | int (*get_conn_param) (struct iscsi_cls_conn *conn, | 107 | int (*get_conn_param) (struct iscsi_cls_conn *conn, |
| 102 | enum iscsi_param param, uint32_t *value); | 108 | enum iscsi_param param, char *buf); |
| 103 | int (*get_session_param) (struct iscsi_cls_session *session, | 109 | int (*get_session_param) (struct iscsi_cls_session *session, |
| 104 | enum iscsi_param param, uint32_t *value); | 110 | enum iscsi_param param, char *buf); |
| 105 | int (*get_conn_str_param) (struct iscsi_cls_conn *conn, | ||
| 106 | enum iscsi_param param, char *buf); | ||
| 107 | int (*get_session_str_param) (struct iscsi_cls_session *session, | ||
| 108 | enum iscsi_param param, char *buf); | ||
| 109 | int (*send_pdu) (struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, | 111 | int (*send_pdu) (struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, |
| 110 | char *data, uint32_t data_size); | 112 | char *data, uint32_t data_size); |
| 111 | void (*get_stats) (struct iscsi_cls_conn *conn, | 113 | void (*get_stats) (struct iscsi_cls_conn *conn, |
| @@ -157,13 +159,6 @@ struct iscsi_cls_conn { | |||
| 157 | struct iscsi_transport *transport; | 159 | struct iscsi_transport *transport; |
| 158 | uint32_t cid; /* connection id */ | 160 | uint32_t cid; /* connection id */ |
| 159 | 161 | ||
| 160 | /* portal/group values we got during discovery */ | ||
| 161 | char *persistent_address; | ||
| 162 | int persistent_port; | ||
| 163 | /* portal/group values we are currently using */ | ||
| 164 | char *address; | ||
| 165 | int port; | ||
| 166 | |||
| 167 | int active; /* must be accessed with the connlock */ | 162 | int active; /* must be accessed with the connlock */ |
| 168 | struct device dev; /* sysfs transport/container device */ | 163 | struct device dev; /* sysfs transport/container device */ |
| 169 | struct mempool_zone *z_error; | 164 | struct mempool_zone *z_error; |
| @@ -187,10 +182,6 @@ struct iscsi_cls_session { | |||
| 187 | struct list_head host_list; | 182 | struct list_head host_list; |
| 188 | struct iscsi_transport *transport; | 183 | struct iscsi_transport *transport; |
| 189 | 184 | ||
| 190 | /* iSCSI values used as unique id by userspace. */ | ||
| 191 | char *targetname; | ||
| 192 | int tpgt; | ||
| 193 | |||
| 194 | /* recovery fields */ | 185 | /* recovery fields */ |
| 195 | int recovery_tmo; | 186 | int recovery_tmo; |
| 196 | struct work_struct recovery_work; | 187 | struct work_struct recovery_work; |
