]> 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 5db31438027109588ea50018a4875bfd64ae9521..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);
 
@@ -129,7 +133,7 @@ error:
  * iscsi_iser_cmd_init - Initialize iSCSI SCSI_READ or SCSI_WRITE commands
  *
  **/
-static void
+static int
 iscsi_iser_cmd_init(struct iscsi_cmd_task *ctask)
 {
        struct iscsi_iser_conn     *iser_conn  = ctask->conn->dd_data;
@@ -138,6 +142,7 @@ iscsi_iser_cmd_init(struct iscsi_cmd_task *ctask)
        iser_ctask->command_sent = 0;
        iser_ctask->iser_conn    = iser_conn;
        iser_ctask_rdma_init(iser_ctask);
+       return 0;
 }
 
 /**
@@ -220,12 +225,6 @@ iscsi_iser_ctask_xmit(struct iscsi_conn *conn,
        debug_scsi("ctask deq [cid %d itt 0x%x]\n",
                   conn->id, ctask->itt);
 
-       /*
-        * serialize with TMF AbortTask
-        */
-       if (ctask->mtask)
-               return error;
-
        /* Send the cmd PDU */
        if (!iser_ctask->command_sent) {
                error = iser_send_command(conn, ctask);
@@ -368,44 +367,70 @@ 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];
                iser_ctask = ctask->dd_data;
                ctask->hdr = (struct iscsi_cmd *)&iser_ctask->desc.iscsi_header;
+               ctask->hdr_max = sizeof(iser_ctask->desc.iscsi_header);
        }
 
        for (i = 0; i < session->mgmtpool_max; i++) {
@@ -416,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
@@ -477,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
@@ -548,13 +582,16 @@ iscsi_iser_ep_disconnect(__u64 ep_handle)
 }
 
 static struct scsi_host_template iscsi_iser_sht = {
+       .module                 = THIS_MODULE,
        .name                   = "iSCSI Initiator over iSER, v." DRV_VER,
        .queuecommand           = iscsi_queuecommand,
+       .change_queue_depth     = iscsi_change_queue_depth,
        .can_queue              = ISCSI_DEF_XMIT_CMDS_MAX - 1,
        .sg_tablesize           = ISCSI_ISER_SG_TABLESIZE,
        .max_sectors            = 1024,
        .cmd_per_lun            = ISCSI_MAX_CMD_PER_LUN,
        .eh_abort_handler       = iscsi_eh_abort,
+       .eh_device_reset_handler= iscsi_eh_device_reset,
        .eh_host_reset_handler  = iscsi_eh_host_reset,
        .use_clustering         = DISABLE_CLUSTERING,
        .proc_name              = "iscsi_iser",
@@ -581,17 +618,17 @@ static struct iscsi_transport iscsi_iser_transport = {
                                  ISCSI_PERSISTENT_ADDRESS |
                                  ISCSI_TARGET_NAME | ISCSI_TPGT |
                                  ISCSI_USERNAME | ISCSI_PASSWORD |
-                                 ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN,
+                                 ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN |
+                                 ISCSI_FAST_ABORT | ISCSI_ABORT_TMO |
+                                 ISCSI_PING_TMO | ISCSI_RECV_TMO,
        .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,
@@ -630,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",
@@ -647,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;