aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_transport_iscsi.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/scsi/scsi_transport_iscsi.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/scsi/scsi_transport_iscsi.c')
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c109
1 files changed, 90 insertions, 19 deletions
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index e84026def1f4..3fd16d7212de 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -537,7 +537,7 @@ static void iscsi_scan_session(struct work_struct *work)
537 537
538/** 538/**
539 * iscsi_block_scsi_eh - block scsi eh until session state has transistioned 539 * iscsi_block_scsi_eh - block scsi eh until session state has transistioned
540 * cmd: scsi cmd passed to scsi eh handler 540 * @cmd: scsi cmd passed to scsi eh handler
541 * 541 *
542 * If the session is down this function will wait for the recovery 542 * If the session is down this function will wait for the recovery
543 * timer to fire or for the session to be logged back in. If the 543 * timer to fire or for the session to be logged back in. If the
@@ -954,6 +954,7 @@ iscsi_create_conn(struct iscsi_cls_session *session, int dd_size, uint32_t cid)
954 if (dd_size) 954 if (dd_size)
955 conn->dd_data = &conn[1]; 955 conn->dd_data = &conn[1];
956 956
957 mutex_init(&conn->ep_mutex);
957 INIT_LIST_HEAD(&conn->conn_list); 958 INIT_LIST_HEAD(&conn->conn_list);
958 conn->transport = transport; 959 conn->transport = transport;
959 conn->cid = cid; 960 conn->cid = cid;
@@ -975,7 +976,6 @@ iscsi_create_conn(struct iscsi_cls_session *session, int dd_size, uint32_t cid)
975 976
976 spin_lock_irqsave(&connlock, flags); 977 spin_lock_irqsave(&connlock, flags);
977 list_add(&conn->conn_list, &connlist); 978 list_add(&conn->conn_list, &connlist);
978 conn->active = 1;
979 spin_unlock_irqrestore(&connlock, flags); 979 spin_unlock_irqrestore(&connlock, flags);
980 980
981 ISCSI_DBG_TRANS_CONN(conn, "Completed conn creation\n"); 981 ISCSI_DBG_TRANS_CONN(conn, "Completed conn creation\n");
@@ -1001,7 +1001,6 @@ int iscsi_destroy_conn(struct iscsi_cls_conn *conn)
1001 unsigned long flags; 1001 unsigned long flags;
1002 1002
1003 spin_lock_irqsave(&connlock, flags); 1003 spin_lock_irqsave(&connlock, flags);
1004 conn->active = 0;
1005 list_del(&conn->conn_list); 1004 list_del(&conn->conn_list);
1006 spin_unlock_irqrestore(&connlock, flags); 1005 spin_unlock_irqrestore(&connlock, flags);
1007 1006
@@ -1430,6 +1429,29 @@ release_host:
1430 return err; 1429 return err;
1431} 1430}
1432 1431
1432static int iscsi_if_ep_disconnect(struct iscsi_transport *transport,
1433 u64 ep_handle)
1434{
1435 struct iscsi_cls_conn *conn;
1436 struct iscsi_endpoint *ep;
1437
1438 if (!transport->ep_disconnect)
1439 return -EINVAL;
1440
1441 ep = iscsi_lookup_endpoint(ep_handle);
1442 if (!ep)
1443 return -EINVAL;
1444 conn = ep->conn;
1445 if (conn) {
1446 mutex_lock(&conn->ep_mutex);
1447 conn->ep = NULL;
1448 mutex_unlock(&conn->ep_mutex);
1449 }
1450
1451 transport->ep_disconnect(ep);
1452 return 0;
1453}
1454
1433static int 1455static int
1434iscsi_if_transport_ep(struct iscsi_transport *transport, 1456iscsi_if_transport_ep(struct iscsi_transport *transport,
1435 struct iscsi_uevent *ev, int msg_type) 1457 struct iscsi_uevent *ev, int msg_type)
@@ -1454,14 +1476,8 @@ iscsi_if_transport_ep(struct iscsi_transport *transport,
1454 ev->u.ep_poll.timeout_ms); 1476 ev->u.ep_poll.timeout_ms);
1455 break; 1477 break;
1456 case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT: 1478 case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT:
1457 if (!transport->ep_disconnect) 1479 rc = iscsi_if_ep_disconnect(transport,
1458 return -EINVAL; 1480 ev->u.ep_disconnect.ep_handle);
1459
1460 ep = iscsi_lookup_endpoint(ev->u.ep_disconnect.ep_handle);
1461 if (!ep)
1462 return -EINVAL;
1463
1464 transport->ep_disconnect(ep);
1465 break; 1481 break;
1466 } 1482 }
1467 return rc; 1483 return rc;
@@ -1609,12 +1625,31 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group)
1609 session = iscsi_session_lookup(ev->u.b_conn.sid); 1625 session = iscsi_session_lookup(ev->u.b_conn.sid);
1610 conn = iscsi_conn_lookup(ev->u.b_conn.sid, ev->u.b_conn.cid); 1626 conn = iscsi_conn_lookup(ev->u.b_conn.sid, ev->u.b_conn.cid);
1611 1627
1612 if (session && conn) 1628 if (conn && conn->ep)
1613 ev->r.retcode = transport->bind_conn(session, conn, 1629 iscsi_if_ep_disconnect(transport, conn->ep->id);
1614 ev->u.b_conn.transport_eph, 1630
1615 ev->u.b_conn.is_leading); 1631 if (!session || !conn) {
1616 else
1617 err = -EINVAL; 1632 err = -EINVAL;
1633 break;
1634 }
1635
1636 ev->r.retcode = transport->bind_conn(session, conn,
1637 ev->u.b_conn.transport_eph,
1638 ev->u.b_conn.is_leading);
1639 if (ev->r.retcode || !transport->ep_connect)
1640 break;
1641
1642 ep = iscsi_lookup_endpoint(ev->u.b_conn.transport_eph);
1643 if (ep) {
1644 ep->conn = conn;
1645
1646 mutex_lock(&conn->ep_mutex);
1647 conn->ep = ep;
1648 mutex_unlock(&conn->ep_mutex);
1649 } else
1650 iscsi_cls_conn_printk(KERN_ERR, conn,
1651 "Could not set ep conn "
1652 "binding\n");
1618 break; 1653 break;
1619 case ISCSI_UEVENT_SET_PARAM: 1654 case ISCSI_UEVENT_SET_PARAM:
1620 err = iscsi_set_param(transport, ev); 1655 err = iscsi_set_param(transport, ev);
@@ -1747,13 +1782,48 @@ iscsi_conn_attr(data_digest, ISCSI_PARAM_DATADGST_EN);
1747iscsi_conn_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN); 1782iscsi_conn_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN);
1748iscsi_conn_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN); 1783iscsi_conn_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN);
1749iscsi_conn_attr(persistent_port, ISCSI_PARAM_PERSISTENT_PORT); 1784iscsi_conn_attr(persistent_port, ISCSI_PARAM_PERSISTENT_PORT);
1750iscsi_conn_attr(port, ISCSI_PARAM_CONN_PORT);
1751iscsi_conn_attr(exp_statsn, ISCSI_PARAM_EXP_STATSN); 1785iscsi_conn_attr(exp_statsn, ISCSI_PARAM_EXP_STATSN);
1752iscsi_conn_attr(persistent_address, ISCSI_PARAM_PERSISTENT_ADDRESS); 1786iscsi_conn_attr(persistent_address, ISCSI_PARAM_PERSISTENT_ADDRESS);
1753iscsi_conn_attr(address, ISCSI_PARAM_CONN_ADDRESS);
1754iscsi_conn_attr(ping_tmo, ISCSI_PARAM_PING_TMO); 1787iscsi_conn_attr(ping_tmo, ISCSI_PARAM_PING_TMO);
1755iscsi_conn_attr(recv_tmo, ISCSI_PARAM_RECV_TMO); 1788iscsi_conn_attr(recv_tmo, ISCSI_PARAM_RECV_TMO);
1756 1789
1790#define iscsi_conn_ep_attr_show(param) \
1791static ssize_t show_conn_ep_param_##param(struct device *dev, \
1792 struct device_attribute *attr,\
1793 char *buf) \
1794{ \
1795 struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev->parent); \
1796 struct iscsi_transport *t = conn->transport; \
1797 struct iscsi_endpoint *ep; \
1798 ssize_t rc; \
1799 \
1800 /* \
1801 * Need to make sure ep_disconnect does not free the LLD's \
1802 * interconnect resources while we are trying to read them. \
1803 */ \
1804 mutex_lock(&conn->ep_mutex); \
1805 ep = conn->ep; \
1806 if (!ep && t->ep_connect) { \
1807 mutex_unlock(&conn->ep_mutex); \
1808 return -ENOTCONN; \
1809 } \
1810 \
1811 if (ep) \
1812 rc = t->get_ep_param(ep, param, buf); \
1813 else \
1814 rc = t->get_conn_param(conn, param, buf); \
1815 mutex_unlock(&conn->ep_mutex); \
1816 return rc; \
1817}
1818
1819#define iscsi_conn_ep_attr(field, param) \
1820 iscsi_conn_ep_attr_show(param) \
1821static ISCSI_CLASS_ATTR(conn, field, S_IRUGO, \
1822 show_conn_ep_param_##param, NULL);
1823
1824iscsi_conn_ep_attr(address, ISCSI_PARAM_CONN_ADDRESS);
1825iscsi_conn_ep_attr(port, ISCSI_PARAM_CONN_PORT);
1826
1757/* 1827/*
1758 * iSCSI session attrs 1828 * iSCSI session attrs
1759 */ 1829 */
@@ -1847,7 +1917,7 @@ store_priv_session_##field(struct device *dev, \
1847#define iscsi_priv_session_rw_attr(field, format) \ 1917#define iscsi_priv_session_rw_attr(field, format) \
1848 iscsi_priv_session_attr_show(field, format) \ 1918 iscsi_priv_session_attr_show(field, format) \
1849 iscsi_priv_session_attr_store(field) \ 1919 iscsi_priv_session_attr_store(field) \
1850static ISCSI_CLASS_ATTR(priv_sess, field, S_IRUGO | S_IWUGO, \ 1920static ISCSI_CLASS_ATTR(priv_sess, field, S_IRUGO | S_IWUSR, \
1851 show_priv_session_##field, \ 1921 show_priv_session_##field, \
1852 store_priv_session_##field) 1922 store_priv_session_##field)
1853iscsi_priv_session_rw_attr(recovery_tmo, "%d"); 1923iscsi_priv_session_rw_attr(recovery_tmo, "%d");
@@ -2200,3 +2270,4 @@ MODULE_AUTHOR("Mike Christie <michaelc@cs.wisc.edu>, "
2200MODULE_DESCRIPTION("iSCSI Transport Interface"); 2270MODULE_DESCRIPTION("iSCSI Transport Interface");
2201MODULE_LICENSE("GPL"); 2271MODULE_LICENSE("GPL");
2202MODULE_VERSION(ISCSI_TRANSPORT_VERSION); 2272MODULE_VERSION(ISCSI_TRANSPORT_VERSION);
2273MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_ISCSI);