aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.c87
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.h4
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c14
3 files changed, 43 insertions, 62 deletions
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index 3a89039e9a96..42e95b833092 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -262,24 +262,6 @@ iscsi_iser_cleanup_task(struct iscsi_conn *conn, struct iscsi_task *task)
262 } 262 }
263} 263}
264 264
265static struct iser_conn *
266iscsi_iser_ib_conn_lookup(__u64 ep_handle)
267{
268 struct iser_conn *ib_conn;
269 struct iser_conn *uib_conn = (struct iser_conn *)(unsigned long)ep_handle;
270
271 mutex_lock(&ig.connlist_mutex);
272 list_for_each_entry(ib_conn, &ig.connlist, conn_list) {
273 if (ib_conn == uib_conn) {
274 mutex_unlock(&ig.connlist_mutex);
275 return ib_conn;
276 }
277 }
278 mutex_unlock(&ig.connlist_mutex);
279 iser_err("no conn exists for eph %llx\n",(unsigned long long)ep_handle);
280 return NULL;
281}
282
283static struct iscsi_cls_conn * 265static struct iscsi_cls_conn *
284iscsi_iser_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx) 266iscsi_iser_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx)
285{ 267{
@@ -335,6 +317,7 @@ iscsi_iser_conn_bind(struct iscsi_cls_session *cls_session,
335 struct iscsi_conn *conn = cls_conn->dd_data; 317 struct iscsi_conn *conn = cls_conn->dd_data;
336 struct iscsi_iser_conn *iser_conn; 318 struct iscsi_iser_conn *iser_conn;
337 struct iser_conn *ib_conn; 319 struct iser_conn *ib_conn;
320 struct iscsi_endpoint *ep;
338 int error; 321 int error;
339 322
340 error = iscsi_conn_bind(cls_session, cls_conn, is_leading); 323 error = iscsi_conn_bind(cls_session, cls_conn, is_leading);
@@ -343,12 +326,14 @@ iscsi_iser_conn_bind(struct iscsi_cls_session *cls_session,
343 326
344 /* the transport ep handle comes from user space so it must be 327 /* the transport ep handle comes from user space so it must be
345 * verified against the global ib connections list */ 328 * verified against the global ib connections list */
346 ib_conn = iscsi_iser_ib_conn_lookup(transport_eph); 329 ep = iscsi_lookup_endpoint(transport_eph);
347 if (!ib_conn) { 330 if (!ep) {
348 iser_err("can't bind eph %llx\n", 331 iser_err("can't bind eph %llx\n",
349 (unsigned long long)transport_eph); 332 (unsigned long long)transport_eph);
350 return -EINVAL; 333 return -EINVAL;
351 } 334 }
335 ib_conn = ep->dd_data;
336
352 /* binds the iSER connection retrieved from the previously 337 /* binds the iSER connection retrieved from the previously
353 * connected ep_handle to the iSCSI layer connection. exchanges 338 * connected ep_handle to the iSCSI layer connection. exchanges
354 * connection pointers */ 339 * connection pointers */
@@ -401,21 +386,17 @@ static void iscsi_iser_session_destroy(struct iscsi_cls_session *cls_session)
401} 386}
402 387
403static struct iscsi_cls_session * 388static struct iscsi_cls_session *
404iscsi_iser_session_create(struct Scsi_Host *shost, 389iscsi_iser_session_create(struct iscsi_endpoint *ep,
405 uint16_t cmds_max, uint16_t qdepth, 390 uint16_t cmds_max, uint16_t qdepth,
406 uint32_t initial_cmdsn, uint32_t *hostno) 391 uint32_t initial_cmdsn, uint32_t *hostno)
407{ 392{
408 struct iscsi_cls_session *cls_session; 393 struct iscsi_cls_session *cls_session;
409 struct iscsi_session *session; 394 struct iscsi_session *session;
395 struct Scsi_Host *shost;
410 int i; 396 int i;
411 struct iscsi_task *task; 397 struct iscsi_task *task;
412 struct iscsi_iser_task *iser_task; 398 struct iscsi_iser_task *iser_task;
413 399 struct iser_conn *ib_conn;
414 if (shost) {
415 printk(KERN_ERR "iscsi_tcp: invalid shost %d.\n",
416 shost->host_no);
417 return NULL;
418 }
419 400
420 shost = iscsi_host_alloc(&iscsi_iser_sht, 0, ISCSI_MAX_CMD_PER_LUN); 401 shost = iscsi_host_alloc(&iscsi_iser_sht, 0, ISCSI_MAX_CMD_PER_LUN);
421 if (!shost) 402 if (!shost)
@@ -426,7 +407,15 @@ iscsi_iser_session_create(struct Scsi_Host *shost,
426 shost->max_channel = 0; 407 shost->max_channel = 0;
427 shost->max_cmd_len = 16; 408 shost->max_cmd_len = 16;
428 409
429 if (iscsi_host_add(shost, NULL)) 410 /*
411 * older userspace tools (before 2.0-870) did not pass us
412 * the leading conn's ep so this will be NULL;
413 */
414 if (ep)
415 ib_conn = ep->dd_data;
416
417 if (iscsi_host_add(shost,
418 ep ? ib_conn->device->ib_device->dma_device : NULL))
430 goto free_host; 419 goto free_host;
431 *hostno = shost->host_no; 420 *hostno = shost->host_no;
432 421
@@ -529,34 +518,37 @@ iscsi_iser_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *s
529 stats->custom[3].value = conn->fmr_unalign_cnt; 518 stats->custom[3].value = conn->fmr_unalign_cnt;
530} 519}
531 520
532static int 521static struct iscsi_endpoint *
533iscsi_iser_ep_connect(struct sockaddr *dst_addr, int non_blocking, 522iscsi_iser_ep_connect(struct sockaddr *dst_addr, int non_blocking)
534 __u64 *ep_handle)
535{ 523{
536 int err; 524 int err;
537 struct iser_conn *ib_conn; 525 struct iser_conn *ib_conn;
526 struct iscsi_endpoint *ep;
538 527
539 err = iser_conn_init(&ib_conn); 528 ep = iscsi_create_endpoint(sizeof(*ib_conn));
540 if (err) 529 if (!ep)
541 goto out; 530 return ERR_PTR(-ENOMEM);
542 531
543 err = iser_connect(ib_conn, NULL, (struct sockaddr_in *)dst_addr, non_blocking); 532 ib_conn = ep->dd_data;
544 if (!err) 533 ib_conn->ep = ep;
545 *ep_handle = (__u64)(unsigned long)ib_conn; 534 iser_conn_init(ib_conn);
546 535
547out: 536 err = iser_connect(ib_conn, NULL, (struct sockaddr_in *)dst_addr,
548 return err; 537 non_blocking);
538 if (err) {
539 iscsi_destroy_endpoint(ep);
540 return ERR_PTR(err);
541 }
542 return ep;
549} 543}
550 544
551static int 545static int
552iscsi_iser_ep_poll(__u64 ep_handle, int timeout_ms) 546iscsi_iser_ep_poll(struct iscsi_endpoint *ep, int timeout_ms)
553{ 547{
554 struct iser_conn *ib_conn = iscsi_iser_ib_conn_lookup(ep_handle); 548 struct iser_conn *ib_conn;
555 int rc; 549 int rc;
556 550
557 if (!ib_conn) 551 ib_conn = ep->dd_data;
558 return -EINVAL;
559
560 rc = wait_event_interruptible_timeout(ib_conn->wait, 552 rc = wait_event_interruptible_timeout(ib_conn->wait,
561 ib_conn->state == ISER_CONN_UP, 553 ib_conn->state == ISER_CONN_UP,
562 msecs_to_jiffies(timeout_ms)); 554 msecs_to_jiffies(timeout_ms));
@@ -578,14 +570,11 @@ iscsi_iser_ep_poll(__u64 ep_handle, int timeout_ms)
578} 570}
579 571
580static void 572static void
581iscsi_iser_ep_disconnect(__u64 ep_handle) 573iscsi_iser_ep_disconnect(struct iscsi_endpoint *ep)
582{ 574{
583 struct iser_conn *ib_conn; 575 struct iser_conn *ib_conn;
584 576
585 ib_conn = iscsi_iser_ib_conn_lookup(ep_handle); 577 ib_conn = ep->dd_data;
586 if (!ib_conn)
587 return;
588
589 if (ib_conn->iser_conn) 578 if (ib_conn->iser_conn)
590 /* 579 /*
591 * Must suspend xmit path if the ep is bound to the 580 * Must suspend xmit path if the ep is bound to the
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h
index 05431f270fe8..cdf48763b082 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.h
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.h
@@ -174,6 +174,7 @@ struct iser_data_buf {
174struct iser_device; 174struct iser_device;
175struct iscsi_iser_conn; 175struct iscsi_iser_conn;
176struct iscsi_iser_task; 176struct iscsi_iser_task;
177struct iscsi_endpoint;
177 178
178struct iser_mem_reg { 179struct iser_mem_reg {
179 u32 lkey; 180 u32 lkey;
@@ -241,6 +242,7 @@ struct iser_device {
241 242
242struct iser_conn { 243struct iser_conn {
243 struct iscsi_iser_conn *iser_conn; /* iser conn for upcalls */ 244 struct iscsi_iser_conn *iser_conn; /* iser conn for upcalls */
245 struct iscsi_endpoint *ep;
244 enum iser_ib_conn_state state; /* rdma connection state */ 246 enum iser_ib_conn_state state; /* rdma connection state */
245 atomic_t refcount; 247 atomic_t refcount;
246 spinlock_t lock; /* used for state changes */ 248 spinlock_t lock; /* used for state changes */
@@ -313,7 +315,7 @@ void iscsi_iser_recv(struct iscsi_conn *conn,
313 char *rx_data, 315 char *rx_data,
314 int rx_data_len); 316 int rx_data_len);
315 317
316int iser_conn_init(struct iser_conn **ib_conn); 318void iser_conn_init(struct iser_conn *ib_conn);
317 319
318void iser_conn_get(struct iser_conn *ib_conn); 320void iser_conn_get(struct iser_conn *ib_conn);
319 321
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index 5daed2bd710e..81b45d4d9aa9 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -325,7 +325,7 @@ static void iser_conn_release(struct iser_conn *ib_conn)
325 iser_device_try_release(device); 325 iser_device_try_release(device);
326 if (ib_conn->iser_conn) 326 if (ib_conn->iser_conn)
327 ib_conn->iser_conn->ib_conn = NULL; 327 ib_conn->iser_conn->ib_conn = NULL;
328 kfree(ib_conn); 328 iscsi_destroy_endpoint(ib_conn->ep);
329} 329}
330 330
331void iser_conn_get(struct iser_conn *ib_conn) 331void iser_conn_get(struct iser_conn *ib_conn)
@@ -494,15 +494,8 @@ static int iser_cma_handler(struct rdma_cm_id *cma_id, struct rdma_cm_event *eve
494 return ret; 494 return ret;
495} 495}
496 496
497int iser_conn_init(struct iser_conn **ibconn) 497void iser_conn_init(struct iser_conn *ib_conn)
498{ 498{
499 struct iser_conn *ib_conn;
500
501 ib_conn = kzalloc(sizeof *ib_conn, GFP_KERNEL);
502 if (!ib_conn) {
503 iser_err("can't alloc memory for struct iser_conn\n");
504 return -ENOMEM;
505 }
506 ib_conn->state = ISER_CONN_INIT; 499 ib_conn->state = ISER_CONN_INIT;
507 init_waitqueue_head(&ib_conn->wait); 500 init_waitqueue_head(&ib_conn->wait);
508 atomic_set(&ib_conn->post_recv_buf_count, 0); 501 atomic_set(&ib_conn->post_recv_buf_count, 0);
@@ -510,9 +503,6 @@ int iser_conn_init(struct iser_conn **ibconn)
510 atomic_set(&ib_conn->refcount, 1); 503 atomic_set(&ib_conn->refcount, 1);
511 INIT_LIST_HEAD(&ib_conn->conn_list); 504 INIT_LIST_HEAD(&ib_conn->conn_list);
512 spin_lock_init(&ib_conn->lock); 505 spin_lock_init(&ib_conn->lock);
513
514 *ibconn = ib_conn;
515 return 0;
516} 506}
517 507
518 /** 508 /**