diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/infiniband/ulp/iser/iscsi_iser.c | 3 | ||||
-rw-r--r-- | drivers/scsi/cxgb3i/cxgb3i.h | 1 | ||||
-rw-r--r-- | drivers/scsi/cxgb3i/cxgb3i_iscsi.c | 25 | ||||
-rw-r--r-- | drivers/scsi/cxgb3i/cxgb3i_offload.c | 23 | ||||
-rw-r--r-- | drivers/scsi/cxgb3i/cxgb3i_offload.h | 3 | ||||
-rw-r--r-- | drivers/scsi/scsi_transport_iscsi.c | 51 |
6 files changed, 79 insertions, 27 deletions
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 75223f50de58..ffbe0c76bc11 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c | |||
@@ -517,7 +517,8 @@ iscsi_iser_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *s | |||
517 | } | 517 | } |
518 | 518 | ||
519 | static struct iscsi_endpoint * | 519 | static struct iscsi_endpoint * |
520 | iscsi_iser_ep_connect(struct sockaddr *dst_addr, int non_blocking) | 520 | iscsi_iser_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, |
521 | int non_blocking) | ||
521 | { | 522 | { |
522 | int err; | 523 | int err; |
523 | struct iser_conn *ib_conn; | 524 | struct iser_conn *ib_conn; |
diff --git a/drivers/scsi/cxgb3i/cxgb3i.h b/drivers/scsi/cxgb3i/cxgb3i.h index 59b0958d2d11..e3133b58e594 100644 --- a/drivers/scsi/cxgb3i/cxgb3i.h +++ b/drivers/scsi/cxgb3i/cxgb3i.h | |||
@@ -144,7 +144,6 @@ struct cxgb3i_adapter *cxgb3i_adapter_find_by_tdev(struct t3cdev *); | |||
144 | void cxgb3i_adapter_open(struct t3cdev *); | 144 | void cxgb3i_adapter_open(struct t3cdev *); |
145 | void cxgb3i_adapter_close(struct t3cdev *); | 145 | void cxgb3i_adapter_close(struct t3cdev *); |
146 | 146 | ||
147 | struct cxgb3i_hba *cxgb3i_hba_find_by_netdev(struct net_device *); | ||
148 | struct cxgb3i_hba *cxgb3i_hba_host_add(struct cxgb3i_adapter *, | 147 | struct cxgb3i_hba *cxgb3i_hba_host_add(struct cxgb3i_adapter *, |
149 | struct net_device *); | 148 | struct net_device *); |
150 | void cxgb3i_hba_host_remove(struct cxgb3i_hba *); | 149 | void cxgb3i_hba_host_remove(struct cxgb3i_hba *); |
diff --git a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c index 9212400b9b13..04a43744aedf 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c +++ b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c | |||
@@ -178,7 +178,7 @@ void cxgb3i_adapter_close(struct t3cdev *t3dev) | |||
178 | * cxgb3i_hba_find_by_netdev - find the cxgb3i_hba structure via net_device | 178 | * cxgb3i_hba_find_by_netdev - find the cxgb3i_hba structure via net_device |
179 | * @t3dev: t3cdev adapter | 179 | * @t3dev: t3cdev adapter |
180 | */ | 180 | */ |
181 | struct cxgb3i_hba *cxgb3i_hba_find_by_netdev(struct net_device *ndev) | 181 | static struct cxgb3i_hba *cxgb3i_hba_find_by_netdev(struct net_device *ndev) |
182 | { | 182 | { |
183 | struct cxgb3i_adapter *snic; | 183 | struct cxgb3i_adapter *snic; |
184 | int i; | 184 | int i; |
@@ -261,20 +261,27 @@ void cxgb3i_hba_host_remove(struct cxgb3i_hba *hba) | |||
261 | 261 | ||
262 | /** | 262 | /** |
263 | * cxgb3i_ep_connect - establish TCP connection to target portal | 263 | * cxgb3i_ep_connect - establish TCP connection to target portal |
264 | * @shost: scsi host to use | ||
264 | * @dst_addr: target IP address | 265 | * @dst_addr: target IP address |
265 | * @non_blocking: blocking or non-blocking call | 266 | * @non_blocking: blocking or non-blocking call |
266 | * | 267 | * |
267 | * Initiates a TCP/IP connection to the dst_addr | 268 | * Initiates a TCP/IP connection to the dst_addr |
268 | */ | 269 | */ |
269 | static struct iscsi_endpoint *cxgb3i_ep_connect(struct sockaddr *dst_addr, | 270 | static struct iscsi_endpoint *cxgb3i_ep_connect(struct Scsi_Host *shost, |
271 | struct sockaddr *dst_addr, | ||
270 | int non_blocking) | 272 | int non_blocking) |
271 | { | 273 | { |
272 | struct iscsi_endpoint *ep; | 274 | struct iscsi_endpoint *ep; |
273 | struct cxgb3i_endpoint *cep; | 275 | struct cxgb3i_endpoint *cep; |
274 | struct cxgb3i_hba *hba; | 276 | struct cxgb3i_hba *hba = NULL; |
275 | struct s3_conn *c3cn = NULL; | 277 | struct s3_conn *c3cn = NULL; |
276 | int err = 0; | 278 | int err = 0; |
277 | 279 | ||
280 | if (shost) | ||
281 | hba = iscsi_host_priv(shost); | ||
282 | |||
283 | cxgb3i_api_debug("shost 0x%p, hba 0x%p.\n", shost, hba); | ||
284 | |||
278 | c3cn = cxgb3i_c3cn_create(); | 285 | c3cn = cxgb3i_c3cn_create(); |
279 | if (!c3cn) { | 286 | if (!c3cn) { |
280 | cxgb3i_log_info("ep connect OOM.\n"); | 287 | cxgb3i_log_info("ep connect OOM.\n"); |
@@ -282,17 +289,27 @@ static struct iscsi_endpoint *cxgb3i_ep_connect(struct sockaddr *dst_addr, | |||
282 | goto release_conn; | 289 | goto release_conn; |
283 | } | 290 | } |
284 | 291 | ||
285 | err = cxgb3i_c3cn_connect(c3cn, (struct sockaddr_in *)dst_addr); | 292 | err = cxgb3i_c3cn_connect(hba ? hba->ndev : NULL, c3cn, |
293 | (struct sockaddr_in *)dst_addr); | ||
286 | if (err < 0) { | 294 | if (err < 0) { |
287 | cxgb3i_log_info("ep connect failed.\n"); | 295 | cxgb3i_log_info("ep connect failed.\n"); |
288 | goto release_conn; | 296 | goto release_conn; |
289 | } | 297 | } |
298 | |||
290 | hba = cxgb3i_hba_find_by_netdev(c3cn->dst_cache->dev); | 299 | hba = cxgb3i_hba_find_by_netdev(c3cn->dst_cache->dev); |
291 | if (!hba) { | 300 | if (!hba) { |
292 | err = -ENOSPC; | 301 | err = -ENOSPC; |
293 | cxgb3i_log_info("NOT going through cxgbi device.\n"); | 302 | cxgb3i_log_info("NOT going through cxgbi device.\n"); |
294 | goto release_conn; | 303 | goto release_conn; |
295 | } | 304 | } |
305 | |||
306 | if (shost && hba != iscsi_host_priv(shost)) { | ||
307 | err = -ENOSPC; | ||
308 | cxgb3i_log_info("Could not connect through request host%u\n", | ||
309 | shost->host_no); | ||
310 | goto release_conn; | ||
311 | } | ||
312 | |||
296 | if (c3cn_is_closing(c3cn)) { | 313 | if (c3cn_is_closing(c3cn)) { |
297 | err = -ENOSPC; | 314 | err = -ENOSPC; |
298 | cxgb3i_log_info("ep connect unable to connect.\n"); | 315 | cxgb3i_log_info("ep connect unable to connect.\n"); |
diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.c b/drivers/scsi/cxgb3i/cxgb3i_offload.c index e11c9c180f39..c1d5be4adf9c 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_offload.c +++ b/drivers/scsi/cxgb3i/cxgb3i_offload.c | |||
@@ -1479,12 +1479,13 @@ static struct net_device *cxgb3_egress_dev(struct net_device *root_dev, | |||
1479 | return NULL; | 1479 | return NULL; |
1480 | } | 1480 | } |
1481 | 1481 | ||
1482 | static struct rtable *find_route(__be32 saddr, __be32 daddr, | 1482 | static struct rtable *find_route(struct net_device *dev, |
1483 | __be32 saddr, __be32 daddr, | ||
1483 | __be16 sport, __be16 dport) | 1484 | __be16 sport, __be16 dport) |
1484 | { | 1485 | { |
1485 | struct rtable *rt; | 1486 | struct rtable *rt; |
1486 | struct flowi fl = { | 1487 | struct flowi fl = { |
1487 | .oif = 0, | 1488 | .oif = dev ? dev->ifindex : 0, |
1488 | .nl_u = { | 1489 | .nl_u = { |
1489 | .ip4_u = { | 1490 | .ip4_u = { |
1490 | .daddr = daddr, | 1491 | .daddr = daddr, |
@@ -1573,36 +1574,40 @@ out_err: | |||
1573 | * | 1574 | * |
1574 | * return 0 if active open request is sent, < 0 otherwise. | 1575 | * return 0 if active open request is sent, < 0 otherwise. |
1575 | */ | 1576 | */ |
1576 | int cxgb3i_c3cn_connect(struct s3_conn *c3cn, struct sockaddr_in *usin) | 1577 | int cxgb3i_c3cn_connect(struct net_device *dev, struct s3_conn *c3cn, |
1578 | struct sockaddr_in *usin) | ||
1577 | { | 1579 | { |
1578 | struct rtable *rt; | 1580 | struct rtable *rt; |
1579 | struct net_device *dev; | ||
1580 | struct cxgb3i_sdev_data *cdata; | 1581 | struct cxgb3i_sdev_data *cdata; |
1581 | struct t3cdev *cdev; | 1582 | struct t3cdev *cdev; |
1582 | __be32 sipv4; | 1583 | __be32 sipv4; |
1583 | int err; | 1584 | int err; |
1584 | 1585 | ||
1586 | c3cn_conn_debug("c3cn 0x%p, dev 0x%p.\n", c3cn, dev); | ||
1587 | |||
1585 | if (usin->sin_family != AF_INET) | 1588 | if (usin->sin_family != AF_INET) |
1586 | return -EAFNOSUPPORT; | 1589 | return -EAFNOSUPPORT; |
1587 | 1590 | ||
1588 | c3cn->daddr.sin_port = usin->sin_port; | 1591 | c3cn->daddr.sin_port = usin->sin_port; |
1589 | c3cn->daddr.sin_addr.s_addr = usin->sin_addr.s_addr; | 1592 | c3cn->daddr.sin_addr.s_addr = usin->sin_addr.s_addr; |
1590 | 1593 | ||
1591 | rt = find_route(c3cn->saddr.sin_addr.s_addr, | 1594 | rt = find_route(dev, c3cn->saddr.sin_addr.s_addr, |
1592 | c3cn->daddr.sin_addr.s_addr, | 1595 | c3cn->daddr.sin_addr.s_addr, |
1593 | c3cn->saddr.sin_port, | 1596 | c3cn->saddr.sin_port, |
1594 | c3cn->daddr.sin_port); | 1597 | c3cn->daddr.sin_port); |
1595 | if (rt == NULL) { | 1598 | if (rt == NULL) { |
1596 | c3cn_conn_debug("NO route to 0x%x, port %u.\n", | 1599 | c3cn_conn_debug("NO route to 0x%x, port %u, dev %s.\n", |
1597 | c3cn->daddr.sin_addr.s_addr, | 1600 | c3cn->daddr.sin_addr.s_addr, |
1598 | ntohs(c3cn->daddr.sin_port)); | 1601 | ntohs(c3cn->daddr.sin_port), |
1602 | dev ? dev->name : "any"); | ||
1599 | return -ENETUNREACH; | 1603 | return -ENETUNREACH; |
1600 | } | 1604 | } |
1601 | 1605 | ||
1602 | if (rt->rt_flags & (RTCF_MULTICAST | RTCF_BROADCAST)) { | 1606 | if (rt->rt_flags & (RTCF_MULTICAST | RTCF_BROADCAST)) { |
1603 | c3cn_conn_debug("multi-cast route to 0x%x, port %u.\n", | 1607 | c3cn_conn_debug("multi-cast route to 0x%x, port %u, dev %s.\n", |
1604 | c3cn->daddr.sin_addr.s_addr, | 1608 | c3cn->daddr.sin_addr.s_addr, |
1605 | ntohs(c3cn->daddr.sin_port)); | 1609 | ntohs(c3cn->daddr.sin_port), |
1610 | dev ? dev->name : "any"); | ||
1606 | ip_rt_put(rt); | 1611 | ip_rt_put(rt); |
1607 | return -ENETUNREACH; | 1612 | return -ENETUNREACH; |
1608 | } | 1613 | } |
diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.h b/drivers/scsi/cxgb3i/cxgb3i_offload.h index ebfca960c0a9..6a1d86b1fafe 100644 --- a/drivers/scsi/cxgb3i/cxgb3i_offload.h +++ b/drivers/scsi/cxgb3i/cxgb3i_offload.h | |||
@@ -169,7 +169,8 @@ void cxgb3i_sdev_add(struct t3cdev *, struct cxgb3_client *); | |||
169 | void cxgb3i_sdev_remove(struct t3cdev *); | 169 | void cxgb3i_sdev_remove(struct t3cdev *); |
170 | 170 | ||
171 | struct s3_conn *cxgb3i_c3cn_create(void); | 171 | struct s3_conn *cxgb3i_c3cn_create(void); |
172 | int cxgb3i_c3cn_connect(struct s3_conn *, struct sockaddr_in *); | 172 | int cxgb3i_c3cn_connect(struct net_device *, struct s3_conn *, |
173 | struct sockaddr_in *); | ||
173 | void cxgb3i_c3cn_rx_credits(struct s3_conn *, int); | 174 | void cxgb3i_c3cn_rx_credits(struct s3_conn *, int); |
174 | int cxgb3i_c3cn_send_pdus(struct s3_conn *, struct sk_buff *); | 175 | int cxgb3i_c3cn_send_pdus(struct s3_conn *, struct sk_buff *); |
175 | void cxgb3i_c3cn_release(struct s3_conn *); | 176 | void cxgb3i_c3cn_release(struct s3_conn *); |
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 0a2ce7b6325c..d69a53aa406f 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) | |||
1268 | return err; | 1268 | return err; |
1269 | } | 1269 | } |
1270 | 1270 | ||
1271 | static int iscsi_if_ep_connect(struct iscsi_transport *transport, | ||
1272 | struct iscsi_uevent *ev, int msg_type) | ||
1273 | { | ||
1274 | struct iscsi_endpoint *ep; | ||
1275 | struct sockaddr *dst_addr; | ||
1276 | struct Scsi_Host *shost = NULL; | ||
1277 | int non_blocking, err = 0; | ||
1278 | |||
1279 | if (!transport->ep_connect) | ||
1280 | return -EINVAL; | ||
1281 | |||
1282 | if (msg_type == ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST) { | ||
1283 | shost = scsi_host_lookup(ev->u.ep_connect_through_host.host_no); | ||
1284 | if (!shost) { | ||
1285 | printk(KERN_ERR "ep connect failed. Could not find " | ||
1286 | "host no %u\n", | ||
1287 | ev->u.ep_connect_through_host.host_no); | ||
1288 | return -ENODEV; | ||
1289 | } | ||
1290 | non_blocking = ev->u.ep_connect_through_host.non_blocking; | ||
1291 | } else | ||
1292 | non_blocking = ev->u.ep_connect.non_blocking; | ||
1293 | |||
1294 | dst_addr = (struct sockaddr *)((char*)ev + sizeof(*ev)); | ||
1295 | ep = transport->ep_connect(shost, dst_addr, non_blocking); | ||
1296 | if (IS_ERR(ep)) { | ||
1297 | err = PTR_ERR(ep); | ||
1298 | goto release_host; | ||
1299 | } | ||
1300 | |||
1301 | ev->r.ep_connect_ret.handle = ep->id; | ||
1302 | release_host: | ||
1303 | if (shost) | ||
1304 | scsi_host_put(shost); | ||
1305 | return err; | ||
1306 | } | ||
1307 | |||
1271 | static int | 1308 | static int |
1272 | iscsi_if_transport_ep(struct iscsi_transport *transport, | 1309 | iscsi_if_transport_ep(struct iscsi_transport *transport, |
1273 | struct iscsi_uevent *ev, int msg_type) | 1310 | struct iscsi_uevent *ev, int msg_type) |
1274 | { | 1311 | { |
1275 | struct iscsi_endpoint *ep; | 1312 | struct iscsi_endpoint *ep; |
1276 | struct sockaddr *dst_addr; | ||
1277 | int rc = 0; | 1313 | int rc = 0; |
1278 | 1314 | ||
1279 | switch (msg_type) { | 1315 | switch (msg_type) { |
1316 | case ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST: | ||
1280 | case ISCSI_UEVENT_TRANSPORT_EP_CONNECT: | 1317 | case ISCSI_UEVENT_TRANSPORT_EP_CONNECT: |
1281 | if (!transport->ep_connect) | 1318 | rc = iscsi_if_ep_connect(transport, ev, msg_type); |
1282 | return -EINVAL; | ||
1283 | |||
1284 | dst_addr = (struct sockaddr *)((char*)ev + sizeof(*ev)); | ||
1285 | ep = transport->ep_connect(dst_addr, | ||
1286 | ev->u.ep_connect.non_blocking); | ||
1287 | if (IS_ERR(ep)) | ||
1288 | return PTR_ERR(ep); | ||
1289 | |||
1290 | ev->r.ep_connect_ret.handle = ep->id; | ||
1291 | break; | 1319 | break; |
1292 | case ISCSI_UEVENT_TRANSPORT_EP_POLL: | 1320 | case ISCSI_UEVENT_TRANSPORT_EP_POLL: |
1293 | if (!transport->ep_poll) | 1321 | if (!transport->ep_poll) |
@@ -1469,6 +1497,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
1469 | case ISCSI_UEVENT_TRANSPORT_EP_CONNECT: | 1497 | case ISCSI_UEVENT_TRANSPORT_EP_CONNECT: |
1470 | case ISCSI_UEVENT_TRANSPORT_EP_POLL: | 1498 | case ISCSI_UEVENT_TRANSPORT_EP_POLL: |
1471 | case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT: | 1499 | case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT: |
1500 | case ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST: | ||
1472 | err = iscsi_if_transport_ep(transport, ev, nlh->nlmsg_type); | 1501 | err = iscsi_if_transport_ep(transport, ev, nlh->nlmsg_type); |
1473 | break; | 1502 | break; |
1474 | case ISCSI_UEVENT_TGT_DSCVR: | 1503 | case ISCSI_UEVENT_TGT_DSCVR: |