diff options
Diffstat (limited to 'drivers/scsi/scsi_transport_iscsi.c')
-rw-r--r-- | drivers/scsi/scsi_transport_iscsi.c | 63 |
1 files changed, 50 insertions, 13 deletions
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index f905ecb5704d..4e09b68a0789 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; |
@@ -1430,6 +1431,29 @@ release_host: | |||
1430 | return err; | 1431 | return err; |
1431 | } | 1432 | } |
1432 | 1433 | ||
1434 | static int iscsi_if_ep_disconnect(struct iscsi_transport *transport, | ||
1435 | u64 ep_handle) | ||
1436 | { | ||
1437 | struct iscsi_cls_conn *conn; | ||
1438 | struct iscsi_endpoint *ep; | ||
1439 | |||
1440 | if (!transport->ep_disconnect) | ||
1441 | return -EINVAL; | ||
1442 | |||
1443 | ep = iscsi_lookup_endpoint(ep_handle); | ||
1444 | if (!ep) | ||
1445 | return -EINVAL; | ||
1446 | conn = ep->conn; | ||
1447 | if (conn) { | ||
1448 | mutex_lock(&conn->ep_mutex); | ||
1449 | conn->ep = NULL; | ||
1450 | mutex_unlock(&conn->ep_mutex); | ||
1451 | } | ||
1452 | |||
1453 | transport->ep_disconnect(ep); | ||
1454 | return 0; | ||
1455 | } | ||
1456 | |||
1433 | static int | 1457 | static int |
1434 | iscsi_if_transport_ep(struct iscsi_transport *transport, | 1458 | iscsi_if_transport_ep(struct iscsi_transport *transport, |
1435 | struct iscsi_uevent *ev, int msg_type) | 1459 | struct iscsi_uevent *ev, int msg_type) |
@@ -1454,14 +1478,8 @@ iscsi_if_transport_ep(struct iscsi_transport *transport, | |||
1454 | ev->u.ep_poll.timeout_ms); | 1478 | ev->u.ep_poll.timeout_ms); |
1455 | break; | 1479 | break; |
1456 | case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT: | 1480 | case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT: |
1457 | if (!transport->ep_disconnect) | 1481 | rc = iscsi_if_ep_disconnect(transport, |
1458 | return -EINVAL; | 1482 | 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; | 1483 | break; |
1466 | } | 1484 | } |
1467 | return rc; | 1485 | return rc; |
@@ -1609,12 +1627,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); | 1627 | session = iscsi_session_lookup(ev->u.b_conn.sid); |
1610 | conn = iscsi_conn_lookup(ev->u.b_conn.sid, ev->u.b_conn.cid); | 1628 | conn = iscsi_conn_lookup(ev->u.b_conn.sid, ev->u.b_conn.cid); |
1611 | 1629 | ||
1612 | if (session && conn) | 1630 | if (conn && conn->ep) |
1613 | ev->r.retcode = transport->bind_conn(session, conn, | 1631 | iscsi_if_ep_disconnect(transport, conn->ep->id); |
1614 | ev->u.b_conn.transport_eph, | 1632 | |
1615 | ev->u.b_conn.is_leading); | 1633 | if (!session || !conn) { |
1616 | else | ||
1617 | err = -EINVAL; | 1634 | err = -EINVAL; |
1635 | break; | ||
1636 | } | ||
1637 | |||
1638 | ev->r.retcode = transport->bind_conn(session, conn, | ||
1639 | ev->u.b_conn.transport_eph, | ||
1640 | ev->u.b_conn.is_leading); | ||
1641 | if (ev->r.retcode || !transport->ep_connect) | ||
1642 | break; | ||
1643 | |||
1644 | ep = iscsi_lookup_endpoint(ev->u.b_conn.transport_eph); | ||
1645 | if (ep) { | ||
1646 | ep->conn = conn; | ||
1647 | |||
1648 | mutex_lock(&conn->ep_mutex); | ||
1649 | conn->ep = ep; | ||
1650 | mutex_unlock(&conn->ep_mutex); | ||
1651 | } else | ||
1652 | iscsi_cls_conn_printk(KERN_ERR, conn, | ||
1653 | "Could not set ep conn " | ||
1654 | "binding\n"); | ||
1618 | break; | 1655 | break; |
1619 | case ISCSI_UEVENT_SET_PARAM: | 1656 | case ISCSI_UEVENT_SET_PARAM: |
1620 | err = iscsi_set_param(transport, ev); | 1657 | err = iscsi_set_param(transport, ev); |