summaryrefslogtreecommitdiff
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.c51
1 files changed, 40 insertions, 11 deletions
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 0a2ce7b6325..d69a53aa406 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -1268,26 +1268,54 @@ iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev)
return err;
}
+static int iscsi_if_ep_connect(struct iscsi_transport *transport,
+ struct iscsi_uevent *ev, int msg_type)
+{
+ struct iscsi_endpoint *ep;
+ struct sockaddr *dst_addr;
+ struct Scsi_Host *shost = NULL;
+ int non_blocking, err = 0;
+
+ if (!transport->ep_connect)
+ return -EINVAL;
+
+ if (msg_type == ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST) {
+ shost = scsi_host_lookup(ev->u.ep_connect_through_host.host_no);
+ if (!shost) {
+ printk(KERN_ERR "ep connect failed. Could not find "
+ "host no %u\n",
+ ev->u.ep_connect_through_host.host_no);
+ return -ENODEV;
+ }
+ non_blocking = ev->u.ep_connect_through_host.non_blocking;
+ } else
+ non_blocking = ev->u.ep_connect.non_blocking;
+
+ dst_addr = (struct sockaddr *)((char*)ev + sizeof(*ev));
+ ep = transport->ep_connect(shost, dst_addr, non_blocking);
+ if (IS_ERR(ep)) {
+ err = PTR_ERR(ep);
+ goto release_host;
+ }
+
+ ev->r.ep_connect_ret.handle = ep->id;
+release_host:
+ if (shost)
+ scsi_host_put(shost);
+ return err;
+}
+
static int
iscsi_if_transport_ep(struct iscsi_transport *transport,
struct iscsi_uevent *ev, int msg_type)
{
struct iscsi_endpoint *ep;
- struct sockaddr *dst_addr;
int rc = 0;
switch (msg_type) {
+ case ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST:
case ISCSI_UEVENT_TRANSPORT_EP_CONNECT:
- if (!transport->ep_connect)
- return -EINVAL;
-
- dst_addr = (struct sockaddr *)((char*)ev + sizeof(*ev));
- ep = transport->ep_connect(dst_addr,
- ev->u.ep_connect.non_blocking);
- if (IS_ERR(ep))
- return PTR_ERR(ep);
-
- ev->r.ep_connect_ret.handle = ep->id;
+ rc = iscsi_if_ep_connect(transport, ev, msg_type);
break;
case ISCSI_UEVENT_TRANSPORT_EP_POLL:
if (!transport->ep_poll)
@@ -1469,6 +1497,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
case ISCSI_UEVENT_TRANSPORT_EP_CONNECT:
case ISCSI_UEVENT_TRANSPORT_EP_POLL:
case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT:
+ case ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST:
err = iscsi_if_transport_ep(transport, ev, nlh->nlmsg_type);
break;
case ISCSI_UEVENT_TGT_DSCVR: