diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2008-05-21 16:54:14 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-07-12 09:22:21 -0400 |
commit | 412eeafa0a51a8d86545d0be637bf84e4374fccf (patch) | |
tree | 70d2e9b274513953fd5df036474c9ae520d6843b /drivers/infiniband | |
parent | d82ff9be733a2e6da4f6c2ab4e9216f3f536503d (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>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/ulp/iser/iscsi_iser.c | 87 | ||||
-rw-r--r-- | drivers/infiniband/ulp/iser/iscsi_iser.h | 4 | ||||
-rw-r--r-- | drivers/infiniband/ulp/iser/iser_verbs.c | 14 |
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 | ||
265 | static struct iser_conn * | ||
266 | iscsi_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 | |||
283 | static struct iscsi_cls_conn * | 265 | static struct iscsi_cls_conn * |
284 | iscsi_iser_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx) | 266 | iscsi_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 | ||
403 | static struct iscsi_cls_session * | 388 | static struct iscsi_cls_session * |
404 | iscsi_iser_session_create(struct Scsi_Host *shost, | 389 | iscsi_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 | ||
532 | static int | 521 | static struct iscsi_endpoint * |
533 | iscsi_iser_ep_connect(struct sockaddr *dst_addr, int non_blocking, | 522 | iscsi_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 | ||
547 | out: | 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 | ||
551 | static int | 545 | static int |
552 | iscsi_iser_ep_poll(__u64 ep_handle, int timeout_ms) | 546 | iscsi_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 | ||
580 | static void | 572 | static void |
581 | iscsi_iser_ep_disconnect(__u64 ep_handle) | 573 | iscsi_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 { | |||
174 | struct iser_device; | 174 | struct iser_device; |
175 | struct iscsi_iser_conn; | 175 | struct iscsi_iser_conn; |
176 | struct iscsi_iser_task; | 176 | struct iscsi_iser_task; |
177 | struct iscsi_endpoint; | ||
177 | 178 | ||
178 | struct iser_mem_reg { | 179 | struct iser_mem_reg { |
179 | u32 lkey; | 180 | u32 lkey; |
@@ -241,6 +242,7 @@ struct iser_device { | |||
241 | 242 | ||
242 | struct iser_conn { | 243 | struct 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 | ||
316 | int iser_conn_init(struct iser_conn **ib_conn); | 318 | void iser_conn_init(struct iser_conn *ib_conn); |
317 | 319 | ||
318 | void iser_conn_get(struct iser_conn *ib_conn); | 320 | void 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 | ||
331 | void iser_conn_get(struct iser_conn *ib_conn) | 331 | void 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 | ||
497 | int iser_conn_init(struct iser_conn **ibconn) | 497 | void 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 | /** |