]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/infiniband/ulp/iser/iscsi_iser.c
[SCSI] iscsi: remove session and host binding in libiscsi
[linux-2.6-omap-h63xx.git] / drivers / infiniband / ulp / iser / iscsi_iser.c
index be1b9fbd416d9cf2a2c70dad4542278704448058..5a750042e2b24cb5c09d625a5c4426c551af515c 100644 (file)
 
 #include "iscsi_iser.h"
 
+static struct scsi_host_template iscsi_iser_sht;
+static struct iscsi_transport iscsi_iser_transport;
+static struct scsi_transport_template *iscsi_iser_scsi_transport;
+
 static unsigned int iscsi_max_lun = 512;
 module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO);
 
@@ -363,39 +367,64 @@ iscsi_iser_conn_start(struct iscsi_cls_conn *cls_conn)
        return iscsi_conn_start(cls_conn);
 }
 
-static struct iscsi_transport iscsi_iser_transport;
+static void iscsi_iser_session_destroy(struct iscsi_cls_session *cls_session)
+{
+       struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
+
+       iscsi_session_teardown(cls_session);
+       scsi_remove_host(shost);
+       iscsi_host_teardown(shost);
+       scsi_host_put(shost);
+}
 
 static struct iscsi_cls_session *
-iscsi_iser_session_create(struct iscsi_transport *iscsit,
-                        struct scsi_transport_template *scsit,
-                        uint16_t cmds_max, uint16_t qdepth,
-                        uint32_t initial_cmdsn, uint32_t *hostno)
+iscsi_iser_session_create(struct Scsi_Host *shost,
+                         uint16_t cmds_max, uint16_t qdepth,
+                         uint32_t initial_cmdsn, uint32_t *hostno)
 {
        struct iscsi_cls_session *cls_session;
        struct iscsi_session *session;
        int i;
-       uint32_t hn;
        struct iscsi_cmd_task  *ctask;
        struct iscsi_mgmt_task *mtask;
        struct iscsi_iser_cmd_task *iser_ctask;
        struct iser_desc *desc;
 
+       if (shost) {
+               printk(KERN_ERR "iscsi_tcp: invalid shost %d.\n",
+                      shost->host_no);
+               return NULL;
+       }
+
+       shost = scsi_host_alloc(&iscsi_iser_sht, 0);
+       if (!shost)
+               return NULL;
+       shost->transportt = iscsi_iser_scsi_transport;
+       shost->max_lun = iscsi_max_lun;
+       shost->max_id = 0;
+       shost->max_channel = 0;
+       shost->max_cmd_len = 16;
+
+       iscsi_host_setup(shost, qdepth);
+
+       if (scsi_add_host(shost, NULL))
+               goto free_host;
+       *hostno = shost->host_no;
+
        /*
         * we do not support setting can_queue cmd_per_lun from userspace yet
         * because we preallocate so many resources
         */
-       cls_session = iscsi_session_setup(iscsit, scsit,
+       cls_session = iscsi_session_setup(&iscsi_iser_transport, shost,
                                          ISCSI_DEF_XMIT_CMDS_MAX,
-                                         ISCSI_MAX_CMD_PER_LUN,
                                          sizeof(struct iscsi_iser_cmd_task),
                                          sizeof(struct iser_desc),
-                                         initial_cmdsn, &hn);
+                                         initial_cmdsn);
        if (!cls_session)
-       return NULL;
-
-       *hostno = hn;
-       session = class_to_transport_session(cls_session);
+               goto remove_host;
+       session = cls_session->dd_data;
 
+       shost->can_queue = session->cmds_max;
        /* libiscsi setup itts, data and pool so just set desc fields */
        for (i = 0; i < session->cmds_max; i++) {
                ctask      = session->cmds[i];
@@ -412,6 +441,13 @@ iscsi_iser_session_create(struct iscsi_transport *iscsit,
        }
 
        return cls_session;
+
+remove_host:
+       scsi_remove_host(shost);
+free_host:
+       iscsi_host_teardown(shost);
+       scsi_host_put(shost);
+       return NULL;
 }
 
 static int
@@ -473,13 +509,15 @@ iscsi_iser_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *s
        stats->r2t_pdus = conn->r2t_pdus_cnt; /* always 0 */
        stats->tmfcmd_pdus = conn->tmfcmd_pdus_cnt;
        stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt;
-       stats->custom_length = 3;
+       stats->custom_length = 4;
        strcpy(stats->custom[0].desc, "qp_tx_queue_full");
        stats->custom[0].value = 0; /* TB iser_conn->qp_tx_queue_full; */
        strcpy(stats->custom[1].desc, "fmr_map_not_avail");
        stats->custom[1].value = 0; /* TB iser_conn->fmr_map_not_avail */;
        strcpy(stats->custom[2].desc, "eh_abort_cnt");
        stats->custom[2].value = conn->eh_abort_cnt;
+       strcpy(stats->custom[3].desc, "fmr_unalign_cnt");
+       stats->custom[3].value = conn->fmr_unalign_cnt;
 }
 
 static int
@@ -586,13 +624,11 @@ static struct iscsi_transport iscsi_iser_transport = {
        .host_param_mask        = ISCSI_HOST_HWADDRESS |
                                  ISCSI_HOST_NETDEV_NAME |
                                  ISCSI_HOST_INITIATOR_NAME,
-       .host_template          = &iscsi_iser_sht,
        .conndata_size          = sizeof(struct iscsi_conn),
-       .max_lun                = ISCSI_ISER_MAX_LUN,
-       .max_cmd_len            = ISCSI_ISER_MAX_CMD_LEN,
+       .sessiondata_size       = sizeof(struct iscsi_session),
        /* session management */
        .create_session         = iscsi_iser_session_create,
-       .destroy_session        = iscsi_session_teardown,
+       .destroy_session        = iscsi_iser_session_destroy,
        /* connection management */
        .create_conn            = iscsi_iser_conn_create,
        .bind_conn              = iscsi_iser_conn_bind,
@@ -631,8 +667,6 @@ static int __init iser_init(void)
                return -EINVAL;
        }
 
-       iscsi_iser_transport.max_lun = iscsi_max_lun;
-
        memset(&ig, 0, sizeof(struct iser_global));
 
        ig.desc_cache = kmem_cache_create("iser_descriptors",
@@ -648,7 +682,9 @@ static int __init iser_init(void)
        mutex_init(&ig.connlist_mutex);
        INIT_LIST_HEAD(&ig.connlist);
 
-       if (!iscsi_register_transport(&iscsi_iser_transport)) {
+       iscsi_iser_scsi_transport = iscsi_register_transport(
+                                                       &iscsi_iser_transport);
+       if (!iscsi_iser_scsi_transport) {
                iser_err("iscsi_register_transport failed\n");
                err = -EINVAL;
                goto register_transport_failure;