diff options
Diffstat (limited to 'drivers/infiniband/ulp/iser/iscsi_iser.c')
-rw-r--r-- | drivers/infiniband/ulp/iser/iscsi_iser.c | 74 |
1 files changed, 54 insertions, 20 deletions
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index 32f5d5e79abf..5a750042e2b2 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c | |||
@@ -74,6 +74,10 @@ | |||
74 | 74 | ||
75 | #include "iscsi_iser.h" | 75 | #include "iscsi_iser.h" |
76 | 76 | ||
77 | static struct scsi_host_template iscsi_iser_sht; | ||
78 | static struct iscsi_transport iscsi_iser_transport; | ||
79 | static struct scsi_transport_template *iscsi_iser_scsi_transport; | ||
80 | |||
77 | static unsigned int iscsi_max_lun = 512; | 81 | static unsigned int iscsi_max_lun = 512; |
78 | module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO); | 82 | module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO); |
79 | 83 | ||
@@ -363,40 +367,64 @@ iscsi_iser_conn_start(struct iscsi_cls_conn *cls_conn) | |||
363 | return iscsi_conn_start(cls_conn); | 367 | return iscsi_conn_start(cls_conn); |
364 | } | 368 | } |
365 | 369 | ||
366 | static struct iscsi_transport iscsi_iser_transport; | 370 | static void iscsi_iser_session_destroy(struct iscsi_cls_session *cls_session) |
371 | { | ||
372 | struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); | ||
373 | |||
374 | iscsi_session_teardown(cls_session); | ||
375 | scsi_remove_host(shost); | ||
376 | iscsi_host_teardown(shost); | ||
377 | scsi_host_put(shost); | ||
378 | } | ||
367 | 379 | ||
368 | static struct iscsi_cls_session * | 380 | static struct iscsi_cls_session * |
369 | iscsi_iser_session_create(struct iscsi_transport *iscsit, | 381 | iscsi_iser_session_create(struct Scsi_Host *shost, |
370 | struct scsi_transport_template *scsit, | 382 | uint16_t cmds_max, uint16_t qdepth, |
371 | struct Scsi_Host *shost, | 383 | uint32_t initial_cmdsn, uint32_t *hostno) |
372 | uint16_t cmds_max, uint16_t qdepth, | ||
373 | uint32_t initial_cmdsn, uint32_t *hostno) | ||
374 | { | 384 | { |
375 | struct iscsi_cls_session *cls_session; | 385 | struct iscsi_cls_session *cls_session; |
376 | struct iscsi_session *session; | 386 | struct iscsi_session *session; |
377 | int i; | 387 | int i; |
378 | uint32_t hn; | ||
379 | struct iscsi_cmd_task *ctask; | 388 | struct iscsi_cmd_task *ctask; |
380 | struct iscsi_mgmt_task *mtask; | 389 | struct iscsi_mgmt_task *mtask; |
381 | struct iscsi_iser_cmd_task *iser_ctask; | 390 | struct iscsi_iser_cmd_task *iser_ctask; |
382 | struct iser_desc *desc; | 391 | struct iser_desc *desc; |
383 | 392 | ||
393 | if (shost) { | ||
394 | printk(KERN_ERR "iscsi_tcp: invalid shost %d.\n", | ||
395 | shost->host_no); | ||
396 | return NULL; | ||
397 | } | ||
398 | |||
399 | shost = scsi_host_alloc(&iscsi_iser_sht, 0); | ||
400 | if (!shost) | ||
401 | return NULL; | ||
402 | shost->transportt = iscsi_iser_scsi_transport; | ||
403 | shost->max_lun = iscsi_max_lun; | ||
404 | shost->max_id = 0; | ||
405 | shost->max_channel = 0; | ||
406 | shost->max_cmd_len = 16; | ||
407 | |||
408 | iscsi_host_setup(shost, qdepth); | ||
409 | |||
410 | if (scsi_add_host(shost, NULL)) | ||
411 | goto free_host; | ||
412 | *hostno = shost->host_no; | ||
413 | |||
384 | /* | 414 | /* |
385 | * we do not support setting can_queue cmd_per_lun from userspace yet | 415 | * we do not support setting can_queue cmd_per_lun from userspace yet |
386 | * because we preallocate so many resources | 416 | * because we preallocate so many resources |
387 | */ | 417 | */ |
388 | cls_session = iscsi_session_setup(iscsit, scsit, | 418 | cls_session = iscsi_session_setup(&iscsi_iser_transport, shost, |
389 | ISCSI_DEF_XMIT_CMDS_MAX, | 419 | ISCSI_DEF_XMIT_CMDS_MAX, |
390 | ISCSI_MAX_CMD_PER_LUN, | ||
391 | sizeof(struct iscsi_iser_cmd_task), | 420 | sizeof(struct iscsi_iser_cmd_task), |
392 | sizeof(struct iser_desc), | 421 | sizeof(struct iser_desc), |
393 | initial_cmdsn, &hn); | 422 | initial_cmdsn); |
394 | if (!cls_session) | 423 | if (!cls_session) |
395 | return NULL; | 424 | goto remove_host; |
396 | 425 | session = cls_session->dd_data; | |
397 | *hostno = hn; | ||
398 | session = class_to_transport_session(cls_session); | ||
399 | 426 | ||
427 | shost->can_queue = session->cmds_max; | ||
400 | /* libiscsi setup itts, data and pool so just set desc fields */ | 428 | /* libiscsi setup itts, data and pool so just set desc fields */ |
401 | for (i = 0; i < session->cmds_max; i++) { | 429 | for (i = 0; i < session->cmds_max; i++) { |
402 | ctask = session->cmds[i]; | 430 | ctask = session->cmds[i]; |
@@ -413,6 +441,13 @@ iscsi_iser_session_create(struct iscsi_transport *iscsit, | |||
413 | } | 441 | } |
414 | 442 | ||
415 | return cls_session; | 443 | return cls_session; |
444 | |||
445 | remove_host: | ||
446 | scsi_remove_host(shost); | ||
447 | free_host: | ||
448 | iscsi_host_teardown(shost); | ||
449 | scsi_host_put(shost); | ||
450 | return NULL; | ||
416 | } | 451 | } |
417 | 452 | ||
418 | static int | 453 | static int |
@@ -589,12 +624,11 @@ static struct iscsi_transport iscsi_iser_transport = { | |||
589 | .host_param_mask = ISCSI_HOST_HWADDRESS | | 624 | .host_param_mask = ISCSI_HOST_HWADDRESS | |
590 | ISCSI_HOST_NETDEV_NAME | | 625 | ISCSI_HOST_NETDEV_NAME | |
591 | ISCSI_HOST_INITIATOR_NAME, | 626 | ISCSI_HOST_INITIATOR_NAME, |
592 | .host_template = &iscsi_iser_sht, | ||
593 | .conndata_size = sizeof(struct iscsi_conn), | 627 | .conndata_size = sizeof(struct iscsi_conn), |
594 | .max_lun = ISCSI_ISER_MAX_LUN, | 628 | .sessiondata_size = sizeof(struct iscsi_session), |
595 | /* session management */ | 629 | /* session management */ |
596 | .create_session = iscsi_iser_session_create, | 630 | .create_session = iscsi_iser_session_create, |
597 | .destroy_session = iscsi_session_teardown, | 631 | .destroy_session = iscsi_iser_session_destroy, |
598 | /* connection management */ | 632 | /* connection management */ |
599 | .create_conn = iscsi_iser_conn_create, | 633 | .create_conn = iscsi_iser_conn_create, |
600 | .bind_conn = iscsi_iser_conn_bind, | 634 | .bind_conn = iscsi_iser_conn_bind, |
@@ -633,8 +667,6 @@ static int __init iser_init(void) | |||
633 | return -EINVAL; | 667 | return -EINVAL; |
634 | } | 668 | } |
635 | 669 | ||
636 | iscsi_iser_transport.max_lun = iscsi_max_lun; | ||
637 | |||
638 | memset(&ig, 0, sizeof(struct iser_global)); | 670 | memset(&ig, 0, sizeof(struct iser_global)); |
639 | 671 | ||
640 | ig.desc_cache = kmem_cache_create("iser_descriptors", | 672 | ig.desc_cache = kmem_cache_create("iser_descriptors", |
@@ -650,7 +682,9 @@ static int __init iser_init(void) | |||
650 | mutex_init(&ig.connlist_mutex); | 682 | mutex_init(&ig.connlist_mutex); |
651 | INIT_LIST_HEAD(&ig.connlist); | 683 | INIT_LIST_HEAD(&ig.connlist); |
652 | 684 | ||
653 | if (!iscsi_register_transport(&iscsi_iser_transport)) { | 685 | iscsi_iser_scsi_transport = iscsi_register_transport( |
686 | &iscsi_iser_transport); | ||
687 | if (!iscsi_iser_scsi_transport) { | ||
654 | iser_err("iscsi_register_transport failed\n"); | 688 | iser_err("iscsi_register_transport failed\n"); |
655 | err = -EINVAL; | 689 | err = -EINVAL; |
656 | goto register_transport_failure; | 690 | goto register_transport_failure; |