aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_transport_iscsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi_transport_iscsi.c')
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c104
1 files changed, 87 insertions, 17 deletions
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index f905ecb5704..b4218390941 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -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 */