aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2008-05-21 16:54:14 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-07-12 09:22:21 -0400
commit412eeafa0a51a8d86545d0be637bf84e4374fccf (patch)
tree70d2e9b274513953fd5df036474c9ae520d6843b
parentd82ff9be733a2e6da4f6c2ab4e9216f3f536503d (diff)
[SCSI] iser: Modify iser to take a iscsi_endpoint struct in ep callouts and session setup
This hooks iser into the iscsi endpoint code. Previously it handled the lookup and allocation. This has been made generic so bnx2i and iser can share it. It also allows us to pass iser the leading conn's ep, so we know the ib_deivce being used and can set it as the scsi_host's parent. And that allows scsi-ml to set the dma_mask based on those values. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-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 /**