]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/target/loopback/tcm_loop.c
target: merge release_cmd methods
[karo-tx-linux.git] / drivers / target / loopback / tcm_loop.c
index dee2a2c909f5386671f593428cbfa837f37e65a6..c2937b2035d33c89f6431f40a36797f842ac0a0e 100644 (file)
@@ -118,17 +118,16 @@ static struct se_cmd *tcm_loop_allocate_core_cmd(
         * Signal BIDI usage with T_TASK(cmd)->t_tasks_bidi
         */
        if (scsi_bidi_cmnd(sc))
-               T_TASK(se_cmd)->t_tasks_bidi = 1;
+               se_cmd->t_tasks_bidi = 1;
        /*
         * Locate the struct se_lun pointer and attach it to struct se_cmd
         */
-       if (transport_get_lun_for_cmd(se_cmd, NULL, tl_cmd->sc->device->lun) < 0) {
+       if (transport_lookup_cmd_lun(se_cmd, tl_cmd->sc->device->lun) < 0) {
                kmem_cache_free(tcm_loop_cmd_cache, tl_cmd);
                set_host_byte(sc, DID_NO_CONNECT);
                return NULL;
        }
 
-       transport_device_setup_cmd(se_cmd);
        return se_cmd;
 }
 
@@ -143,17 +142,17 @@ static int tcm_loop_new_cmd_map(struct se_cmd *se_cmd)
        struct tcm_loop_cmd *tl_cmd = container_of(se_cmd,
                                struct tcm_loop_cmd, tl_se_cmd);
        struct scsi_cmnd *sc = tl_cmd->sc;
-       void *mem_ptr, *mem_bidi_ptr = NULL;
-       u32 sg_no_bidi = 0;
+       struct scatterlist *sgl_bidi = NULL;
+       u32 sgl_bidi_count = 0;
        int ret;
        /*
         * Allocate the necessary tasks to complete the received CDB+data
         */
-       ret = transport_generic_allocate_tasks(se_cmd, tl_cmd->sc->cmnd);
-       if (ret == -1) {
+       ret = transport_generic_allocate_tasks(se_cmd, sc->cmnd);
+       if (ret == -ENOMEM) {
                /* Out of Resources */
                return PYX_TRANSPORT_LU_COMM_FAILURE;
-       } else if (ret == -2) {
+       } else if (ret == -EINVAL) {
                /*
                 * Handle case for SAM_STAT_RESERVATION_CONFLICT
                 */
@@ -165,35 +164,24 @@ static int tcm_loop_new_cmd_map(struct se_cmd *se_cmd)
                 */
                return PYX_TRANSPORT_USE_SENSE_REASON;
        }
+
        /*
-        * Setup the struct scatterlist memory from the received
-        * struct scsi_cmnd.
+        * For BIDI commands, pass in the extra READ buffer
+        * to transport_generic_map_mem_to_cmd() below..
         */
-       if (scsi_sg_count(sc)) {
-               se_cmd->se_cmd_flags |= SCF_PASSTHROUGH_SG_TO_MEM;
-               mem_ptr = (void *)scsi_sglist(sc);
-               /*
-                * For BIDI commands, pass in the extra READ buffer
-                * to transport_generic_map_mem_to_cmd() below..
-                */
-               if (T_TASK(se_cmd)->t_tasks_bidi) {
-                       struct scsi_data_buffer *sdb = scsi_in(sc);
+       if (se_cmd->t_tasks_bidi) {
+               struct scsi_data_buffer *sdb = scsi_in(sc);
 
-                       mem_bidi_ptr = (void *)sdb->table.sgl;
-                       sg_no_bidi = sdb->table.nents;
-               }
-       } else {
-               /*
-                * Used for DMA_NONE
-                */
-               mem_ptr = NULL;
+               sgl_bidi = sdb->table.sgl;
+               sgl_bidi_count = sdb->table.nents;
        }
+
        /*
         * Map the SG memory into struct se_mem->page linked list using the same
         * physical memory at sg->page_link.
         */
-       ret = transport_generic_map_mem_to_cmd(se_cmd, mem_ptr,
-                       scsi_sg_count(sc), mem_bidi_ptr, sg_no_bidi);
+       ret = transport_generic_map_mem_to_cmd(se_cmd, scsi_sglist(sc),
+                       scsi_sg_count(sc), sgl_bidi, sgl_bidi_count);
        if (ret < 0)
                return PYX_TRANSPORT_LU_COMM_FAILURE;
 
@@ -216,13 +204,10 @@ static void tcm_loop_check_stop_free(struct se_cmd *se_cmd)
         * Release the struct se_cmd, which will make a callback to release
         * struct tcm_loop_cmd * in tcm_loop_deallocate_core_cmd()
         */
-       transport_generic_free_cmd(se_cmd, 0, 1, 0);
+       transport_generic_free_cmd(se_cmd, 0, 0);
 }
 
-/*
- * Called from struct target_core_fabric_ops->release_cmd_to_pool()
- */
-static void tcm_loop_deallocate_core_cmd(struct se_cmd *se_cmd)
+static void tcm_loop_release_cmd(struct se_cmd *se_cmd)
 {
        struct tcm_loop_cmd *tl_cmd = container_of(se_cmd,
                                struct tcm_loop_cmd, tl_se_cmd);
@@ -384,14 +369,14 @@ static int tcm_loop_device_reset(struct scsi_cmnd *sc)
        /*
         * Allocate the LUN_RESET TMR
         */
-       se_cmd->se_tmr_req = core_tmr_alloc_req(se_cmd, (void *)tl_tmr,
+       se_cmd->se_tmr_req = core_tmr_alloc_req(se_cmd, tl_tmr,
                                TMR_LUN_RESET);
-       if (!se_cmd->se_tmr_req)
+       if (IS_ERR(se_cmd->se_tmr_req))
                goto release;
        /*
         * Locate the underlying TCM struct se_lun from sc->device->lun
         */
-       if (transport_get_lun_for_tmr(se_cmd, sc->device->lun) < 0)
+       if (transport_lookup_tmr_lun(se_cmd, sc->device->lun) < 0)
                goto release;
        /*
         * Queue the TMR to TCM Core and sleep waiting for tcm_loop_queue_tm_rsp()
@@ -407,7 +392,7 @@ static int tcm_loop_device_reset(struct scsi_cmnd *sc)
                SUCCESS : FAILED;
 release:
        if (se_cmd)
-               transport_generic_free_cmd(se_cmd, 1, 1, 0);
+               transport_generic_free_cmd(se_cmd, 1, 0);
        else
                kmem_cache_free(tcm_loop_cmd_cache, tl_cmd);
        kfree(tl_tmr);
@@ -784,16 +769,6 @@ static u32 tcm_loop_get_inst_index(struct se_portal_group *se_tpg)
        return 1;
 }
 
-static void tcm_loop_new_cmd_failure(struct se_cmd *se_cmd)
-{
-       /*
-        * Since TCM_loop is already passing struct scatterlist data from
-        * struct scsi_cmnd, no more Linux/SCSI failure dependent state need
-        * to be handled here.
-        */
-       return;
-}
-
 static int tcm_loop_is_state_remove(struct se_cmd *se_cmd)
 {
        /*
@@ -904,7 +879,7 @@ static int tcm_loop_queue_status(struct se_cmd *se_cmd)
           ((se_cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) ||
            (se_cmd->se_cmd_flags & SCF_EMULATED_TASK_SENSE))) {
 
-               memcpy((void *)sc->sense_buffer, (void *)se_cmd->sense_buffer,
+               memcpy(sc->sense_buffer, se_cmd->sense_buffer,
                                SCSI_SENSE_BUFFERSIZE);
                sc->result = SAM_STAT_CHECK_CONDITION;
                set_driver_byte(sc, DRIVER_SENSE);
@@ -1017,6 +992,7 @@ static int tcm_loop_make_nexus(
        struct se_portal_group *se_tpg;
        struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
        struct tcm_loop_nexus *tl_nexus;
+       int ret = -ENOMEM;
 
        if (tl_tpg->tl_hba->tl_nexus) {
                printk(KERN_INFO "tl_tpg->tl_hba->tl_nexus already exists\n");
@@ -1033,8 +1009,10 @@ static int tcm_loop_make_nexus(
         * Initialize the struct se_session pointer
         */
        tl_nexus->se_sess = transport_init_session();
-       if (!tl_nexus->se_sess)
+       if (IS_ERR(tl_nexus->se_sess)) {
+               ret = PTR_ERR(tl_nexus->se_sess);
                goto out;
+       }
        /*
         * Since we are running in 'demo mode' this call with generate a
         * struct se_node_acl for the tcm_loop struct se_portal_group with the SCSI
@@ -1051,7 +1029,7 @@ static int tcm_loop_make_nexus(
         * transport_register_session()
         */
        __transport_register_session(se_tpg, tl_nexus->se_sess->se_node_acl,
-                       tl_nexus->se_sess, (void *)tl_nexus);
+                       tl_nexus->se_sess, tl_nexus);
        tl_tpg->tl_hba->tl_nexus = tl_nexus;
        printk(KERN_INFO "TCM_Loop_ConfigFS: Established I_T Nexus to emulated"
                " %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tl_hba),
@@ -1060,7 +1038,7 @@ static int tcm_loop_make_nexus(
 
 out:
        kfree(tl_nexus);
-       return -ENOMEM;
+       return ret;
 }
 
 static int tcm_loop_drop_nexus(
@@ -1140,7 +1118,7 @@ static ssize_t tcm_loop_tpg_store_nexus(
         * the fabric protocol_id set in tcm_loop_make_scsi_hba(), and call
         * tcm_loop_make_nexus()
         */
-       if (strlen(page) > TL_WWN_ADDR_LEN) {
+       if (strlen(page) >= TL_WWN_ADDR_LEN) {
                printk(KERN_ERR "Emulated NAA Sas Address: %s, exceeds"
                                " max: %d\n", page, TL_WWN_ADDR_LEN);
                return -EINVAL;
@@ -1239,7 +1217,7 @@ struct se_portal_group *tcm_loop_make_naa_tpg(
         * Register the tl_tpg as a emulated SAS TCM Target Endpoint
         */
        ret = core_tpg_register(&tcm_loop_fabric_configfs->tf_ops,
-                       wwn, &tl_tpg->tl_se_tpg, (void *)tl_tpg,
+                       wwn, &tl_tpg->tl_se_tpg, tl_tpg,
                        TRANSPORT_TPG_TYPE_NORMAL);
        if (ret < 0)
                return ERR_PTR(-ENOMEM);
@@ -1321,7 +1299,7 @@ struct se_wwn *tcm_loop_make_scsi_hba(
        return ERR_PTR(-EINVAL);
 
 check_len:
-       if (strlen(name) > TL_WWN_ADDR_LEN) {
+       if (strlen(name) >= TL_WWN_ADDR_LEN) {
                printk(KERN_ERR "Emulated NAA %s Address: %s, exceeds"
                        " max: %d\n", name, tcm_loop_dump_proto_id(tl_hba),
                        TL_WWN_ADDR_LEN);
@@ -1399,9 +1377,9 @@ static int tcm_loop_register_configfs(void)
         * Register the top level struct config_item_type with TCM core
         */
        fabric = target_fabric_configfs_init(THIS_MODULE, "loopback");
-       if (!fabric) {
+       if (IS_ERR(fabric)) {
                printk(KERN_ERR "tcm_loop_register_configfs() failed!\n");
-               return -1;
+               return PTR_ERR(fabric);
        }
        /*
         * Setup the fabric API of function pointers used by target_core_mod
@@ -1432,20 +1410,12 @@ static int tcm_loop_register_configfs(void)
        fabric->tf_ops.tpg_release_fabric_acl =
                                        &tcm_loop_tpg_release_fabric_acl;
        fabric->tf_ops.tpg_get_inst_index = &tcm_loop_get_inst_index;
-       /*
-        * Since tcm_loop is mapping physical memory from Linux/SCSI
-        * struct scatterlist arrays for each struct scsi_cmnd I/O,
-        * we do not need TCM to allocate a iovec array for
-        * virtual memory address mappings
-        */
-       fabric->tf_ops.alloc_cmd_iovecs = NULL;
        /*
         * Used for setting up remaining TCM resources in process context
         */
        fabric->tf_ops.new_cmd_map = &tcm_loop_new_cmd_map;
        fabric->tf_ops.check_stop_free = &tcm_loop_check_stop_free;
-       fabric->tf_ops.release_cmd_to_pool = &tcm_loop_deallocate_core_cmd;
-       fabric->tf_ops.release_cmd_direct = &tcm_loop_deallocate_core_cmd;
+       fabric->tf_ops.release_cmd = &tcm_loop_release_cmd;
        fabric->tf_ops.shutdown_session = &tcm_loop_shutdown_session;
        fabric->tf_ops.close_session = &tcm_loop_close_session;
        fabric->tf_ops.stop_session = &tcm_loop_stop_session;
@@ -1462,7 +1432,6 @@ static int tcm_loop_register_configfs(void)
                                        &tcm_loop_set_default_node_attributes;
        fabric->tf_ops.get_task_tag = &tcm_loop_get_task_tag;
        fabric->tf_ops.get_cmd_state = &tcm_loop_get_cmd_state;
-       fabric->tf_ops.new_cmd_failure = &tcm_loop_new_cmd_failure;
        fabric->tf_ops.queue_data_in = &tcm_loop_queue_data_in;
        fabric->tf_ops.queue_status = &tcm_loop_queue_status;
        fabric->tf_ops.queue_tm_rsp = &tcm_loop_queue_tm_rsp;