aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/iscsi_tcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/iscsi_tcp.c')
-rw-r--r--drivers/scsi/iscsi_tcp.c102
1 files changed, 57 insertions, 45 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index aecadbdce9df..8cdcaf33fb4e 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -64,6 +64,10 @@ MODULE_LICENSE("GPL");
64#define BUG_ON(expr) 64#define BUG_ON(expr)
65#endif 65#endif
66 66
67static struct scsi_transport_template *iscsi_tcp_scsi_transport;
68static struct scsi_host_template iscsi_sht;
69static struct iscsi_transport iscsi_tcp_transport;
70
67static unsigned int iscsi_max_lun = 512; 71static unsigned int iscsi_max_lun = 512;
68module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO); 72module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO);
69 73
@@ -1623,6 +1627,8 @@ iscsi_tcp_conn_bind(struct iscsi_cls_session *cls_session,
1623 struct iscsi_cls_conn *cls_conn, uint64_t transport_eph, 1627 struct iscsi_cls_conn *cls_conn, uint64_t transport_eph,
1624 int is_leading) 1628 int is_leading)
1625{ 1629{
1630 struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
1631 struct iscsi_host *ihost = shost_priv(shost);
1626 struct iscsi_conn *conn = cls_conn->dd_data; 1632 struct iscsi_conn *conn = cls_conn->dd_data;
1627 struct iscsi_tcp_conn *tcp_conn = conn->dd_data; 1633 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
1628 struct sock *sk; 1634 struct sock *sk;
@@ -1646,8 +1652,8 @@ iscsi_tcp_conn_bind(struct iscsi_cls_session *cls_session,
1646 if (err) 1652 if (err)
1647 goto free_socket; 1653 goto free_socket;
1648 1654
1649 err = iscsi_tcp_get_addr(conn, sock, conn->local_address, 1655 err = iscsi_tcp_get_addr(conn, sock, ihost->local_address,
1650 &conn->local_port, kernel_getsockname); 1656 &ihost->local_port, kernel_getsockname);
1651 if (err) 1657 if (err)
1652 goto free_socket; 1658 goto free_socket;
1653 1659
@@ -1821,29 +1827,6 @@ iscsi_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn,
1821 return len; 1827 return len;
1822} 1828}
1823 1829
1824static int
1825iscsi_tcp_host_get_param(struct Scsi_Host *shost, enum iscsi_host_param param,
1826 char *buf)
1827{
1828 struct iscsi_session *session = iscsi_hostdata(shost->hostdata);
1829 int len;
1830
1831 switch (param) {
1832 case ISCSI_HOST_PARAM_IPADDRESS:
1833 spin_lock_bh(&session->lock);
1834 if (!session->leadconn)
1835 len = -ENODEV;
1836 else
1837 len = sprintf(buf, "%s\n",
1838 session->leadconn->local_address);
1839 spin_unlock_bh(&session->lock);
1840 break;
1841 default:
1842 return iscsi_host_get_param(shost, param, buf);
1843 }
1844 return len;
1845}
1846
1847static void 1830static void
1848iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats) 1831iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats)
1849{ 1832{
@@ -1869,26 +1852,44 @@ iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats)
1869} 1852}
1870 1853
1871static struct iscsi_cls_session * 1854static struct iscsi_cls_session *
1872iscsi_tcp_session_create(struct iscsi_transport *iscsit, 1855iscsi_tcp_session_create(struct Scsi_Host *shost, uint16_t cmds_max,
1873 struct scsi_transport_template *scsit,
1874 struct Scsi_Host *shost, uint16_t cmds_max,
1875 uint16_t qdepth, uint32_t initial_cmdsn, 1856 uint16_t qdepth, uint32_t initial_cmdsn,
1876 uint32_t *hostno) 1857 uint32_t *hostno)
1877{ 1858{
1878 struct iscsi_cls_session *cls_session; 1859 struct iscsi_cls_session *cls_session;
1879 struct iscsi_session *session; 1860 struct iscsi_session *session;
1880 uint32_t hn;
1881 int cmd_i; 1861 int cmd_i;
1882 1862
1883 cls_session = iscsi_session_setup(iscsit, scsit, cmds_max, qdepth, 1863 if (shost) {
1884 sizeof(struct iscsi_tcp_cmd_task), 1864 printk(KERN_ERR "iscsi_tcp: invalid shost %d.\n",
1885 sizeof(struct iscsi_tcp_mgmt_task), 1865 shost->host_no);
1886 initial_cmdsn, &hn); 1866 return NULL;
1887 if (!cls_session) 1867 }
1868
1869 shost = scsi_host_alloc(&iscsi_sht, sizeof(struct iscsi_host));
1870 if (!shost)
1888 return NULL; 1871 return NULL;
1889 *hostno = hn; 1872 shost->transportt = iscsi_tcp_scsi_transport;
1873 shost->max_lun = iscsi_max_lun;
1874 shost->max_id = 0;
1875 shost->max_channel = 0;
1876 shost->max_cmd_len = 16;
1877
1878 iscsi_host_setup(shost, qdepth);
1879
1880 if (scsi_add_host(shost, NULL))
1881 goto free_host;
1882 *hostno = shost->host_no;
1883
1884 cls_session = iscsi_session_setup(&iscsi_tcp_transport, shost, cmds_max,
1885 sizeof(struct iscsi_tcp_cmd_task),
1886 sizeof(struct iscsi_tcp_mgmt_task),
1887 initial_cmdsn);
1888 if (!cls_session)
1889 goto remove_host;
1890 session = cls_session->dd_data;
1890 1891
1891 session = class_to_transport_session(cls_session); 1892 shost->can_queue = session->cmds_max;
1892 for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) { 1893 for (cmd_i = 0; cmd_i < session->cmds_max; cmd_i++) {
1893 struct iscsi_cmd_task *ctask = session->cmds[cmd_i]; 1894 struct iscsi_cmd_task *ctask = session->cmds[cmd_i];
1894 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 1895 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
@@ -1904,20 +1905,30 @@ iscsi_tcp_session_create(struct iscsi_transport *iscsit,
1904 mtask->hdr = (struct iscsi_hdr *) &tcp_mtask->hdr; 1905 mtask->hdr = (struct iscsi_hdr *) &tcp_mtask->hdr;
1905 } 1906 }
1906 1907
1907 if (iscsi_r2tpool_alloc(class_to_transport_session(cls_session))) 1908 if (iscsi_r2tpool_alloc(session))
1908 goto r2tpool_alloc_fail; 1909 goto remove_session;
1909
1910 return cls_session; 1910 return cls_session;
1911 1911
1912r2tpool_alloc_fail: 1912remove_session:
1913 iscsi_session_teardown(cls_session); 1913 iscsi_session_teardown(cls_session);
1914remove_host:
1915 scsi_remove_host(shost);
1916free_host:
1917 iscsi_host_teardown(shost);
1918 scsi_host_put(shost);
1914 return NULL; 1919 return NULL;
1915} 1920}
1916 1921
1917static void iscsi_tcp_session_destroy(struct iscsi_cls_session *cls_session) 1922static void iscsi_tcp_session_destroy(struct iscsi_cls_session *cls_session)
1918{ 1923{
1919 iscsi_r2tpool_free(class_to_transport_session(cls_session)); 1924 struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
1925
1926 iscsi_r2tpool_free(cls_session->dd_data);
1920 iscsi_session_teardown(cls_session); 1927 iscsi_session_teardown(cls_session);
1928
1929 scsi_remove_host(shost);
1930 iscsi_host_teardown(shost);
1931 scsi_host_put(shost);
1921} 1932}
1922 1933
1923static int iscsi_tcp_slave_configure(struct scsi_device *sdev) 1934static int iscsi_tcp_slave_configure(struct scsi_device *sdev)
@@ -1976,8 +1987,8 @@ static struct iscsi_transport iscsi_tcp_transport = {
1976 .host_param_mask = ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS | 1987 .host_param_mask = ISCSI_HOST_HWADDRESS | ISCSI_HOST_IPADDRESS |
1977 ISCSI_HOST_INITIATOR_NAME | 1988 ISCSI_HOST_INITIATOR_NAME |
1978 ISCSI_HOST_NETDEV_NAME, 1989 ISCSI_HOST_NETDEV_NAME,
1979 .host_template = &iscsi_sht,
1980 .conndata_size = sizeof(struct iscsi_conn), 1990 .conndata_size = sizeof(struct iscsi_conn),
1991 .sessiondata_size = sizeof(struct iscsi_session),
1981 /* session management */ 1992 /* session management */
1982 .create_session = iscsi_tcp_session_create, 1993 .create_session = iscsi_tcp_session_create,
1983 .destroy_session = iscsi_tcp_session_destroy, 1994 .destroy_session = iscsi_tcp_session_destroy,
@@ -1991,7 +2002,7 @@ static struct iscsi_transport iscsi_tcp_transport = {
1991 .start_conn = iscsi_conn_start, 2002 .start_conn = iscsi_conn_start,
1992 .stop_conn = iscsi_tcp_conn_stop, 2003 .stop_conn = iscsi_tcp_conn_stop,
1993 /* iscsi host params */ 2004 /* iscsi host params */
1994 .get_host_param = iscsi_tcp_host_get_param, 2005 .get_host_param = iscsi_host_get_param,
1995 .set_host_param = iscsi_host_set_param, 2006 .set_host_param = iscsi_host_set_param,
1996 /* IO */ 2007 /* IO */
1997 .send_pdu = iscsi_conn_send_pdu, 2008 .send_pdu = iscsi_conn_send_pdu,
@@ -2013,9 +2024,10 @@ iscsi_tcp_init(void)
2013 iscsi_max_lun); 2024 iscsi_max_lun);
2014 return -EINVAL; 2025 return -EINVAL;
2015 } 2026 }
2016 iscsi_tcp_transport.max_lun = iscsi_max_lun;
2017 2027
2018 if (!iscsi_register_transport(&iscsi_tcp_transport)) 2028 iscsi_tcp_scsi_transport = iscsi_register_transport(
2029 &iscsi_tcp_transport);
2030 if (!iscsi_tcp_scsi_transport)
2019 return -ENODEV; 2031 return -ENODEV;
2020 2032
2021 return 0; 2033 return 0;