aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/ulp/iser/iscsi_iser.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/ulp/iser/iscsi_iser.c')
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.c74
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
77static struct scsi_host_template iscsi_iser_sht;
78static struct iscsi_transport iscsi_iser_transport;
79static struct scsi_transport_template *iscsi_iser_scsi_transport;
80
77static unsigned int iscsi_max_lun = 512; 81static unsigned int iscsi_max_lun = 512;
78module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO); 82module_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
366static struct iscsi_transport iscsi_iser_transport; 370static 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
368static struct iscsi_cls_session * 380static struct iscsi_cls_session *
369iscsi_iser_session_create(struct iscsi_transport *iscsit, 381iscsi_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
445remove_host:
446 scsi_remove_host(shost);
447free_host:
448 iscsi_host_teardown(shost);
449 scsi_host_put(shost);
450 return NULL;
416} 451}
417 452
418static int 453static 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;