The cmd to task mapping is almost the same for all control CDBs, except for calling different backend methods to do the backed-specific mapping. Merge the code performing the mapping into a single new transport_map_control_cmd_to_task helper, and kill the transport_map_task callback by simplify calling the backend methods directly for the single task for a control CDB, and hardcoding ->map_task_SG for data CDBs. Signed-off-by: Christoph Hellwig <hch@xxxxxx> Index: lio-core/drivers/target/target_core_transport.c =================================================================== --- lio-core.orig/drivers/target/target_core_transport.c 2010-11-16 18:55:26.414004751 +0100 +++ lio-core/drivers/target/target_core_transport.c 2010-11-16 18:55:30.075004681 +0100 @@ -2258,132 +2258,6 @@ static struct se_task *transport_generic return task; } -static int transport_do_se_mem_map(struct se_device *, struct se_task *, - struct list_head *, void *, struct se_mem *, struct se_mem **, - u32 *, u32 *); - -/* transport_process_control_sg_transform(): - * - * - */ -static int transport_process_control_sg_transform( - struct se_cmd *cmd, - struct se_transform_info *ti) -{ - unsigned char *cdb; - struct se_task *task; - struct se_mem *se_mem, *se_mem_lout = NULL; - struct se_device *dev = SE_DEV(cmd); - int ret; - u32 se_mem_cnt = 0, task_offset = 0; - - list_for_each_entry(se_mem, T_TASK(cmd)->t_mem_list, se_list) - break; - - if (!se_mem) { - printk(KERN_ERR "se_mem is NULL!\n"); - return -1; - } - - task = transport_generic_get_task(ti, cmd, ti->se_obj_ptr, - cmd->data_direction); - if (!(task)) - return -1; - - task->transport_map_task = ti->se_obj_ptr->transport->map_task_SG; - - cdb = TRANSPORT(dev)->get_cdb(task); - if (cdb) - memcpy(cdb, T_TASK(cmd)->t_task_cdb, - scsi_command_size(T_TASK(cmd)->t_task_cdb)); - - task->task_size = cmd->data_length; - task->task_sg_num = 1; - - atomic_inc(&T_TASK(cmd)->t_fe_count); - atomic_inc(&T_TASK(cmd)->t_se_count); - - ret = transport_do_se_mem_map(ti->se_obj_ptr, task, - T_TASK(cmd)->t_mem_list, NULL, se_mem, &se_mem_lout, - &se_mem_cnt, &task_offset); - if (ret < 0) - return ret; - - DEBUG_CDB_H("task_no[%u]: SCF_SCSI_CONTROL_SG_IO_CDB task_size: %d\n", - task->task_no, task->task_size); - return 0; -} - -/* transport_process_control_nonsg_transform(): - * - * - */ -static int transport_process_control_nonsg_transform( - struct se_cmd *cmd, - struct se_transform_info *ti) -{ - struct se_device *dev = SE_DEV(cmd); - unsigned char *cdb; - struct se_task *task; - - task = transport_generic_get_task(ti, cmd, ti->se_obj_ptr, - cmd->data_direction); - if (!(task)) - return -1; - - task->transport_map_task = ti->se_obj_ptr->transport->map_task_non_SG; - - cdb = TRANSPORT(dev)->get_cdb(task); - if (cdb) - memcpy(cdb, T_TASK(cmd)->t_task_cdb, - scsi_command_size(T_TASK(cmd)->t_task_cdb)); - - task->task_size = cmd->data_length; - task->task_sg_num = 0; - - atomic_inc(&T_TASK(cmd)->t_fe_count); - atomic_inc(&T_TASK(cmd)->t_se_count); - - DEBUG_CDB_H("task_no[%u]: SCF_SCSI_CONTROL_NONSG_IO_CDB task_size:" - " %d\n", task->task_no, task->task_size); - return 0; -} - -/* transport_process_non_data_transform(): - * - * - */ -static int transport_process_non_data_transform( - struct se_cmd *cmd, - struct se_transform_info *ti) -{ - struct se_device *dev = SE_DEV(cmd); - unsigned char *cdb; - struct se_task *task; - - task = transport_generic_get_task(ti, cmd, ti->se_obj_ptr, - cmd->data_direction); - if (!(task)) - return -1; - - task->transport_map_task = ti->se_obj_ptr->transport->cdb_none; - - cdb = TRANSPORT(dev)->get_cdb(task); - if (cdb) - memcpy(cdb, T_TASK(cmd)->t_task_cdb, - scsi_command_size(T_TASK(cmd)->t_task_cdb)); - - task->task_size = cmd->data_length; - task->task_sg_num = 0; - - atomic_inc(&T_TASK(cmd)->t_fe_count); - atomic_inc(&T_TASK(cmd)->t_se_count); - - DEBUG_CDB_H("task_no[%u]: SCF_SCSI_NON_DATA_CDB task_size: %d\n", - task->task_no, task->task_size); - return 0; -} - static int transport_generic_cmd_sequencer(struct se_cmd *, unsigned char *); void transport_device_setup_cmd(struct se_cmd *cmd) @@ -5942,8 +5816,6 @@ u32 transport_generic_get_cdb_count( task->task_size = (task->task_sectors * DEV_ATTRIB(dev)->block_size); - task->transport_map_task = dev->transport->map_task_SG; - cdb = TRANSPORT(dev)->get_cdb(task); if ((cdb)) { memcpy(cdb, T_TASK(cmd)->t_task_cdb, @@ -6011,6 +5883,61 @@ out: return 0; } +static int +transport_map_control_cmd_to_task(struct se_cmd *cmd, + struct se_transform_info *ti) +{ + struct se_device *dev = SE_DEV(cmd); + unsigned char *cdb; + struct se_task *task; + int ret; + + task = transport_generic_get_task(ti, cmd, ti->se_obj_ptr, + cmd->data_direction); + if (!task) + return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES; + + cdb = TRANSPORT(dev)->get_cdb(task); + if (cdb) + memcpy(cdb, cmd->t_task->t_task_cdb, + scsi_command_size(cmd->t_task->t_task_cdb)); + + task->task_size = cmd->data_length; + task->task_sg_num = + (cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB) ? 1 : 0; + + atomic_inc(&cmd->t_task->t_fe_count); + atomic_inc(&cmd->t_task->t_se_count); + + if (cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB) { + struct se_mem *se_mem, *se_mem_lout = NULL; + u32 se_mem_cnt = 0, task_offset = 0; + + BUG_ON(list_empty(cmd->t_task->t_mem_list)); + + ret = transport_do_se_mem_map(dev, task, + cmd->t_task->t_mem_list, NULL, se_mem, + &se_mem_lout, &se_mem_cnt, &task_offset); + if (ret < 0) + return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES; + + if (dev->transport->map_task_SG) + return dev->transport->map_task_SG(task); + return 0; + } else if (cmd->se_cmd_flags & SCF_SCSI_CONTROL_NONSG_IO_CDB) { + if (dev->transport->map_task_non_SG(task)) + return dev->transport->map_task_non_SG(task); + return 0; + } else if (cmd->se_cmd_flags & SCF_SCSI_NON_DATA_CDB) { + if (dev->transport->cdb_none(task)) + return dev->transport->cdb_none(task); + return 0; + } else { + BUG(); + return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES; + } +} + /* transport_generic_new_cmd(): Called from transport_processing_thread() * * Allocate storage transport resources from a set of values predefined @@ -6041,16 +5968,17 @@ int transport_generic_new_cmd(struct se_ if (!(cmd->se_cmd_flags & SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC)) { ret = transport_allocate_resources(cmd); if (ret < 0) - goto failure; + return ret; } ret = transport_get_sectors(cmd); if (ret < 0) - goto failure; + return ret; ret = transport_new_cmd_obj(cmd, &ti, 0); if (ret < 0) - goto failure; + return ret; + /* * Determine if the calling TCM fabric module is talking to * Linux/NET via kernel sockets and needs to allocate a @@ -6059,41 +5987,26 @@ int transport_generic_new_cmd(struct se_ se_tpg = SE_LUN(cmd)->lun_sep->sep_tpg; if (TPG_TFO(se_tpg)->alloc_cmd_iovecs != NULL) { ret = TPG_TFO(se_tpg)->alloc_cmd_iovecs(cmd); - if (ret < 0) { - ret = PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES; - goto failure; - } + if (ret < 0) + return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES; } } - if (cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB) - ret = transport_process_control_sg_transform(cmd, &ti); - else if (cmd->se_cmd_flags & SCF_SCSI_CONTROL_NONSG_IO_CDB) - ret = transport_process_control_nonsg_transform(cmd, &ti); - else if (cmd->se_cmd_flags & SCF_SCSI_NON_DATA_CDB) - ret = transport_process_non_data_transform(cmd, &ti); - else - BUG_ON(!(cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB)); - - if (ret < 0) { - ret = PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES; - goto failure; - } + if (cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) { + list_for_each_entry(task, &T_TASK(cmd)->t_task_list, t_list) { + if (atomic_read(&task->task_sent)) + continue; + if (!ti.se_obj_ptr->transport->map_task_SG) + continue; - /* - * Set the correct (usually DMAable) buffer pointers from the master - * buffer list in struct se_cmd to the transport task's native - * buffers format. - */ - list_for_each_entry(task, &T_TASK(cmd)->t_task_list, t_list) { - if (atomic_read(&task->task_sent)) - continue; - - if (task->transport_map_task) { - ret = task->transport_map_task(task); + ret = ti.se_obj_ptr->transport->map_task_SG(task); if (ret < 0) - goto failure; + return ret; } + } else { + ret = transport_map_control_cmd_to_task(cmd, &ti); + if (ret < 0) + return ret; } /* @@ -6113,9 +6026,6 @@ int transport_generic_new_cmd(struct se_ */ transport_execute_tasks(cmd); return 0; - -failure: - return ret; } /* transport_generic_process_write(): Index: lio-core/include/target/target_core_base.h =================================================================== --- lio-core.orig/include/target/target_core_base.h 2010-11-16 18:55:26.415004611 +0100 +++ lio-core/include/target/target_core_base.h 2010-11-16 18:55:30.076003773 +0100 @@ -499,7 +499,6 @@ struct se_task { atomic_t task_stop; atomic_t task_state_active; struct timer_list task_timer; - int (*transport_map_task)(struct se_task *); struct se_device *se_obj_ptr; struct list_head t_list; struct list_head t_execute_list; -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html