* [PATCH 0/9] target core review feedback
@ 2010-11-08 15:56 Christoph Hellwig
2010-11-08 15:56 ` [PATCH 1/9] target: remove never changing indirections in se_cmd Christoph Hellwig
` (9 more replies)
0 siblings, 10 replies; 23+ messages in thread
From: Christoph Hellwig @ 2010-11-08 15:56 UTC (permalink / raw)
To: nab; +Cc: linux-scsi
Here's a couple of target core things I noticed while looking over it.
I don't have a test setup for it yet, so the patches are only compile tested so
far.
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 1/9] target: remove never changing indirections in se_cmd
2010-11-08 15:56 [PATCH 0/9] target core review feedback Christoph Hellwig
@ 2010-11-08 15:56 ` Christoph Hellwig
2010-11-08 21:57 ` Nicholas A. Bellinger
2010-11-08 15:56 ` [PATCH 2/9] target: remove activate_device/deactivate_device methods Christoph Hellwig
` (8 subsequent siblings)
9 siblings, 1 reply; 23+ messages in thread
From: Christoph Hellwig @ 2010-11-08 15:56 UTC (permalink / raw)
To: nab; +Cc: linux-scsi
[-- Attachment #1: lio-cleanup-transform --]
[-- Type: text/plain, Size: 26740 bytes --]
De-virtualize various function pointers in struct se_cmd that never change, and
remove the transport_add_cmd_to_dev_queue wrapper.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Index: lio-core-2.6/drivers/target/target_core_transport.c
===================================================================
--- lio-core-2.6.orig/drivers/target/target_core_transport.c 2010-11-06 19:54:02.380003811 +0100
+++ lio-core-2.6/drivers/target/target_core_transport.c 2010-11-06 20:17:24.519255311 +0100
@@ -207,6 +207,8 @@ typedef int (*map_func_t)(struct se_task
static int transport_generic_write_pending(struct se_cmd *);
static int transport_processing_thread(void *);
+static int transport_new_cmd_obj(struct se_cmd *cmd,
+ struct se_transform_info *ti, int post_execute);
static char *transport_passthrough_get_fabric_name(void)
{
@@ -1036,9 +1038,10 @@ void transport_cmd_finish_abort_tmr(stru
int transport_add_cmd_to_queue(
struct se_cmd *cmd,
- struct se_queue_obj *qobj,
int t_state)
{
+ struct se_device *dev = cmd->se_dev;
+ struct se_queue_obj *qobj = dev->dev_queue_obj;
struct se_queue_req *qr;
unsigned long flags;
@@ -1070,13 +1073,6 @@ int transport_add_cmd_to_queue(
return 0;
}
-static int transport_add_cmd_to_dev_queue(struct se_cmd *cmd, int t_state)
-{
- struct se_device *dev = cmd->se_dev;
-
- return transport_add_cmd_to_queue(cmd, dev->dev_queue_obj, t_state);
-}
-
/*
* Called with struct se_queue_obj->cmd_queue_lock held.
*/
@@ -1173,7 +1169,7 @@ void transport_complete_cmd(struct se_cm
atomic_set(&T_TASK(cmd)->t_transport_complete, 1);
spin_unlock_irqrestore(&T_TASK(cmd)->t_state_lock, flags);
- cmd->transport_add_cmd_to_queue(cmd, t_state);
+ transport_add_cmd_to_queue(cmd, t_state);
}
/*
@@ -1272,7 +1268,7 @@ check_task_stop:
t_state = TRANSPORT_COMPLETE_TIMEOUT;
spin_unlock_irqrestore(&T_TASK(cmd)->t_state_lock, flags);
- cmd->transport_add_cmd_to_queue(cmd, t_state);
+ transport_add_cmd_to_queue(cmd, t_state);
return;
}
atomic_dec(&T_TASK(cmd)->t_task_cdbs_timeout_left);
@@ -1315,7 +1311,7 @@ check_task_stop:
}
spin_unlock_irqrestore(&T_TASK(cmd)->t_state_lock, flags);
- cmd->transport_add_cmd_to_queue(cmd, t_state);
+ transport_add_cmd_to_queue(cmd, t_state);
}
EXPORT_SYMBOL(transport_complete_task);
@@ -1457,7 +1453,8 @@ void transport_add_tasks_from_cmd(struct
*
* Called with dev->execute_task_lock held.
*/
-struct se_task *transport_get_task_from_execute_queue(struct se_device *dev)
+static struct se_task *
+transport_get_task_from_execute_queue(struct se_device *dev)
{
struct se_task *task;
@@ -2604,8 +2601,8 @@ static int transport_process_control_sg_
return -1;
}
- task = cmd->transport_get_task(ti, cmd, ti->se_obj_ptr,
- cmd->data_direction);
+ task = transport_generic_get_task(ti, cmd, ti->se_obj_ptr,
+ cmd->data_direction);
if (!(task))
return -1;
@@ -2646,8 +2643,8 @@ static int transport_process_control_non
unsigned char *cdb;
struct se_task *task;
- task = cmd->transport_get_task(ti, cmd, ti->se_obj_ptr,
- cmd->data_direction);
+ task = transport_generic_get_task(ti, cmd, ti->se_obj_ptr,
+ cmd->data_direction);
if (!(task))
return -1;
@@ -2682,8 +2679,8 @@ static int transport_process_non_data_tr
unsigned char *cdb;
struct se_task *task;
- task = cmd->transport_get_task(ti, cmd, ti->se_obj_ptr,
- cmd->data_direction);
+ task = transport_generic_get_task(ti, cmd, ti->se_obj_ptr,
+ cmd->data_direction);
if (!(task))
return -1;
@@ -2709,7 +2706,6 @@ static int transport_generic_cmd_sequenc
void transport_device_setup_cmd(struct se_cmd *cmd)
{
- cmd->transport_add_cmd_to_queue = &transport_add_cmd_to_dev_queue;
cmd->se_dev = SE_LUN(cmd)->lun_se_dev;
}
EXPORT_SYMBOL(transport_device_setup_cmd);
@@ -3018,7 +3014,7 @@ int transport_generic_handle_cdb(
return -1;
}
- cmd->transport_add_cmd_to_queue(cmd, TRANSPORT_NEW_CMD);
+ transport_add_cmd_to_queue(cmd, TRANSPORT_NEW_CMD);
return 0;
}
EXPORT_SYMBOL(transport_generic_handle_cdb);
@@ -3034,7 +3030,7 @@ int transport_generic_handle_data(
* Make sure that the transport has been disabled by
* transport_write_pending() before readding this struct se_cmd to the
* processing queue. If it has not yet been reset to zero by the
- * processing thread in cmd->transport_add_cmd_to_queue(), let other
+ * processing thread in transport_add_cmd_to_queue(), let other
* processes run. If a signal was received, then we assume the
* connection is being failed/shutdown, so we return a failure.
*/
@@ -3053,7 +3049,7 @@ int transport_generic_handle_data(
if (transport_check_aborted_status(cmd, 1) != 0)
return 0;
- cmd->transport_add_cmd_to_queue(cmd, TRANSPORT_PROCESS_WRITE);
+ transport_add_cmd_to_queue(cmd, TRANSPORT_PROCESS_WRITE);
return 0;
}
EXPORT_SYMBOL(transport_generic_handle_data);
@@ -3071,7 +3067,7 @@ int transport_generic_handle_tmr(
cmd->transport_wait_for_tasks = &transport_generic_wait_for_tasks;
transport_device_setup_cmd(cmd);
- cmd->transport_add_cmd_to_queue(cmd, TRANSPORT_PROCESS_TMR);
+ transport_add_cmd_to_queue(cmd, TRANSPORT_PROCESS_TMR);
return 0;
}
EXPORT_SYMBOL(transport_generic_handle_tmr);
@@ -3600,11 +3596,7 @@ static void iscsi_check_iovec_map(
#define iscsi_check_iovec_map(a, b, c, d)
#endif
-/* transport_generic_set_iovec_ptrs():
- *
- *
- */
-static int transport_generic_set_iovec_ptrs(
+int transport_generic_set_iovec_ptrs(
struct se_map_sg *map_sg,
struct se_unmap_sg *unmap_sg)
{
@@ -3732,6 +3724,7 @@ static int transport_generic_set_iovec_p
return i;
}
+EXPORT_SYMBOL(transport_generic_set_iovec_ptrs);
/* transport_generic_allocate_buf():
*
@@ -3914,7 +3907,7 @@ void transport_task_timeout_handler(unsi
cmd->t_state = TRANSPORT_COMPLETE_FAILURE;
spin_unlock_irqrestore(&T_TASK(cmd)->t_state_lock, flags);
- cmd->transport_add_cmd_to_queue(cmd, TRANSPORT_COMPLETE_FAILURE);
+ transport_add_cmd_to_queue(cmd, TRANSPORT_COMPLETE_FAILURE);
}
u32 transport_get_default_task_timeout(struct se_device *dev)
@@ -4285,7 +4278,6 @@ void transport_new_cmd_failure(struct se
CMD_TFO(se_cmd)->new_cmd_failure(se_cmd);
}
-static int transport_generic_map_buffers_to_tasks(struct se_cmd *);
static void transport_nop_wait_for_tasks(struct se_cmd *, int, int);
static inline u32 transport_get_sectors_6(
@@ -5683,18 +5675,6 @@ static inline void transport_dev_get_mem
TRANSPORT(dev)->free_DMA : NULL;
}
-/*
- * Generic function pointers for target_core_mod/ConfigFS
- */
-#define SET_GENERIC_TRANSPORT_FUNCTIONS(cmd) \
-do { \
- cmd->transport_get_task = &transport_generic_get_task; \
- cmd->transport_map_buffers_to_tasks = \
- &transport_generic_map_buffers_to_tasks; \
- cmd->transport_set_iovec_ptrs = \
- &transport_generic_set_iovec_ptrs; \
-} while (0)
-
/* transport_generic_cmd_sequencer():
*
* Generic Command Sequencer that should work for most DAS transport
@@ -5767,7 +5747,6 @@ static int transport_generic_cmd_sequenc
switch (cdb[0]) {
case READ_6:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
sectors = transport_get_sectors_6(cdb, cmd, §or_ret);
if (sector_ret)
return TGCS_UNSUPPORTED_CDB;
@@ -5779,7 +5758,6 @@ static int transport_generic_cmd_sequenc
ret = TGCS_DATA_SG_IO_CDB;
break;
case READ_10:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
sectors = transport_get_sectors_10(cdb, cmd, §or_ret);
if (sector_ret)
return TGCS_UNSUPPORTED_CDB;
@@ -5791,7 +5769,6 @@ static int transport_generic_cmd_sequenc
ret = TGCS_DATA_SG_IO_CDB;
break;
case READ_12:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
sectors = transport_get_sectors_12(cdb, cmd, §or_ret);
if (sector_ret)
return TGCS_UNSUPPORTED_CDB;
@@ -5803,7 +5780,6 @@ static int transport_generic_cmd_sequenc
ret = TGCS_DATA_SG_IO_CDB;
break;
case READ_16:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
sectors = transport_get_sectors_16(cdb, cmd, §or_ret);
if (sector_ret)
return TGCS_UNSUPPORTED_CDB;
@@ -5815,7 +5791,6 @@ static int transport_generic_cmd_sequenc
ret = TGCS_DATA_SG_IO_CDB;
break;
case WRITE_6:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
sectors = transport_get_sectors_6(cdb, cmd, §or_ret);
if (sector_ret)
return TGCS_UNSUPPORTED_CDB;
@@ -5827,7 +5802,6 @@ static int transport_generic_cmd_sequenc
ret = TGCS_DATA_SG_IO_CDB;
break;
case WRITE_10:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
sectors = transport_get_sectors_10(cdb, cmd, §or_ret);
if (sector_ret)
return TGCS_UNSUPPORTED_CDB;
@@ -5840,7 +5814,6 @@ static int transport_generic_cmd_sequenc
ret = TGCS_DATA_SG_IO_CDB;
break;
case WRITE_12:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
sectors = transport_get_sectors_12(cdb, cmd, §or_ret);
if (sector_ret)
return TGCS_UNSUPPORTED_CDB;
@@ -5853,7 +5826,6 @@ static int transport_generic_cmd_sequenc
ret = TGCS_DATA_SG_IO_CDB;
break;
case WRITE_16:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
sectors = transport_get_sectors_16(cdb, cmd, §or_ret);
if (sector_ret)
return TGCS_UNSUPPORTED_CDB;
@@ -5866,7 +5838,6 @@ static int transport_generic_cmd_sequenc
ret = TGCS_DATA_SG_IO_CDB;
break;
case XDWRITEREAD_10:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
if ((cmd->data_direction != DMA_TO_DEVICE) ||
!(T_TASK(cmd)->t_tasks_bidi))
return TGCS_INVALID_CDB_FIELD;
@@ -5893,7 +5864,6 @@ static int transport_generic_cmd_sequenc
ret = TGCS_DATA_SG_IO_CDB;
break;
case VARIABLE_LENGTH_CMD:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
service_action = get_unaligned_be16(&cdb[8]);
/*
* Check the additional CDB length (+ 8 bytes for header) does
@@ -5983,7 +5953,6 @@ static int transport_generic_cmd_sequenc
}
break;
case 0xa3:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
if (TRANSPORT(dev)->get_device_type(dev) != TYPE_ROM) {
/* MAINTENANCE_IN from SCC-2 */
/*
@@ -6007,21 +5976,18 @@ static int transport_generic_cmd_sequenc
ret = TGCS_CONTROL_NONSG_IO_CDB;
break;
case MODE_SELECT:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
size = cdb[4];
transport_dev_get_mem_SG(cmd->se_orig_obj_ptr, cmd);
transport_get_maps(cmd);
ret = TGCS_CONTROL_SG_IO_CDB;
break;
case MODE_SELECT_10:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
size = (cdb[7] << 8) + cdb[8];
transport_dev_get_mem_SG(cmd->se_orig_obj_ptr, cmd);
transport_get_maps(cmd);
ret = TGCS_CONTROL_SG_IO_CDB;
break;
case MODE_SENSE:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
size = cdb[4];
transport_dev_get_mem_buf(cmd->se_orig_obj_ptr, cmd);
transport_get_maps(cmd);
@@ -6032,14 +5998,12 @@ static int transport_generic_cmd_sequenc
case GPCMD_SEND_OPC:
case LOG_SELECT:
case LOG_SENSE:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
size = (cdb[7] << 8) + cdb[8];
transport_dev_get_mem_buf(cmd->se_orig_obj_ptr, cmd);
transport_get_maps(cmd);
ret = TGCS_CONTROL_NONSG_IO_CDB;
break;
case READ_BLOCK_LIMITS:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
size = READ_BLOCK_LEN;
transport_dev_get_mem_buf(cmd->se_orig_obj_ptr, cmd);
transport_get_maps(cmd);
@@ -6049,7 +6013,6 @@ static int transport_generic_cmd_sequenc
case GPCMD_READ_FORMAT_CAPACITIES:
case GPCMD_READ_DISC_INFO:
case GPCMD_READ_TRACK_RZONE_INFO:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
size = (cdb[7] << 8) + cdb[8];
transport_dev_get_mem_SG(cmd->se_orig_obj_ptr, cmd);
transport_get_maps(cmd);
@@ -6057,7 +6020,6 @@ static int transport_generic_cmd_sequenc
break;
case PERSISTENT_RESERVE_IN:
case PERSISTENT_RESERVE_OUT:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
cmd->transport_emulate_cdb =
(T10_RES(su_dev)->res_type ==
SPC3_PERSISTENT_RESERVATIONS) ?
@@ -6069,21 +6031,18 @@ static int transport_generic_cmd_sequenc
break;
case GPCMD_MECHANISM_STATUS:
case GPCMD_READ_DVD_STRUCTURE:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
size = (cdb[8] << 8) + cdb[9];
transport_dev_get_mem_SG(cmd->se_orig_obj_ptr, cmd);
transport_get_maps(cmd);
ret = TGCS_CONTROL_SG_IO_CDB;
break;
case READ_POSITION:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
size = READ_POSITION_LEN;
transport_dev_get_mem_buf(cmd->se_orig_obj_ptr, cmd);
transport_get_maps(cmd);
ret = TGCS_CONTROL_NONSG_IO_CDB;
break;
case 0xa4:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
if (TRANSPORT(dev)->get_device_type(dev) != TYPE_ROM) {
/* MAINTENANCE_OUT from SCC-2
*
@@ -6108,7 +6067,6 @@ static int transport_generic_cmd_sequenc
ret = TGCS_CONTROL_NONSG_IO_CDB;
break;
case INQUIRY:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
size = (cdb[3] << 8) + cdb[4];
transport_dev_get_mem_buf(cmd->se_orig_obj_ptr, cmd);
transport_get_maps(cmd);
@@ -6121,14 +6079,12 @@ static int transport_generic_cmd_sequenc
ret = TGCS_CONTROL_NONSG_IO_CDB;
break;
case READ_BUFFER:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
size = (cdb[6] << 16) + (cdb[7] << 8) + cdb[8];
transport_dev_get_mem_buf(cmd->se_orig_obj_ptr, cmd);
transport_get_maps(cmd);
ret = TGCS_CONTROL_NONSG_IO_CDB;
break;
case READ_CAPACITY:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
size = READ_CAP_LEN;
transport_dev_get_mem_buf(cmd->se_orig_obj_ptr, cmd);
transport_get_maps(cmd);
@@ -6137,7 +6093,6 @@ static int transport_generic_cmd_sequenc
case READ_MEDIA_SERIAL_NUMBER:
case SECURITY_PROTOCOL_IN:
case SECURITY_PROTOCOL_OUT:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
size = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9];
transport_dev_get_mem_buf(cmd->se_orig_obj_ptr, cmd);
transport_get_maps(cmd);
@@ -6150,7 +6105,6 @@ static int transport_generic_cmd_sequenc
case READ_ATTRIBUTE:
case RECEIVE_COPY_RESULTS:
case WRITE_ATTRIBUTE:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
size = (cdb[10] << 24) | (cdb[11] << 16) |
(cdb[12] << 8) | cdb[13];
transport_dev_get_mem_buf(cmd->se_orig_obj_ptr, cmd);
@@ -6159,7 +6113,6 @@ static int transport_generic_cmd_sequenc
break;
case RECEIVE_DIAGNOSTIC:
case SEND_DIAGNOSTIC:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
size = (cdb[3] << 8) | cdb[4];
transport_dev_get_mem_buf(cmd->se_orig_obj_ptr, cmd);
transport_get_maps(cmd);
@@ -6168,7 +6121,6 @@ static int transport_generic_cmd_sequenc
/* #warning FIXME: Figure out correct GPCMD_READ_CD blocksize. */
#if 0
case GPCMD_READ_CD:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
sectors = (cdb[6] << 16) + (cdb[7] << 8) + cdb[8];
size = (2336 * sectors);
transport_dev_get_mem_buf(cmd->se_orig_obj_ptr, cmd);
@@ -6177,28 +6129,24 @@ static int transport_generic_cmd_sequenc
break;
#endif
case READ_TOC:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
size = cdb[8];
transport_dev_get_mem_buf(cmd->se_orig_obj_ptr, cmd);
transport_get_maps(cmd);
ret = TGCS_CONTROL_NONSG_IO_CDB;
break;
case REQUEST_SENSE:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
size = cdb[4];
transport_dev_get_mem_buf(cmd->se_orig_obj_ptr, cmd);
transport_get_maps(cmd);
ret = TGCS_CONTROL_NONSG_IO_CDB;
break;
case READ_ELEMENT_STATUS:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
size = 65536 * cdb[7] + 256 * cdb[8] + cdb[9];
transport_dev_get_mem_buf(cmd->se_orig_obj_ptr, cmd);
transport_get_maps(cmd);
ret = TGCS_CONTROL_NONSG_IO_CDB;
break;
case WRITE_BUFFER:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
size = (cdb[6] << 16) + (cdb[7] << 8) + cdb[8];
transport_dev_get_mem_buf(cmd->se_orig_obj_ptr, cmd);
transport_get_maps(cmd);
@@ -6215,7 +6163,6 @@ static int transport_generic_cmd_sequenc
else
size = cmd->data_length;
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
cmd->transport_allocate_resources =
&transport_generic_allocate_none;
transport_get_maps(cmd);
@@ -6243,7 +6190,6 @@ static int transport_generic_cmd_sequenc
else
size = cmd->data_length;
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
cmd->transport_allocate_resources =
&transport_generic_allocate_none;
transport_get_maps(cmd);
@@ -6255,7 +6201,6 @@ static int transport_generic_cmd_sequenc
break;
case SYNCHRONIZE_CACHE:
case 0x91: /* SYNCHRONIZE_CACHE_16: */
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
cmd->transport_allocate_resources =
&transport_generic_allocate_none;
transport_get_maps(cmd);
@@ -6292,7 +6237,6 @@ static int transport_generic_cmd_sequenc
return TGCS_INVALID_CDB_FIELD;
break;
case UNMAP:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
cmd->transport_allocate_resources =
&transport_generic_allocate_buf;
size = get_unaligned_be16(&cdb[7]);
@@ -6313,7 +6257,6 @@ static int transport_generic_cmd_sequenc
ret = TGCS_CONTROL_NONSG_IO_CDB;
break;
case WRITE_SAME_16:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
cmd->transport_allocate_resources =
&transport_generic_allocate_buf;
sectors = transport_get_sectors_16(cdb, cmd, §or_ret);
@@ -6365,14 +6308,12 @@ static int transport_generic_cmd_sequenc
case VERIFY:
case WRITE_FILEMARKS:
case MOVE_MEDIUM:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
cmd->transport_allocate_resources =
&transport_generic_allocate_none;
transport_get_maps(cmd);
ret = TGCS_NON_DATA_CDB;
break;
case REPORT_LUNS:
- SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
cmd->transport_emulate_cdb =
&transport_core_report_lun_response;
size = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9];
@@ -7258,23 +7199,6 @@ non_scsi_data:
return 0;
}
-/* transport_generic_do_transform():
- *
- *
- */
-int transport_generic_do_transform(struct se_cmd *cmd, struct se_transform_info *ti)
-{
- if (!(cmd->transport_cdb_transform)) {
- dump_stack();
- return -1;
- }
-
- if (cmd->transport_cdb_transform(cmd, ti) < 0)
- return -1;
-
- return 0;
-}
-
static inline long long transport_dev_end_lba(struct se_device *dev)
{
return dev->dev_sectors_total + 1;
@@ -7306,7 +7230,7 @@ int transport_get_sectors(struct se_cmd
return 0;
}
-int transport_new_cmd_obj(
+static int transport_new_cmd_obj(
struct se_cmd *cmd,
struct se_transform_info *ti,
int post_execute)
@@ -7365,7 +7289,6 @@ int transport_new_cmd_obj(
#endif
}
- cmd->transport_do_transform = &transport_generic_do_transform;
if (!post_execute) {
atomic_set(&T_TASK(cmd)->t_task_cdbs_left, task_cdbs);
atomic_set(&T_TASK(cmd)->t_task_cdbs_ex_left, task_cdbs);
@@ -8016,12 +7939,7 @@ u32 transport_generic_get_cdb_count(
CMD_TFO(cmd)->get_task_tag(cmd), lba, sectors,
transport_dev_end_lba(dev));
- if (!(cmd->transport_get_task)) {
- dump_stack();
- goto out;
- }
-
- task = cmd->transport_get_task(ti, cmd, dev, data_direction);
+ task = transport_generic_get_task(ti, cmd, dev, data_direction);
if (!(task))
goto out;
@@ -8158,21 +8076,27 @@ int transport_generic_new_cmd(struct se_
}
}
}
- /*
- * This is dependent upon the storage processing algorithm.
- */
- if (cmd->transport_do_transform(cmd, &ti) < 0) {
+
+ if (!(cmd->transport_cdb_transform)) {
+ dump_stack();
+ ret = PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES;
+ goto failure;
+ }
+
+ if (cmd->transport_cdb_transform(cmd, &ti) < 0) {
ret = PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES;
goto failure;
}
+
/*
* Set the correct (usually DMAable) buffer pointers from the master
* buffer list in struct se_cmd to the transport task's native
* buffers format.
*/
- ret = cmd->transport_map_buffers_to_tasks(cmd);
+ ret = transport_generic_map_buffers_to_tasks(cmd);
if (ret < 0)
goto failure;
+
/*
* For WRITEs, let the iSCSI Target RX Thread know its buffer is ready..
* This WRITE struct se_cmd (and all of its associated struct se_task's)
Index: lio-core-2.6/include/target/target_core_base.h
===================================================================
--- lio-core-2.6.orig/include/target/target_core_base.h 2010-11-06 19:54:02.404025601 +0100
+++ lio-core-2.6/include/target/target_core_base.h 2010-11-06 20:12:40.348261038 +0100
@@ -608,25 +608,16 @@ struct se_cmd {
struct se_transport_task *t_task;
struct se_transport_task t_task_backstore;
struct target_core_fabric_ops *se_tfo;
- int (*transport_add_cmd_to_queue)(struct se_cmd *, int);
int (*transport_allocate_resources)(struct se_cmd *, u32, u32);
int (*transport_cdb_transform)(struct se_cmd *,
struct se_transform_info *);
- int (*transport_do_transform)(struct se_cmd *,
- struct se_transform_info *);
int (*transport_emulate_cdb)(struct se_cmd *);
void (*transport_free_resources)(struct se_cmd *);
u32 (*transport_get_lba)(unsigned char *);
unsigned long long (*transport_get_long_lba)(unsigned char *);
- struct se_task *(*transport_get_task)(struct se_transform_info *,
- struct se_cmd *, void *,
- enum dma_data_direction);
- int (*transport_map_buffers_to_tasks)(struct se_cmd *);
void (*transport_map_SG_segments)(struct se_unmap_sg *);
void (*transport_passthrough_done)(struct se_cmd *);
void (*transport_unmap_SG_segments)(struct se_unmap_sg *);
- int (*transport_set_iovec_ptrs)(struct se_map_sg *,
- struct se_unmap_sg *);
void (*transport_split_cdb)(unsigned long long, u32 *, unsigned char *);
void (*transport_wait_for_tasks)(struct se_cmd *, int, int);
void (*transport_complete_callback)(struct se_cmd *);
Index: lio-core-2.6/include/target/target_core_transport.h
===================================================================
--- lio-core-2.6.orig/include/target/target_core_transport.h 2010-11-06 19:54:02.416004160 +0100
+++ lio-core-2.6/include/target/target_core_transport.h 2010-11-06 20:16:00.956255873 +0100
@@ -159,8 +159,7 @@ extern void transport_task_dev_remove_st
struct se_device *);
extern void transport_cmd_finish_abort(struct se_cmd *, int);
extern void transport_cmd_finish_abort_tmr(struct se_cmd *);
-extern int transport_add_cmd_to_queue(struct se_cmd *,
- struct se_queue_obj *, int);
+extern int transport_add_cmd_to_queue(struct se_cmd *, int);
extern struct se_queue_req *__transport_get_qr_from_queue(
struct se_queue_obj *);
extern void transport_remove_cmd_from_queue(struct se_cmd *,
@@ -172,8 +171,6 @@ extern void transport_add_task_to_execut
struct se_task *,
struct se_device *);
extern void transport_add_tasks_from_cmd(struct se_cmd *);
-extern struct se_task *transport_get_task_from_execute_queue(
- struct se_device *);
extern struct se_queue_req *transport_get_qr_from_queue(struct se_queue_obj *);
extern int transport_check_device_tcq(struct se_device *, u32, u32);
unsigned char *transport_dump_cmd_direction(struct se_cmd *);
@@ -272,11 +269,7 @@ extern void transport_send_task_abort(st
extern void transport_release_cmd_to_pool(struct se_cmd *);
extern void transport_generic_free_cmd(struct se_cmd *, int, int, int);
extern void transport_generic_wait_for_cmds(struct se_cmd *, int);
-extern int transport_generic_do_transform(struct se_cmd *,
- struct se_transform_info *);
extern int transport_get_sectors(struct se_cmd *);
-extern int transport_new_cmd_obj(struct se_cmd *,
- struct se_transform_info *, int);
extern unsigned char *transport_get_vaddr(struct se_mem *);
extern struct list_head *transport_init_se_mem_list(void);
extern void transport_free_se_mem_list(struct list_head *);
@@ -296,6 +289,8 @@ extern u32 transport_generic_get_cdb_cou
extern int transport_generic_new_cmd(struct se_cmd *);
extern void transport_generic_process_write(struct se_cmd *);
extern int transport_generic_do_tmr(struct se_cmd *);
+extern int transport_generic_set_iovec_ptrs(struct se_map_sg *map_sg,
+ struct se_unmap_sg *unmap_sg);
/* From target_core_alua.c */
extern int core_alua_check_nonop_delay(struct se_cmd *);
Index: lio-core-2.6/drivers/target/lio-target/iscsi_target.c
===================================================================
--- lio-core-2.6.orig/drivers/target/lio-target/iscsi_target.c 2010-11-06 19:54:02.387010236 +0100
+++ lio-core-2.6/drivers/target/lio-target/iscsi_target.c 2010-11-06 20:12:40.361004229 +0100
@@ -1944,7 +1944,7 @@ static inline int iscsi_handle_data_out(
unmap_sg.fabric_cmd = (void *)cmd;
unmap_sg.se_cmd = SE_CMD(cmd);
- iov_ret = SE_CMD(cmd)->transport_set_iovec_ptrs(&map_sg, &unmap_sg);
+ iov_ret = transport_generic_set_iovec_ptrs(&map_sg, &unmap_sg);
if (iov_ret < 0)
return -1;
@@ -1989,8 +1989,7 @@ static inline int iscsi_handle_data_out(
map_sg.data_length = hdr->length;
map_sg.data_offset = hdr->offset;
- if (SE_CMD(cmd)->transport_set_iovec_ptrs(
- &map_sg, &unmap_sg) < 0)
+ if (transport_generic_set_iovec_ptrs(&map_sg, &unmap_sg) < 0)
return -1;
crypto_hash_init(&conn->conn_rx_hash);
@@ -2971,7 +2970,7 @@ static int iscsi_handle_immediate_data(
unmap_sg.fabric_cmd = (void *)cmd;
unmap_sg.se_cmd = SE_CMD(cmd);
- iov_ret = SE_CMD(cmd)->transport_set_iovec_ptrs(&map_sg, &unmap_sg);
+ iov_ret = transport_generic_set_iovec_ptrs(&map_sg, &unmap_sg);
if (iov_ret < 0)
return IMMEDIDATE_DATA_CANNOT_RECOVER;
@@ -3019,8 +3018,7 @@ static int iscsi_handle_immediate_data(
map_sg.data_length = length;
map_sg.data_offset = cmd->write_data_done;
- if (SE_CMD(cmd)->transport_set_iovec_ptrs(&map_sg,
- &unmap_sg) < 0)
+ if (transport_generic_set_iovec_ptrs(&map_sg, &unmap_sg) < 0)
return IMMEDIDATE_DATA_CANNOT_RECOVER;
crypto_hash_init(&conn->conn_rx_hash);
@@ -3454,7 +3452,7 @@ static inline int iscsi_send_data_in(
map_sg.data_length = datain.length;
map_sg.data_offset = datain.offset;
- iov_ret = SE_CMD(cmd)->transport_set_iovec_ptrs(&map_sg, unmap_sg);
+ iov_ret = transport_generic_set_iovec_ptrs(&map_sg, unmap_sg);
if (iov_ret < 0)
return -1;
Index: lio-core-2.6/drivers/target/tcm_loop/tcm_loop_fabric_scsi.c
===================================================================
--- lio-core-2.6.orig/drivers/target/tcm_loop/tcm_loop_fabric_scsi.c 2010-11-06 19:54:02.395010935 +0100
+++ lio-core-2.6/drivers/target/tcm_loop/tcm_loop_fabric_scsi.c 2010-11-06 20:12:40.367032166 +0100
@@ -122,11 +122,8 @@ static struct se_cmd *tcm_loop_allocate_
se_cmd->scsi_sense_reason, 0);
return 0;
}
- /*
- * Make early call to setup se_cmd->transport_add_cmd_to_queue() pointer
- */
- transport_device_setup_cmd(se_cmd);
+ transport_device_setup_cmd(se_cmd);
return se_cmd;
}
@@ -353,7 +350,7 @@ static int tcm_loop_queuecommand(
/*
* Queue up the newly allocated to be processed in TCM thread context.
*/
- se_cmd->transport_add_cmd_to_queue(se_cmd, TRANSPORT_NEW_CMD_MAP);
+ transport_add_cmd_to_queue(se_cmd, TRANSPORT_NEW_CMD_MAP);
/*
* Reaquire the the struct scsi_host->host_lock before returning
*/
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 2/9] target: remove activate_device/deactivate_device methods
2010-11-08 15:56 [PATCH 0/9] target core review feedback Christoph Hellwig
2010-11-08 15:56 ` [PATCH 1/9] target: remove never changing indirections in se_cmd Christoph Hellwig
@ 2010-11-08 15:56 ` Christoph Hellwig
2010-11-08 22:00 ` Nicholas A. Bellinger
2010-11-08 15:56 ` [PATCH 3/9] From: Christoph Hellwig <hch@lst.de> Sujbect: target: remove SHUTDOWN_SIGS Christoph Hellwig
` (7 subsequent siblings)
9 siblings, 1 reply; 23+ messages in thread
From: Christoph Hellwig @ 2010-11-08 15:56 UTC (permalink / raw)
To: nab; +Cc: linux-scsi
[-- Attachment #1: lio-cleanup-activate-deactivate --]
[-- Type: text/plain, Size: 16159 bytes --]
These are no-ops in all backends. Also remove the waitqueues around
kthread start/stop for each device as kthread_run/stop are synchronous.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Index: lio-core-2.6/drivers/target/target_core_file.c
===================================================================
--- lio-core-2.6.orig/drivers/target/target_core_file.c 2010-11-06 20:18:44.613011213 +0100
+++ lio-core-2.6/drivers/target/target_core_file.c 2010-11-06 20:19:08.470663550 +0100
@@ -266,38 +266,6 @@ fail:
return NULL;
}
-/* fd_activate_device(): (Part of se_subsystem_api_t template)
- *
- *
- */
-static int fd_activate_device(struct se_device *dev)
-{
- struct fd_dev *fd_dev = dev->dev_ptr;
- struct fd_host *fd_host = fd_dev->fd_host;
-
- printk(KERN_INFO "CORE_FILE[%u] - Activating Device with TCQ: %d at"
- " FILEIO Device ID: %d\n", fd_host->fd_host_id,
- fd_dev->fd_queue_depth, fd_dev->fd_dev_id);
-
- return 0;
-}
-
-/* fd_deactivate_device(): (Part of se_subsystem_api_t template)
- *
- *
- */
-static void fd_deactivate_device(struct se_device *dev)
-{
- struct fd_dev *fd_dev = dev->dev_ptr;
- struct fd_host *fd_host = fd_dev->fd_host;
-
- printk(KERN_INFO "CORE_FILE[%u] - Deactivating Device with TCQ: %d at"
- " FILEIO Device ID: %d\n", fd_host->fd_host_id,
- fd_dev->fd_queue_depth, fd_dev->fd_dev_id);
-
- return;
-}
-
/* fd_free_device(): (Part of se_subsystem_api_t template)
*
*
@@ -997,8 +965,6 @@ static struct se_subsystem_api fileio_te
.cdb_write_SG = fd_CDB_write_SG,
.allocate_virtdevice = fd_allocate_virtdevice,
.create_virtdevice = fd_create_virtdevice,
- .activate_device = fd_activate_device,
- .deactivate_device = fd_deactivate_device,
.free_device = fd_free_device,
.dpo_emulated = fd_emulated_dpo,
.fua_write_emulated = fd_emulated_fua_write,
Index: lio-core-2.6/drivers/target/target_core_iblock.c
===================================================================
--- lio-core-2.6.orig/drivers/target/target_core_iblock.c 2010-11-06 20:17:55.062262645 +0100
+++ lio-core-2.6/drivers/target/target_core_iblock.c 2010-11-06 20:18:39.142005277 +0100
@@ -247,36 +247,6 @@ failed:
return NULL;
}
-/* iblock_activate_device(): (Part of se_subsystem_api_t template)
- *
- *
- */
-static int iblock_activate_device(struct se_device *dev)
-{
- struct iblock_dev *ib_dev = dev->dev_ptr;
- struct iblock_hba *ib_hba = ib_dev->ibd_host;
-
- printk(KERN_INFO "CORE_iBLOCK[%u] - Activating Device with TCQ: %d at"
- " Major: %d Minor %d\n", ib_hba->iblock_host_id,
- ib_dev->ibd_depth, ib_dev->ibd_major, ib_dev->ibd_minor);
-
- return 0;
-}
-
-/* iblock_deactivate_device(): (Part of se_subsystem_api_t template)
- *
- *
- */
-static void iblock_deactivate_device(struct se_device *dev)
-{
- struct iblock_dev *ib_dev = dev->dev_ptr;
- struct iblock_hba *ib_hba = ib_dev->ibd_host;
-
- printk(KERN_INFO "CORE_iBLOCK[%u] - Deactivating Device with TCQ: %d"
- " at Major: %d Minor %d\n", ib_hba->iblock_host_id,
- ib_dev->ibd_depth, ib_dev->ibd_major, ib_dev->ibd_minor);
-}
-
static void iblock_free_device(void *p)
{
struct iblock_dev *ib_dev = p;
@@ -963,8 +933,6 @@ static struct se_subsystem_api iblock_te
.detach_hba = iblock_detach_hba,
.allocate_virtdevice = iblock_allocate_virtdevice,
.create_virtdevice = iblock_create_virtdevice,
- .activate_device = iblock_activate_device,
- .deactivate_device = iblock_deactivate_device,
.free_device = iblock_free_device,
.dpo_emulated = iblock_emulated_dpo,
.fua_write_emulated = iblock_emulated_fua_write,
Index: lio-core-2.6/drivers/target/target_core_pscsi.c
===================================================================
--- lio-core-2.6.orig/drivers/target/target_core_pscsi.c 2010-11-06 20:18:54.140024065 +0100
+++ lio-core-2.6/drivers/target/target_core_pscsi.c 2010-11-06 20:19:03.139048436 +0100
@@ -565,42 +565,6 @@ static struct se_device *pscsi_create_vi
return NULL;
}
-/* pscsi_activate_device(): (Part of se_subsystem_api_t template)
- *
- *
- */
-static int pscsi_activate_device(struct se_device *dev)
-{
- struct pscsi_dev_virt *pdv = dev->dev_ptr;
- struct pscsi_hba_virt *phv = pdv->pdv_se_hba->hba_ptr;
- struct scsi_device *sd = pdv->pdv_sd;
- struct Scsi_Host *sh = sd->host;
-
- printk(KERN_INFO "CORE_PSCSI[%d] - Activating Device with TCQ: %d at"
- " SCSI Location (Host/Channel/Target/LUN) %d/%d/%d/%d\n",
- phv->phv_host_id, sd->queue_depth, sh->host_no, sd->channel,
- sd->id, sd->lun);
-
- return 0;
-}
-
-/* pscsi_deactivate_device(): (Part of se_subsystem_api_t template)
- *
- *
- */
-static void pscsi_deactivate_device(struct se_device *dev)
-{
- struct pscsi_dev_virt *pdv = dev->dev_ptr;
- struct pscsi_hba_virt *phv = pdv->pdv_se_hba->hba_ptr;
- struct scsi_device *sd = pdv->pdv_sd;
- struct Scsi_Host *sh = sd->host;
-
- printk(KERN_INFO "CORE_PSCSI[%d] - Deactivating Device with TCQ: %d at"
- " SCSI Location (Host/Channel/Target/LUN) %d/%d/%d/%d\n",
- phv->phv_host_id, sd->queue_depth, sh->host_no, sd->channel,
- sd->id, sd->lun);
-}
-
/* pscsi_free_device(): (Part of se_subsystem_api_t template)
*
*
@@ -1532,8 +1496,6 @@ static struct se_subsystem_api pscsi_tem
.attach_hba = pscsi_attach_hba,
.detach_hba = pscsi_detach_hba,
.pmode_enable_hba = pscsi_pmode_enable_hba,
- .activate_device = pscsi_activate_device,
- .deactivate_device = pscsi_deactivate_device,
.allocate_virtdevice = pscsi_allocate_virtdevice,
.create_virtdevice = pscsi_create_virtdevice,
.free_device = pscsi_free_device,
Index: lio-core-2.6/drivers/target/target_core_rd.c
===================================================================
--- lio-core-2.6.orig/drivers/target/target_core_rd.c 2010-11-06 20:19:14.701260270 +0100
+++ lio-core-2.6/drivers/target/target_core_rd.c 2010-11-06 20:19:30.633255381 +0100
@@ -330,36 +330,6 @@ static struct se_device *rd_MEMCPY_creat
return rd_create_virtdevice(hba, se_dev, p, 0);
}
-/* rd_activate_device(): (Part of se_subsystem_api_t template)
- *
- *
- */
-static int rd_activate_device(struct se_device *dev)
-{
- struct rd_dev *rd_dev = dev->dev_ptr;
- struct rd_host *rd_host = rd_dev->rd_host;
-
- printk(KERN_INFO "CORE_RD[%u] - Activating Device with TCQ: %d at"
- " Ramdisk Device ID: %d\n", rd_host->rd_host_id,
- rd_dev->rd_queue_depth, rd_dev->rd_dev_id);
-
- return 0;
-}
-
-/* rd_deactivate_device(): (Part of se_subsystem_api_t template)
- *
- *
- */
-static void rd_deactivate_device(struct se_device *dev)
-{
- struct rd_dev *rd_dev = dev->dev_ptr;
- struct rd_host *rd_host = rd_dev->rd_host;
-
- printk(KERN_INFO "CORE_RD[%u] - Deactivating Device with TCQ: %d at"
- " Ramdisk Device ID: %d\n", rd_host->rd_host_id,
- rd_dev->rd_queue_depth, rd_dev->rd_dev_id);
-}
-
/* rd_free_device(): (Part of se_subsystem_api_t template)
*
*
@@ -1323,8 +1293,6 @@ static struct se_subsystem_api rd_dr_tem
.detach_hba = rd_detach_hba,
.allocate_virtdevice = rd_DIRECT_allocate_virtdevice,
.create_virtdevice = rd_DIRECT_create_virtdevice,
- .activate_device = rd_activate_device,
- .deactivate_device = rd_deactivate_device,
.free_device = rd_free_device,
.transport_complete = rd_transport_complete,
.allocate_DMA = rd_DIRECT_allocate_DMA,
@@ -1363,8 +1331,6 @@ static struct se_subsystem_api rd_mcp_te
.detach_hba = rd_detach_hba,
.allocate_virtdevice = rd_MEMCPY_allocate_virtdevice,
.create_virtdevice = rd_MEMCPY_create_virtdevice,
- .activate_device = rd_activate_device,
- .deactivate_device = rd_deactivate_device,
.free_device = rd_free_device,
.transport_complete = rd_transport_complete,
.allocate_request = rd_allocate_request,
Index: lio-core-2.6/drivers/target/target_core_stgt.c
===================================================================
--- lio-core-2.6.orig/drivers/target/target_core_stgt.c 2010-11-06 20:19:40.388254264 +0100
+++ lio-core-2.6/drivers/target/target_core_stgt.c 2010-11-06 20:19:49.419190498 +0100
@@ -314,40 +314,6 @@ static struct se_device *stgt_create_vir
return NULL;
}
-/* stgt_activate_device(): (Part of se_subsystem_api_t template)
- *
- *
- */
-static int stgt_activate_device(struct se_device *dev)
-{
- struct stgt_dev_virt *sdv = dev->dev_ptr;
- struct scsi_device *sd = sdv->sdv_sd;
- struct Scsi_Host *sh = sd->host;
-
- printk(KERN_INFO "CORE_STGT[%d] - Activating %s Device with TCQ: %d at"
- " SCSI Location (Channel/Target/LUN) %d/%d/%d\n", sh->host_no,
- (sdv->sdv_legacy) ? "Legacy" : "REQ", sd->queue_depth,
- sd->channel, sd->id, sd->lun);
-
- return 0;
-}
-
-/* stgt_deactivate_device(): (Part of se_subsystem_api_t template)
- *
- *
- */
-static void stgt_deactivate_device(struct se_device *dev)
-{
- struct stgt_dev_virt *sdv = dev->dev_ptr;
- struct scsi_device *sd = sdv->sdv_sd;
- struct Scsi_Host *sh = sd->host;
-
- printk(KERN_INFO "CORE_STGT[%d] - Deactivating %s Device with TCQ: %d"
- " at SCSI Location (Channel/Target/LUN) %d/%d/%d\n",
- sh->host_no, (sdv->sdv_legacy) ? "Legacy" : "REQ",
- sd->queue_depth, sd->channel, sd->id, sd->lun);
-}
-
/* stgt_free_device(): (Part of se_subsystem_api_t template)
*
*
@@ -877,8 +843,6 @@ static struct se_subsystem_api stgt_temp
.cdb_write_SG = stgt_CDB_write_SG,
.attach_hba = stgt_attach_hba,
.detach_hba = stgt_detach_hba,
- .activate_device = stgt_activate_device,
- .deactivate_device = stgt_deactivate_device,
.allocate_virtdevice = stgt_allocate_virtdevice,
.create_virtdevice = stgt_create_virtdevice,
.free_device = stgt_free_device,
Index: lio-core-2.6/drivers/target/target_core_transport.c
===================================================================
--- lio-core-2.6.orig/drivers/target/target_core_transport.c 2010-11-06 20:20:04.617254054 +0100
+++ lio-core-2.6/drivers/target/target_core_transport.c 2010-11-06 20:28:22.335005310 +0100
@@ -503,8 +503,6 @@ void transport_init_queue_obj(struct se_
atomic_set(&qobj->queue_cnt, 0);
INIT_LIST_HEAD(&qobj->qobj_list);
init_waitqueue_head(&qobj->thread_wq);
- init_completion(&qobj->thread_create_comp);
- init_completion(&qobj->thread_done_comp);
spin_lock_init(&qobj->cmd_queue_lock);
}
EXPORT_SYMBOL(transport_init_queue_obj);
@@ -2296,11 +2294,18 @@ struct se_device *transport_add_device_t
*/
if (core_setup_alua(dev, force_pt) < 0)
goto out;
+
/*
* Startup the struct se_device processing thread
*/
- if (transport_generic_activate_device(dev) < 0)
+ dev->process_thread = kthread_run(transport_processing_thread, dev,
+ "LIO_%s", TRANSPORT(dev)->name);
+ if (IS_ERR(dev->process_thread)) {
+ printk(KERN_ERR "Unable to create kthread: LIO_%s\n",
+ TRANSPORT(dev)->name);
goto out;
+ }
+
/*
* Preload the initial INQUIRY const values if we are doing
* anything virtual (IBLOCK, FILEIO, RAMDISK), but not for TCM/pSCSI
@@ -2352,10 +2357,7 @@ struct se_device *transport_add_device_t
out:
if (!ret)
return dev;
- /*
- * Release newly allocated state for struct se_device
- */
- transport_generic_deactivate_device(dev);
+ kthread_stop(dev->process_thread);
spin_lock(&hba->device_lock);
list_del(&dev->dev_list);
@@ -2372,46 +2374,6 @@ out:
}
EXPORT_SYMBOL(transport_add_device_to_core_hba);
-/* transport_generic_activate_device():
- *
- *
- */
-int transport_generic_activate_device(struct se_device *dev)
-{
- char name[16];
-
- if (TRANSPORT(dev)->activate_device)
- TRANSPORT(dev)->activate_device(dev);
-
- memset(name, 0, 16);
- snprintf(name, 16, "LIO_%s", TRANSPORT(dev)->name);
-
- dev->process_thread = kthread_run(transport_processing_thread,
- (void *)dev, name);
- if (IS_ERR(dev->process_thread)) {
- printk(KERN_ERR "Unable to create kthread: %s\n", name);
- return -1;
- }
-
- wait_for_completion(&dev->dev_queue_obj->thread_create_comp);
-
- return 0;
-}
-
-/* transport_generic_deactivate_device():
- *
- *
- */
-void transport_generic_deactivate_device(struct se_device *dev)
-{
- if (TRANSPORT(dev)->deactivate_device)
- TRANSPORT(dev)->deactivate_device(dev);
-
- kthread_stop(dev->process_thread);
-
- wait_for_completion(&dev->dev_queue_obj->thread_done_comp);
-}
-
/* transport_generic_free_device():
*
*
@@ -2421,7 +2383,7 @@ void transport_generic_free_device(struc
if (!(dev->dev_ptr))
return;
- transport_generic_deactivate_device(dev);
+ kthread_stop(dev->process_thread);
if (TRANSPORT(dev)->free_device)
TRANSPORT(dev)->free_device(dev->dev_ptr);
@@ -9098,8 +9060,6 @@ static int transport_processing_thread(v
recalc_sigpending();
spin_unlock_irq(¤t->sighand->siglock);
- complete(&dev->dev_queue_obj->thread_create_comp);
-
while (!(kthread_should_stop())) {
ret = wait_event_interruptible(dev->dev_queue_obj->thread_wq,
atomic_read(&dev->dev_queue_obj->queue_cnt) ||
@@ -9187,6 +9147,5 @@ get_cmd:
out:
transport_release_all_cmds(dev);
dev->process_thread = NULL;
- complete(&dev->dev_queue_obj->thread_done_comp);
return 0;
}
Index: lio-core-2.6/drivers/target/tcm_fc/tfc_cmd.c
===================================================================
--- lio-core-2.6.orig/drivers/target/tcm_fc/tfc_cmd.c 2010-11-06 20:23:27.561023505 +0100
+++ lio-core-2.6/drivers/target/tcm_fc/tfc_cmd.c 2010-11-06 20:24:45.698005617 +0100
@@ -654,8 +654,6 @@ int ft_thread(void *arg)
recalc_sigpending();
spin_unlock_irq(¤t->sighand->siglock);
- complete(&qobj->thread_create_comp);
-
while (!(kthread_should_stop())) {
ret = wait_event_interruptible(qobj->thread_wq,
atomic_read(&qobj->queue_cnt) || kthread_should_stop());
@@ -667,6 +665,5 @@ int ft_thread(void *arg)
}
out:
- complete(&qobj->thread_done_comp);
return 0;
}
Index: lio-core-2.6/drivers/target/tcm_fc/tfc_conf.c
===================================================================
--- lio-core-2.6.orig/drivers/target/tcm_fc/tfc_conf.c 2010-11-06 20:23:35.362254054 +0100
+++ lio-core-2.6/drivers/target/tcm_fc/tfc_conf.c 2010-11-06 20:24:38.170005695 +0100
@@ -342,7 +342,6 @@ static struct se_portal_group *ft_add_tp
kfree(tpg);
return NULL;
}
- wait_for_completion(&tpg->qobj.thread_create_comp);
mutex_lock(&ft_lport_lock);
list_add_tail(&tpg->list, &lacl->tpg_list);
@@ -359,7 +358,6 @@ static void ft_del_tpg(struct se_portal_
config_item_name(&tpg->se_tpg.tpg_group.cg_item));
kthread_stop(tpg->thread);
- wait_for_completion(&tpg->qobj.thread_done_comp);
/* Wait for sessions to be freed thru RCU, for BUG_ON below */
synchronize_rcu();
Index: lio-core-2.6/include/target/target_core_base.h
===================================================================
--- lio-core-2.6.orig/include/target/target_core_base.h 2010-11-06 20:23:53.939003740 +0100
+++ lio-core-2.6/include/target/target_core_base.h 2010-11-06 20:27:11.226005136 +0100
@@ -415,8 +415,6 @@ struct se_queue_obj {
spinlock_t cmd_queue_lock;
struct list_head qobj_list;
wait_queue_head_t thread_wq;
- struct completion thread_create_comp;
- struct completion thread_done_comp;
} ____cacheline_aligned;
/*
Index: lio-core-2.6/include/target/target_core_transport.h
===================================================================
--- lio-core-2.6.orig/include/target/target_core_transport.h 2010-11-06 20:21:04.487003811 +0100
+++ lio-core-2.6/include/target/target_core_transport.h 2010-11-06 20:21:09.952587550 +0100
@@ -191,8 +191,6 @@ extern struct se_device *transport_add_d
struct se_subsystem_dev *, u32,
void *, struct se_dev_limits *,
const char *, const char *);
-extern int transport_generic_activate_device(struct se_device *);
-extern void transport_generic_deactivate_device(struct se_device *);
extern void transport_generic_free_device(struct se_device *);
extern int transport_generic_allocate_iovecs(struct se_cmd *);
extern void transport_device_setup_cmd(struct se_cmd *);
@@ -383,14 +381,6 @@ struct se_subsystem_api {
struct se_device *(*create_virtdevice)(struct se_hba *,
struct se_subsystem_dev *, void *);
/*
- * activate_device():
- */
- int (*activate_device)(struct se_device *);
- /*
- * deactivate_device():
- */
- void (*deactivate_device)(struct se_device *);
- /*
* free_device():
*/
void (*free_device)(void *);
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 3/9] From: Christoph Hellwig <hch@lst.de> Sujbect: target: remove SHUTDOWN_SIGS
2010-11-08 15:56 [PATCH 0/9] target core review feedback Christoph Hellwig
2010-11-08 15:56 ` [PATCH 1/9] target: remove never changing indirections in se_cmd Christoph Hellwig
2010-11-08 15:56 ` [PATCH 2/9] target: remove activate_device/deactivate_device methods Christoph Hellwig
@ 2010-11-08 15:56 ` Christoph Hellwig
2010-11-08 22:21 ` [PATCH 3/9] " Nicholas A. Bellinger
2010-11-08 15:56 ` [PATCH 4/9] target: remove transport_generic_map_buffers_to_tasks Christoph Hellwig
` (6 subsequent siblings)
9 siblings, 1 reply; 23+ messages in thread
From: Christoph Hellwig @ 2010-11-08 15:56 UTC (permalink / raw)
To: nab; +Cc: linux-scsi
[-- Attachment #1: lio-fix-thread-shutdown --]
[-- Type: text/plain, Size: 5659 bytes --]
In the these days with the kthread API we should never send signals to
kernel threads, but let start/stop be handled by the kthread helpers.
Note that the set_user_nice for all threads in the target code does not
seem particularly nice to the rest of the system. Please re-evaluate if
the nice value is nessecary.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Index: lio-core-2.6/drivers/target/lio-target/iscsi_target.c
===================================================================
--- lio-core-2.6.orig/drivers/target/lio-target/iscsi_target.c 2010-11-06 20:36:08.953253984 +0100
+++ lio-core-2.6/drivers/target/lio-target/iscsi_target.c 2010-11-06 20:37:11.221005277 +0100
@@ -4524,13 +4524,8 @@ int iscsi_target_tx_thread(void *arg)
struct se_thread_set *ts = (struct se_thread_set *) arg;
struct se_unmap_sg unmap_sg;
- {
- char name[20];
-
- memset(name, 0, 20);
- sprintf(name, "%s/%u", ISCSI_TX_THREAD_NAME, ts->thread_id);
- iscsi_daemon(ts->tx_thread, name, SHUTDOWN_SIGS);
- }
+ set_user_nice(current, -20);
+ ts->tx_thread = current;
restart:
conn = iscsi_tx_thread_pre_handler(ts, TARGET);
@@ -4877,13 +4872,8 @@ int iscsi_target_rx_thread(void *arg)
struct iovec iov;
struct scatterlist sg;
- {
- char name[20];
-
- memset(name, 0, 20);
- sprintf(name, "%s/%u", ISCSI_RX_THREAD_NAME, ts->thread_id);
- iscsi_daemon(ts->rx_thread, name, SHUTDOWN_SIGS);
- }
+ set_user_nice(current, -20);
+ ts->rx_thread = current;
restart:
conn = iscsi_rx_thread_pre_handler(ts, TARGET);
Index: lio-core-2.6/drivers/target/lio-target/iscsi_target_core.h
===================================================================
--- lio-core-2.6.orig/drivers/target/lio-target/iscsi_target_core.h 2010-11-06 20:35:44.269003880 +0100
+++ lio-core-2.6/drivers/target/lio-target/iscsi_target_core.h 2010-11-06 20:37:38.953319148 +0100
@@ -10,7 +10,6 @@
#include <target/target_core_base.h>
-#define SHUTDOWN_SIGS (sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGABRT))
#define ISCSI_MISC_IOVECS 5
#define ISCSI_MAX_DATASN_MISSING_COUNT 16
#define ISCSI_TX_THREAD_TCP_TIMEOUT 2
@@ -258,21 +257,6 @@
#define TARGET_ERL_FORCE_TX_TRANSPORT_RESET 16
#define TARGET_ERL_FORCE_RX_TRANSPORT_RESET 17
-/*
- * Threads and timers
- */
-#define iscsi_daemon(thread, name, sigs) \
-do { \
- daemonize(name); \
- current->policy = SCHED_NORMAL; \
- set_user_nice(current, -20); \
- spin_lock_irq(¤t->sighand->siglock); \
- siginitsetinv(¤t->blocked, (sigs)); \
- recalc_sigpending(); \
- (thread) = current; \
- spin_unlock_irq(¤t->sighand->siglock); \
-} while (0);
-
#define MOD_TIMER(t, exp) mod_timer(t, (get_jiffies_64() + exp * HZ))
#define SETUP_TIMER(timer, t, d, func) \
timer.expires = (get_jiffies_64() + t * HZ); \
Index: lio-core-2.6/drivers/target/lio-target/iscsi_target_login.c
===================================================================
--- lio-core-2.6.orig/drivers/target/lio-target/iscsi_target_login.c 2010-11-06 20:36:08.941260061 +0100
+++ lio-core-2.6/drivers/target/lio-target/iscsi_target_login.c 2010-11-06 20:36:42.358255815 +0100
@@ -1011,12 +1011,8 @@ int iscsi_target_login_thread(void *arg)
struct sockaddr_in sock_in;
struct sockaddr_in6 sock_in6;
- {
- char name[16];
- memset(name, 0, 16);
- sprintf(name, "iscsi_np");
- iscsi_daemon(np->np_thread, name, SHUTDOWN_SIGS);
- }
+ set_user_nice(current, -20);
+ np->np_thread = current;
sock = iscsi_target_setup_login_socket(np);
if (!(sock)) {
Index: lio-core-2.6/drivers/target/target_core_transport.c
===================================================================
--- lio-core-2.6.orig/drivers/target/target_core_transport.c 2010-11-06 20:34:36.070254263 +0100
+++ lio-core-2.6/drivers/target/target_core_transport.c 2010-11-06 20:35:10.989005277 +0100
@@ -9053,14 +9053,9 @@ static int transport_processing_thread(v
struct se_device *dev = (struct se_device *) param;
struct se_queue_req *qr;
- current->policy = SCHED_NORMAL;
set_user_nice(current, -20);
- spin_lock_irq(¤t->sighand->siglock);
- siginitsetinv(¤t->blocked, SHUTDOWN_SIGS);
- recalc_sigpending();
- spin_unlock_irq(¤t->sighand->siglock);
- while (!(kthread_should_stop())) {
+ while (!kthread_should_stop()) {
ret = wait_event_interruptible(dev->dev_queue_obj->thread_wq,
atomic_read(&dev->dev_queue_obj->queue_cnt) ||
kthread_should_stop());
Index: lio-core-2.6/drivers/target/tcm_fc/tfc_cmd.c
===================================================================
--- lio-core-2.6.orig/drivers/target/tcm_fc/tfc_cmd.c 2010-11-06 20:35:19.325012122 +0100
+++ lio-core-2.6/drivers/target/tcm_fc/tfc_cmd.c 2010-11-06 20:35:27.377011353 +0100
@@ -649,10 +649,6 @@ int ft_thread(void *arg)
int ret;
set_user_nice(current, -20);
- spin_lock_irq(¤t->sighand->siglock);
- siginitsetinv(¤t->blocked, SHUTDOWN_SIGS);
- recalc_sigpending();
- spin_unlock_irq(¤t->sighand->siglock);
while (!(kthread_should_stop())) {
ret = wait_event_interruptible(qobj->thread_wq,
Index: lio-core-2.6/include/target/target_core_base.h
===================================================================
--- lio-core-2.6.orig/include/target/target_core_base.h 2010-11-06 20:37:52.400253495 +0100
+++ lio-core-2.6/include/target/target_core_base.h 2010-11-06 20:37:55.809255241 +0100
@@ -10,7 +10,6 @@
#include "target_core_mib.h"
#define TARGET_CORE_MOD_VERSION "v4.0.0-rc5"
-#define SHUTDOWN_SIGS (sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGABRT))
/* Used by transport_generic_allocate_iovecs() */
#define TRANSPORT_IOV_DATA_BUFFER 5
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 4/9] target: remove transport_generic_map_buffers_to_tasks
2010-11-08 15:56 [PATCH 0/9] target core review feedback Christoph Hellwig
` (2 preceding siblings ...)
2010-11-08 15:56 ` [PATCH 3/9] From: Christoph Hellwig <hch@lst.de> Sujbect: target: remove SHUTDOWN_SIGS Christoph Hellwig
@ 2010-11-08 15:56 ` Christoph Hellwig
2010-11-08 22:29 ` Nicholas A. Bellinger
2010-11-08 15:56 ` [PATCH 5/9] target: clean up transport_subsystem_register Christoph Hellwig
` (5 subsequent siblings)
9 siblings, 1 reply; 23+ messages in thread
From: Christoph Hellwig @ 2010-11-08 15:56 UTC (permalink / raw)
To: nab; +Cc: linux-scsi
[-- Attachment #1: lio-cleanup-transport_generic_map_buffers_to_tasks --]
[-- Type: text/plain, Size: 3395 bytes --]
transport_generic_map_buffers_to_tasks has three difference cases that all
perform the same loop. Remove the function and inline that small loop into
the only caller.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Index: lio-core-2.6/drivers/target/target_core_transport.c
===================================================================
--- lio-core-2.6.orig/drivers/target/target_core_transport.c 2010-11-06 20:44:44.378004019 +0100
+++ lio-core-2.6/drivers/target/target_core_transport.c 2010-11-06 20:50:48.133255099 +0100
@@ -7092,75 +7092,6 @@ int transport_generic_map_mem_to_cmd(
EXPORT_SYMBOL(transport_generic_map_mem_to_cmd);
-/* transport_generic_map_buffers_to_tasks():
- *
- * Called from transport_generic_new_cmd() in Transport Processing Thread.
- */
-static int transport_generic_map_buffers_to_tasks(struct se_cmd *cmd)
-{
- struct se_task *task = NULL;
- int ret;
-
- /*
- * Deal with non [READ,WRITE]_XX CDBs here.
- */
- if (cmd->se_cmd_flags & SCF_SCSI_NON_DATA_CDB)
- goto non_scsi_data;
- else if (cmd->se_cmd_flags & SCF_SCSI_CONTROL_NONSG_IO_CDB) {
- list_for_each_entry(task, &T_TASK(cmd)->t_task_list, t_list) {
- if (atomic_read(&task->task_sent))
- continue;
-
- ret = task->transport_map_task(task, task->task_size);
- if (ret < 0)
- return ret;
-
- DEBUG_CMD_M("Mapping SCF_SCSI_CONTROL_NONSG_IO_CDB"
- " task_size: %u\n", task->task_size);
- }
- return 0;
- }
-
- /*
- * Determine the scatterlist offset for each struct se_task,
- * and segment and set pointers to storage transport buffers
- * via task->transport_map_task().
- */
- list_for_each_entry(task, &T_TASK(cmd)->t_task_list, t_list) {
- if (atomic_read(&task->task_sent))
- continue;
-
- ret = task->transport_map_task(task, task->task_size);
- if (ret < 0)
- return ret;
-
- DEBUG_CMD_M("Mapping task[%d]_se_obj_ptr[%p] %s_IO task_lba:"
- " %llu task_size: %u task_sg_num: %d\n",
- task->task_no, task->se_obj_ptr,
- (cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB) ?
- "CONTROL" : "DATA", task->task_lba, task->task_size,
- task->task_sg_num);
- }
-
- return 0;
-
-non_scsi_data:
- list_for_each_entry(task, &T_TASK(cmd)->t_task_list, t_list) {
- if (atomic_read(&task->task_sent))
- continue;
-
- ret = task->transport_map_task(task, task->task_size);
- if (ret < 0)
- return ret;
-
- DEBUG_CMD_M("Mapping SCF_SCSI_NON_DATA_CDB task_size: %u"
- " task->task_sg_num: %d\n", task->task_size,
- task->task_sg_num);
- }
-
- return 0;
-}
-
static inline long long transport_dev_end_lba(struct se_device *dev)
{
return dev->dev_sectors_total + 1;
@@ -7993,6 +7924,7 @@ int transport_generic_new_cmd(struct se_
{
struct se_portal_group *se_tpg;
struct se_transform_info ti;
+ struct se_task *task;
int ret = 0;
/*
* Generate struct se_task(s) and/or their payloads for this CDB.
@@ -8055,9 +7987,14 @@ int transport_generic_new_cmd(struct se_
* buffer list in struct se_cmd to the transport task's native
* buffers format.
*/
- ret = transport_generic_map_buffers_to_tasks(cmd);
- if (ret < 0)
- goto failure;
+ list_for_each_entry(task, &T_TASK(cmd)->t_task_list, t_list) {
+ if (atomic_read(&task->task_sent))
+ continue;
+
+ ret = task->transport_map_task(task, task->task_size);
+ if (ret < 0)
+ goto failure;
+ }
/*
* For WRITEs, let the iSCSI Target RX Thread know its buffer is ready..
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 5/9] target: clean up transport_subsystem_register
2010-11-08 15:56 [PATCH 0/9] target core review feedback Christoph Hellwig
` (3 preceding siblings ...)
2010-11-08 15:56 ` [PATCH 4/9] target: remove transport_generic_map_buffers_to_tasks Christoph Hellwig
@ 2010-11-08 15:56 ` Christoph Hellwig
2010-11-08 22:32 ` Nicholas A. Bellinger
2010-11-08 15:56 ` [PATCH 6/9] target: remove dead blockdevice claim/release code Christoph Hellwig
` (4 subsequent siblings)
9 siblings, 1 reply; 23+ messages in thread
From: Christoph Hellwig @ 2010-11-08 15:56 UTC (permalink / raw)
To: nab; +Cc: linux-scsi
[-- Attachment #1: lio-simplify-transport_subsystem_register --]
[-- Type: text/plain, Size: 11843 bytes --]
Move initialization of the list into transport_subsystem_register, set the
owner field in the operations vector like for most others, remove the
external_submod field and replace it by not having an owner pointer.
Remove unessecary initializations to zero for se_subsystem_api fields.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Index: lio-core-2.6/drivers/target/target_core_file.c
===================================================================
--- lio-core-2.6.orig/drivers/target/target_core_file.c 2010-11-08 15:37:15.944863013 +0100
+++ lio-core-2.6/drivers/target/target_core_file.c 2010-11-08 15:49:05.428196347 +0100
@@ -953,9 +953,9 @@ static sector_t fd_get_blocks(struct se_
static struct se_subsystem_api fileio_template = {
.name = "fileio",
+ .owner = THIS_MODULE,
.type = FILEIO,
.transport_type = TRANSPORT_PLUGIN_VHBA_PDEV,
- .external_submod = 1,
.attach_hba = fd_attach_hba,
.detach_hba = fd_detach_hba,
.cdb_none = fd_CDB_none,
@@ -973,7 +973,6 @@ static struct se_subsystem_api fileio_te
.transport_complete = fd_transport_complete,
.allocate_request = fd_allocate_request,
.do_task = fd_do_task,
- .do_discard = NULL,
.do_sync_cache = fd_emulate_sync_cache,
.free_task = fd_free_task,
.check_configfs_dev_params = fd_check_configfs_dev_params,
@@ -989,23 +988,14 @@ static struct se_subsystem_api fileio_te
.get_device_type = fd_get_device_type,
.get_dma_length = fd_get_dma_length,
.get_blocks = fd_get_blocks,
- .write_pending = NULL,
};
-int __init fileio_module_init(void)
+static int __init fileio_module_init(void)
{
- int ret;
-
- INIT_LIST_HEAD(&fileio_template.sub_api_list);
-
- ret = transport_subsystem_register(&fileio_template, THIS_MODULE);
- if (ret < 0)
- return ret;
-
- return 0;
+ return transport_subsystem_register(&fileio_template);
}
-void fileio_module_exit(void)
+static void fileio_module_exit(void)
{
transport_subsystem_release(&fileio_template);
}
Index: lio-core-2.6/drivers/target/target_core_hba.c
===================================================================
--- lio-core-2.6.orig/drivers/target/target_core_hba.c 2010-11-08 15:41:43.444863012 +0100
+++ lio-core-2.6/drivers/target/target_core_hba.c 2010-11-08 15:48:43.508196346 +0100
@@ -100,23 +100,17 @@ int se_core_add_hba(
return -EINVAL;
hba->transport = t;
+
/*
* Get TCM subsystem api struct module reference to struct se_hba
*/
- if (t->external_submod) {
- if (!(t->sub_owner)) {
- printk(KERN_ERR "Pointer to struct module does not"
- " exist for %s\n", t->name);
- hba->transport = NULL;
- transport_core_put_sub(t);
- return -EINVAL;
- }
+ if (t->owner) {
/*
* Grab a struct module reference count for subsystem plugin
*/
- if (!(try_module_get(t->sub_owner))) {
- printk(KERN_ERR "try_module_get() failed for"
- " t->sub_owner\n");
+ if (!try_module_get(t->owner)) {
+ printk(KERN_ERR "try_module_get() failed for %s\n",
+ t->owner->name);
hba->transport = NULL;
transport_core_put_sub(t);
return -EINVAL;
@@ -126,8 +120,8 @@ int se_core_add_hba(
ret = t->attach_hba(hba, plugin_dep_id);
if (ret < 0) {
hba->transport = NULL;
- if (t->external_submod)
- module_put(t->sub_owner);
+ if (t->owner)
+ module_put(t->owner);
transport_core_put_sub(t);
return ret;
}
@@ -157,8 +151,8 @@ static int se_core_shutdown_hba(
/*
* Release TCM subsystem api struct module reference from struct se_hba
*/
- if (t->external_submod)
- module_put(t->sub_owner);
+ if (t->owner)
+ module_put(t->owner);
return 0;
}
Index: lio-core-2.6/drivers/target/target_core_iblock.c
===================================================================
--- lio-core-2.6.orig/drivers/target/target_core_iblock.c 2010-11-08 15:38:27.891529681 +0100
+++ lio-core-2.6/drivers/target/target_core_iblock.c 2010-11-08 15:48:47.868196356 +0100
@@ -921,9 +921,9 @@ static void iblock_bio_done(struct bio *
static struct se_subsystem_api iblock_template = {
.name = "iblock",
+ .owner = THIS_MODULE,
.type = IBLOCK,
.transport_type = TRANSPORT_PLUGIN_VHBA_PDEV,
- .external_submod = 1,
.cdb_none = iblock_CDB_none,
.cdb_read_non_SG = iblock_CDB_read_non_SG,
.cdb_read_SG = iblock_CDB_read_SG,
@@ -957,23 +957,14 @@ static struct se_subsystem_api iblock_te
.get_device_type = iblock_get_device_type,
.get_dma_length = iblock_get_dma_length,
.get_blocks = iblock_get_blocks,
- .write_pending = NULL,
};
-int __init iblock_module_init(void)
+static int __init iblock_module_init(void)
{
- int ret;
-
- INIT_LIST_HEAD(&iblock_template.sub_api_list);
-
- ret = transport_subsystem_register(&iblock_template, THIS_MODULE);
- if (ret < 0)
- return ret;
-
- return 0;
+ return transport_subsystem_register(&iblock_template);
}
-void iblock_module_exit(void)
+static void iblock_module_exit(void)
{
transport_subsystem_release(&iblock_template);
}
Index: lio-core-2.6/drivers/target/target_core_pscsi.c
===================================================================
--- lio-core-2.6.orig/drivers/target/target_core_pscsi.c 2010-11-08 15:38:27.901529680 +0100
+++ lio-core-2.6/drivers/target/target_core_pscsi.c 2010-11-08 15:48:49.844863013 +0100
@@ -1485,9 +1485,9 @@ static void pscsi_req_done(struct reques
static struct se_subsystem_api pscsi_template = {
.name = "pscsi",
+ .owner = THIS_MODULE,
.type = PSCSI,
.transport_type = TRANSPORT_PLUGIN_PHBA_PDEV,
- .external_submod = 1,
.cdb_none = pscsi_CDB_none,
.cdb_read_non_SG = pscsi_CDB_read_non_SG,
.cdb_read_SG = pscsi_CDB_read_SG,
@@ -1516,23 +1516,14 @@ static struct se_subsystem_api pscsi_tem
.get_device_rev = pscsi_get_device_rev,
.get_device_type = pscsi_get_device_type,
.get_dma_length = pscsi_get_dma_length,
- .write_pending = NULL,
};
-int __init pscsi_module_init(void)
+static int __init pscsi_module_init(void)
{
- int ret;
-
- INIT_LIST_HEAD(&pscsi_template.sub_api_list);
-
- ret = transport_subsystem_register(&pscsi_template, THIS_MODULE);
- if (ret < 0)
- return ret;
-
- return 0;
+ return transport_subsystem_register(&pscsi_template);
}
-void pscsi_module_exit(void)
+static void pscsi_module_exit(void)
{
transport_subsystem_release(&pscsi_template);
}
Index: lio-core-2.6/drivers/target/target_core_rd.c
===================================================================
--- lio-core-2.6.orig/drivers/target/target_core_rd.c 2010-11-08 15:38:27.911529679 +0100
+++ lio-core-2.6/drivers/target/target_core_rd.c 2010-11-08 15:49:00.321529680 +0100
@@ -1283,7 +1283,6 @@ static struct se_subsystem_api rd_dr_tem
.name = "rd_dr",
.type = RAMDISK_DR,
.transport_type = TRANSPORT_PLUGIN_VHBA_VDEV,
- .external_submod = 0,
.cdb_none = rd_CDB_none,
.cdb_read_non_SG = rd_CDB_read_non_SG,
.cdb_read_SG = rd_CDB_read_SG,
@@ -1314,14 +1313,12 @@ static struct se_subsystem_api rd_dr_tem
.get_dma_length = rd_get_dma_length,
.get_blocks = rd_get_blocks,
.do_se_mem_map = rd_DIRECT_do_se_mem_map,
- .write_pending = NULL,
};
static struct se_subsystem_api rd_mcp_template = {
.name = "rd_mcp",
.type = RAMDISK_MCP,
.transport_type = TRANSPORT_PLUGIN_VHBA_VDEV,
- .external_submod = 0,
.cdb_none = rd_CDB_none,
.cdb_read_non_SG = rd_CDB_read_non_SG,
.cdb_read_SG = rd_CDB_read_SG,
@@ -1348,21 +1345,17 @@ static struct se_subsystem_api rd_mcp_te
.get_device_rev = rd_get_device_rev,
.get_device_type = rd_get_device_type,
.get_dma_length = rd_get_dma_length,
- .write_pending = NULL,
};
int __init rd_module_init(void)
{
int ret;
- INIT_LIST_HEAD(&rd_dr_template.sub_api_list);
- INIT_LIST_HEAD(&rd_mcp_template.sub_api_list);
-
- ret = transport_subsystem_register(&rd_dr_template, NULL);
+ ret = transport_subsystem_register(&rd_dr_template);
if (ret < 0)
return ret;
- ret = transport_subsystem_register(&rd_mcp_template, NULL);
+ ret = transport_subsystem_register(&rd_mcp_template);
if (ret < 0) {
transport_subsystem_release(&rd_dr_template);
return ret;
Index: lio-core-2.6/drivers/target/target_core_stgt.c
===================================================================
--- lio-core-2.6.orig/drivers/target/target_core_stgt.c 2010-11-08 15:38:27.924863014 +0100
+++ lio-core-2.6/drivers/target/target_core_stgt.c 2010-11-08 15:49:02.761529680 +0100
@@ -833,9 +833,9 @@ static int stgt_transfer_response(struct
static struct se_subsystem_api stgt_template = {
.name = "stgt",
+ .owner = THIS_MODULE,
.type = STGT,
.transport_type = TRANSPORT_PLUGIN_VHBA_PDEV,
- .external_submod = 1,
.cdb_none = stgt_CDB_none,
.cdb_read_non_SG = stgt_CDB_read_non_SG,
.cdb_read_SG = stgt_CDB_read_SG,
@@ -865,23 +865,14 @@ static struct se_subsystem_api stgt_temp
.get_device_rev = stgt_get_device_rev,
.get_device_type = stgt_get_device_type,
.get_dma_length = stgt_get_dma_length,
- .write_pending = NULL,
};
-int __init stgt_module_init(void)
+static int __init stgt_module_init(void)
{
- int ret;
-
- INIT_LIST_HEAD(&stgt_template.sub_api_list);
-
- ret = transport_subsystem_register(&stgt_template, THIS_MODULE);
- if (ret < 0)
- return ret;
-
- return 0;
+ return transport_subsystem_register(&stgt_template);
}
-void stgt_module_exit(void)
+static void stgt_module_exit(void)
{
transport_subsystem_release(&stgt_template);
}
Index: lio-core-2.6/drivers/target/target_core_transport.c
===================================================================
--- lio-core-2.6.orig/drivers/target/target_core_transport.c 2010-11-08 15:37:15.928196347 +0100
+++ lio-core-2.6/drivers/target/target_core_transport.c 2010-11-08 15:44:43.708196346 +0100
@@ -545,18 +545,11 @@ int transport_subsystem_check_init(void)
}
int transport_subsystem_register(
- struct se_subsystem_api *sub_api,
- struct module *sub_owner)
+ struct se_subsystem_api *sub_api)
{
struct se_subsystem_api *s;
- /*
- * Save struct module * for TFO [attach,detach]_hba() reference
- * in se_core_add_hba()
- */
- if (sub_api->external_submod && (sub_owner != NULL))
- sub_api->sub_owner = sub_owner;
- else
- sub_api->sub_owner = NULL;
+
+ INIT_LIST_HEAD(&sub_api->sub_api_list);
mutex_lock(&se_global->g_sub_api_mutex);
list_for_each_entry(s, &se_global->g_sub_api_list, sub_api_list) {
@@ -572,7 +565,7 @@ int transport_subsystem_register(
mutex_unlock(&se_global->g_sub_api_mutex);
printk(KERN_INFO "TCM: Registered subsystem plugin: %s struct module:"
- " %p\n", sub_api->name, sub_api->sub_owner);
+ " %p\n", sub_api->name, sub_api->owner);
return 0;
}
EXPORT_SYMBOL(transport_subsystem_register);
Index: lio-core-2.6/include/target/target_core_transport.h
===================================================================
--- lio-core-2.6.orig/include/target/target_core_transport.h 2010-11-08 15:42:48.694863012 +0100
+++ lio-core-2.6/include/target/target_core_transport.h 2010-11-08 15:49:30.924863014 +0100
@@ -138,8 +138,7 @@ extern int __iscsi_debug_dev(struct se_d
extern unsigned char *transport_get_iqn_sn(void);
extern void transport_init_queue_obj(struct se_queue_obj *);
extern int transport_subsystem_check_init(void);
-extern int transport_subsystem_register(struct se_subsystem_api *,
- struct module *);
+extern int transport_subsystem_register(struct se_subsystem_api *);
extern void transport_subsystem_release(struct se_subsystem_api *);
extern void transport_load_plugins(void);
extern struct se_subsystem_api *transport_core_get_sub_by_name(const char *);
@@ -323,13 +322,9 @@ struct se_subsystem_api {
*/
u8 transport_type;
/*
- * For target_core_rd.c internal usage
- */
- int external_submod;
- /*
* struct module for struct se_hba references
*/
- struct module *sub_owner;
+ struct module *owner;
/*
* Counter for struct se_hba reference
*/
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 6/9] target: remove dead blockdevice claim/release code
2010-11-08 15:56 [PATCH 0/9] target core review feedback Christoph Hellwig
` (4 preceding siblings ...)
2010-11-08 15:56 ` [PATCH 5/9] target: clean up transport_subsystem_register Christoph Hellwig
@ 2010-11-08 15:56 ` Christoph Hellwig
2010-11-08 22:35 ` Nicholas A. Bellinger
2010-11-08 15:56 ` [PATCH 7/9] target: remove transport_generic_free_device Christoph Hellwig
` (3 subsequent siblings)
9 siblings, 1 reply; 23+ messages in thread
From: Christoph Hellwig @ 2010-11-08 15:56 UTC (permalink / raw)
To: nab; +Cc: linux-scsi
[-- Attachment #1: lio-cleanup-claim --]
[-- Type: text/plain, Size: 8692 bytes --]
This code is entirely unused - even the last reference to
linux_blockdevice_release was unreachable at this point.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Index: lio-core-2.6/drivers/target/target_core_device.c
===================================================================
--- lio-core-2.6.orig/drivers/target/target_core_device.c 2010-11-08 15:52:26.154863014 +0100
+++ lio-core-2.6/drivers/target/target_core_device.c 2010-11-08 15:57:14.058196347 +0100
@@ -50,111 +50,6 @@
#include "target_core_pr.h"
#include "target_core_ua.h"
-struct block_device *__linux_blockdevice_claim(
- int major,
- int minor,
- void *claim_ptr,
- int *ret)
-{
- dev_t dev;
- struct block_device *bd;
-
- dev = MKDEV(major, minor);
-
- bd = bdget(dev);
- if (!(bd)) {
- *ret = -1;
- return NULL;
- }
-
- if (blkdev_get(bd, FMODE_WRITE|FMODE_READ) < 0) {
- *ret = -1;
- return NULL;
- }
- /*
- * If no claim pointer was passed from claimee, use struct block_device.
- */
- if (!claim_ptr)
- claim_ptr = (void *)bd;
-
- if (bd_claim(bd, claim_ptr) < 0) {
- blkdev_put(bd, FMODE_WRITE|FMODE_READ);
- *ret = 0;
- return bd;
- }
-
- *ret = 1;
- return bd;
-}
-
-struct block_device *linux_blockdevice_claim(
- int major,
- int minor,
- void *claim_ptr)
-{
- dev_t dev;
- struct block_device *bd;
-
- dev = MKDEV(major, minor);
-
- bd = bdget(dev);
- if (!(bd))
- return NULL;
-
- if (blkdev_get(bd, FMODE_WRITE|FMODE_READ) < 0)
- return NULL;
- /*
- * If no claim pointer was passed from claimee, use struct block_device.
- */
- if (!claim_ptr)
- claim_ptr = (void *)bd;
-
- if (bd_claim(bd, claim_ptr) < 0) {
- blkdev_put(bd, FMODE_WRITE|FMODE_READ);
- return NULL;
- }
-
- return bd;
-}
-EXPORT_SYMBOL(linux_blockdevice_claim);
-
-int linux_blockdevice_release(int major, int minor, struct block_device *bd_p)
-{
- dev_t dev;
- struct block_device *bd;
-
- if (!bd_p) {
- dev = MKDEV(major, minor);
-
- bd = bdget(dev);
- if (!(bd))
- return -1;
- } else
- bd = bd_p;
-
- bd_release(bd);
- blkdev_put(bd, FMODE_WRITE|FMODE_READ);
-
- return 0;
-}
-EXPORT_SYMBOL(linux_blockdevice_release);
-
-int linux_blockdevice_check(int major, int minor)
-{
- struct block_device *bd;
-
- bd = linux_blockdevice_claim(major, minor, NULL);
- if (!(bd))
- return -1;
- /*
- * Blockdevice was able to be claimed, now unclaim it and return success
- */
- linux_blockdevice_release(major, minor, NULL);
-
- return 0;
-}
-EXPORT_SYMBOL(linux_blockdevice_check);
-
extern int __transport_get_lun_for_cmd(
struct se_cmd *se_cmd,
u32 unpacked_lun)
Index: lio-core-2.6/drivers/target/target_core_file.c
===================================================================
--- lio-core-2.6.orig/drivers/target/target_core_file.c 2010-11-08 15:54:21.721529679 +0100
+++ lio-core-2.6/drivers/target/target_core_file.c 2010-11-08 15:55:27.531529681 +0100
@@ -234,14 +234,7 @@ static struct se_device *fd_create_virtd
dev_limits.max_cdb_len = TCM_MAX_COMMAND_SIZE;
dev_limits.hw_queue_depth = FD_MAX_DEVICE_QUEUE_DEPTH;
dev_limits.queue_depth = FD_DEVICE_QUEUE_DEPTH;
- /*
- * Pass dev_flags for linux_blockdevice_claim_bd or
- * linux_blockdevice_claim() from the usage above.
- *
- * Note that transport_add_device_to_core_hba() will call
- * linux_blockdevice_release() internally on failure to
- * call bd_release() on the referenced struct block_device.
- */
+
dev = transport_add_device_to_core_hba(hba, &fileio_template,
se_dev, dev_flags, (void *)fd_dev,
&dev_limits, "FILEIO", FD_VERSION);
Index: lio-core-2.6/drivers/target/target_core_file.h
===================================================================
--- lio-core-2.6.orig/drivers/target/target_core_file.h 2010-11-08 15:52:03.078196347 +0100
+++ lio-core-2.6/drivers/target/target_core_file.h 2010-11-08 15:56:30.278196346 +0100
@@ -16,10 +16,6 @@
#define FD_DATA_NONE 3
extern struct se_global *se_global;
-extern struct block_device *__linux_blockdevice_claim(int, int, void *, int *);
-extern struct block_device *linux_blockdevice_claim(int, int, void *);
-extern int linux_blockdevice_release(int, int, struct block_device *);
-extern int linux_blockdevice_check(int, int);
#define RRF_EMULATE_CDB 0x01
#define RRF_GOT_LBA 0x02
Index: lio-core-2.6/drivers/target/target_core_iblock.c
===================================================================
--- lio-core-2.6.orig/drivers/target/target_core_iblock.c 2010-11-08 15:54:21.734863014 +0100
+++ lio-core-2.6/drivers/target/target_core_iblock.c 2010-11-08 16:03:22.868196349 +0100
@@ -187,15 +187,7 @@ static struct se_device *iblock_create_v
ib_dev->ibd_major = MAJOR(bd->bd_dev);
ib_dev->ibd_minor = MINOR(bd->bd_dev);
ib_dev->ibd_bd = bd;
- ib_dev->ibd_flags |= IBDF_BDEV_EXCLUSIVE;
- /*
- * Pass dev_flags for linux_blockdevice_claim() or
- * linux_blockdevice_claim() from the usage above.
- *
- * Note that transport_add_device_to_core_hba() will call
- * linux_blockdevice_release() internally on failure to
- * call bd_release() on the referenced struct block_device.
- */
+
dev = transport_add_device_to_core_hba(hba,
&iblock_template, se_dev, dev_flags, (void *)ib_dev,
&dev_limits, "IBLOCK", IBLOCK_VERSION);
@@ -251,25 +243,8 @@ static void iblock_free_device(void *p)
{
struct iblock_dev *ib_dev = p;
- if (ib_dev->ibd_bd) {
- printk(KERN_INFO "IBLOCK: Releasing Major:Minor - %d:%d\n",
- ib_dev->ibd_major, ib_dev->ibd_minor);
-
- if (ib_dev->ibd_flags & IBDF_BDEV_EXCLUSIVE)
- close_bdev_exclusive(ib_dev->ibd_bd,
- FMODE_WRITE|FMODE_READ);
- else
- linux_blockdevice_release(ib_dev->ibd_major,
- ib_dev->ibd_minor, ib_dev->ibd_bd);
- ib_dev->ibd_bd = NULL;
- }
-
- if (ib_dev->ibd_bio_set) {
- DEBUG_IBLOCK("Calling bioset_free ib_dev->ibd_bio_set: %p\n",
- ib_dev->ibd_bio_set);
- bioset_free(ib_dev->ibd_bio_set);
- }
-
+ close_bdev_exclusive(ib_dev->ibd_bd, FMODE_WRITE|FMODE_READ);
+ bioset_free(ib_dev->ibd_bio_set);
kfree(ib_dev);
}
Index: lio-core-2.6/drivers/target/target_core_iblock.h
===================================================================
--- lio-core-2.6.orig/drivers/target/target_core_iblock.h 2010-11-08 15:59:59.918196346 +0100
+++ lio-core-2.6/drivers/target/target_core_iblock.h 2010-11-08 16:00:08.661529684 +0100
@@ -23,8 +23,7 @@ struct iblock_req {
#define IBDF_HAS_UDEV_PATH 0x01
#define IBDF_HAS_FORCE 0x02
-#define IBDF_BDEV_EXCLUSIVE 0x04
-#define IBDF_BDEV_ISSUE_FLUSH 0x08
+#define IBDF_BDEV_ISSUE_FLUSH 0x04
struct iblock_dev {
unsigned char ibd_udev_path[SE_UDEV_PATH_LEN];
Index: lio-core-2.6/drivers/target/target_core_pscsi.h
===================================================================
--- lio-core-2.6.orig/drivers/target/target_core_pscsi.h 2010-11-08 15:53:09.088196347 +0100
+++ lio-core-2.6/drivers/target/target_core_pscsi.h 2010-11-08 15:56:11.404863014 +0100
@@ -20,9 +20,6 @@
#define PS_TIMEOUT_OTHER (500*HZ)
extern struct se_global *se_global;
-extern struct block_device *linux_blockdevice_claim(int, int, void *);
-extern int linux_blockdevice_release(int, int, struct block_device *);
-extern int linux_blockdevice_check(int, int);
#include <linux/device.h>
#include <scsi/scsi_driver.h>
Index: lio-core-2.6/drivers/target/target_core_stgt.h
===================================================================
--- lio-core-2.6.orig/drivers/target/target_core_stgt.h 2010-11-08 15:53:17.704863012 +0100
+++ lio-core-2.6/drivers/target/target_core_stgt.h 2010-11-08 15:56:13.564863014 +0100
@@ -12,9 +12,6 @@
#define PS_TIMEOUT_OTHER (500*HZ)
extern struct se_global *se_global;
-extern struct block_device *linux_blockdevice_claim(int, int, void *);
-extern int linux_blockdevice_release(int, int, struct block_device *);
-extern int linux_blockdevice_check(int, int);
#include <linux/device.h>
#include <scsi/scsi_driver.h>
Index: lio-core-2.6/include/target/target_core_device.h
===================================================================
--- lio-core-2.6.orig/include/target/target_core_device.h 2010-11-08 15:52:18.101529681 +0100
+++ lio-core-2.6/include/target/target_core_device.h 2010-11-08 15:56:17.911529680 +0100
@@ -3,10 +3,6 @@
extern struct se_global *se_global;
-extern struct block_device *__linux_blockdevice_claim(int, int, void *, int *);
-extern struct block_device *linux_blockdevice_claim(int, int, void *);
-extern int linux_blockdevice_release(int, int, struct block_device *);
-extern int linux_blockdevice_check(int, int);
extern int transport_get_lun_for_cmd(struct se_cmd *, unsigned char *, u32);
extern int transport_get_lun_for_tmr(struct se_cmd *, u32);
extern struct se_dev_entry *core_get_se_deve_from_rtpi(
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 7/9] target: remove transport_generic_free_device
2010-11-08 15:56 [PATCH 0/9] target core review feedback Christoph Hellwig
` (5 preceding siblings ...)
2010-11-08 15:56 ` [PATCH 6/9] target: remove dead blockdevice claim/release code Christoph Hellwig
@ 2010-11-08 15:56 ` Christoph Hellwig
2010-11-08 22:40 ` Nicholas A. Bellinger
2010-11-08 15:56 ` [PATCH 8/9] target: remove unused split_cdb_RW_* handlers Christoph Hellwig
` (2 subsequent siblings)
9 siblings, 1 reply; 23+ messages in thread
From: Christoph Hellwig @ 2010-11-08 15:56 UTC (permalink / raw)
To: nab; +Cc: linux-scsi
[-- Attachment #1: lio-kill-transport_generic_free_device --]
[-- Type: text/plain, Size: 2548 bytes --]
It's simple enough to inline into the only caller.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Index: lio-core-2.6/drivers/target/target_core_device.c
===================================================================
--- lio-core-2.6.orig/drivers/target/target_core_device.c 2010-11-08 16:07:13.631529681 +0100
+++ lio-core-2.6/drivers/target/target_core_device.c 2010-11-08 16:08:56.528196347 +0100
@@ -34,6 +34,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/smp_lock.h>
+#include <linux/kthread.h>
#include <linux/in.h>
#include <net/sock.h>
#include <net/tcp.h>
@@ -733,7 +734,11 @@ void se_release_device_for_hba(struct se
(dev->dev_status & TRANSPORT_DEVICE_OFFLINE_DEACTIVATED))
se_dev_stop(dev);
- transport_generic_free_device(dev);
+ if (dev->dev_ptr) {
+ kthread_stop(dev->process_thread);
+ if (dev->transport->free_device)
+ dev->transport->free_device(dev->dev_ptr);
+ }
spin_lock(&hba->device_lock);
list_del(&dev->dev_list);
Index: lio-core-2.6/drivers/target/target_core_transport.c
===================================================================
--- lio-core-2.6.orig/drivers/target/target_core_transport.c 2010-11-08 16:07:13.618196346 +0100
+++ lio-core-2.6/drivers/target/target_core_transport.c 2010-11-08 16:08:26.438196370 +0100
@@ -2367,22 +2367,6 @@ out:
}
EXPORT_SYMBOL(transport_add_device_to_core_hba);
-/* transport_generic_free_device():
- *
- *
- */
-void transport_generic_free_device(struct se_device *dev)
-{
- if (!(dev->dev_ptr))
- return;
-
- kthread_stop(dev->process_thread);
-
- if (TRANSPORT(dev)->free_device)
- TRANSPORT(dev)->free_device(dev->dev_ptr);
-}
-EXPORT_SYMBOL(transport_generic_free_device);
-
static inline int transport_allocate_iovecs_for_cmd(
struct se_cmd *cmd,
u32 iov_count)
Index: lio-core-2.6/include/target/target_core_transport.h
===================================================================
--- lio-core-2.6.orig/include/target/target_core_transport.h 2010-11-08 16:08:08.554863013 +0100
+++ lio-core-2.6/include/target/target_core_transport.h 2010-11-08 16:08:10.134863013 +0100
@@ -190,7 +190,6 @@ extern struct se_device *transport_add_d
struct se_subsystem_dev *, u32,
void *, struct se_dev_limits *,
const char *, const char *);
-extern void transport_generic_free_device(struct se_device *);
extern int transport_generic_allocate_iovecs(struct se_cmd *);
extern void transport_device_setup_cmd(struct se_cmd *);
extern int transport_check_alloc_task_attr(struct se_cmd *);
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 8/9] target: remove unused split_cdb_RW_* handlers
2010-11-08 15:56 [PATCH 0/9] target core review feedback Christoph Hellwig
` (6 preceding siblings ...)
2010-11-08 15:56 ` [PATCH 7/9] target: remove transport_generic_free_device Christoph Hellwig
@ 2010-11-08 15:56 ` Christoph Hellwig
2010-11-08 22:41 ` Nicholas A. Bellinger
2010-11-08 15:56 ` [PATCH 9/9] target: remove dead call to transport_emulate_control_cdb in rd driver Christoph Hellwig
2010-11-08 17:19 ` [PATCH 10/9] target: split CDB emulation out of target_core_transport.c Christoph Hellwig
9 siblings, 1 reply; 23+ messages in thread
From: Christoph Hellwig @ 2010-11-08 15:56 UTC (permalink / raw)
To: nab; +Cc: linux-scsi
[-- Attachment #1: lio-cleanup-cdb-split --]
[-- Type: text/plain, Size: 3149 bytes --]
Signed-off-by: Christoph Hellwig <hch@lst.de>
Index: lio-core-2.6/drivers/target/target_core_scdb.c
===================================================================
--- lio-core-2.6.orig/drivers/target/target_core_scdb.c 2010-11-08 16:18:26.328196347 +0100
+++ lio-core-2.6/drivers/target/target_core_scdb.c 2010-11-08 16:18:42.911529680 +0100
@@ -51,16 +51,6 @@ void split_cdb_XX_6(
cdb[4] = *sectors & 0xff;
}
-void split_cdb_RW_6(
- unsigned long long lba,
- u32 *sectors,
- unsigned char *cdb,
- int rw)
-{
- cdb[0] = (rw) ? WRITE_6 : READ_6;
- split_cdb_XX_6(lba, sectors, &cdb[0]);
-}
-
/* split_cdb_XX_10():
*
* 32-bit LBA w/ 16-bit SECTORS
@@ -74,16 +64,6 @@ void split_cdb_XX_10(
put_unaligned_be16(*sectors, &cdb[7]);
}
-void split_cdb_RW_10(
- unsigned long long lba,
- u32 *sectors,
- unsigned char *cdb,
- int rw)
-{
- cdb[0] = (rw) ? WRITE_10 : READ_10;
- split_cdb_XX_10(lba, sectors, &cdb[0]);
-}
-
/* split_cdb_XX_12():
*
* 32-bit LBA w/ 32-bit SECTORS
@@ -97,16 +77,6 @@ void split_cdb_XX_12(
put_unaligned_be32(*sectors, &cdb[6]);
}
-void split_cdb_RW_12(
- unsigned long long lba,
- u32 *sectors,
- unsigned char *cdb,
- int rw)
-{
- cdb[0] = (rw) ? WRITE_12 : READ_12;
- split_cdb_XX_12(lba, sectors, &cdb[0]);
-}
-
/* split_cdb_XX_16():
*
* 64-bit LBA w/ 32-bit SECTORS
@@ -120,16 +90,6 @@ void split_cdb_XX_16(
put_unaligned_be32(*sectors, &cdb[10]);
}
-void split_cdb_RW_16(
- unsigned long long lba,
- u32 *sectors,
- unsigned char *cdb,
- int rw)
-{
- cdb[0] = (rw) ? WRITE_16 : READ_16;
- split_cdb_XX_16(lba, sectors, &cdb[0]);
-}
-
/*
* split_cdb_XX_32():
*
@@ -143,16 +103,3 @@ void split_cdb_XX_32(
put_unaligned_be64(lba, &cdb[12]);
put_unaligned_be32(*sectors, &cdb[28]);
}
-
-void split_cdb_RW_32(
- unsigned long long lba,
- u32 *sectors,
- unsigned char *cdb,
- int rw)
-{
- /*
- * Set service action for VARIABLE_LENGTH_CMD
- */
- cdb[9] = (rw) ? WRITE_32 : READ_32;
- split_cdb_XX_32(lba, sectors, &cdb[0]);
-}
Index: lio-core-2.6/drivers/target/target_core_scdb.h
===================================================================
--- lio-core-2.6.orig/drivers/target/target_core_scdb.h 2010-11-08 16:18:52.318196349 +0100
+++ lio-core-2.6/drivers/target/target_core_scdb.h 2010-11-08 16:18:57.131529680 +0100
@@ -2,14 +2,9 @@
#define TARGET_CORE_SCDB_H
extern void split_cdb_XX_6(unsigned long long, u32 *, unsigned char *);
-extern void split_cdb_RW_6(unsigned long long, u32 *, unsigned char *, int);
extern void split_cdb_XX_10(unsigned long long, u32 *, unsigned char *);
-extern void split_cdb_RW_10(unsigned long long, u32 *, unsigned char *, int);
extern void split_cdb_XX_12(unsigned long long, u32 *, unsigned char *);
-extern void split_cdb_RW_12(unsigned long long, u32 *, unsigned char *, int);
extern void split_cdb_XX_16(unsigned long long, u32 *, unsigned char *);
-extern void split_cdb_RW_16(unsigned long long, u32 *, unsigned char *, int);
extern void split_cdb_XX_32(unsigned long long, u32 *, unsigned char *);
-extern void split_cdb_RW_32(unsigned long long, u32 *, unsigned char *, int);
#endif /* TARGET_CORE_SCDB_H */
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 9/9] target: remove dead call to transport_emulate_control_cdb in rd driver
2010-11-08 15:56 [PATCH 0/9] target core review feedback Christoph Hellwig
` (7 preceding siblings ...)
2010-11-08 15:56 ` [PATCH 8/9] target: remove unused split_cdb_RW_* handlers Christoph Hellwig
@ 2010-11-08 15:56 ` Christoph Hellwig
2010-11-08 22:44 ` Nicholas A. Bellinger
2010-11-08 17:19 ` [PATCH 10/9] target: split CDB emulation out of target_core_transport.c Christoph Hellwig
9 siblings, 1 reply; 23+ messages in thread
From: Christoph Hellwig @ 2010-11-08 15:56 UTC (permalink / raw)
To: nab; +Cc: linux-scsi
[-- Attachment #1: lio-mark-target_core_transport-static --]
[-- Type: text/plain, Size: 2589 bytes --]
We'll never reach a non-pscsi backend for non-data CDBs these days.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Index: lio-core-2.6/drivers/target/target_core_rd.c
===================================================================
--- lio-core-2.6.orig/drivers/target/target_core_rd.c 2010-11-08 16:31:38.968196346 +0100
+++ lio-core-2.6/drivers/target/target_core_rd.c 2010-11-08 16:31:42.041529681 +0100
@@ -972,9 +972,6 @@ static int rd_DIRECT_allocate_DMA(struct
*/
static int rd_DIRECT_do_task(struct se_task *task)
{
- if (!(TASK_CMD(task)->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB))
- return transport_emulate_control_cdb(task);
-
/*
* At this point the locally allocated RD tables have been mapped
* to struct se_mem elements in rd_DIRECT_do_se_mem_map().
Index: lio-core-2.6/drivers/target/target_core_transport.c
===================================================================
--- lio-core-2.6.orig/drivers/target/target_core_transport.c 2010-11-08 16:31:58.868196346 +0100
+++ lio-core-2.6/drivers/target/target_core_transport.c 2010-11-08 16:32:42.158196349 +0100
@@ -209,6 +209,7 @@ static int transport_generic_write_pendi
static int transport_processing_thread(void *);
static int transport_new_cmd_obj(struct se_cmd *cmd,
struct se_transform_info *ti, int post_execute);
+static int transport_emulate_control_cdb(struct se_task *task);
static char *transport_passthrough_get_fabric_name(void)
{
@@ -5462,7 +5463,7 @@ static int transport_generic_write_same(
* Used by TCM subsystem plugins IBLOCK, FILEIO, and RAMDISK as a
* generic non SCF_SCSI_DATA_SG_IO_CDB ops.
*/
-int transport_emulate_control_cdb(struct se_task *task)
+static int transport_emulate_control_cdb(struct se_task *task)
{
struct se_cmd *cmd = TASK_CMD(task);
struct se_device *dev = SE_DEV(cmd);
Index: lio-core-2.6/include/target/target_core_transport.h
===================================================================
--- lio-core-2.6.orig/include/target/target_core_transport.h 2010-11-08 16:31:49.168196346 +0100
+++ lio-core-2.6/include/target/target_core_transport.h 2010-11-08 16:31:51.141529681 +0100
@@ -232,7 +232,6 @@ extern int transport_generic_emulate_mod
extern int transport_generic_emulate_request_sense(struct se_cmd *,
unsigned char *);
extern int transport_get_sense_data(struct se_cmd *);
-extern int transport_emulate_control_cdb(struct se_task *);
extern struct se_cmd *transport_allocate_passthrough(unsigned char *, int, u32,
void *, u32, u32, void *);
extern void transport_passthrough_release(struct se_cmd *);
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 10/9] target: split CDB emulation out of target_core_transport.c
2010-11-08 15:56 [PATCH 0/9] target core review feedback Christoph Hellwig
` (8 preceding siblings ...)
2010-11-08 15:56 ` [PATCH 9/9] target: remove dead call to transport_emulate_control_cdb in rd driver Christoph Hellwig
@ 2010-11-08 17:19 ` Christoph Hellwig
2010-11-08 22:48 ` Nicholas A. Bellinger
9 siblings, 1 reply; 23+ messages in thread
From: Christoph Hellwig @ 2010-11-08 17:19 UTC (permalink / raw)
To: nab; +Cc: linux-scsi
Split out the CDB emulation into it's own file, and refactor it along proper
boundaries.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Index: lio-core-2.6/drivers/target/target_core_cdb.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ lio-core-2.6/drivers/target/target_core_cdb.c 2010-11-08 18:14:35.028196347 +0100
@@ -0,0 +1,1128 @@
+/*
+ * CDB emulation for non-READ/WRITE commands.
+ *
+ * Copyright (c) 2002, 2003, 2004, 2005 PyX Technologies, Inc.
+ * Copyright (c) 2005, 2006, 2007 SBE, Inc.
+ * Copyright (c) 2007-2010 Rising Tide Systems
+ * Copyright (c) 2008-2010 Linux-iSCSI.org
+ *
+ * Nicholas A. Bellinger <nab@kernel.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <asm/unaligned.h>
+#include <scsi/scsi.h>
+
+#include <target/target_core_base.h>
+#include <target/target_core_transport.h>
+#include <target/target_core_fabric_ops.h>
+#include "target_core_ua.h"
+
+static void
+target_fill_alua_data(struct se_port *port, unsigned char *buf)
+{
+ struct t10_alua_tg_pt_gp *tg_pt_gp;
+ struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem;
+
+ /*
+ * Set SCCS for MAINTENANCE_IN + REPORT_TARGET_PORT_GROUPS.
+ */
+ buf[5] = 0x80;
+
+ /*
+ * Set TPGS field for explict and/or implict ALUA access type
+ * and opteration.
+ *
+ * See spc4r17 section 6.4.2 Table 135
+ */
+ if (!port)
+ return;
+ tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem;
+ if (!tg_pt_gp_mem)
+ return;
+
+ spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
+ tg_pt_gp = tg_pt_gp_mem->tg_pt_gp;
+ if (tg_pt_gp)
+ buf[5] |= tg_pt_gp->tg_pt_gp_alua_access_type;
+ spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
+}
+
+static int
+target_emulate_inquiry_std(struct se_cmd *cmd)
+{
+ struct se_lun *lun = SE_LUN(cmd);
+ struct se_device *dev = SE_DEV(cmd);
+ unsigned char *buf = cmd->t_task->t_task_buf;
+
+ /*
+ * Make sure we at least have 6 bytes of INQUIRY response
+ * payload going back for EVPD=0
+ */
+ if (cmd->data_length < 6) {
+ printk(KERN_ERR "SCSI Inquiry payload length: %u"
+ " too small for EVPD=0\n", cmd->data_length);
+ return -1;
+ }
+
+ buf[0] = dev->transport->get_device_type(dev);
+ if (buf[0] == TYPE_TAPE)
+ buf[1] = 0x80;
+ buf[2] = dev->transport->get_device_rev(dev);
+
+ /*
+ * Enable SCCS and TPGS fields for Emulated ALUA
+ */
+ if (T10_ALUA(dev->se_sub_dev)->alua_type == SPC3_ALUA_EMULATED)
+ target_fill_alua_data(lun->lun_sep, buf);
+
+ if (cmd->data_length < 8) {
+ buf[4] = 1; /* Set additional length to 1 */
+ return 0;
+ }
+
+ buf[7] = 0x32; /* Sync=1 and CmdQue=1 */
+
+ /*
+ * Do not include vendor, product, reversion info in INQUIRY
+ * response payload for cdbs with a small allocation length.
+ */
+ if (cmd->data_length < 36) {
+ buf[4] = 3; /* Set additional length to 3 */
+ return 0;
+ }
+
+ snprintf((unsigned char *)&buf[8], 8, "LIO-ORG");
+ snprintf((unsigned char *)&buf[16], 16, "%s",
+ &DEV_T10_WWN(dev)->model[0]);
+ snprintf((unsigned char *)&buf[32], 4, "%s",
+ &DEV_T10_WWN(dev)->revision[0]);
+ buf[4] = 31; /* Set additional length to 31 */
+ return 0;
+}
+
+/* supported vital product data pages */
+static int
+target_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf)
+{
+ buf[1] = 0x00;
+ if (cmd->data_length < 8)
+ return 0;
+
+ buf[4] = 0x0;
+ /*
+ * Only report the INQUIRY EVPD=1 pages after a valid NAA
+ * Registered Extended LUN WWN has been set via ConfigFS
+ * during device creation/restart.
+ */
+ if (SE_DEV(cmd)->se_sub_dev->su_dev_flags &
+ SDF_EMULATED_VPD_UNIT_SERIAL) {
+ buf[3] = 3;
+ buf[5] = 0x80;
+ buf[6] = 0x83;
+ buf[7] = 0x86;
+ }
+
+ return 0;
+}
+
+/* unit serial number */
+static int
+target_emulate_evpd_80(struct se_cmd *cmd, unsigned char *buf)
+{
+ struct se_device *dev = SE_DEV(cmd);
+ u16 len;
+
+ buf[1] = 0x80;
+ if (dev->se_sub_dev->su_dev_flags &
+ SDF_EMULATED_VPD_UNIT_SERIAL) {
+ u32 unit_serial_len;
+
+ unit_serial_len =
+ strlen(&DEV_T10_WWN(dev)->unit_serial[0]);
+ unit_serial_len++; /* For NULL Terminator */
+
+ if (((len + 4) + unit_serial_len) > cmd->data_length) {
+ len += unit_serial_len;
+ buf[2] = ((len >> 8) & 0xff);
+ buf[3] = (len & 0xff);
+ return 0;
+ }
+ len += sprintf((unsigned char *)&buf[4], "%s",
+ &DEV_T10_WWN(dev)->unit_serial[0]);
+ len++; /* Extra Byte for NULL Terminator */
+ buf[3] = len;
+ }
+ return 0;
+}
+
+/*
+ * Device identification VPD, for a complete list of
+ * DESIGNATOR TYPEs see spc4r17 Table 459.
+ */
+static int
+target_emulate_evpd_83(struct se_cmd *cmd, unsigned char *buf)
+{
+ struct se_device *dev = SE_DEV(cmd);
+ struct se_lun *lun = SE_LUN(cmd);
+ struct se_port *port = NULL;
+ struct se_portal_group *tpg = NULL;
+ struct t10_alua_lu_gp_member *lu_gp_mem;
+ struct t10_alua_tg_pt_gp *tg_pt_gp;
+ struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem;
+ unsigned char binary, binary_new;
+ unsigned char *prod = &DEV_T10_WWN(dev)->model[0];
+ u32 prod_len;
+ u32 unit_serial_len, off = 0;
+ int i;
+ u16 len = 0, id_len;
+
+ buf[1] = 0x83;
+ off = 4;
+
+ /*
+ * NAA IEEE Registered Extended Assigned designator format, see
+ * spc4r17 section 7.7.3.6.5
+ *
+ * We depend upon a target_core_mod/ConfigFS provided
+ * /sys/kernel/config/target/core/$HBA/$DEV/wwn/vpd_unit_serial
+ * value in order to return the NAA id.
+ */
+ if (!(dev->se_sub_dev->su_dev_flags & SDF_EMULATED_VPD_UNIT_SERIAL))
+ goto check_t10_vend_desc;
+
+ if (off + 20 > cmd->data_length)
+ goto check_t10_vend_desc;
+
+ /* CODE SET == Binary */
+ buf[off++] = 0x1;
+
+ /* Set ASSOICATION == addressed logical unit: 0)b */
+ buf[off] = 0x00;
+
+ /* Identifier/Designator type == NAA identifier */
+ buf[off++] = 0x3;
+ off++;
+
+ /* Identifier/Designator length */
+ buf[off++] = 0x10;
+
+ /*
+ * Start NAA IEEE Registered Extended Identifier/Designator
+ */
+ buf[off++] = (0x6 << 4);
+
+ /*
+ * Use OpenFabrics IEEE Company ID: 00 14 05
+ */
+ buf[off++] = 0x01;
+ buf[off++] = 0x40;
+ buf[off] = (0x5 << 4);
+
+ /*
+ * Return ConfigFS Unit Serial Number information for
+ * VENDOR_SPECIFIC_IDENTIFIER and
+ * VENDOR_SPECIFIC_IDENTIFIER_EXTENTION
+ */
+ binary = transport_asciihex_to_binaryhex(
+ &DEV_T10_WWN(dev)->unit_serial[0]);
+ buf[off++] |= (binary & 0xf0) >> 4;
+ for (i = 0; i < 24; i += 2) {
+ binary_new = transport_asciihex_to_binaryhex(
+ &DEV_T10_WWN(dev)->unit_serial[i+2]);
+ buf[off] = (binary & 0x0f) << 4;
+ buf[off++] |= (binary_new & 0xf0) >> 4;
+ binary = binary_new;
+ }
+ len = 20;
+ off = (len + 4);
+
+check_t10_vend_desc:
+ /*
+ * T10 Vendor Identifier Page, see spc4r17 section 7.7.3.4
+ */
+ id_len = 8; /* For Vendor field */
+ prod_len = 4; /* For VPD Header */
+ prod_len += 8; /* For Vendor field */
+ prod_len += strlen(prod);
+ prod_len++; /* For : */
+
+ if (dev->se_sub_dev->su_dev_flags &
+ SDF_EMULATED_VPD_UNIT_SERIAL) {
+ unit_serial_len =
+ strlen(&DEV_T10_WWN(dev)->unit_serial[0]);
+ unit_serial_len++; /* For NULL Terminator */
+
+ if ((len + (id_len + 4) +
+ (prod_len + unit_serial_len)) >
+ cmd->data_length) {
+ len += (prod_len + unit_serial_len);
+ goto check_port;
+ }
+ id_len += sprintf((unsigned char *)&buf[off+12],
+ "%s:%s", prod,
+ &DEV_T10_WWN(dev)->unit_serial[0]);
+ }
+ buf[off] = 0x2; /* ASCII */
+ buf[off+1] = 0x1; /* T10 Vendor ID */
+ buf[off+2] = 0x0;
+ memcpy((unsigned char *)&buf[off+4], "LIO-ORG", 8);
+ /* Extra Byte for NULL Terminator */
+ id_len++;
+ /* Identifier Length */
+ buf[off+3] = id_len;
+ /* Header size for Designation descriptor */
+ len += (id_len + 4);
+ off += (id_len + 4);
+ /*
+ * struct se_port is only set for INQUIRY VPD=1 through $FABRIC_MOD
+ */
+check_port:
+ port = lun->lun_sep;
+ if (port) {
+ struct t10_alua_lu_gp *lu_gp;
+ u32 padding, scsi_name_len;
+ u16 lu_gp_id = 0;
+ u16 tg_pt_gp_id = 0;
+ u16 tpgt;
+
+ tpg = port->sep_tpg;
+ /*
+ * Relative target port identifer, see spc4r17
+ * section 7.7.3.7
+ *
+ * Get the PROTOCOL IDENTIFIER as defined by spc4r17
+ * section 7.5.1 Table 362
+ */
+ if (((len + 4) + 8) > cmd->data_length) {
+ len += 8;
+ goto check_tpgi;
+ }
+ buf[off] =
+ (TPG_TFO(tpg)->get_fabric_proto_ident(tpg) << 4);
+ buf[off++] |= 0x1; /* CODE SET == Binary */
+ buf[off] = 0x80; /* Set PIV=1 */
+ /* Set ASSOICATION == target port: 01b */
+ buf[off] |= 0x10;
+ /* DESIGNATOR TYPE == Relative target port identifer */
+ buf[off++] |= 0x4;
+ off++; /* Skip over Reserved */
+ buf[off++] = 4; /* DESIGNATOR LENGTH */
+ /* Skip over Obsolete field in RTPI payload
+ * in Table 472 */
+ off += 2;
+ buf[off++] = ((port->sep_rtpi >> 8) & 0xff);
+ buf[off++] = (port->sep_rtpi & 0xff);
+ len += 8; /* Header size + Designation descriptor */
+ /*
+ * Target port group identifier, see spc4r17
+ * section 7.7.3.8
+ *
+ * Get the PROTOCOL IDENTIFIER as defined by spc4r17
+ * section 7.5.1 Table 362
+ */
+check_tpgi:
+ if (T10_ALUA(dev->se_sub_dev)->alua_type !=
+ SPC3_ALUA_EMULATED)
+ goto check_scsi_name;
+
+ if (((len + 4) + 8) > cmd->data_length) {
+ len += 8;
+ goto check_lu_gp;
+ }
+ tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem;
+ if (!tg_pt_gp_mem)
+ goto check_lu_gp;
+
+ spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
+ tg_pt_gp = tg_pt_gp_mem->tg_pt_gp;
+ if (!(tg_pt_gp)) {
+ spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
+ goto check_lu_gp;
+ }
+ tg_pt_gp_id = tg_pt_gp->tg_pt_gp_id;
+ spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
+
+ buf[off] =
+ (TPG_TFO(tpg)->get_fabric_proto_ident(tpg) << 4);
+ buf[off++] |= 0x1; /* CODE SET == Binary */
+ buf[off] = 0x80; /* Set PIV=1 */
+ /* Set ASSOICATION == target port: 01b */
+ buf[off] |= 0x10;
+ /* DESIGNATOR TYPE == Target port group identifier */
+ buf[off++] |= 0x5;
+ off++; /* Skip over Reserved */
+ buf[off++] = 4; /* DESIGNATOR LENGTH */
+ off += 2; /* Skip over Reserved Field */
+ buf[off++] = ((tg_pt_gp_id >> 8) & 0xff);
+ buf[off++] = (tg_pt_gp_id & 0xff);
+ len += 8; /* Header size + Designation descriptor */
+ /*
+ * Logical Unit Group identifier, see spc4r17
+ * section 7.7.3.8
+ */
+check_lu_gp:
+ if (((len + 4) + 8) > cmd->data_length) {
+ len += 8;
+ goto check_scsi_name;
+ }
+ lu_gp_mem = dev->dev_alua_lu_gp_mem;
+ if (!(lu_gp_mem))
+ goto check_scsi_name;
+
+ spin_lock(&lu_gp_mem->lu_gp_mem_lock);
+ lu_gp = lu_gp_mem->lu_gp;
+ if (!(lu_gp)) {
+ spin_unlock(&lu_gp_mem->lu_gp_mem_lock);
+ goto check_scsi_name;
+ }
+ lu_gp_id = lu_gp->lu_gp_id;
+ spin_unlock(&lu_gp_mem->lu_gp_mem_lock);
+
+ buf[off++] |= 0x1; /* CODE SET == Binary */
+ /* DESIGNATOR TYPE == Logical Unit Group identifier */
+ buf[off++] |= 0x6;
+ off++; /* Skip over Reserved */
+ buf[off++] = 4; /* DESIGNATOR LENGTH */
+ off += 2; /* Skip over Reserved Field */
+ buf[off++] = ((lu_gp_id >> 8) & 0xff);
+ buf[off++] = (lu_gp_id & 0xff);
+ len += 8; /* Header size + Designation descriptor */
+ /*
+ * SCSI name string designator, see spc4r17
+ * section 7.7.3.11
+ *
+ * Get the PROTOCOL IDENTIFIER as defined by spc4r17
+ * section 7.5.1 Table 362
+ */
+check_scsi_name:
+ scsi_name_len = strlen(TPG_TFO(tpg)->tpg_get_wwn(tpg));
+ /* UTF-8 ",t,0x<16-bit TPGT>" + NULL Terminator */
+ scsi_name_len += 10;
+ /* Check for 4-byte padding */
+ padding = ((-scsi_name_len) & 3);
+ if (padding != 0)
+ scsi_name_len += padding;
+ /* Header size + Designation descriptor */
+ scsi_name_len += 4;
+
+ if (((len + 4) + scsi_name_len) > cmd->data_length) {
+ len += scsi_name_len;
+ goto set_len;
+ }
+ buf[off] =
+ (TPG_TFO(tpg)->get_fabric_proto_ident(tpg) << 4);
+ buf[off++] |= 0x3; /* CODE SET == UTF-8 */
+ buf[off] = 0x80; /* Set PIV=1 */
+ /* Set ASSOICATION == target port: 01b */
+ buf[off] |= 0x10;
+ /* DESIGNATOR TYPE == SCSI name string */
+ buf[off++] |= 0x8;
+ off += 2; /* Skip over Reserved and length */
+ /*
+ * SCSI name string identifer containing, $FABRIC_MOD
+ * dependent information. For LIO-Target and iSCSI
+ * Target Port, this means "<iSCSI name>,t,0x<TPGT> in
+ * UTF-8 encoding.
+ */
+ tpgt = TPG_TFO(tpg)->tpg_get_tag(tpg);
+ scsi_name_len = sprintf(&buf[off], "%s,t,0x%04x",
+ TPG_TFO(tpg)->tpg_get_wwn(tpg), tpgt);
+ scsi_name_len += 1 /* Include NULL terminator */;
+ /*
+ * The null-terminated, null-padded (see 4.4.2) SCSI
+ * NAME STRING field contains a UTF-8 format string.
+ * The number of bytes in the SCSI NAME STRING field
+ * (i.e., the value in the DESIGNATOR LENGTH field)
+ * shall be no larger than 256 and shall be a multiple
+ * of four.
+ */
+ if (padding)
+ scsi_name_len += padding;
+
+ buf[off-1] = scsi_name_len;
+ off += scsi_name_len;
+ /* Header size + Designation descriptor */
+ len += (scsi_name_len + 4);
+ }
+set_len:
+ buf[2] = ((len >> 8) & 0xff);
+ buf[3] = (len & 0xff); /* Page Length for VPD 0x83 */
+ return 0;
+}
+
+/* Extended INQUIRY Data VPD Page */
+static int
+target_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf)
+{
+ if (cmd->data_length < 60)
+ return 0;
+
+ buf[1] = 0x86;
+ buf[2] = 0x3c;
+ /* Set HEADSUP, ORDSUP, SIMPSUP */
+ buf[5] = 0x07;
+
+ /* If WriteCache emulation is enabled, set V_SUP */
+ if (DEV_ATTRIB(SE_DEV(cmd))->emulate_write_cache > 0)
+ buf[6] = 0x01;
+ return 0;
+}
+
+/* Block Limits VPD page */
+static int
+target_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf)
+{
+ struct se_device *dev = SE_DEV(cmd);
+ int have_tp = 0;
+
+ /*
+ * Following sbc3r22 section 6.5.3 Block Limits VPD page, when
+ * emulate_tpu=1 or emulate_tpws=1 we will be expect a
+ * different page length for Thin Provisioning.
+ */
+ if (DEV_ATTRIB(dev)->emulate_tpu || DEV_ATTRIB(dev)->emulate_tpws)
+ have_tp = 1;
+
+ if (have_tp) {
+ if (cmd->data_length < (0x3c + 4)) {
+ printk(KERN_INFO "Received data_length: %u"
+ " too small for TPE=1 EVPD 0xb0\n",
+ cmd->data_length);
+ return -1;
+ }
+ } else {
+ if (cmd->data_length < (0x10 + 4)) {
+ printk(KERN_INFO "Received data_length: %u"
+ " too small for TPE=1 EVPD 0xb0\n",
+ cmd->data_length);
+ return -1;
+ }
+ }
+
+ buf[0] = dev->transport->get_device_type(dev);
+ buf[1] = 0xb0;
+ buf[3] = have_tp ? 0x3c : 0x10;
+
+ /*
+ * Set OPTIMAL TRANSFER LENGTH GRANULARITY
+ */
+ put_unaligned_be16(1, &buf[6]);
+
+ /*
+ * Set MAXIMUM TRANSFER LENGTH
+ */
+ put_unaligned_be32(DEV_ATTRIB(dev)->max_sectors, &buf[8]);
+
+ /*
+ * Set OPTIMAL TRANSFER LENGTH
+ */
+ put_unaligned_be32(DEV_ATTRIB(dev)->optimal_sectors, &buf[12]);
+
+ if (!have_tp)
+ return 0;
+
+ /*
+ * Set MAXIMUM UNMAP LBA COUNT
+ */
+ put_unaligned_be32(DEV_ATTRIB(dev)->max_unmap_lba_count, &buf[20]);
+
+ /*
+ * Set MAXIMUM UNMAP BLOCK DESCRIPTOR COUNT
+ */
+ put_unaligned_be32(DEV_ATTRIB(dev)->max_unmap_block_desc_count,
+ &buf[24]);
+
+ /*
+ * Set OPTIMAL UNMAP GRANULARITY
+ */
+ put_unaligned_be32(DEV_ATTRIB(dev)->unmap_granularity, &buf[28]);
+
+ /*
+ * UNMAP GRANULARITY ALIGNMENT
+ */
+ put_unaligned_be32(DEV_ATTRIB(dev)->unmap_granularity_alignment,
+ &buf[32]);
+ if (DEV_ATTRIB(dev)->unmap_granularity_alignment != 0)
+ buf[32] |= 0x80; /* Set the UGAVALID bit */
+
+ return 0;
+}
+
+/* Thin Provisioning VPD */
+static int
+target_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf)
+{
+ struct se_device *dev = SE_DEV(cmd);
+
+ /*
+ * From sbc3r22 section 6.5.4 Thin Provisioning VPD page:
+ *
+ * The PAGE LENGTH field is defined in SPC-4. If the DP bit is set to
+ * zero, then the page length shall be set to 0004h. If the DP bit
+ * is set to one, then the page length shall be set to the value
+ * defined in table 162.
+ */
+ buf[0] = dev->transport->get_device_type(dev);
+ buf[1] = 0xb2;
+
+ /*
+ * Set Hardcoded length mentioned above for DP=0
+ */
+ put_unaligned_be16(0x0004, &buf[2]);
+
+ /*
+ * The THRESHOLD EXPONENT field indicates the threshold set size in
+ * LBAs as a power of 2 (i.e., the threshold set size is equal to
+ * 2(threshold exponent)).
+ *
+ * Note that this is currently set to 0x00 as mkp says it will be
+ * changing again. We can enable this once it has settled in T10
+ * and is actually used by Linux/SCSI ML code.
+ */
+ buf[4] = 0x00;
+
+ /*
+ * A TPU bit set to one indicates that the device server supports
+ * the UNMAP command (see 5.25). A TPU bit set to zero indicates
+ * that the device server does not support the UNMAP command.
+ */
+ if (DEV_ATTRIB(dev)->emulate_tpu != 0)
+ buf[5] = 0x80;
+
+ /*
+ * A TPWS bit set to one indicates that the device server supports
+ * the use of the WRITE SAME (16) command (see 5.42) to unmap LBAs.
+ * A TPWS bit set to zero indicates that the device server does not
+ * support the use of the WRITE SAME (16) command to unmap LBAs.
+ */
+ if (DEV_ATTRIB(dev)->emulate_tpws != 0)
+ buf[5] |= 0x40;
+
+ return 0;
+}
+
+static int
+target_emulate_inquiry(struct se_cmd *cmd)
+{
+ struct se_device *dev = SE_DEV(cmd);
+ unsigned char *buf = cmd->t_task->t_task_buf;
+ unsigned char *cdb = cmd->t_task->t_task_cdb;
+
+ if (!(cdb[1] & 0x1))
+ return target_emulate_inquiry_std(cmd);
+
+ /*
+ * Make sure we at least have 4 bytes of INQUIRY response
+ * payload for 0x00 going back for EVPD=1. Note that 0x80
+ * and 0x83 will check for enough payload data length and
+ * jump to set_len: label when there is not enough inquiry EVPD
+ * payload length left for the next outgoing EVPD metadata
+ */
+ if (cmd->data_length < 4) {
+ printk(KERN_ERR "SCSI Inquiry payload length: %u"
+ " too small for EVPD=1\n", cmd->data_length);
+ return -1;
+ }
+ buf[0] = dev->transport->get_device_type(dev);
+
+ switch (cdb[2]) {
+ case 0x00:
+ return target_emulate_evpd_00(cmd, buf);
+ case 0x80:
+ return target_emulate_evpd_80(cmd, buf);
+ case 0x83:
+ return target_emulate_evpd_83(cmd, buf);
+ case 0x86:
+ return target_emulate_evpd_86(cmd, buf);
+ case 0xb0:
+ return target_emulate_evpd_b0(cmd, buf);
+ case 0xb2:
+ return target_emulate_evpd_b2(cmd, buf);
+ default:
+ printk(KERN_ERR "Unknown VPD Code: 0x%02x\n", cdb[2]);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+target_emulate_readcapacity(struct se_cmd *cmd)
+{
+ struct se_device *dev = SE_DEV(cmd);
+ unsigned char *buf = cmd->t_task->t_task_buf;
+ u32 blocks = dev->transport->get_blocks(dev);
+
+ buf[0] = (blocks >> 24) & 0xff;
+ buf[1] = (blocks >> 16) & 0xff;
+ buf[2] = (blocks >> 8) & 0xff;
+ buf[3] = blocks & 0xff;
+ buf[4] = (DEV_ATTRIB(dev)->block_size >> 24) & 0xff;
+ buf[5] = (DEV_ATTRIB(dev)->block_size >> 16) & 0xff;
+ buf[6] = (DEV_ATTRIB(dev)->block_size >> 8) & 0xff;
+ buf[7] = DEV_ATTRIB(dev)->block_size & 0xff;
+ /*
+ * Set max 32-bit blocks to signal SERVICE ACTION READ_CAPACITY_16
+ */
+ if (DEV_ATTRIB(dev)->emulate_tpu || DEV_ATTRIB(dev)->emulate_tpws)
+ put_unaligned_be32(0xFFFFFFFF, &buf[0]);
+
+ return 0;
+}
+
+static int
+target_emulate_readcapacity_16(struct se_cmd *cmd)
+{
+ struct se_device *dev = SE_DEV(cmd);
+ unsigned char *buf = cmd->t_task->t_task_buf;
+ unsigned long long blocks = dev->transport->get_blocks(dev);
+
+ buf[0] = (blocks >> 56) & 0xff;
+ buf[1] = (blocks >> 48) & 0xff;
+ buf[2] = (blocks >> 40) & 0xff;
+ buf[3] = (blocks >> 32) & 0xff;
+ buf[4] = (blocks >> 24) & 0xff;
+ buf[5] = (blocks >> 16) & 0xff;
+ buf[6] = (blocks >> 8) & 0xff;
+ buf[7] = blocks & 0xff;
+ buf[8] = (DEV_ATTRIB(dev)->block_size >> 24) & 0xff;
+ buf[9] = (DEV_ATTRIB(dev)->block_size >> 16) & 0xff;
+ buf[10] = (DEV_ATTRIB(dev)->block_size >> 8) & 0xff;
+ buf[11] = DEV_ATTRIB(dev)->block_size & 0xff;
+ /*
+ * Set Thin Provisioning Enable bit following sbc3r22 in section
+ * READ CAPACITY (16) byte 14 if emulate_tpu or emulate_tpws is enabled.
+ */
+ if (DEV_ATTRIB(dev)->emulate_tpu || DEV_ATTRIB(dev)->emulate_tpws)
+ buf[14] = 0x80;
+
+ return 0;
+}
+
+static int
+target_modesense_rwrecovery(unsigned char *p)
+{
+ p[0] = 0x01;
+ p[1] = 0x0a;
+
+ return 12;
+}
+
+static int
+target_modesense_control(struct se_device *dev, unsigned char *p)
+{
+ p[0] = 0x0a;
+ p[1] = 0x0a;
+ p[2] = 2;
+ /*
+ * From spc4r17, section 7.4.6 Control mode Page
+ *
+ * Unit Attention interlocks control (UN_INTLCK_CTRL) to code 00b
+ *
+ * 00b: The logical unit shall clear any unit attention condition
+ * reported in the same I_T_L_Q nexus transaction as a CHECK CONDITION
+ * status and shall not establish a unit attention condition when a com-
+ * mand is completed with BUSY, TASK SET FULL, or RESERVATION CONFLICT
+ * status.
+ *
+ * 10b: The logical unit shall not clear any unit attention condition
+ * reported in the same I_T_L_Q nexus transaction as a CHECK CONDITION
+ * status and shall not establish a unit attention condition when
+ * a command is completed with BUSY, TASK SET FULL, or RESERVATION
+ * CONFLICT status.
+ *
+ * 11b a The logical unit shall not clear any unit attention condition
+ * reported in the same I_T_L_Q nexus transaction as a CHECK CONDITION
+ * status and shall establish a unit attention condition for the
+ * initiator port associated with the I_T nexus on which the BUSY,
+ * TASK SET FULL, or RESERVATION CONFLICT status is being returned.
+ * Depending on the status, the additional sense code shall be set to
+ * PREVIOUS BUSY STATUS, PREVIOUS TASK SET FULL STATUS, or PREVIOUS
+ * RESERVATION CONFLICT STATUS. Until it is cleared by a REQUEST SENSE
+ * command, a unit attention condition shall be established only once
+ * for a BUSY, TASK SET FULL, or RESERVATION CONFLICT status regardless
+ * to the number of commands completed with one of those status codes.
+ */
+ p[4] = (DEV_ATTRIB(dev)->emulate_ua_intlck_ctrl == 2) ? 0x30 :
+ (DEV_ATTRIB(dev)->emulate_ua_intlck_ctrl == 1) ? 0x20 : 0x00;
+ /*
+ * From spc4r17, section 7.4.6 Control mode Page
+ *
+ * Task Aborted Status (TAS) bit set to zero.
+ *
+ * A task aborted status (TAS) bit set to zero specifies that aborted
+ * tasks shall be terminated by the device server without any response
+ * to the application client. A TAS bit set to one specifies that tasks
+ * aborted by the actions of an I_T nexus other than the I_T nexus on
+ * which the command was received shall be completed with TASK ABORTED
+ * status (see SAM-4).
+ */
+ p[5] = (DEV_ATTRIB(dev)->emulate_tas) ? 0x40 : 0x00;
+ p[8] = 0xff;
+ p[9] = 0xff;
+ p[11] = 30;
+
+ return 12;
+}
+
+static int
+target_modesense_caching(struct se_device *dev, unsigned char *p)
+{
+ p[0] = 0x08;
+ p[1] = 0x12;
+ if (DEV_ATTRIB(dev)->emulate_write_cache > 0)
+ p[2] = 0x04; /* Write Cache Enable */
+ p[12] = 0x20; /* Disabled Read Ahead */
+
+ return 20;
+}
+
+static void
+target_modesense_write_protect(unsigned char *buf, int type)
+{
+ /*
+ * I believe that the WP bit (bit 7) in the mode header is the same for
+ * all device types..
+ */
+ switch (type) {
+ case TYPE_DISK:
+ case TYPE_TAPE:
+ default:
+ buf[0] |= 0x80; /* WP bit */
+ break;
+ }
+}
+
+static void
+target_modesense_dpofua(unsigned char *buf, int type)
+{
+ switch (type) {
+ case TYPE_DISK:
+ buf[0] |= 0x10; /* DPOFUA bit */
+ break;
+ default:
+ break;
+ }
+}
+
+static int
+target_emulate_modesense(struct se_cmd *cmd, int ten)
+{
+ struct se_device *dev = SE_DEV(cmd);
+ char *cdb = cmd->t_task->t_task_cdb;
+ unsigned char *rbuf = cmd->t_task->t_task_buf;
+ int type = dev->transport->get_device_type(dev);
+ int offset = (ten) ? 8 : 4;
+ int length = 0;
+ unsigned char buf[SE_MODE_PAGE_BUF];
+
+ memset(buf, 0, SE_MODE_PAGE_BUF);
+
+ switch (cdb[2] & 0x3f) {
+ case 0x01:
+ length = target_modesense_rwrecovery(&buf[offset]);
+ break;
+ case 0x08:
+ length = target_modesense_caching(dev, &buf[offset]);
+ break;
+ case 0x0a:
+ length = target_modesense_control(dev, &buf[offset]);
+ break;
+ case 0x3f:
+ length = target_modesense_rwrecovery(&buf[offset]);
+ length += target_modesense_caching(dev, &buf[offset+length]);
+ length += target_modesense_control(dev, &buf[offset+length]);
+ break;
+ default:
+ printk(KERN_ERR "Got Unknown Mode Page: 0x%02x\n",
+ cdb[2] & 0x3f);
+ return PYX_TRANSPORT_UNKNOWN_MODE_PAGE;
+ }
+ offset += length;
+
+ if (ten) {
+ offset -= 2;
+ buf[0] = (offset >> 8) & 0xff;
+ buf[1] = offset & 0xff;
+
+ if ((SE_LUN(cmd)->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) ||
+ (cmd->se_deve &&
+ (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY)))
+ target_modesense_write_protect(&buf[3], type);
+
+ if ((DEV_ATTRIB(dev)->emulate_write_cache > 0) &&
+ (DEV_ATTRIB(dev)->emulate_fua_write > 0))
+ target_modesense_dpofua(&buf[3], type);
+
+ if ((offset + 2) > cmd->data_length)
+ offset = cmd->data_length;
+
+ } else {
+ offset -= 1;
+ buf[0] = offset & 0xff;
+
+ if ((SE_LUN(cmd)->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) ||
+ (cmd->se_deve &&
+ (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY)))
+ target_modesense_write_protect(&buf[2], type);
+
+ if ((DEV_ATTRIB(dev)->emulate_write_cache > 0) &&
+ (DEV_ATTRIB(dev)->emulate_fua_write > 0))
+ target_modesense_dpofua(&buf[2], type);
+
+ if ((offset + 1) > cmd->data_length)
+ offset = cmd->data_length;
+ }
+ memcpy(rbuf, buf, offset);
+
+ return 0;
+}
+
+static int
+target_emulate_request_sense(struct se_cmd *cmd)
+{
+ unsigned char *cdb = cmd->t_task->t_task_cdb;
+ unsigned char *buf = cmd->t_task->t_task_buf;
+ u8 ua_asc = 0, ua_ascq = 0;
+
+ if (cdb[1] & 0x01) {
+ printk(KERN_ERR "REQUEST_SENSE description emulation not"
+ " supported\n");
+ return PYX_TRANSPORT_INVALID_CDB_FIELD;
+ }
+ if (!(core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq))) {
+ /*
+ * CURRENT ERROR, UNIT ATTENTION
+ */
+ buf[0] = 0x70;
+ buf[SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION;
+ /*
+ * Make sure request data length is enough for additional
+ * sense data.
+ */
+ if (cmd->data_length <= 18) {
+ buf[7] = 0x00;
+ return 0;
+ }
+ /*
+ * The Additional Sense Code (ASC) from the UNIT ATTENTION
+ */
+ buf[SPC_ASC_KEY_OFFSET] = ua_asc;
+ buf[SPC_ASCQ_KEY_OFFSET] = ua_ascq;
+ buf[7] = 0x0A;
+ } else {
+ /*
+ * CURRENT ERROR, NO SENSE
+ */
+ buf[0] = 0x70;
+ buf[SPC_SENSE_KEY_OFFSET] = NO_SENSE;
+ /*
+ * Make sure request data length is enough for additional
+ * sense data.
+ */
+ if (cmd->data_length <= 18) {
+ buf[7] = 0x00;
+ return 0;
+ }
+ /*
+ * NO ADDITIONAL SENSE INFORMATION
+ */
+ buf[SPC_ASC_KEY_OFFSET] = 0x00;
+ buf[7] = 0x0A;
+ }
+
+ return 0;
+}
+
+/*
+ * Used for TCM/IBLOCK and TCM/FILEIO for block/blk-lib.c level discard support.
+ * Note this is not used for TCM/pSCSI passthrough
+ */
+static int
+target_emulate_unmap(struct se_task *task)
+{
+ struct se_cmd *cmd = TASK_CMD(task);
+ struct se_device *dev = SE_DEV(cmd);
+ unsigned char *buf = cmd->t_task->t_task_buf, *ptr = NULL;
+ unsigned char *cdb = &cmd->t_task->t_task_cdb[0];
+ sector_t lba;
+ unsigned int size = cmd->data_length, range;
+ int ret, offset;
+ unsigned short dl, bd_dl;
+
+ /* First UNMAP block descriptor starts at 8 byte offset */
+ offset = 8;
+ size -= 8;
+ dl = get_unaligned_be16(&cdb[0]);
+ bd_dl = get_unaligned_be16(&cdb[2]);
+ ptr = &buf[offset];
+ printk(KERN_INFO "UNMAP: Sub: %s Using dl: %hu bd_dl: %hu size: %hu"
+ " ptr: %p\n", dev->transport->name, dl, bd_dl, size, ptr);
+
+ while (size) {
+ lba = get_unaligned_be64(&ptr[0]);
+ range = get_unaligned_be32(&ptr[8]);
+ printk(KERN_INFO "UNMAP: Using lba: %llu and range: %u\n",
+ (unsigned long long)lba, range);
+
+ ret = dev->transport->do_discard(dev, lba, range);
+ if (ret < 0) {
+ printk(KERN_ERR "blkdev_issue_discard() failed: %d\n",
+ ret);
+ return -1;
+ }
+
+ ptr += 16;
+ size -= 16;
+ }
+
+ task->task_scsi_status = GOOD;
+ transport_complete_task(task, 1);
+ return 0;
+}
+
+/*
+ * Used for TCM/IBLOCK and TCM/FILEIO for block/blk-lib.c level discard support.
+ * Note this is not used for TCM/pSCSI passthrough
+ */
+static int
+target_emulate_write_same(struct se_task *task)
+{
+ struct se_cmd *cmd = TASK_CMD(task);
+ struct se_device *dev = SE_DEV(cmd);
+ sector_t lba = cmd->t_task->t_task_lba;
+ unsigned int range;
+ int ret;
+
+ range = (cmd->data_length / DEV_ATTRIB(dev)->block_size);
+
+ printk(KERN_INFO "WRITE_SAME UNMAP: LBA: %llu Range: %u\n",
+ (unsigned long long)lba, range);
+
+ ret = dev->transport->do_discard(dev, lba, range);
+ if (ret < 0) {
+ printk(KERN_INFO "blkdev_issue_discard() failed for WRITE_SAME\n");
+ return -1;
+ }
+
+ task->task_scsi_status = GOOD;
+ transport_complete_task(task, 1);
+ return 0;
+}
+
+int
+transport_emulate_control_cdb(struct se_task *task)
+{
+ struct se_cmd *cmd = TASK_CMD(task);
+ struct se_device *dev = SE_DEV(cmd);
+ unsigned short service_action;
+ int ret = 0;
+
+ switch (cmd->t_task->t_task_cdb[0]) {
+ case INQUIRY:
+ ret = target_emulate_inquiry(cmd);
+ break;
+ case READ_CAPACITY:
+ ret = target_emulate_readcapacity(cmd);
+ break;
+ case MODE_SENSE:
+ ret = target_emulate_modesense(cmd, 0);
+ break;
+ case MODE_SENSE_10:
+ ret = target_emulate_modesense(cmd, 1);
+ break;
+ case SERVICE_ACTION_IN:
+ switch (cmd->t_task->t_task_cdb[1] & 0x1f) {
+ case SAI_READ_CAPACITY_16:
+ ret = target_emulate_readcapacity_16(cmd);
+ break;
+ default:
+ printk(KERN_ERR "Unsupported SA: 0x%02x\n",
+ cmd->t_task->t_task_cdb[1] & 0x1f);
+ return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
+ }
+ case REQUEST_SENSE:
+ ret = target_emulate_request_sense(cmd);
+ break;
+ case UNMAP:
+ if (!dev->transport->do_discard) {
+ printk(KERN_ERR "UNMAP emulation not supported for: %s\n",
+ dev->transport->name);
+ return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
+ }
+ ret = target_emulate_unmap(task);
+ break;
+ case WRITE_SAME_16:
+ if (!dev->transport->do_discard) {
+ printk(KERN_ERR "WRITE_SAME_16 emulation not supported"
+ " for: %s\n", dev->transport->name);
+ return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
+ }
+ ret = target_emulate_write_same(task);
+ break;
+ case VARIABLE_LENGTH_CMD:
+ service_action =
+ get_unaligned_be16(&cmd->t_task->t_task_cdb[8]);
+ switch (service_action) {
+ case WRITE_SAME_32:
+ if (!dev->transport->do_discard) {
+ printk(KERN_ERR "WRITE_SAME_32 SA emulation not"
+ " supported for: %s\n",
+ dev->transport->name);
+ return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
+ }
+ ret = target_emulate_write_same(task);
+ break;
+ default:
+ printk(KERN_ERR "Unsupported VARIABLE_LENGTH_CMD SA:"
+ " 0x%02x\n", service_action);
+ break;
+ }
+ break;
+ case SYNCHRONIZE_CACHE:
+ case 0x91: /* SYNCHRONIZE_CACHE_16: */
+ if (!dev->transport->do_sync_cache) {
+ printk(KERN_ERR
+ "SYNCHRONIZE_CACHE emulation not supported"
+ " for: %s\n", dev->transport->name);
+ return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
+ }
+ dev->transport->do_sync_cache(task);
+ break;
+ case ALLOW_MEDIUM_REMOVAL:
+ case ERASE:
+ case REZERO_UNIT:
+ case SEEK_10:
+ case SPACE:
+ case START_STOP:
+ case TEST_UNIT_READY:
+ case VERIFY:
+ case WRITE_FILEMARKS:
+ break;
+ default:
+ printk(KERN_ERR "Unsupported SCSI Opcode: 0x%02x for %s\n",
+ cmd->t_task->t_task_cdb[0], dev->transport->name);
+ return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
+ }
+
+ if (ret < 0)
+ return ret;
+ task->task_scsi_status = GOOD;
+ transport_complete_task(task, 1);
+
+ return PYX_TRANSPORT_SENT_TO_TRANSPORT;
+}
Index: lio-core-2.6/drivers/target/target_core_transport.c
===================================================================
--- lio-core-2.6.orig/drivers/target/target_core_transport.c 2010-11-08 17:06:49.144863013 +0100
+++ lio-core-2.6/drivers/target/target_core_transport.c 2010-11-08 18:13:15.068196347 +0100
@@ -4405,871 +4405,6 @@ unsigned char transport_asciihex_to_bina
}
EXPORT_SYMBOL(transport_asciihex_to_binaryhex);
-extern int transport_generic_emulate_inquiry(
- struct se_cmd *cmd,
- unsigned char type,
- unsigned char *prod,
- unsigned char *version)
-{
- struct se_device *dev = SE_DEV(cmd);
- struct se_lun *lun = SE_LUN(cmd);
- struct se_port *port = NULL;
- struct se_portal_group *tpg = NULL;
- struct t10_alua_lu_gp_member *lu_gp_mem;
- struct t10_alua_tg_pt_gp *tg_pt_gp;
- struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem;
- unsigned char *buf = (unsigned char *) T_TASK(cmd)->t_task_buf;
- unsigned char *cdb = T_TASK(cmd)->t_task_cdb;
- unsigned char binary, binary_new;
- u32 prod_len;
- u32 unit_serial_len, off = 0;
- int i;
- u16 len = 0, id_len;
-
- if (!(cdb[1] & 0x1)) {
- /*
- * Make sure we at least have 6 bytes of INQUIRY response
- * payload going back for EVPD=0
- */
- if (cmd->data_length < 6) {
- printk(KERN_ERR "SCSI Inquiry payload length: %u"
- " too small for EVPD=0\n", cmd->data_length);
- return -1;
- }
- buf[0] = type;
-
- if (type == TYPE_TAPE)
- buf[1] = 0x80;
- buf[2] = TRANSPORT(dev)->get_device_rev(dev);
- /*
- * Enable SCCS and TPGS fields for Emulated ALUA
- */
- if (T10_ALUA(dev->se_sub_dev)->alua_type ==
- SPC3_ALUA_EMULATED) {
- /*
- * Set SCCS for MAINTENANCE_IN +
- * REPORT_TARGET_PORT_GROUPS
- */
- buf[5] = 0x80;
- /*
- * Set TPGS field for explict and/or implict ALUA
- * access type and opteration.
- *
- * See spc4r17 section 6.4.2 Table 135
- */
- port = lun->lun_sep;
- if (!(port))
- goto after_tpgs;
- tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem;
- if (!(tg_pt_gp_mem))
- goto after_tpgs;
-
- spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
- tg_pt_gp = tg_pt_gp_mem->tg_pt_gp;
- if (!(tg_pt_gp)) {
- spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
- goto after_tpgs;
- }
- buf[5] |= tg_pt_gp->tg_pt_gp_alua_access_type;
- spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
- }
-after_tpgs:
- if (cmd->data_length < 8) {
- buf[4] = 1; /* Set additional length to 1 */
- return 0;
- }
-
- buf[7] = 0x32; /* Sync=1 and CmdQue=1 */
- /*
- * Do not include vendor, product, reversion info in INQUIRY
- * response payload for cdbs with a small allocation length.
- */
- if (cmd->data_length < 36) {
- buf[4] = 3; /* Set additional length to 3 */
- return 0;
- }
-
- snprintf((unsigned char *)&buf[8], 8, "LIO-ORG");
- snprintf((unsigned char *)&buf[16], 16, "%s", prod);
- snprintf((unsigned char *)&buf[32], 4, "%s", version);
- buf[4] = 31; /* Set additional length to 31 */
- return 0;
- }
- /*
- * Make sure we at least have 4 bytes of INQUIRY response
- * payload for 0x00 going back for EVPD=1. Note that 0x80
- * and 0x83 will check for enough payload data length and
- * jump to set_len: label when there is not enough inquiry EVPD
- * payload length left for the next outgoing EVPD metadata
- */
- if (cmd->data_length < 4) {
- printk(KERN_ERR "SCSI Inquiry payload length: %u"
- " too small for EVPD=1\n", cmd->data_length);
- return -1;
- }
- buf[0] = type;
-
- switch (cdb[2]) {
- case 0x00: /* supported vital product data pages */
- buf[1] = 0x00;
- if (cmd->data_length < 8)
- return 0;
- buf[4] = 0x0;
- /*
- * Only report the INQUIRY EVPD=1 pages after a valid NAA
- * Registered Extended LUN WWN has been set via ConfigFS
- * during device creation/restart.
- */
- if (dev->se_sub_dev->su_dev_flags &
- SDF_EMULATED_VPD_UNIT_SERIAL) {
- buf[3] = 3;
- buf[5] = 0x80;
- buf[6] = 0x83;
- buf[7] = 0x86;
- len = 3;
- }
- break;
- case 0x80: /* unit serial number */
- buf[1] = 0x80;
- if (dev->se_sub_dev->su_dev_flags &
- SDF_EMULATED_VPD_UNIT_SERIAL) {
-
- unit_serial_len =
- strlen(&DEV_T10_WWN(dev)->unit_serial[0]);
- unit_serial_len++; /* For NULL Terminator */
-
- if (((len + 4) + unit_serial_len) > cmd->data_length) {
- len += unit_serial_len;
- goto set_len;
- }
- len += sprintf((unsigned char *)&buf[4], "%s",
- &DEV_T10_WWN(dev)->unit_serial[0]);
- len++; /* Extra Byte for NULL Terminator */
- buf[3] = len;
- }
- break;
- case 0x83:
- /*
- * Device identification VPD, for a complete list of
- * DESIGNATOR TYPEs see spc4r17 Table 459.
- */
- buf[1] = 0x83;
- off = 4;
- /*
- * NAA IEEE Registered Extended Assigned designator format,
- * see spc4r17 section 7.7.3.6.5
- *
- * We depend upon a target_core_mod/ConfigFS provided
- * /sys/kernel/config/target/core/$HBA/$DEV/wwn/vpd_unit_serial
- * value in order to return the NAA id.
- */
- if (!(dev->se_sub_dev->su_dev_flags &
- SDF_EMULATED_VPD_UNIT_SERIAL))
- goto check_t10_vend_desc;
- if ((off + 20) > cmd->data_length)
- goto check_t10_vend_desc;
- /* CODE SET == Binary */
- buf[off++] = 0x1;
- /* Set ASSOICATION == addressed logical unit: 0)b */
- buf[off] = 0x00;
- /* Identifier/Designator type == NAA identifier */
- buf[off++] = 0x3;
- off++;
- /* Identifier/Designator length */
- buf[off++] = 0x10;
- /*
- * Start NAA IEEE Registered Extended Identifier/Designator
- */
- buf[off++] = (0x6 << 4);
- /*
- * Use OpenFabrics IEEE Company ID: 00 14 05
- */
- buf[off++] = 0x01;
- buf[off++] = 0x40;
- buf[off] = (0x5 << 4);
- /*
- * Return ConfigFS Unit Serial Number information for
- * VENDOR_SPECIFIC_IDENTIFIER and
- * VENDOR_SPECIFIC_IDENTIFIER_EXTENTION
- */
- binary = transport_asciihex_to_binaryhex(
- &DEV_T10_WWN(dev)->unit_serial[0]);
- buf[off++] |= (binary & 0xf0) >> 4;
- for (i = 0; i < 24; i += 2) {
- binary_new = transport_asciihex_to_binaryhex(
- &DEV_T10_WWN(dev)->unit_serial[i+2]);
- buf[off] = (binary & 0x0f) << 4;
- buf[off++] |= (binary_new & 0xf0) >> 4;
- binary = binary_new;
- }
- len = 20;
- off = (len + 4);
-check_t10_vend_desc:
- /*
- * T10 Vendor Identifier Page, see spc4r17 section 7.7.3.4
- */
- id_len = 8; /* For Vendor field */
- prod_len = 4; /* For VPD Header */
- prod_len += 8; /* For Vendor field */
- prod_len += strlen(prod);
- prod_len++; /* For : */
-
- if (dev->se_sub_dev->su_dev_flags &
- SDF_EMULATED_VPD_UNIT_SERIAL) {
- unit_serial_len =
- strlen(&DEV_T10_WWN(dev)->unit_serial[0]);
- unit_serial_len++; /* For NULL Terminator */
-
- if ((len + (id_len + 4) +
- (prod_len + unit_serial_len)) >
- cmd->data_length) {
- len += (prod_len + unit_serial_len);
- goto check_port;
- }
- id_len += sprintf((unsigned char *)&buf[off+12],
- "%s:%s", prod,
- &DEV_T10_WWN(dev)->unit_serial[0]);
- }
- buf[off] = 0x2; /* ASCII */
- buf[off+1] = 0x1; /* T10 Vendor ID */
- buf[off+2] = 0x0;
- memcpy((unsigned char *)&buf[off+4], "LIO-ORG", 8);
- /* Extra Byte for NULL Terminator */
- id_len++;
- /* Identifier Length */
- buf[off+3] = id_len;
- /* Header size for Designation descriptor */
- len += (id_len + 4);
- off += (id_len + 4);
- /*
- * struct se_port is only set for INQUIRY VPD=1 through $FABRIC_MOD
- */
-check_port:
- port = lun->lun_sep;
- if (port) {
- struct t10_alua_lu_gp *lu_gp;
- u32 padding, scsi_name_len;
- u16 lu_gp_id = 0;
- u16 tg_pt_gp_id = 0;
- u16 tpgt;
-
- tpg = port->sep_tpg;
- /*
- * Relative target port identifer, see spc4r17
- * section 7.7.3.7
- *
- * Get the PROTOCOL IDENTIFIER as defined by spc4r17
- * section 7.5.1 Table 362
- */
- if (((len + 4) + 8) > cmd->data_length) {
- len += 8;
- goto check_tpgi;
- }
- buf[off] =
- (TPG_TFO(tpg)->get_fabric_proto_ident(tpg) << 4);
- buf[off++] |= 0x1; /* CODE SET == Binary */
- buf[off] = 0x80; /* Set PIV=1 */
- /* Set ASSOICATION == target port: 01b */
- buf[off] |= 0x10;
- /* DESIGNATOR TYPE == Relative target port identifer */
- buf[off++] |= 0x4;
- off++; /* Skip over Reserved */
- buf[off++] = 4; /* DESIGNATOR LENGTH */
- /* Skip over Obsolete field in RTPI payload
- * in Table 472 */
- off += 2;
- buf[off++] = ((port->sep_rtpi >> 8) & 0xff);
- buf[off++] = (port->sep_rtpi & 0xff);
- len += 8; /* Header size + Designation descriptor */
- /*
- * Target port group identifier, see spc4r17
- * section 7.7.3.8
- *
- * Get the PROTOCOL IDENTIFIER as defined by spc4r17
- * section 7.5.1 Table 362
- */
-check_tpgi:
- if (T10_ALUA(dev->se_sub_dev)->alua_type !=
- SPC3_ALUA_EMULATED)
- goto check_scsi_name;
-
- if (((len + 4) + 8) > cmd->data_length) {
- len += 8;
- goto check_lu_gp;
- }
- tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem;
- if (!(tg_pt_gp_mem))
- goto check_lu_gp;
-
- spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
- tg_pt_gp = tg_pt_gp_mem->tg_pt_gp;
- if (!(tg_pt_gp)) {
- spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
- goto check_lu_gp;
- }
- tg_pt_gp_id = tg_pt_gp->tg_pt_gp_id;
- spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
-
- buf[off] =
- (TPG_TFO(tpg)->get_fabric_proto_ident(tpg) << 4);
- buf[off++] |= 0x1; /* CODE SET == Binary */
- buf[off] = 0x80; /* Set PIV=1 */
- /* Set ASSOICATION == target port: 01b */
- buf[off] |= 0x10;
- /* DESIGNATOR TYPE == Target port group identifier */
- buf[off++] |= 0x5;
- off++; /* Skip over Reserved */
- buf[off++] = 4; /* DESIGNATOR LENGTH */
- off += 2; /* Skip over Reserved Field */
- buf[off++] = ((tg_pt_gp_id >> 8) & 0xff);
- buf[off++] = (tg_pt_gp_id & 0xff);
- len += 8; /* Header size + Designation descriptor */
- /*
- * Logical Unit Group identifier, see spc4r17
- * section 7.7.3.8
- */
-check_lu_gp:
- if (((len + 4) + 8) > cmd->data_length) {
- len += 8;
- goto check_scsi_name;
- }
- lu_gp_mem = dev->dev_alua_lu_gp_mem;
- if (!(lu_gp_mem))
- goto check_scsi_name;
-
- spin_lock(&lu_gp_mem->lu_gp_mem_lock);
- lu_gp = lu_gp_mem->lu_gp;
- if (!(lu_gp)) {
- spin_unlock(&lu_gp_mem->lu_gp_mem_lock);
- goto check_scsi_name;
- }
- lu_gp_id = lu_gp->lu_gp_id;
- spin_unlock(&lu_gp_mem->lu_gp_mem_lock);
-
- buf[off++] |= 0x1; /* CODE SET == Binary */
- /* DESIGNATOR TYPE == Logical Unit Group identifier */
- buf[off++] |= 0x6;
- off++; /* Skip over Reserved */
- buf[off++] = 4; /* DESIGNATOR LENGTH */
- off += 2; /* Skip over Reserved Field */
- buf[off++] = ((lu_gp_id >> 8) & 0xff);
- buf[off++] = (lu_gp_id & 0xff);
- len += 8; /* Header size + Designation descriptor */
- /*
- * SCSI name string designator, see spc4r17
- * section 7.7.3.11
- *
- * Get the PROTOCOL IDENTIFIER as defined by spc4r17
- * section 7.5.1 Table 362
- */
-check_scsi_name:
- scsi_name_len = strlen(TPG_TFO(tpg)->tpg_get_wwn(tpg));
- /* UTF-8 ",t,0x<16-bit TPGT>" + NULL Terminator */
- scsi_name_len += 10;
- /* Check for 4-byte padding */
- padding = ((-scsi_name_len) & 3);
- if (padding != 0)
- scsi_name_len += padding;
- /* Header size + Designation descriptor */
- scsi_name_len += 4;
-
- if (((len + 4) + scsi_name_len) > cmd->data_length) {
- len += scsi_name_len;
- goto set_len;
- }
- buf[off] =
- (TPG_TFO(tpg)->get_fabric_proto_ident(tpg) << 4);
- buf[off++] |= 0x3; /* CODE SET == UTF-8 */
- buf[off] = 0x80; /* Set PIV=1 */
- /* Set ASSOICATION == target port: 01b */
- buf[off] |= 0x10;
- /* DESIGNATOR TYPE == SCSI name string */
- buf[off++] |= 0x8;
- off += 2; /* Skip over Reserved and length */
- /*
- * SCSI name string identifer containing, $FABRIC_MOD
- * dependent information. For LIO-Target and iSCSI
- * Target Port, this means "<iSCSI name>,t,0x<TPGT> in
- * UTF-8 encoding.
- */
- tpgt = TPG_TFO(tpg)->tpg_get_tag(tpg);
- scsi_name_len = sprintf(&buf[off], "%s,t,0x%04x",
- TPG_TFO(tpg)->tpg_get_wwn(tpg), tpgt);
- scsi_name_len += 1 /* Include NULL terminator */;
- /*
- * The null-terminated, null-padded (see 4.4.2) SCSI
- * NAME STRING field contains a UTF-8 format string.
- * The number of bytes in the SCSI NAME STRING field
- * (i.e., the value in the DESIGNATOR LENGTH field)
- * shall be no larger than 256 and shall be a multiple
- * of four.
- */
- if (padding)
- scsi_name_len += padding;
-
- buf[off-1] = scsi_name_len;
- off += scsi_name_len;
- /* Header size + Designation descriptor */
- len += (scsi_name_len + 4);
- }
-set_len:
- buf[2] = ((len >> 8) & 0xff);
- buf[3] = (len & 0xff); /* Page Length for VPD 0x83 */
- break;
- case 0x86: /* Extended INQUIRY Data VPD Page */
- /*
- * This page uses a hardcoded value of 60
- */
- if (cmd->data_length < 60)
- return 0;
-
- buf[1] = 0x86;
- buf[2] = 0x3c;
- /* Set HEADSUP, ORDSUP, SIMPSUP */
- buf[5] = 0x07;
- /* If WriteCache emulation is enabled, set V_SUP */
- if (DEV_ATTRIB(dev)->emulate_write_cache > 0)
- buf[6] = 0x01;
-
- break;
- case 0xb0: /* Block Limits VPD page */
- /*
- * Following sbc3r22 section 6.5.3 Block Limits VPD page,
- * when emulate_tpu=1 or emulate_tpws=1 we will be expect
- * a different page length for Thin Provisioning.
- */
- if (!(DEV_ATTRIB(dev)->emulate_tpu) &&
- !(DEV_ATTRIB(dev)->emulate_tpws)) {
- if (cmd->data_length < (0x10 + 4)) {
- printk(KERN_INFO "Received data_length: %u"
- " too small for TPE=1 EVPD 0xb0\n",
- cmd->data_length);
- return -1;
- }
- buf[0] = TRANSPORT(dev)->get_device_type(dev);
- buf[1] = 0xb0;
- buf[3] = 0x10; /* Set hardcoded TPE=0 length */
- /*
- * Set OPTIMAL TRANSFER LENGTH GRANULARITY
- */
- put_unaligned_be16(1, &buf[6]);
- /*
- * Set MAXIMUM TRANSFER LENGTH
- */
- put_unaligned_be32(DEV_ATTRIB(dev)->max_sectors,
- &buf[8]);
- /*
- * Set OPTIMAL TRANSFER LENGTH
- */
- put_unaligned_be32(DEV_ATTRIB(dev)->optimal_sectors,
- &buf[12]);
- break;
- }
-
- if (cmd->data_length < (0x3c + 4)) {
- printk(KERN_INFO "Received data_length: %u"
- " too small for TPE=1 EVPD 0xb0\n",
- cmd->data_length);
- return -1;
- }
- buf[0] = TRANSPORT(dev)->get_device_type(dev);
- buf[1] = 0xb0;
- buf[3] = 0x3c; /* Set hardcoded TPE=1 length */
- /*
- * Set OPTIMAL TRANSFER LENGTH GRANULARITY
- * Note that this follows what scsi_debug.c reports to SCSI ML
- */
- put_unaligned_be16(1, &buf[6]);
- /*
- * Set MAXIMUM TRANSFER LENGTH
- */
- put_unaligned_be32(DEV_ATTRIB(dev)->max_sectors, &buf[8]);
- /*
- * Set OPTIMAL TRANSFER LENGTH
- */
- put_unaligned_be32(DEV_ATTRIB(dev)->optimal_sectors, &buf[12]);
- /*
- * Set MAXIMUM UNMAP LBA COUNT
- */
- put_unaligned_be32(DEV_ATTRIB(dev)->max_unmap_lba_count,
- &buf[20]);
- /*
- * Set MAXIMUM UNMAP BLOCK DESCRIPTOR COUNT
- */
- put_unaligned_be32(DEV_ATTRIB(dev)->max_unmap_block_desc_count,
- &buf[24]);
- /*
- * Set OPTIMAL UNMAP GRANULARITY
- */
- put_unaligned_be32(DEV_ATTRIB(dev)->unmap_granularity,
- &buf[28]);
- /*
- * UNMAP GRANULARITY ALIGNMENT
- */
- put_unaligned_be32(DEV_ATTRIB(dev)->unmap_granularity_alignment,
- &buf[32]);
- if (DEV_ATTRIB(dev)->unmap_granularity_alignment != 0)
- buf[32] |= 0x80; /* Set the UGAVALID bit */
- break;
- case 0xb2: /* Thin Provisioning VPD */
- /*
- * From sbc3r22 section 6.5.4 Thin Provisioning VPD page:
- *
- * The PAGE LENGTH field is defined in SPC-4. If the DP bit is
- * set to zero, then the page length shall be set to 0004h. If the
- * DP bit is set to one, then the page length shall be set to the value
- * defined in table 162.
- */
- buf[0] = TRANSPORT(dev)->get_device_type(dev);
- buf[1] = 0xb2;
- /*
- * Set Hardcoded length mentioned above for DP=0
- */
- put_unaligned_be16(0x0004, &buf[2]);
- /*
- * The THRESHOLD EXPONENT field indicates the threshold set size in LBAs
- * as a power of 2 (i.e., the threshold set size is equal to 2(threshold exponent)).
- *
- * Note that this is currently set to 0x00 as mkp says it will be
- * changing again. We can enable this once it has settled in T10
- * and is actually used by Linux/SCSI ML code.
- */
- buf[4] = 0x00;
- /*
- * A TPU bit set to one indicates that the device server supports
- * the UNMAP command (see 5.25). A TPU bit set to zero indicates
- * that the device server does not support the UNMAP command.
- */
- if (DEV_ATTRIB(dev)->emulate_tpu != 0)
- buf[5] = 0x80;
- /*
- * A TPWS bit set to one indicates that the device server supports
- * the use of the WRITE SAME (16) command (see 5.42) to unmap LBAs.
- * A TPWS bit set to zero indicates that the device server does not
- * support the use of the WRITE SAME (16) command to unmap LBAs.
- */
- if (DEV_ATTRIB(dev)->emulate_tpws != 0)
- buf[5] |= 0x40;
- break;
- default:
- printk(KERN_ERR "Unknown VPD Code: 0x%02x\n", cdb[2]);
- return -1;
- }
-
- return 0;
-}
-EXPORT_SYMBOL(transport_generic_emulate_inquiry);
-
-int transport_generic_emulate_readcapacity(
- struct se_cmd *cmd,
- u32 blocks)
-{
- struct se_device *dev = SE_DEV(cmd);
- unsigned char *buf = (unsigned char *) T_TASK(cmd)->t_task_buf;
-
- buf[0] = (blocks >> 24) & 0xff;
- buf[1] = (blocks >> 16) & 0xff;
- buf[2] = (blocks >> 8) & 0xff;
- buf[3] = blocks & 0xff;
- buf[4] = (DEV_ATTRIB(dev)->block_size >> 24) & 0xff;
- buf[5] = (DEV_ATTRIB(dev)->block_size >> 16) & 0xff;
- buf[6] = (DEV_ATTRIB(dev)->block_size >> 8) & 0xff;
- buf[7] = DEV_ATTRIB(dev)->block_size & 0xff;
- /*
- * Set max 32-bit blocks to signal SERVICE ACTION READ_CAPACITY_16
- */
- if (DEV_ATTRIB(dev)->emulate_tpu || DEV_ATTRIB(dev)->emulate_tpws)
- put_unaligned_be32(0xFFFFFFFF, &buf[0]);
-
- return 0;
-}
-EXPORT_SYMBOL(transport_generic_emulate_readcapacity);
-
-int transport_generic_emulate_readcapacity_16(
- struct se_cmd *cmd,
- unsigned long long blocks)
-{
- struct se_device *dev = SE_DEV(cmd);
- unsigned char *buf = (unsigned char *) T_TASK(cmd)->t_task_buf;
-
- buf[0] = (blocks >> 56) & 0xff;
- buf[1] = (blocks >> 48) & 0xff;
- buf[2] = (blocks >> 40) & 0xff;
- buf[3] = (blocks >> 32) & 0xff;
- buf[4] = (blocks >> 24) & 0xff;
- buf[5] = (blocks >> 16) & 0xff;
- buf[6] = (blocks >> 8) & 0xff;
- buf[7] = blocks & 0xff;
- buf[8] = (DEV_ATTRIB(dev)->block_size >> 24) & 0xff;
- buf[9] = (DEV_ATTRIB(dev)->block_size >> 16) & 0xff;
- buf[10] = (DEV_ATTRIB(dev)->block_size >> 8) & 0xff;
- buf[11] = DEV_ATTRIB(dev)->block_size & 0xff;
- /*
- * Set Thin Provisioning Enable bit following sbc3r22 in section
- * READ CAPACITY (16) byte 14 if emulate_tpu or emulate_tpws is enabled.
- */
- if (DEV_ATTRIB(dev)->emulate_tpu || DEV_ATTRIB(dev)->emulate_tpws)
- buf[14] = 0x80;
-
- return 0;
-}
-EXPORT_SYMBOL(transport_generic_emulate_readcapacity_16);
-
-static int transport_modesense_rwrecovery(unsigned char *p)
-{
- p[0] = 0x01;
- p[1] = 0x0a;
-
- return 12;
-}
-
-static int transport_modesense_control(struct se_device *dev, unsigned char *p)
-{
- p[0] = 0x0a;
- p[1] = 0x0a;
- p[2] = 2;
- /*
- * From spc4r17, section 7.4.6 Control mode Page
- *
- * Unit Attention interlocks control (UN_INTLCK_CTRL) to code 00b
- *
- * 00b: The logical unit shall clear any unit attention condition
- * reported in the same I_T_L_Q nexus transaction as a CHECK CONDITION
- * status and shall not establish a unit attention condition when a com-
- * mand is completed with BUSY, TASK SET FULL, or RESERVATION CONFLICT
- * status.
- *
- * 10b: The logical unit shall not clear any unit attention condition
- * reported in the same I_T_L_Q nexus transaction as a CHECK CONDITION
- * status and shall not establish a unit attention condition when
- * a command is completed with BUSY, TASK SET FULL, or RESERVATION
- * CONFLICT status.
- *
- * 11b a The logical unit shall not clear any unit attention condition
- * reported in the same I_T_L_Q nexus transaction as a CHECK CONDITION
- * status and shall establish a unit attention condition for the
- * initiator port associated with the I_T nexus on which the BUSY,
- * TASK SET FULL, or RESERVATION CONFLICT status is being returned.
- * Depending on the status, the additional sense code shall be set to
- * PREVIOUS BUSY STATUS, PREVIOUS TASK SET FULL STATUS, or PREVIOUS
- * RESERVATION CONFLICT STATUS. Until it is cleared by a REQUEST SENSE
- * command, a unit attention condition shall be established only once
- * for a BUSY, TASK SET FULL, or RESERVATION CONFLICT status regardless
- * to the number of commands completed with one of those status codes.
- */
- p[4] = (DEV_ATTRIB(dev)->emulate_ua_intlck_ctrl == 2) ? 0x30 :
- (DEV_ATTRIB(dev)->emulate_ua_intlck_ctrl == 1) ? 0x20 : 0x00;
- /*
- * From spc4r17, section 7.4.6 Control mode Page
- *
- * Task Aborted Status (TAS) bit set to zero.
- *
- * A task aborted status (TAS) bit set to zero specifies that aborted
- * tasks shall be terminated by the device server without any response
- * to the application client. A TAS bit set to one specifies that tasks
- * aborted by the actions of an I_T nexus other than the I_T nexus on
- * which the command was received shall be completed with TASK ABORTED
- * status (see SAM-4).
- */
- p[5] = (DEV_ATTRIB(dev)->emulate_tas) ? 0x40 : 0x00;
- p[8] = 0xff;
- p[9] = 0xff;
- p[11] = 30;
-
- return 12;
-}
-
-static int transport_modesense_caching(struct se_device *dev, unsigned char *p)
-{
- p[0] = 0x08;
- p[1] = 0x12;
- if (DEV_ATTRIB(dev)->emulate_write_cache > 0)
- p[2] = 0x04; /* Write Cache Enable */
- p[12] = 0x20; /* Disabled Read Ahead */
-
- return 20;
-}
-
-#if 0
-static int transport_modesense_devicecaps(unsigned char *p)
-{
- p[0] = 0x2a;
- p[1] = 0x0a;
-
- return 12;
-}
-#endif
-
-static void transport_modesense_write_protect(
- unsigned char *buf,
- int type)
-{
- /*
- * I believe that the WP bit (bit 7) in the mode header is the same for
- * all device types..
- */
- switch (type) {
- case TYPE_DISK:
- case TYPE_TAPE:
- default:
- buf[0] |= 0x80; /* WP bit */
- break;
- }
-}
-
-static void transport_modesense_dpofua(
- unsigned char *buf,
- int type)
-{
- switch (type) {
- case TYPE_DISK:
- buf[0] |= 0x10; /* DPOFUA bit */
- break;
- default:
- break;
- }
-}
-
-int transport_generic_emulate_modesense(
- struct se_cmd *cmd,
- unsigned char *cdb,
- unsigned char *rbuf,
- int ten,
- int type)
-{
- struct se_device *dev = SE_DEV(cmd);
- int offset = (ten) ? 8 : 4;
- int length = 0;
- unsigned char buf[SE_MODE_PAGE_BUF];
-
- memset(buf, 0, SE_MODE_PAGE_BUF);
-
- switch (cdb[2] & 0x3f) {
- case 0x01:
- length = transport_modesense_rwrecovery(&buf[offset]);
- break;
- case 0x08:
- length = transport_modesense_caching(dev, &buf[offset]);
- break;
- case 0x0a:
- length = transport_modesense_control(dev, &buf[offset]);
- break;
-#if 0
- case 0x2a:
- length = transport_modesense_devicecaps(&buf[offset]);
- break;
-#endif
- case 0x3f:
- length = transport_modesense_rwrecovery(&buf[offset]);
- length += transport_modesense_caching(dev, &buf[offset+length]);
- length += transport_modesense_control(dev, &buf[offset+length]);
-#if 0
- length += transport_modesense_devicecaps(&buf[offset+length]);
-#endif
- break;
- default:
- printk(KERN_ERR "Got Unknown Mode Page: 0x%02x\n",
- cdb[2] & 0x3f);
- return PYX_TRANSPORT_UNKNOWN_MODE_PAGE;
- }
- offset += length;
-
- if (ten) {
- offset -= 2;
- buf[0] = (offset >> 8) & 0xff;
- buf[1] = offset & 0xff;
-
- if ((SE_LUN(cmd)->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) ||
- (cmd->se_deve &&
- (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY)))
- transport_modesense_write_protect(&buf[3], type);
-
- if ((DEV_ATTRIB(dev)->emulate_write_cache > 0) &&
- (DEV_ATTRIB(dev)->emulate_fua_write > 0))
- transport_modesense_dpofua(&buf[3], type);
-
- if ((offset + 2) > cmd->data_length)
- offset = cmd->data_length;
-
- } else {
- offset -= 1;
- buf[0] = offset & 0xff;
-
- if ((SE_LUN(cmd)->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) ||
- (cmd->se_deve &&
- (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY)))
- transport_modesense_write_protect(&buf[2], type);
-
- if ((DEV_ATTRIB(dev)->emulate_write_cache > 0) &&
- (DEV_ATTRIB(dev)->emulate_fua_write > 0))
- transport_modesense_dpofua(&buf[2], type);
-
- if ((offset + 1) > cmd->data_length)
- offset = cmd->data_length;
- }
- memcpy(rbuf, buf, offset);
-
- return 0;
-}
-EXPORT_SYMBOL(transport_generic_emulate_modesense);
-
-int transport_generic_emulate_request_sense(
- struct se_cmd *cmd,
- unsigned char *cdb)
-{
- unsigned char *buf = (unsigned char *) T_TASK(cmd)->t_task_buf;
- u8 ua_asc = 0, ua_ascq = 0;
-
- if (cdb[1] & 0x01) {
- printk(KERN_ERR "REQUEST_SENSE description emulation not"
- " supported\n");
- return PYX_TRANSPORT_INVALID_CDB_FIELD;
- }
- if (!(core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq))) {
- /*
- * CURRENT ERROR, UNIT ATTENTION
- */
- buf[0] = 0x70;
- buf[SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION;
- /*
- * Make sure request data length is enough for additional
- * sense data.
- */
- if (cmd->data_length <= 18) {
- buf[7] = 0x00;
- return 0;
- }
- /*
- * The Additional Sense Code (ASC) from the UNIT ATTENTION
- */
- buf[SPC_ASC_KEY_OFFSET] = ua_asc;
- buf[SPC_ASCQ_KEY_OFFSET] = ua_ascq;
- buf[7] = 0x0A;
- } else {
- /*
- * CURRENT ERROR, NO SENSE
- */
- buf[0] = 0x70;
- buf[SPC_SENSE_KEY_OFFSET] = NO_SENSE;
- /*
- * Make sure request data length is enough for additional
- * sense data.
- */
- if (cmd->data_length <= 18) {
- buf[7] = 0x00;
- return 0;
- }
- /*
- * NO ADDITIONAL SENSE INFORMATION
- */
- buf[SPC_ASC_KEY_OFFSET] = 0x00;
- buf[7] = 0x0A;
- }
-
- return 0;
-}
-EXPORT_SYMBOL(transport_generic_emulate_request_sense);
-
static void transport_xor_callback(struct se_cmd *cmd)
{
unsigned char *buf, *addr;
@@ -5385,215 +4520,6 @@ int transport_get_sense_data(struct se_c
return -1;
}
-/*
- * Used for TCM/IBLOCK and TCM/FILEIO for block/blk-lib.c level discard support.
- * Note this is not used for TCM/pSCSI passthrough
- */
-static int transport_generic_unmap(struct se_task *task)
-{
- struct se_cmd *cmd = TASK_CMD(task);
- struct se_device *dev = SE_DEV(cmd);
- unsigned char *buf = T_TASK(cmd)->t_task_buf, *ptr = NULL;
- unsigned char *cdb = &T_TASK(cmd)->t_task_cdb[0];
- sector_t lba;
- unsigned int size = cmd->data_length, range;
- int ret, offset = 8; /* First UNMAP block descriptor starts at 8 byte offset */
- unsigned short dl, bd_dl;
-
- /* Skip over UNMAP header */
- size -= 8;
- dl = get_unaligned_be16(&cdb[0]);
- bd_dl = get_unaligned_be16(&cdb[2]);
- ptr = &buf[offset];
- printk(KERN_INFO "UNMAP: Sub: %s Using dl: %hu bd_dl: %hu size: %hu"
- " ptr: %p\n", TRANSPORT(dev)->name, dl, bd_dl, size, ptr);
-
- while (size) {
- lba = get_unaligned_be64(&ptr[0]);
- range = get_unaligned_be32(&ptr[8]);
- printk(KERN_INFO "UNMAP: Using lba: %llu and range: %u\n",
- (unsigned long long)lba, range);
-
- ret = TRANSPORT(dev)->do_discard(dev, lba, range);
- if (ret < 0) {
- printk(KERN_ERR "blkdev_issue_discard() failed: %d\n", ret);
- return -1;
- }
-
- ptr += 16;
- size -= 16;
- }
-
- task->task_scsi_status = GOOD;
- transport_complete_task(task, 1);
- return 0;
-}
-
-/*
- * Used for TCM/IBLOCK and TCM/FILEIO for block/blk-lib.c level discard support.
- * Note this is not used for TCM/pSCSI passthrough
- */
-static int transport_generic_write_same(struct se_task *task)
-{
- struct se_cmd *cmd = TASK_CMD(task);
- struct se_device *dev = SE_DEV(cmd);
- sector_t lba;
- unsigned int range;
- int ret;
-
- lba = T_TASK(cmd)->t_task_lba;
- range = (cmd->data_length / DEV_ATTRIB(dev)->block_size);
-
- printk(KERN_INFO "WRITE_SAME UNMAP: LBA: %llu Range: %u\n",
- (unsigned long long)lba, range);
-
- ret = TRANSPORT(dev)->do_discard(dev, lba, range);
- if (ret < 0) {
- printk(KERN_INFO "blkdev_issue_discard() failed for WRITE_SAME\n");
- return -1;
- }
-
- task->task_scsi_status = GOOD;
- transport_complete_task(task, 1);
- return 0;
-}
-
-/*
- * Used by TCM subsystem plugins IBLOCK, FILEIO, and RAMDISK as a
- * generic non SCF_SCSI_DATA_SG_IO_CDB ops.
- */
-int transport_emulate_control_cdb(struct se_task *task)
-{
- struct se_cmd *cmd = TASK_CMD(task);
- struct se_device *dev = SE_DEV(cmd);
- sector_t blocks_long;
- unsigned int blocks;
- int ret;
- unsigned short service_action;
-
- switch (T_TASK(cmd)->t_task_cdb[0]) {
- case INQUIRY:
- ret = transport_generic_emulate_inquiry(cmd,
- TRANSPORT(dev)->get_device_type(dev),
- &DEV_T10_WWN(dev)->model[0],
- &DEV_T10_WWN(dev)->revision[0]);
- if (ret < 0)
- return ret;
- break;
- case READ_CAPACITY:
- blocks = TRANSPORT(dev)->get_blocks(dev);
- ret = transport_generic_emulate_readcapacity(cmd,
- blocks);
- if (ret < 0)
- return ret;
- break;
- case MODE_SENSE:
- ret = transport_generic_emulate_modesense(TASK_CMD(task),
- T_TASK(cmd)->t_task_cdb,
- T_TASK(cmd)->t_task_buf, 0,
- TRANSPORT(dev)->get_device_type(dev));
- if (ret < 0)
- return ret;
- break;
- case MODE_SENSE_10:
- ret = transport_generic_emulate_modesense(TASK_CMD(task),
- T_TASK(cmd)->t_task_cdb,
- T_TASK(cmd)->t_task_buf, 1,
- TRANSPORT(dev)->get_device_type(dev));
- if (ret < 0)
- return ret;
- break;
- case SERVICE_ACTION_IN:
- switch (T_TASK(cmd)->t_task_cdb[1] & 0x1f) {
- case SAI_READ_CAPACITY_16:
- blocks_long = TRANSPORT(dev)->get_blocks(dev);
- ret = transport_generic_emulate_readcapacity_16(cmd,
- blocks_long);
- if (ret < 0)
- return ret;
- break;
- default:
- printk(KERN_ERR "Unsupported SA: 0x%02x\n",
- T_TASK(cmd)->t_task_cdb[1] & 0x1f);
- return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
- }
- case REQUEST_SENSE:
- ret = transport_generic_emulate_request_sense(cmd,
- T_TASK(cmd)->t_task_cdb);
- if (ret < 0)
- return ret;
- break;
- case UNMAP:
- if (!(TRANSPORT(dev)->do_discard)) {
- printk(KERN_ERR "UNMAP emulation not supported for: %s\n",
- TRANSPORT(dev)->name);
- return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
- }
- ret = transport_generic_unmap(task);
- if (ret < 0)
- return ret;
- break;
- case WRITE_SAME_16:
- if (!(TRANSPORT(dev)->do_discard)) {
- printk(KERN_ERR "WRITE_SAME_16 emulation not supported"
- " for: %s\n", TRANSPORT(dev)->name);
- return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
- }
- ret = transport_generic_write_same(task);
- if (ret < 0)
- return ret;
- break;
- case VARIABLE_LENGTH_CMD:
- service_action = get_unaligned_be16(&T_TASK(cmd)->t_task_cdb[8]);
- switch (service_action) {
- case WRITE_SAME_32:
- if (!(TRANSPORT(dev)->do_discard)) {
- printk(KERN_ERR "WRITE_SAME_32 SA emulation not"
- " supported for: %s\n", TRANSPORT(dev)->name);
- return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
- }
- ret = transport_generic_write_same(task);
- if (ret < 0)
- return ret;
- break;
- default:
- printk(KERN_ERR "Unsupported VARIABLE_LENGTH_CMD SA:"
- " 0x%02x\n", service_action);
- break;
- }
- break;
- case SYNCHRONIZE_CACHE:
- case 0x91: /* SYNCHRONIZE_CACHE_16: */
- if (!(TRANSPORT(dev)->do_sync_cache)) {
- printk(KERN_ERR "SYNCHRONIZE_CACHE emulation not supported"
- " for: %s\n", TRANSPORT(dev)->name);
- return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
- }
- TRANSPORT(dev)->do_sync_cache(task);
- break;
- case ALLOW_MEDIUM_REMOVAL:
- case ERASE:
- case REZERO_UNIT:
- case SEEK_10:
- case SPACE:
- case START_STOP:
- case TEST_UNIT_READY:
- case VERIFY:
- case WRITE_FILEMARKS:
- break;
- default:
- printk(KERN_ERR "Unsupported SCSI Opcode: 0x%02x for %s\n",
- T_TASK(cmd)->t_task_cdb[0], TRANSPORT(dev)->name);
- return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
- }
-
- task->task_scsi_status = GOOD;
- transport_complete_task(task, 1);
-
- return PYX_TRANSPORT_SENT_TO_TRANSPORT;
-}
-EXPORT_SYMBOL(transport_emulate_control_cdb);
-
static inline void transport_dev_get_mem_buf(
struct se_device *dev,
struct se_cmd *cmd)
Index: lio-core-2.6/include/target/target_core_transport.h
===================================================================
--- lio-core-2.6.orig/include/target/target_core_transport.h 2010-11-08 17:06:49.151529680 +0100
+++ lio-core-2.6/include/target/target_core_transport.h 2010-11-08 17:06:49.221529679 +0100
@@ -221,16 +221,6 @@ extern void transport_stop_task_timer(st
extern void transport_stop_all_task_timers(struct se_cmd *);
extern int transport_execute_tasks(struct se_cmd *);
extern unsigned char transport_asciihex_to_binaryhex(unsigned char val[2]);
-extern int transport_generic_emulate_inquiry(struct se_cmd *, unsigned char,
- unsigned char *, unsigned char *);
-extern int transport_generic_emulate_readcapacity(struct se_cmd *, u32);
-extern int transport_generic_emulate_readcapacity_16(struct se_cmd *,
- unsigned long long);
-extern int transport_generic_emulate_modesense(struct se_cmd *,
- unsigned char *,
- unsigned char *, int, int);
-extern int transport_generic_emulate_request_sense(struct se_cmd *,
- unsigned char *);
extern int transport_get_sense_data(struct se_cmd *);
extern int transport_emulate_control_cdb(struct se_task *);
extern struct se_cmd *transport_allocate_passthrough(unsigned char *, int, u32,
Index: lio-core-2.6/drivers/target/Kbuild
===================================================================
--- lio-core-2.6.orig/drivers/target/Kbuild 2010-11-08 17:07:01.288196347 +0100
+++ lio-core-2.6/drivers/target/Kbuild 2010-11-08 17:07:18.058196348 +0100
@@ -11,6 +11,7 @@ target_core_mod-y := target_core_config
target_core_tmr.o \
target_core_tpg.o \
target_core_transport.o \
+ target_core_cdb.o \
target_core_ua.o \
target_core_rd.o \
target_core_mib.o
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 1/9] target: remove never changing indirections in se_cmd
2010-11-08 15:56 ` [PATCH 1/9] target: remove never changing indirections in se_cmd Christoph Hellwig
@ 2010-11-08 21:57 ` Nicholas A. Bellinger
0 siblings, 0 replies; 23+ messages in thread
From: Nicholas A. Bellinger @ 2010-11-08 21:57 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linux-scsi
On Mon, 2010-11-08 at 10:56 -0500, Christoph Hellwig wrote:
> plain text document attachment (lio-cleanup-transform)
> De-virtualize various function pointers in struct se_cmd that never change, and
> remove the transport_add_cmd_to_dev_queue wrapper.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
>
Committed as bf8b39d. Thanks for taking care of this long overdue
cleanup of this legacy cruft..
--nab
> Index: lio-core-2.6/drivers/target/target_core_transport.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/target_core_transport.c 2010-11-06 19:54:02.380003811 +0100
> +++ lio-core-2.6/drivers/target/target_core_transport.c 2010-11-06 20:17:24.519255311 +0100
> @@ -207,6 +207,8 @@ typedef int (*map_func_t)(struct se_task
>
> static int transport_generic_write_pending(struct se_cmd *);
> static int transport_processing_thread(void *);
> +static int transport_new_cmd_obj(struct se_cmd *cmd,
> + struct se_transform_info *ti, int post_execute);
>
> static char *transport_passthrough_get_fabric_name(void)
> {
> @@ -1036,9 +1038,10 @@ void transport_cmd_finish_abort_tmr(stru
>
> int transport_add_cmd_to_queue(
> struct se_cmd *cmd,
> - struct se_queue_obj *qobj,
> int t_state)
> {
> + struct se_device *dev = cmd->se_dev;
> + struct se_queue_obj *qobj = dev->dev_queue_obj;
> struct se_queue_req *qr;
> unsigned long flags;
>
> @@ -1070,13 +1073,6 @@ int transport_add_cmd_to_queue(
> return 0;
> }
>
> -static int transport_add_cmd_to_dev_queue(struct se_cmd *cmd, int t_state)
> -{
> - struct se_device *dev = cmd->se_dev;
> -
> - return transport_add_cmd_to_queue(cmd, dev->dev_queue_obj, t_state);
> -}
> -
> /*
> * Called with struct se_queue_obj->cmd_queue_lock held.
> */
> @@ -1173,7 +1169,7 @@ void transport_complete_cmd(struct se_cm
> atomic_set(&T_TASK(cmd)->t_transport_complete, 1);
> spin_unlock_irqrestore(&T_TASK(cmd)->t_state_lock, flags);
>
> - cmd->transport_add_cmd_to_queue(cmd, t_state);
> + transport_add_cmd_to_queue(cmd, t_state);
> }
>
> /*
> @@ -1272,7 +1268,7 @@ check_task_stop:
> t_state = TRANSPORT_COMPLETE_TIMEOUT;
> spin_unlock_irqrestore(&T_TASK(cmd)->t_state_lock, flags);
>
> - cmd->transport_add_cmd_to_queue(cmd, t_state);
> + transport_add_cmd_to_queue(cmd, t_state);
> return;
> }
> atomic_dec(&T_TASK(cmd)->t_task_cdbs_timeout_left);
> @@ -1315,7 +1311,7 @@ check_task_stop:
> }
> spin_unlock_irqrestore(&T_TASK(cmd)->t_state_lock, flags);
>
> - cmd->transport_add_cmd_to_queue(cmd, t_state);
> + transport_add_cmd_to_queue(cmd, t_state);
> }
> EXPORT_SYMBOL(transport_complete_task);
>
> @@ -1457,7 +1453,8 @@ void transport_add_tasks_from_cmd(struct
> *
> * Called with dev->execute_task_lock held.
> */
> -struct se_task *transport_get_task_from_execute_queue(struct se_device *dev)
> +static struct se_task *
> +transport_get_task_from_execute_queue(struct se_device *dev)
> {
> struct se_task *task;
>
> @@ -2604,8 +2601,8 @@ static int transport_process_control_sg_
> return -1;
> }
>
> - task = cmd->transport_get_task(ti, cmd, ti->se_obj_ptr,
> - cmd->data_direction);
> + task = transport_generic_get_task(ti, cmd, ti->se_obj_ptr,
> + cmd->data_direction);
> if (!(task))
> return -1;
>
> @@ -2646,8 +2643,8 @@ static int transport_process_control_non
> unsigned char *cdb;
> struct se_task *task;
>
> - task = cmd->transport_get_task(ti, cmd, ti->se_obj_ptr,
> - cmd->data_direction);
> + task = transport_generic_get_task(ti, cmd, ti->se_obj_ptr,
> + cmd->data_direction);
> if (!(task))
> return -1;
>
> @@ -2682,8 +2679,8 @@ static int transport_process_non_data_tr
> unsigned char *cdb;
> struct se_task *task;
>
> - task = cmd->transport_get_task(ti, cmd, ti->se_obj_ptr,
> - cmd->data_direction);
> + task = transport_generic_get_task(ti, cmd, ti->se_obj_ptr,
> + cmd->data_direction);
> if (!(task))
> return -1;
>
> @@ -2709,7 +2706,6 @@ static int transport_generic_cmd_sequenc
>
> void transport_device_setup_cmd(struct se_cmd *cmd)
> {
> - cmd->transport_add_cmd_to_queue = &transport_add_cmd_to_dev_queue;
> cmd->se_dev = SE_LUN(cmd)->lun_se_dev;
> }
> EXPORT_SYMBOL(transport_device_setup_cmd);
> @@ -3018,7 +3014,7 @@ int transport_generic_handle_cdb(
> return -1;
> }
>
> - cmd->transport_add_cmd_to_queue(cmd, TRANSPORT_NEW_CMD);
> + transport_add_cmd_to_queue(cmd, TRANSPORT_NEW_CMD);
> return 0;
> }
> EXPORT_SYMBOL(transport_generic_handle_cdb);
> @@ -3034,7 +3030,7 @@ int transport_generic_handle_data(
> * Make sure that the transport has been disabled by
> * transport_write_pending() before readding this struct se_cmd to the
> * processing queue. If it has not yet been reset to zero by the
> - * processing thread in cmd->transport_add_cmd_to_queue(), let other
> + * processing thread in transport_add_cmd_to_queue(), let other
> * processes run. If a signal was received, then we assume the
> * connection is being failed/shutdown, so we return a failure.
> */
> @@ -3053,7 +3049,7 @@ int transport_generic_handle_data(
> if (transport_check_aborted_status(cmd, 1) != 0)
> return 0;
>
> - cmd->transport_add_cmd_to_queue(cmd, TRANSPORT_PROCESS_WRITE);
> + transport_add_cmd_to_queue(cmd, TRANSPORT_PROCESS_WRITE);
> return 0;
> }
> EXPORT_SYMBOL(transport_generic_handle_data);
> @@ -3071,7 +3067,7 @@ int transport_generic_handle_tmr(
> cmd->transport_wait_for_tasks = &transport_generic_wait_for_tasks;
> transport_device_setup_cmd(cmd);
>
> - cmd->transport_add_cmd_to_queue(cmd, TRANSPORT_PROCESS_TMR);
> + transport_add_cmd_to_queue(cmd, TRANSPORT_PROCESS_TMR);
> return 0;
> }
> EXPORT_SYMBOL(transport_generic_handle_tmr);
> @@ -3600,11 +3596,7 @@ static void iscsi_check_iovec_map(
> #define iscsi_check_iovec_map(a, b, c, d)
> #endif
>
> -/* transport_generic_set_iovec_ptrs():
> - *
> - *
> - */
> -static int transport_generic_set_iovec_ptrs(
> +int transport_generic_set_iovec_ptrs(
> struct se_map_sg *map_sg,
> struct se_unmap_sg *unmap_sg)
> {
> @@ -3732,6 +3724,7 @@ static int transport_generic_set_iovec_p
>
> return i;
> }
> +EXPORT_SYMBOL(transport_generic_set_iovec_ptrs);
>
> /* transport_generic_allocate_buf():
> *
> @@ -3914,7 +3907,7 @@ void transport_task_timeout_handler(unsi
> cmd->t_state = TRANSPORT_COMPLETE_FAILURE;
> spin_unlock_irqrestore(&T_TASK(cmd)->t_state_lock, flags);
>
> - cmd->transport_add_cmd_to_queue(cmd, TRANSPORT_COMPLETE_FAILURE);
> + transport_add_cmd_to_queue(cmd, TRANSPORT_COMPLETE_FAILURE);
> }
>
> u32 transport_get_default_task_timeout(struct se_device *dev)
> @@ -4285,7 +4278,6 @@ void transport_new_cmd_failure(struct se
> CMD_TFO(se_cmd)->new_cmd_failure(se_cmd);
> }
>
> -static int transport_generic_map_buffers_to_tasks(struct se_cmd *);
> static void transport_nop_wait_for_tasks(struct se_cmd *, int, int);
>
> static inline u32 transport_get_sectors_6(
> @@ -5683,18 +5675,6 @@ static inline void transport_dev_get_mem
> TRANSPORT(dev)->free_DMA : NULL;
> }
>
> -/*
> - * Generic function pointers for target_core_mod/ConfigFS
> - */
> -#define SET_GENERIC_TRANSPORT_FUNCTIONS(cmd) \
> -do { \
> - cmd->transport_get_task = &transport_generic_get_task; \
> - cmd->transport_map_buffers_to_tasks = \
> - &transport_generic_map_buffers_to_tasks; \
> - cmd->transport_set_iovec_ptrs = \
> - &transport_generic_set_iovec_ptrs; \
> -} while (0)
> -
> /* transport_generic_cmd_sequencer():
> *
> * Generic Command Sequencer that should work for most DAS transport
> @@ -5767,7 +5747,6 @@ static int transport_generic_cmd_sequenc
>
> switch (cdb[0]) {
> case READ_6:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> sectors = transport_get_sectors_6(cdb, cmd, §or_ret);
> if (sector_ret)
> return TGCS_UNSUPPORTED_CDB;
> @@ -5779,7 +5758,6 @@ static int transport_generic_cmd_sequenc
> ret = TGCS_DATA_SG_IO_CDB;
> break;
> case READ_10:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> sectors = transport_get_sectors_10(cdb, cmd, §or_ret);
> if (sector_ret)
> return TGCS_UNSUPPORTED_CDB;
> @@ -5791,7 +5769,6 @@ static int transport_generic_cmd_sequenc
> ret = TGCS_DATA_SG_IO_CDB;
> break;
> case READ_12:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> sectors = transport_get_sectors_12(cdb, cmd, §or_ret);
> if (sector_ret)
> return TGCS_UNSUPPORTED_CDB;
> @@ -5803,7 +5780,6 @@ static int transport_generic_cmd_sequenc
> ret = TGCS_DATA_SG_IO_CDB;
> break;
> case READ_16:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> sectors = transport_get_sectors_16(cdb, cmd, §or_ret);
> if (sector_ret)
> return TGCS_UNSUPPORTED_CDB;
> @@ -5815,7 +5791,6 @@ static int transport_generic_cmd_sequenc
> ret = TGCS_DATA_SG_IO_CDB;
> break;
> case WRITE_6:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> sectors = transport_get_sectors_6(cdb, cmd, §or_ret);
> if (sector_ret)
> return TGCS_UNSUPPORTED_CDB;
> @@ -5827,7 +5802,6 @@ static int transport_generic_cmd_sequenc
> ret = TGCS_DATA_SG_IO_CDB;
> break;
> case WRITE_10:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> sectors = transport_get_sectors_10(cdb, cmd, §or_ret);
> if (sector_ret)
> return TGCS_UNSUPPORTED_CDB;
> @@ -5840,7 +5814,6 @@ static int transport_generic_cmd_sequenc
> ret = TGCS_DATA_SG_IO_CDB;
> break;
> case WRITE_12:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> sectors = transport_get_sectors_12(cdb, cmd, §or_ret);
> if (sector_ret)
> return TGCS_UNSUPPORTED_CDB;
> @@ -5853,7 +5826,6 @@ static int transport_generic_cmd_sequenc
> ret = TGCS_DATA_SG_IO_CDB;
> break;
> case WRITE_16:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> sectors = transport_get_sectors_16(cdb, cmd, §or_ret);
> if (sector_ret)
> return TGCS_UNSUPPORTED_CDB;
> @@ -5866,7 +5838,6 @@ static int transport_generic_cmd_sequenc
> ret = TGCS_DATA_SG_IO_CDB;
> break;
> case XDWRITEREAD_10:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> if ((cmd->data_direction != DMA_TO_DEVICE) ||
> !(T_TASK(cmd)->t_tasks_bidi))
> return TGCS_INVALID_CDB_FIELD;
> @@ -5893,7 +5864,6 @@ static int transport_generic_cmd_sequenc
> ret = TGCS_DATA_SG_IO_CDB;
> break;
> case VARIABLE_LENGTH_CMD:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> service_action = get_unaligned_be16(&cdb[8]);
> /*
> * Check the additional CDB length (+ 8 bytes for header) does
> @@ -5983,7 +5953,6 @@ static int transport_generic_cmd_sequenc
> }
> break;
> case 0xa3:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> if (TRANSPORT(dev)->get_device_type(dev) != TYPE_ROM) {
> /* MAINTENANCE_IN from SCC-2 */
> /*
> @@ -6007,21 +5976,18 @@ static int transport_generic_cmd_sequenc
> ret = TGCS_CONTROL_NONSG_IO_CDB;
> break;
> case MODE_SELECT:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> size = cdb[4];
> transport_dev_get_mem_SG(cmd->se_orig_obj_ptr, cmd);
> transport_get_maps(cmd);
> ret = TGCS_CONTROL_SG_IO_CDB;
> break;
> case MODE_SELECT_10:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> size = (cdb[7] << 8) + cdb[8];
> transport_dev_get_mem_SG(cmd->se_orig_obj_ptr, cmd);
> transport_get_maps(cmd);
> ret = TGCS_CONTROL_SG_IO_CDB;
> break;
> case MODE_SENSE:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> size = cdb[4];
> transport_dev_get_mem_buf(cmd->se_orig_obj_ptr, cmd);
> transport_get_maps(cmd);
> @@ -6032,14 +5998,12 @@ static int transport_generic_cmd_sequenc
> case GPCMD_SEND_OPC:
> case LOG_SELECT:
> case LOG_SENSE:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> size = (cdb[7] << 8) + cdb[8];
> transport_dev_get_mem_buf(cmd->se_orig_obj_ptr, cmd);
> transport_get_maps(cmd);
> ret = TGCS_CONTROL_NONSG_IO_CDB;
> break;
> case READ_BLOCK_LIMITS:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> size = READ_BLOCK_LEN;
> transport_dev_get_mem_buf(cmd->se_orig_obj_ptr, cmd);
> transport_get_maps(cmd);
> @@ -6049,7 +6013,6 @@ static int transport_generic_cmd_sequenc
> case GPCMD_READ_FORMAT_CAPACITIES:
> case GPCMD_READ_DISC_INFO:
> case GPCMD_READ_TRACK_RZONE_INFO:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> size = (cdb[7] << 8) + cdb[8];
> transport_dev_get_mem_SG(cmd->se_orig_obj_ptr, cmd);
> transport_get_maps(cmd);
> @@ -6057,7 +6020,6 @@ static int transport_generic_cmd_sequenc
> break;
> case PERSISTENT_RESERVE_IN:
> case PERSISTENT_RESERVE_OUT:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> cmd->transport_emulate_cdb =
> (T10_RES(su_dev)->res_type ==
> SPC3_PERSISTENT_RESERVATIONS) ?
> @@ -6069,21 +6031,18 @@ static int transport_generic_cmd_sequenc
> break;
> case GPCMD_MECHANISM_STATUS:
> case GPCMD_READ_DVD_STRUCTURE:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> size = (cdb[8] << 8) + cdb[9];
> transport_dev_get_mem_SG(cmd->se_orig_obj_ptr, cmd);
> transport_get_maps(cmd);
> ret = TGCS_CONTROL_SG_IO_CDB;
> break;
> case READ_POSITION:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> size = READ_POSITION_LEN;
> transport_dev_get_mem_buf(cmd->se_orig_obj_ptr, cmd);
> transport_get_maps(cmd);
> ret = TGCS_CONTROL_NONSG_IO_CDB;
> break;
> case 0xa4:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> if (TRANSPORT(dev)->get_device_type(dev) != TYPE_ROM) {
> /* MAINTENANCE_OUT from SCC-2
> *
> @@ -6108,7 +6067,6 @@ static int transport_generic_cmd_sequenc
> ret = TGCS_CONTROL_NONSG_IO_CDB;
> break;
> case INQUIRY:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> size = (cdb[3] << 8) + cdb[4];
> transport_dev_get_mem_buf(cmd->se_orig_obj_ptr, cmd);
> transport_get_maps(cmd);
> @@ -6121,14 +6079,12 @@ static int transport_generic_cmd_sequenc
> ret = TGCS_CONTROL_NONSG_IO_CDB;
> break;
> case READ_BUFFER:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> size = (cdb[6] << 16) + (cdb[7] << 8) + cdb[8];
> transport_dev_get_mem_buf(cmd->se_orig_obj_ptr, cmd);
> transport_get_maps(cmd);
> ret = TGCS_CONTROL_NONSG_IO_CDB;
> break;
> case READ_CAPACITY:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> size = READ_CAP_LEN;
> transport_dev_get_mem_buf(cmd->se_orig_obj_ptr, cmd);
> transport_get_maps(cmd);
> @@ -6137,7 +6093,6 @@ static int transport_generic_cmd_sequenc
> case READ_MEDIA_SERIAL_NUMBER:
> case SECURITY_PROTOCOL_IN:
> case SECURITY_PROTOCOL_OUT:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> size = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9];
> transport_dev_get_mem_buf(cmd->se_orig_obj_ptr, cmd);
> transport_get_maps(cmd);
> @@ -6150,7 +6105,6 @@ static int transport_generic_cmd_sequenc
> case READ_ATTRIBUTE:
> case RECEIVE_COPY_RESULTS:
> case WRITE_ATTRIBUTE:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> size = (cdb[10] << 24) | (cdb[11] << 16) |
> (cdb[12] << 8) | cdb[13];
> transport_dev_get_mem_buf(cmd->se_orig_obj_ptr, cmd);
> @@ -6159,7 +6113,6 @@ static int transport_generic_cmd_sequenc
> break;
> case RECEIVE_DIAGNOSTIC:
> case SEND_DIAGNOSTIC:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> size = (cdb[3] << 8) | cdb[4];
> transport_dev_get_mem_buf(cmd->se_orig_obj_ptr, cmd);
> transport_get_maps(cmd);
> @@ -6168,7 +6121,6 @@ static int transport_generic_cmd_sequenc
> /* #warning FIXME: Figure out correct GPCMD_READ_CD blocksize. */
> #if 0
> case GPCMD_READ_CD:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> sectors = (cdb[6] << 16) + (cdb[7] << 8) + cdb[8];
> size = (2336 * sectors);
> transport_dev_get_mem_buf(cmd->se_orig_obj_ptr, cmd);
> @@ -6177,28 +6129,24 @@ static int transport_generic_cmd_sequenc
> break;
> #endif
> case READ_TOC:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> size = cdb[8];
> transport_dev_get_mem_buf(cmd->se_orig_obj_ptr, cmd);
> transport_get_maps(cmd);
> ret = TGCS_CONTROL_NONSG_IO_CDB;
> break;
> case REQUEST_SENSE:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> size = cdb[4];
> transport_dev_get_mem_buf(cmd->se_orig_obj_ptr, cmd);
> transport_get_maps(cmd);
> ret = TGCS_CONTROL_NONSG_IO_CDB;
> break;
> case READ_ELEMENT_STATUS:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> size = 65536 * cdb[7] + 256 * cdb[8] + cdb[9];
> transport_dev_get_mem_buf(cmd->se_orig_obj_ptr, cmd);
> transport_get_maps(cmd);
> ret = TGCS_CONTROL_NONSG_IO_CDB;
> break;
> case WRITE_BUFFER:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> size = (cdb[6] << 16) + (cdb[7] << 8) + cdb[8];
> transport_dev_get_mem_buf(cmd->se_orig_obj_ptr, cmd);
> transport_get_maps(cmd);
> @@ -6215,7 +6163,6 @@ static int transport_generic_cmd_sequenc
> else
> size = cmd->data_length;
>
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> cmd->transport_allocate_resources =
> &transport_generic_allocate_none;
> transport_get_maps(cmd);
> @@ -6243,7 +6190,6 @@ static int transport_generic_cmd_sequenc
> else
> size = cmd->data_length;
>
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> cmd->transport_allocate_resources =
> &transport_generic_allocate_none;
> transport_get_maps(cmd);
> @@ -6255,7 +6201,6 @@ static int transport_generic_cmd_sequenc
> break;
> case SYNCHRONIZE_CACHE:
> case 0x91: /* SYNCHRONIZE_CACHE_16: */
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> cmd->transport_allocate_resources =
> &transport_generic_allocate_none;
> transport_get_maps(cmd);
> @@ -6292,7 +6237,6 @@ static int transport_generic_cmd_sequenc
> return TGCS_INVALID_CDB_FIELD;
> break;
> case UNMAP:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> cmd->transport_allocate_resources =
> &transport_generic_allocate_buf;
> size = get_unaligned_be16(&cdb[7]);
> @@ -6313,7 +6257,6 @@ static int transport_generic_cmd_sequenc
> ret = TGCS_CONTROL_NONSG_IO_CDB;
> break;
> case WRITE_SAME_16:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> cmd->transport_allocate_resources =
> &transport_generic_allocate_buf;
> sectors = transport_get_sectors_16(cdb, cmd, §or_ret);
> @@ -6365,14 +6308,12 @@ static int transport_generic_cmd_sequenc
> case VERIFY:
> case WRITE_FILEMARKS:
> case MOVE_MEDIUM:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> cmd->transport_allocate_resources =
> &transport_generic_allocate_none;
> transport_get_maps(cmd);
> ret = TGCS_NON_DATA_CDB;
> break;
> case REPORT_LUNS:
> - SET_GENERIC_TRANSPORT_FUNCTIONS(cmd);
> cmd->transport_emulate_cdb =
> &transport_core_report_lun_response;
> size = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9];
> @@ -7258,23 +7199,6 @@ non_scsi_data:
> return 0;
> }
>
> -/* transport_generic_do_transform():
> - *
> - *
> - */
> -int transport_generic_do_transform(struct se_cmd *cmd, struct se_transform_info *ti)
> -{
> - if (!(cmd->transport_cdb_transform)) {
> - dump_stack();
> - return -1;
> - }
> -
> - if (cmd->transport_cdb_transform(cmd, ti) < 0)
> - return -1;
> -
> - return 0;
> -}
> -
> static inline long long transport_dev_end_lba(struct se_device *dev)
> {
> return dev->dev_sectors_total + 1;
> @@ -7306,7 +7230,7 @@ int transport_get_sectors(struct se_cmd
> return 0;
> }
>
> -int transport_new_cmd_obj(
> +static int transport_new_cmd_obj(
> struct se_cmd *cmd,
> struct se_transform_info *ti,
> int post_execute)
> @@ -7365,7 +7289,6 @@ int transport_new_cmd_obj(
> #endif
> }
>
> - cmd->transport_do_transform = &transport_generic_do_transform;
> if (!post_execute) {
> atomic_set(&T_TASK(cmd)->t_task_cdbs_left, task_cdbs);
> atomic_set(&T_TASK(cmd)->t_task_cdbs_ex_left, task_cdbs);
> @@ -8016,12 +7939,7 @@ u32 transport_generic_get_cdb_count(
> CMD_TFO(cmd)->get_task_tag(cmd), lba, sectors,
> transport_dev_end_lba(dev));
>
> - if (!(cmd->transport_get_task)) {
> - dump_stack();
> - goto out;
> - }
> -
> - task = cmd->transport_get_task(ti, cmd, dev, data_direction);
> + task = transport_generic_get_task(ti, cmd, dev, data_direction);
> if (!(task))
> goto out;
>
> @@ -8158,21 +8076,27 @@ int transport_generic_new_cmd(struct se_
> }
> }
> }
> - /*
> - * This is dependent upon the storage processing algorithm.
> - */
> - if (cmd->transport_do_transform(cmd, &ti) < 0) {
> +
> + if (!(cmd->transport_cdb_transform)) {
> + dump_stack();
> + ret = PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES;
> + goto failure;
> + }
> +
> + if (cmd->transport_cdb_transform(cmd, &ti) < 0) {
> ret = PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES;
> goto failure;
> }
> +
> /*
> * Set the correct (usually DMAable) buffer pointers from the master
> * buffer list in struct se_cmd to the transport task's native
> * buffers format.
> */
> - ret = cmd->transport_map_buffers_to_tasks(cmd);
> + ret = transport_generic_map_buffers_to_tasks(cmd);
> if (ret < 0)
> goto failure;
> +
> /*
> * For WRITEs, let the iSCSI Target RX Thread know its buffer is ready..
> * This WRITE struct se_cmd (and all of its associated struct se_task's)
> Index: lio-core-2.6/include/target/target_core_base.h
> ===================================================================
> --- lio-core-2.6.orig/include/target/target_core_base.h 2010-11-06 19:54:02.404025601 +0100
> +++ lio-core-2.6/include/target/target_core_base.h 2010-11-06 20:12:40.348261038 +0100
> @@ -608,25 +608,16 @@ struct se_cmd {
> struct se_transport_task *t_task;
> struct se_transport_task t_task_backstore;
> struct target_core_fabric_ops *se_tfo;
> - int (*transport_add_cmd_to_queue)(struct se_cmd *, int);
> int (*transport_allocate_resources)(struct se_cmd *, u32, u32);
> int (*transport_cdb_transform)(struct se_cmd *,
> struct se_transform_info *);
> - int (*transport_do_transform)(struct se_cmd *,
> - struct se_transform_info *);
> int (*transport_emulate_cdb)(struct se_cmd *);
> void (*transport_free_resources)(struct se_cmd *);
> u32 (*transport_get_lba)(unsigned char *);
> unsigned long long (*transport_get_long_lba)(unsigned char *);
> - struct se_task *(*transport_get_task)(struct se_transform_info *,
> - struct se_cmd *, void *,
> - enum dma_data_direction);
> - int (*transport_map_buffers_to_tasks)(struct se_cmd *);
> void (*transport_map_SG_segments)(struct se_unmap_sg *);
> void (*transport_passthrough_done)(struct se_cmd *);
> void (*transport_unmap_SG_segments)(struct se_unmap_sg *);
> - int (*transport_set_iovec_ptrs)(struct se_map_sg *,
> - struct se_unmap_sg *);
> void (*transport_split_cdb)(unsigned long long, u32 *, unsigned char *);
> void (*transport_wait_for_tasks)(struct se_cmd *, int, int);
> void (*transport_complete_callback)(struct se_cmd *);
> Index: lio-core-2.6/include/target/target_core_transport.h
> ===================================================================
> --- lio-core-2.6.orig/include/target/target_core_transport.h 2010-11-06 19:54:02.416004160 +0100
> +++ lio-core-2.6/include/target/target_core_transport.h 2010-11-06 20:16:00.956255873 +0100
> @@ -159,8 +159,7 @@ extern void transport_task_dev_remove_st
> struct se_device *);
> extern void transport_cmd_finish_abort(struct se_cmd *, int);
> extern void transport_cmd_finish_abort_tmr(struct se_cmd *);
> -extern int transport_add_cmd_to_queue(struct se_cmd *,
> - struct se_queue_obj *, int);
> +extern int transport_add_cmd_to_queue(struct se_cmd *, int);
> extern struct se_queue_req *__transport_get_qr_from_queue(
> struct se_queue_obj *);
> extern void transport_remove_cmd_from_queue(struct se_cmd *,
> @@ -172,8 +171,6 @@ extern void transport_add_task_to_execut
> struct se_task *,
> struct se_device *);
> extern void transport_add_tasks_from_cmd(struct se_cmd *);
> -extern struct se_task *transport_get_task_from_execute_queue(
> - struct se_device *);
> extern struct se_queue_req *transport_get_qr_from_queue(struct se_queue_obj *);
> extern int transport_check_device_tcq(struct se_device *, u32, u32);
> unsigned char *transport_dump_cmd_direction(struct se_cmd *);
> @@ -272,11 +269,7 @@ extern void transport_send_task_abort(st
> extern void transport_release_cmd_to_pool(struct se_cmd *);
> extern void transport_generic_free_cmd(struct se_cmd *, int, int, int);
> extern void transport_generic_wait_for_cmds(struct se_cmd *, int);
> -extern int transport_generic_do_transform(struct se_cmd *,
> - struct se_transform_info *);
> extern int transport_get_sectors(struct se_cmd *);
> -extern int transport_new_cmd_obj(struct se_cmd *,
> - struct se_transform_info *, int);
> extern unsigned char *transport_get_vaddr(struct se_mem *);
> extern struct list_head *transport_init_se_mem_list(void);
> extern void transport_free_se_mem_list(struct list_head *);
> @@ -296,6 +289,8 @@ extern u32 transport_generic_get_cdb_cou
> extern int transport_generic_new_cmd(struct se_cmd *);
> extern void transport_generic_process_write(struct se_cmd *);
> extern int transport_generic_do_tmr(struct se_cmd *);
> +extern int transport_generic_set_iovec_ptrs(struct se_map_sg *map_sg,
> + struct se_unmap_sg *unmap_sg);
> /* From target_core_alua.c */
> extern int core_alua_check_nonop_delay(struct se_cmd *);
>
> Index: lio-core-2.6/drivers/target/lio-target/iscsi_target.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/lio-target/iscsi_target.c 2010-11-06 19:54:02.387010236 +0100
> +++ lio-core-2.6/drivers/target/lio-target/iscsi_target.c 2010-11-06 20:12:40.361004229 +0100
> @@ -1944,7 +1944,7 @@ static inline int iscsi_handle_data_out(
> unmap_sg.fabric_cmd = (void *)cmd;
> unmap_sg.se_cmd = SE_CMD(cmd);
>
> - iov_ret = SE_CMD(cmd)->transport_set_iovec_ptrs(&map_sg, &unmap_sg);
> + iov_ret = transport_generic_set_iovec_ptrs(&map_sg, &unmap_sg);
> if (iov_ret < 0)
> return -1;
>
> @@ -1989,8 +1989,7 @@ static inline int iscsi_handle_data_out(
> map_sg.data_length = hdr->length;
> map_sg.data_offset = hdr->offset;
>
> - if (SE_CMD(cmd)->transport_set_iovec_ptrs(
> - &map_sg, &unmap_sg) < 0)
> + if (transport_generic_set_iovec_ptrs(&map_sg, &unmap_sg) < 0)
> return -1;
>
> crypto_hash_init(&conn->conn_rx_hash);
> @@ -2971,7 +2970,7 @@ static int iscsi_handle_immediate_data(
> unmap_sg.fabric_cmd = (void *)cmd;
> unmap_sg.se_cmd = SE_CMD(cmd);
>
> - iov_ret = SE_CMD(cmd)->transport_set_iovec_ptrs(&map_sg, &unmap_sg);
> + iov_ret = transport_generic_set_iovec_ptrs(&map_sg, &unmap_sg);
> if (iov_ret < 0)
> return IMMEDIDATE_DATA_CANNOT_RECOVER;
>
> @@ -3019,8 +3018,7 @@ static int iscsi_handle_immediate_data(
> map_sg.data_length = length;
> map_sg.data_offset = cmd->write_data_done;
>
> - if (SE_CMD(cmd)->transport_set_iovec_ptrs(&map_sg,
> - &unmap_sg) < 0)
> + if (transport_generic_set_iovec_ptrs(&map_sg, &unmap_sg) < 0)
> return IMMEDIDATE_DATA_CANNOT_RECOVER;
>
> crypto_hash_init(&conn->conn_rx_hash);
> @@ -3454,7 +3452,7 @@ static inline int iscsi_send_data_in(
> map_sg.data_length = datain.length;
> map_sg.data_offset = datain.offset;
>
> - iov_ret = SE_CMD(cmd)->transport_set_iovec_ptrs(&map_sg, unmap_sg);
> + iov_ret = transport_generic_set_iovec_ptrs(&map_sg, unmap_sg);
> if (iov_ret < 0)
> return -1;
>
> Index: lio-core-2.6/drivers/target/tcm_loop/tcm_loop_fabric_scsi.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/tcm_loop/tcm_loop_fabric_scsi.c 2010-11-06 19:54:02.395010935 +0100
> +++ lio-core-2.6/drivers/target/tcm_loop/tcm_loop_fabric_scsi.c 2010-11-06 20:12:40.367032166 +0100
> @@ -122,11 +122,8 @@ static struct se_cmd *tcm_loop_allocate_
> se_cmd->scsi_sense_reason, 0);
> return 0;
> }
> - /*
> - * Make early call to setup se_cmd->transport_add_cmd_to_queue() pointer
> - */
> - transport_device_setup_cmd(se_cmd);
>
> + transport_device_setup_cmd(se_cmd);
> return se_cmd;
> }
>
> @@ -353,7 +350,7 @@ static int tcm_loop_queuecommand(
> /*
> * Queue up the newly allocated to be processed in TCM thread context.
> */
> - se_cmd->transport_add_cmd_to_queue(se_cmd, TRANSPORT_NEW_CMD_MAP);
> + transport_add_cmd_to_queue(se_cmd, TRANSPORT_NEW_CMD_MAP);
> /*
> * Reaquire the the struct scsi_host->host_lock before returning
> */
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/9] target: remove activate_device/deactivate_device methods
2010-11-08 15:56 ` [PATCH 2/9] target: remove activate_device/deactivate_device methods Christoph Hellwig
@ 2010-11-08 22:00 ` Nicholas A. Bellinger
0 siblings, 0 replies; 23+ messages in thread
From: Nicholas A. Bellinger @ 2010-11-08 22:00 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linux-scsi
On Mon, 2010-11-08 at 10:56 -0500, Christoph Hellwig wrote:
> plain text document attachment (lio-cleanup-activate-deactivate)
> These are no-ops in all backends. Also remove the waitqueues around
> kthread start/stop for each device as kthread_run/stop are synchronous.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Committed as a36ceb5.
Thanks!
--nab
>
> Index: lio-core-2.6/drivers/target/target_core_file.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/target_core_file.c 2010-11-06 20:18:44.613011213 +0100
> +++ lio-core-2.6/drivers/target/target_core_file.c 2010-11-06 20:19:08.470663550 +0100
> @@ -266,38 +266,6 @@ fail:
> return NULL;
> }
>
> -/* fd_activate_device(): (Part of se_subsystem_api_t template)
> - *
> - *
> - */
> -static int fd_activate_device(struct se_device *dev)
> -{
> - struct fd_dev *fd_dev = dev->dev_ptr;
> - struct fd_host *fd_host = fd_dev->fd_host;
> -
> - printk(KERN_INFO "CORE_FILE[%u] - Activating Device with TCQ: %d at"
> - " FILEIO Device ID: %d\n", fd_host->fd_host_id,
> - fd_dev->fd_queue_depth, fd_dev->fd_dev_id);
> -
> - return 0;
> -}
> -
> -/* fd_deactivate_device(): (Part of se_subsystem_api_t template)
> - *
> - *
> - */
> -static void fd_deactivate_device(struct se_device *dev)
> -{
> - struct fd_dev *fd_dev = dev->dev_ptr;
> - struct fd_host *fd_host = fd_dev->fd_host;
> -
> - printk(KERN_INFO "CORE_FILE[%u] - Deactivating Device with TCQ: %d at"
> - " FILEIO Device ID: %d\n", fd_host->fd_host_id,
> - fd_dev->fd_queue_depth, fd_dev->fd_dev_id);
> -
> - return;
> -}
> -
> /* fd_free_device(): (Part of se_subsystem_api_t template)
> *
> *
> @@ -997,8 +965,6 @@ static struct se_subsystem_api fileio_te
> .cdb_write_SG = fd_CDB_write_SG,
> .allocate_virtdevice = fd_allocate_virtdevice,
> .create_virtdevice = fd_create_virtdevice,
> - .activate_device = fd_activate_device,
> - .deactivate_device = fd_deactivate_device,
> .free_device = fd_free_device,
> .dpo_emulated = fd_emulated_dpo,
> .fua_write_emulated = fd_emulated_fua_write,
> Index: lio-core-2.6/drivers/target/target_core_iblock.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/target_core_iblock.c 2010-11-06 20:17:55.062262645 +0100
> +++ lio-core-2.6/drivers/target/target_core_iblock.c 2010-11-06 20:18:39.142005277 +0100
> @@ -247,36 +247,6 @@ failed:
> return NULL;
> }
>
> -/* iblock_activate_device(): (Part of se_subsystem_api_t template)
> - *
> - *
> - */
> -static int iblock_activate_device(struct se_device *dev)
> -{
> - struct iblock_dev *ib_dev = dev->dev_ptr;
> - struct iblock_hba *ib_hba = ib_dev->ibd_host;
> -
> - printk(KERN_INFO "CORE_iBLOCK[%u] - Activating Device with TCQ: %d at"
> - " Major: %d Minor %d\n", ib_hba->iblock_host_id,
> - ib_dev->ibd_depth, ib_dev->ibd_major, ib_dev->ibd_minor);
> -
> - return 0;
> -}
> -
> -/* iblock_deactivate_device(): (Part of se_subsystem_api_t template)
> - *
> - *
> - */
> -static void iblock_deactivate_device(struct se_device *dev)
> -{
> - struct iblock_dev *ib_dev = dev->dev_ptr;
> - struct iblock_hba *ib_hba = ib_dev->ibd_host;
> -
> - printk(KERN_INFO "CORE_iBLOCK[%u] - Deactivating Device with TCQ: %d"
> - " at Major: %d Minor %d\n", ib_hba->iblock_host_id,
> - ib_dev->ibd_depth, ib_dev->ibd_major, ib_dev->ibd_minor);
> -}
> -
> static void iblock_free_device(void *p)
> {
> struct iblock_dev *ib_dev = p;
> @@ -963,8 +933,6 @@ static struct se_subsystem_api iblock_te
> .detach_hba = iblock_detach_hba,
> .allocate_virtdevice = iblock_allocate_virtdevice,
> .create_virtdevice = iblock_create_virtdevice,
> - .activate_device = iblock_activate_device,
> - .deactivate_device = iblock_deactivate_device,
> .free_device = iblock_free_device,
> .dpo_emulated = iblock_emulated_dpo,
> .fua_write_emulated = iblock_emulated_fua_write,
> Index: lio-core-2.6/drivers/target/target_core_pscsi.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/target_core_pscsi.c 2010-11-06 20:18:54.140024065 +0100
> +++ lio-core-2.6/drivers/target/target_core_pscsi.c 2010-11-06 20:19:03.139048436 +0100
> @@ -565,42 +565,6 @@ static struct se_device *pscsi_create_vi
> return NULL;
> }
>
> -/* pscsi_activate_device(): (Part of se_subsystem_api_t template)
> - *
> - *
> - */
> -static int pscsi_activate_device(struct se_device *dev)
> -{
> - struct pscsi_dev_virt *pdv = dev->dev_ptr;
> - struct pscsi_hba_virt *phv = pdv->pdv_se_hba->hba_ptr;
> - struct scsi_device *sd = pdv->pdv_sd;
> - struct Scsi_Host *sh = sd->host;
> -
> - printk(KERN_INFO "CORE_PSCSI[%d] - Activating Device with TCQ: %d at"
> - " SCSI Location (Host/Channel/Target/LUN) %d/%d/%d/%d\n",
> - phv->phv_host_id, sd->queue_depth, sh->host_no, sd->channel,
> - sd->id, sd->lun);
> -
> - return 0;
> -}
> -
> -/* pscsi_deactivate_device(): (Part of se_subsystem_api_t template)
> - *
> - *
> - */
> -static void pscsi_deactivate_device(struct se_device *dev)
> -{
> - struct pscsi_dev_virt *pdv = dev->dev_ptr;
> - struct pscsi_hba_virt *phv = pdv->pdv_se_hba->hba_ptr;
> - struct scsi_device *sd = pdv->pdv_sd;
> - struct Scsi_Host *sh = sd->host;
> -
> - printk(KERN_INFO "CORE_PSCSI[%d] - Deactivating Device with TCQ: %d at"
> - " SCSI Location (Host/Channel/Target/LUN) %d/%d/%d/%d\n",
> - phv->phv_host_id, sd->queue_depth, sh->host_no, sd->channel,
> - sd->id, sd->lun);
> -}
> -
> /* pscsi_free_device(): (Part of se_subsystem_api_t template)
> *
> *
> @@ -1532,8 +1496,6 @@ static struct se_subsystem_api pscsi_tem
> .attach_hba = pscsi_attach_hba,
> .detach_hba = pscsi_detach_hba,
> .pmode_enable_hba = pscsi_pmode_enable_hba,
> - .activate_device = pscsi_activate_device,
> - .deactivate_device = pscsi_deactivate_device,
> .allocate_virtdevice = pscsi_allocate_virtdevice,
> .create_virtdevice = pscsi_create_virtdevice,
> .free_device = pscsi_free_device,
> Index: lio-core-2.6/drivers/target/target_core_rd.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/target_core_rd.c 2010-11-06 20:19:14.701260270 +0100
> +++ lio-core-2.6/drivers/target/target_core_rd.c 2010-11-06 20:19:30.633255381 +0100
> @@ -330,36 +330,6 @@ static struct se_device *rd_MEMCPY_creat
> return rd_create_virtdevice(hba, se_dev, p, 0);
> }
>
> -/* rd_activate_device(): (Part of se_subsystem_api_t template)
> - *
> - *
> - */
> -static int rd_activate_device(struct se_device *dev)
> -{
> - struct rd_dev *rd_dev = dev->dev_ptr;
> - struct rd_host *rd_host = rd_dev->rd_host;
> -
> - printk(KERN_INFO "CORE_RD[%u] - Activating Device with TCQ: %d at"
> - " Ramdisk Device ID: %d\n", rd_host->rd_host_id,
> - rd_dev->rd_queue_depth, rd_dev->rd_dev_id);
> -
> - return 0;
> -}
> -
> -/* rd_deactivate_device(): (Part of se_subsystem_api_t template)
> - *
> - *
> - */
> -static void rd_deactivate_device(struct se_device *dev)
> -{
> - struct rd_dev *rd_dev = dev->dev_ptr;
> - struct rd_host *rd_host = rd_dev->rd_host;
> -
> - printk(KERN_INFO "CORE_RD[%u] - Deactivating Device with TCQ: %d at"
> - " Ramdisk Device ID: %d\n", rd_host->rd_host_id,
> - rd_dev->rd_queue_depth, rd_dev->rd_dev_id);
> -}
> -
> /* rd_free_device(): (Part of se_subsystem_api_t template)
> *
> *
> @@ -1323,8 +1293,6 @@ static struct se_subsystem_api rd_dr_tem
> .detach_hba = rd_detach_hba,
> .allocate_virtdevice = rd_DIRECT_allocate_virtdevice,
> .create_virtdevice = rd_DIRECT_create_virtdevice,
> - .activate_device = rd_activate_device,
> - .deactivate_device = rd_deactivate_device,
> .free_device = rd_free_device,
> .transport_complete = rd_transport_complete,
> .allocate_DMA = rd_DIRECT_allocate_DMA,
> @@ -1363,8 +1331,6 @@ static struct se_subsystem_api rd_mcp_te
> .detach_hba = rd_detach_hba,
> .allocate_virtdevice = rd_MEMCPY_allocate_virtdevice,
> .create_virtdevice = rd_MEMCPY_create_virtdevice,
> - .activate_device = rd_activate_device,
> - .deactivate_device = rd_deactivate_device,
> .free_device = rd_free_device,
> .transport_complete = rd_transport_complete,
> .allocate_request = rd_allocate_request,
> Index: lio-core-2.6/drivers/target/target_core_stgt.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/target_core_stgt.c 2010-11-06 20:19:40.388254264 +0100
> +++ lio-core-2.6/drivers/target/target_core_stgt.c 2010-11-06 20:19:49.419190498 +0100
> @@ -314,40 +314,6 @@ static struct se_device *stgt_create_vir
> return NULL;
> }
>
> -/* stgt_activate_device(): (Part of se_subsystem_api_t template)
> - *
> - *
> - */
> -static int stgt_activate_device(struct se_device *dev)
> -{
> - struct stgt_dev_virt *sdv = dev->dev_ptr;
> - struct scsi_device *sd = sdv->sdv_sd;
> - struct Scsi_Host *sh = sd->host;
> -
> - printk(KERN_INFO "CORE_STGT[%d] - Activating %s Device with TCQ: %d at"
> - " SCSI Location (Channel/Target/LUN) %d/%d/%d\n", sh->host_no,
> - (sdv->sdv_legacy) ? "Legacy" : "REQ", sd->queue_depth,
> - sd->channel, sd->id, sd->lun);
> -
> - return 0;
> -}
> -
> -/* stgt_deactivate_device(): (Part of se_subsystem_api_t template)
> - *
> - *
> - */
> -static void stgt_deactivate_device(struct se_device *dev)
> -{
> - struct stgt_dev_virt *sdv = dev->dev_ptr;
> - struct scsi_device *sd = sdv->sdv_sd;
> - struct Scsi_Host *sh = sd->host;
> -
> - printk(KERN_INFO "CORE_STGT[%d] - Deactivating %s Device with TCQ: %d"
> - " at SCSI Location (Channel/Target/LUN) %d/%d/%d\n",
> - sh->host_no, (sdv->sdv_legacy) ? "Legacy" : "REQ",
> - sd->queue_depth, sd->channel, sd->id, sd->lun);
> -}
> -
> /* stgt_free_device(): (Part of se_subsystem_api_t template)
> *
> *
> @@ -877,8 +843,6 @@ static struct se_subsystem_api stgt_temp
> .cdb_write_SG = stgt_CDB_write_SG,
> .attach_hba = stgt_attach_hba,
> .detach_hba = stgt_detach_hba,
> - .activate_device = stgt_activate_device,
> - .deactivate_device = stgt_deactivate_device,
> .allocate_virtdevice = stgt_allocate_virtdevice,
> .create_virtdevice = stgt_create_virtdevice,
> .free_device = stgt_free_device,
> Index: lio-core-2.6/drivers/target/target_core_transport.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/target_core_transport.c 2010-11-06 20:20:04.617254054 +0100
> +++ lio-core-2.6/drivers/target/target_core_transport.c 2010-11-06 20:28:22.335005310 +0100
> @@ -503,8 +503,6 @@ void transport_init_queue_obj(struct se_
> atomic_set(&qobj->queue_cnt, 0);
> INIT_LIST_HEAD(&qobj->qobj_list);
> init_waitqueue_head(&qobj->thread_wq);
> - init_completion(&qobj->thread_create_comp);
> - init_completion(&qobj->thread_done_comp);
> spin_lock_init(&qobj->cmd_queue_lock);
> }
> EXPORT_SYMBOL(transport_init_queue_obj);
> @@ -2296,11 +2294,18 @@ struct se_device *transport_add_device_t
> */
> if (core_setup_alua(dev, force_pt) < 0)
> goto out;
> +
> /*
> * Startup the struct se_device processing thread
> */
> - if (transport_generic_activate_device(dev) < 0)
> + dev->process_thread = kthread_run(transport_processing_thread, dev,
> + "LIO_%s", TRANSPORT(dev)->name);
> + if (IS_ERR(dev->process_thread)) {
> + printk(KERN_ERR "Unable to create kthread: LIO_%s\n",
> + TRANSPORT(dev)->name);
> goto out;
> + }
> +
> /*
> * Preload the initial INQUIRY const values if we are doing
> * anything virtual (IBLOCK, FILEIO, RAMDISK), but not for TCM/pSCSI
> @@ -2352,10 +2357,7 @@ struct se_device *transport_add_device_t
> out:
> if (!ret)
> return dev;
> - /*
> - * Release newly allocated state for struct se_device
> - */
> - transport_generic_deactivate_device(dev);
> + kthread_stop(dev->process_thread);
>
> spin_lock(&hba->device_lock);
> list_del(&dev->dev_list);
> @@ -2372,46 +2374,6 @@ out:
> }
> EXPORT_SYMBOL(transport_add_device_to_core_hba);
>
> -/* transport_generic_activate_device():
> - *
> - *
> - */
> -int transport_generic_activate_device(struct se_device *dev)
> -{
> - char name[16];
> -
> - if (TRANSPORT(dev)->activate_device)
> - TRANSPORT(dev)->activate_device(dev);
> -
> - memset(name, 0, 16);
> - snprintf(name, 16, "LIO_%s", TRANSPORT(dev)->name);
> -
> - dev->process_thread = kthread_run(transport_processing_thread,
> - (void *)dev, name);
> - if (IS_ERR(dev->process_thread)) {
> - printk(KERN_ERR "Unable to create kthread: %s\n", name);
> - return -1;
> - }
> -
> - wait_for_completion(&dev->dev_queue_obj->thread_create_comp);
> -
> - return 0;
> -}
> -
> -/* transport_generic_deactivate_device():
> - *
> - *
> - */
> -void transport_generic_deactivate_device(struct se_device *dev)
> -{
> - if (TRANSPORT(dev)->deactivate_device)
> - TRANSPORT(dev)->deactivate_device(dev);
> -
> - kthread_stop(dev->process_thread);
> -
> - wait_for_completion(&dev->dev_queue_obj->thread_done_comp);
> -}
> -
> /* transport_generic_free_device():
> *
> *
> @@ -2421,7 +2383,7 @@ void transport_generic_free_device(struc
> if (!(dev->dev_ptr))
> return;
>
> - transport_generic_deactivate_device(dev);
> + kthread_stop(dev->process_thread);
>
> if (TRANSPORT(dev)->free_device)
> TRANSPORT(dev)->free_device(dev->dev_ptr);
> @@ -9098,8 +9060,6 @@ static int transport_processing_thread(v
> recalc_sigpending();
> spin_unlock_irq(¤t->sighand->siglock);
>
> - complete(&dev->dev_queue_obj->thread_create_comp);
> -
> while (!(kthread_should_stop())) {
> ret = wait_event_interruptible(dev->dev_queue_obj->thread_wq,
> atomic_read(&dev->dev_queue_obj->queue_cnt) ||
> @@ -9187,6 +9147,5 @@ get_cmd:
> out:
> transport_release_all_cmds(dev);
> dev->process_thread = NULL;
> - complete(&dev->dev_queue_obj->thread_done_comp);
> return 0;
> }
> Index: lio-core-2.6/drivers/target/tcm_fc/tfc_cmd.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/tcm_fc/tfc_cmd.c 2010-11-06 20:23:27.561023505 +0100
> +++ lio-core-2.6/drivers/target/tcm_fc/tfc_cmd.c 2010-11-06 20:24:45.698005617 +0100
> @@ -654,8 +654,6 @@ int ft_thread(void *arg)
> recalc_sigpending();
> spin_unlock_irq(¤t->sighand->siglock);
>
> - complete(&qobj->thread_create_comp);
> -
> while (!(kthread_should_stop())) {
> ret = wait_event_interruptible(qobj->thread_wq,
> atomic_read(&qobj->queue_cnt) || kthread_should_stop());
> @@ -667,6 +665,5 @@ int ft_thread(void *arg)
> }
>
> out:
> - complete(&qobj->thread_done_comp);
> return 0;
> }
> Index: lio-core-2.6/drivers/target/tcm_fc/tfc_conf.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/tcm_fc/tfc_conf.c 2010-11-06 20:23:35.362254054 +0100
> +++ lio-core-2.6/drivers/target/tcm_fc/tfc_conf.c 2010-11-06 20:24:38.170005695 +0100
> @@ -342,7 +342,6 @@ static struct se_portal_group *ft_add_tp
> kfree(tpg);
> return NULL;
> }
> - wait_for_completion(&tpg->qobj.thread_create_comp);
>
> mutex_lock(&ft_lport_lock);
> list_add_tail(&tpg->list, &lacl->tpg_list);
> @@ -359,7 +358,6 @@ static void ft_del_tpg(struct se_portal_
> config_item_name(&tpg->se_tpg.tpg_group.cg_item));
>
> kthread_stop(tpg->thread);
> - wait_for_completion(&tpg->qobj.thread_done_comp);
>
> /* Wait for sessions to be freed thru RCU, for BUG_ON below */
> synchronize_rcu();
> Index: lio-core-2.6/include/target/target_core_base.h
> ===================================================================
> --- lio-core-2.6.orig/include/target/target_core_base.h 2010-11-06 20:23:53.939003740 +0100
> +++ lio-core-2.6/include/target/target_core_base.h 2010-11-06 20:27:11.226005136 +0100
> @@ -415,8 +415,6 @@ struct se_queue_obj {
> spinlock_t cmd_queue_lock;
> struct list_head qobj_list;
> wait_queue_head_t thread_wq;
> - struct completion thread_create_comp;
> - struct completion thread_done_comp;
> } ____cacheline_aligned;
>
> /*
> Index: lio-core-2.6/include/target/target_core_transport.h
> ===================================================================
> --- lio-core-2.6.orig/include/target/target_core_transport.h 2010-11-06 20:21:04.487003811 +0100
> +++ lio-core-2.6/include/target/target_core_transport.h 2010-11-06 20:21:09.952587550 +0100
> @@ -191,8 +191,6 @@ extern struct se_device *transport_add_d
> struct se_subsystem_dev *, u32,
> void *, struct se_dev_limits *,
> const char *, const char *);
> -extern int transport_generic_activate_device(struct se_device *);
> -extern void transport_generic_deactivate_device(struct se_device *);
> extern void transport_generic_free_device(struct se_device *);
> extern int transport_generic_allocate_iovecs(struct se_cmd *);
> extern void transport_device_setup_cmd(struct se_cmd *);
> @@ -383,14 +381,6 @@ struct se_subsystem_api {
> struct se_device *(*create_virtdevice)(struct se_hba *,
> struct se_subsystem_dev *, void *);
> /*
> - * activate_device():
> - */
> - int (*activate_device)(struct se_device *);
> - /*
> - * deactivate_device():
> - */
> - void (*deactivate_device)(struct se_device *);
> - /*
> * free_device():
> */
> void (*free_device)(void *);
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 3/9] target: remove SHUTDOWN_SIGS
2010-11-08 15:56 ` [PATCH 3/9] From: Christoph Hellwig <hch@lst.de> Sujbect: target: remove SHUTDOWN_SIGS Christoph Hellwig
@ 2010-11-08 22:21 ` Nicholas A. Bellinger
2010-11-08 22:31 ` Christoph Hellwig
0 siblings, 1 reply; 23+ messages in thread
From: Nicholas A. Bellinger @ 2010-11-08 22:21 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linux-scsi, Joe Eykholt
On Mon, 2010-11-08 at 10:56 -0500, Christoph Hellwig wrote:
> plain text document attachment (lio-fix-thread-shutdown)
> In the these days with the kthread API we should never send signals to
> kernel threads, but let start/stop be handled by the kthread helpers.
>
> Note that the set_user_nice for all threads in the target code does not
> seem particularly nice to the rest of the system. Please re-evaluate if
> the nice value is nessecary.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
This patch is not quite correct as drivers/target/lio-target/ is
currently the last code *not* using linux/kthread.h in the tree. I
recall running into some issue wrt to kernel sockets + signals during
the original convertion use kthread.h, but I don't recall the specifics
atm. For now I will drop the lio-target part of this patch, and have a
look at doing this conversion to kthread.h properly during the
drivers/target/lio-target review for Boaz in the upcoming week.
Thanks!
--nab
>
> Index: lio-core-2.6/drivers/target/lio-target/iscsi_target.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/lio-target/iscsi_target.c 2010-11-06 20:36:08.953253984 +0100
> +++ lio-core-2.6/drivers/target/lio-target/iscsi_target.c 2010-11-06 20:37:11.221005277 +0100
> @@ -4524,13 +4524,8 @@ int iscsi_target_tx_thread(void *arg)
> struct se_thread_set *ts = (struct se_thread_set *) arg;
> struct se_unmap_sg unmap_sg;
>
> - {
> - char name[20];
> -
> - memset(name, 0, 20);
> - sprintf(name, "%s/%u", ISCSI_TX_THREAD_NAME, ts->thread_id);
> - iscsi_daemon(ts->tx_thread, name, SHUTDOWN_SIGS);
> - }
> + set_user_nice(current, -20);
> + ts->tx_thread = current;
>
> restart:
> conn = iscsi_tx_thread_pre_handler(ts, TARGET);
> @@ -4877,13 +4872,8 @@ int iscsi_target_rx_thread(void *arg)
> struct iovec iov;
> struct scatterlist sg;
>
> - {
> - char name[20];
> -
> - memset(name, 0, 20);
> - sprintf(name, "%s/%u", ISCSI_RX_THREAD_NAME, ts->thread_id);
> - iscsi_daemon(ts->rx_thread, name, SHUTDOWN_SIGS);
> - }
> + set_user_nice(current, -20);
> + ts->rx_thread = current;
>
> restart:
> conn = iscsi_rx_thread_pre_handler(ts, TARGET);
> Index: lio-core-2.6/drivers/target/lio-target/iscsi_target_core.h
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/lio-target/iscsi_target_core.h 2010-11-06 20:35:44.269003880 +0100
> +++ lio-core-2.6/drivers/target/lio-target/iscsi_target_core.h 2010-11-06 20:37:38.953319148 +0100
> @@ -10,7 +10,6 @@
>
> #include <target/target_core_base.h>
>
> -#define SHUTDOWN_SIGS (sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGABRT))
> #define ISCSI_MISC_IOVECS 5
> #define ISCSI_MAX_DATASN_MISSING_COUNT 16
> #define ISCSI_TX_THREAD_TCP_TIMEOUT 2
> @@ -258,21 +257,6 @@
> #define TARGET_ERL_FORCE_TX_TRANSPORT_RESET 16
> #define TARGET_ERL_FORCE_RX_TRANSPORT_RESET 17
>
> -/*
> - * Threads and timers
> - */
> -#define iscsi_daemon(thread, name, sigs) \
> -do { \
> - daemonize(name); \
> - current->policy = SCHED_NORMAL; \
> - set_user_nice(current, -20); \
> - spin_lock_irq(¤t->sighand->siglock); \
> - siginitsetinv(¤t->blocked, (sigs)); \
> - recalc_sigpending(); \
> - (thread) = current; \
> - spin_unlock_irq(¤t->sighand->siglock); \
> -} while (0);
> -
> #define MOD_TIMER(t, exp) mod_timer(t, (get_jiffies_64() + exp * HZ))
> #define SETUP_TIMER(timer, t, d, func) \
> timer.expires = (get_jiffies_64() + t * HZ); \
> Index: lio-core-2.6/drivers/target/lio-target/iscsi_target_login.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/lio-target/iscsi_target_login.c 2010-11-06 20:36:08.941260061 +0100
> +++ lio-core-2.6/drivers/target/lio-target/iscsi_target_login.c 2010-11-06 20:36:42.358255815 +0100
> @@ -1011,12 +1011,8 @@ int iscsi_target_login_thread(void *arg)
> struct sockaddr_in sock_in;
> struct sockaddr_in6 sock_in6;
>
> - {
> - char name[16];
> - memset(name, 0, 16);
> - sprintf(name, "iscsi_np");
> - iscsi_daemon(np->np_thread, name, SHUTDOWN_SIGS);
> - }
> + set_user_nice(current, -20);
> + np->np_thread = current;
>
> sock = iscsi_target_setup_login_socket(np);
> if (!(sock)) {
> Index: lio-core-2.6/drivers/target/target_core_transport.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/target_core_transport.c 2010-11-06 20:34:36.070254263 +0100
> +++ lio-core-2.6/drivers/target/target_core_transport.c 2010-11-06 20:35:10.989005277 +0100
> @@ -9053,14 +9053,9 @@ static int transport_processing_thread(v
> struct se_device *dev = (struct se_device *) param;
> struct se_queue_req *qr;
>
> - current->policy = SCHED_NORMAL;
> set_user_nice(current, -20);
> - spin_lock_irq(¤t->sighand->siglock);
> - siginitsetinv(¤t->blocked, SHUTDOWN_SIGS);
> - recalc_sigpending();
> - spin_unlock_irq(¤t->sighand->siglock);
>
> - while (!(kthread_should_stop())) {
> + while (!kthread_should_stop()) {
> ret = wait_event_interruptible(dev->dev_queue_obj->thread_wq,
> atomic_read(&dev->dev_queue_obj->queue_cnt) ||
> kthread_should_stop());
> Index: lio-core-2.6/drivers/target/tcm_fc/tfc_cmd.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/tcm_fc/tfc_cmd.c 2010-11-06 20:35:19.325012122 +0100
> +++ lio-core-2.6/drivers/target/tcm_fc/tfc_cmd.c 2010-11-06 20:35:27.377011353 +0100
> @@ -649,10 +649,6 @@ int ft_thread(void *arg)
> int ret;
>
> set_user_nice(current, -20);
> - spin_lock_irq(¤t->sighand->siglock);
> - siginitsetinv(¤t->blocked, SHUTDOWN_SIGS);
> - recalc_sigpending();
> - spin_unlock_irq(¤t->sighand->siglock);
>
> while (!(kthread_should_stop())) {
> ret = wait_event_interruptible(qobj->thread_wq,
> Index: lio-core-2.6/include/target/target_core_base.h
> ===================================================================
> --- lio-core-2.6.orig/include/target/target_core_base.h 2010-11-06 20:37:52.400253495 +0100
> +++ lio-core-2.6/include/target/target_core_base.h 2010-11-06 20:37:55.809255241 +0100
> @@ -10,7 +10,6 @@
> #include "target_core_mib.h"
>
> #define TARGET_CORE_MOD_VERSION "v4.0.0-rc5"
> -#define SHUTDOWN_SIGS (sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGABRT))
>
> /* Used by transport_generic_allocate_iovecs() */
> #define TRANSPORT_IOV_DATA_BUFFER 5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 4/9] target: remove transport_generic_map_buffers_to_tasks
2010-11-08 15:56 ` [PATCH 4/9] target: remove transport_generic_map_buffers_to_tasks Christoph Hellwig
@ 2010-11-08 22:29 ` Nicholas A. Bellinger
0 siblings, 0 replies; 23+ messages in thread
From: Nicholas A. Bellinger @ 2010-11-08 22:29 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linux-scsi
On Mon, 2010-11-08 at 10:56 -0500, Christoph Hellwig wrote:
> plain text document attachment
> (lio-cleanup-transport_generic_map_buffers_to_tasks)
> transport_generic_map_buffers_to_tasks has three difference cases that all
> perform the same loop. Remove the function and inline that small loop into
> the only caller.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Committed as 2e20f790f. Good catch on more unnecessary legacy cruft!!
--nab
>
> Index: lio-core-2.6/drivers/target/target_core_transport.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/target_core_transport.c 2010-11-06 20:44:44.378004019 +0100
> +++ lio-core-2.6/drivers/target/target_core_transport.c 2010-11-06 20:50:48.133255099 +0100
> @@ -7092,75 +7092,6 @@ int transport_generic_map_mem_to_cmd(
> EXPORT_SYMBOL(transport_generic_map_mem_to_cmd);
>
>
> -/* transport_generic_map_buffers_to_tasks():
> - *
> - * Called from transport_generic_new_cmd() in Transport Processing Thread.
> - */
> -static int transport_generic_map_buffers_to_tasks(struct se_cmd *cmd)
> -{
> - struct se_task *task = NULL;
> - int ret;
> -
> - /*
> - * Deal with non [READ,WRITE]_XX CDBs here.
> - */
> - if (cmd->se_cmd_flags & SCF_SCSI_NON_DATA_CDB)
> - goto non_scsi_data;
> - else if (cmd->se_cmd_flags & SCF_SCSI_CONTROL_NONSG_IO_CDB) {
> - list_for_each_entry(task, &T_TASK(cmd)->t_task_list, t_list) {
> - if (atomic_read(&task->task_sent))
> - continue;
> -
> - ret = task->transport_map_task(task, task->task_size);
> - if (ret < 0)
> - return ret;
> -
> - DEBUG_CMD_M("Mapping SCF_SCSI_CONTROL_NONSG_IO_CDB"
> - " task_size: %u\n", task->task_size);
> - }
> - return 0;
> - }
> -
> - /*
> - * Determine the scatterlist offset for each struct se_task,
> - * and segment and set pointers to storage transport buffers
> - * via task->transport_map_task().
> - */
> - list_for_each_entry(task, &T_TASK(cmd)->t_task_list, t_list) {
> - if (atomic_read(&task->task_sent))
> - continue;
> -
> - ret = task->transport_map_task(task, task->task_size);
> - if (ret < 0)
> - return ret;
> -
> - DEBUG_CMD_M("Mapping task[%d]_se_obj_ptr[%p] %s_IO task_lba:"
> - " %llu task_size: %u task_sg_num: %d\n",
> - task->task_no, task->se_obj_ptr,
> - (cmd->se_cmd_flags & SCF_SCSI_CONTROL_SG_IO_CDB) ?
> - "CONTROL" : "DATA", task->task_lba, task->task_size,
> - task->task_sg_num);
> - }
> -
> - return 0;
> -
> -non_scsi_data:
> - list_for_each_entry(task, &T_TASK(cmd)->t_task_list, t_list) {
> - if (atomic_read(&task->task_sent))
> - continue;
> -
> - ret = task->transport_map_task(task, task->task_size);
> - if (ret < 0)
> - return ret;
> -
> - DEBUG_CMD_M("Mapping SCF_SCSI_NON_DATA_CDB task_size: %u"
> - " task->task_sg_num: %d\n", task->task_size,
> - task->task_sg_num);
> - }
> -
> - return 0;
> -}
> -
> static inline long long transport_dev_end_lba(struct se_device *dev)
> {
> return dev->dev_sectors_total + 1;
> @@ -7993,6 +7924,7 @@ int transport_generic_new_cmd(struct se_
> {
> struct se_portal_group *se_tpg;
> struct se_transform_info ti;
> + struct se_task *task;
> int ret = 0;
> /*
> * Generate struct se_task(s) and/or their payloads for this CDB.
> @@ -8055,9 +7987,14 @@ int transport_generic_new_cmd(struct se_
> * buffer list in struct se_cmd to the transport task's native
> * buffers format.
> */
> - ret = transport_generic_map_buffers_to_tasks(cmd);
> - if (ret < 0)
> - goto failure;
> + list_for_each_entry(task, &T_TASK(cmd)->t_task_list, t_list) {
> + if (atomic_read(&task->task_sent))
> + continue;
> +
> + ret = task->transport_map_task(task, task->task_size);
> + if (ret < 0)
> + goto failure;
> + }
>
> /*
> * For WRITEs, let the iSCSI Target RX Thread know its buffer is ready..
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 3/9] target: remove SHUTDOWN_SIGS
2010-11-08 22:21 ` [PATCH 3/9] " Nicholas A. Bellinger
@ 2010-11-08 22:31 ` Christoph Hellwig
0 siblings, 0 replies; 23+ messages in thread
From: Christoph Hellwig @ 2010-11-08 22:31 UTC (permalink / raw)
To: Nicholas A. Bellinger; +Cc: Christoph Hellwig, linux-scsi, Joe Eykholt
On Mon, Nov 08, 2010 at 02:21:09PM -0800, Nicholas A. Bellinger wrote:
> This patch is not quite correct as drivers/target/lio-target/ is
> currently the last code *not* using linux/kthread.h in the tree. I
> recall running into some issue wrt to kernel sockets + signals during
> the original convertion use kthread.h, but I don't recall the specifics
> atm. For now I will drop the lio-target part of this patch, and have a
> look at doing this conversion to kthread.h properly during the
> drivers/target/lio-target review for Boaz in the upcoming week.
Ok, skip that part for now. I meant to delete it from the patch anyway.
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 5/9] target: clean up transport_subsystem_register
2010-11-08 15:56 ` [PATCH 5/9] target: clean up transport_subsystem_register Christoph Hellwig
@ 2010-11-08 22:32 ` Nicholas A. Bellinger
0 siblings, 0 replies; 23+ messages in thread
From: Nicholas A. Bellinger @ 2010-11-08 22:32 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linux-scsi
On Mon, 2010-11-08 at 10:56 -0500, Christoph Hellwig wrote:
> plain text document attachment
> (lio-simplify-transport_subsystem_register)
> Move initialization of the list into transport_subsystem_register, set the
> owner field in the operations vector like for most others, remove the
> external_submod field and replace it by not having an owner pointer.
> Remove unessecary initializations to zero for se_subsystem_api fields.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
>
Commited as f1479e8, thanks Christoph!
--nab
> Index: lio-core-2.6/drivers/target/target_core_file.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/target_core_file.c 2010-11-08 15:37:15.944863013 +0100
> +++ lio-core-2.6/drivers/target/target_core_file.c 2010-11-08 15:49:05.428196347 +0100
> @@ -953,9 +953,9 @@ static sector_t fd_get_blocks(struct se_
>
> static struct se_subsystem_api fileio_template = {
> .name = "fileio",
> + .owner = THIS_MODULE,
> .type = FILEIO,
> .transport_type = TRANSPORT_PLUGIN_VHBA_PDEV,
> - .external_submod = 1,
> .attach_hba = fd_attach_hba,
> .detach_hba = fd_detach_hba,
> .cdb_none = fd_CDB_none,
> @@ -973,7 +973,6 @@ static struct se_subsystem_api fileio_te
> .transport_complete = fd_transport_complete,
> .allocate_request = fd_allocate_request,
> .do_task = fd_do_task,
> - .do_discard = NULL,
> .do_sync_cache = fd_emulate_sync_cache,
> .free_task = fd_free_task,
> .check_configfs_dev_params = fd_check_configfs_dev_params,
> @@ -989,23 +988,14 @@ static struct se_subsystem_api fileio_te
> .get_device_type = fd_get_device_type,
> .get_dma_length = fd_get_dma_length,
> .get_blocks = fd_get_blocks,
> - .write_pending = NULL,
> };
>
> -int __init fileio_module_init(void)
> +static int __init fileio_module_init(void)
> {
> - int ret;
> -
> - INIT_LIST_HEAD(&fileio_template.sub_api_list);
> -
> - ret = transport_subsystem_register(&fileio_template, THIS_MODULE);
> - if (ret < 0)
> - return ret;
> -
> - return 0;
> + return transport_subsystem_register(&fileio_template);
> }
>
> -void fileio_module_exit(void)
> +static void fileio_module_exit(void)
> {
> transport_subsystem_release(&fileio_template);
> }
> Index: lio-core-2.6/drivers/target/target_core_hba.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/target_core_hba.c 2010-11-08 15:41:43.444863012 +0100
> +++ lio-core-2.6/drivers/target/target_core_hba.c 2010-11-08 15:48:43.508196346 +0100
> @@ -100,23 +100,17 @@ int se_core_add_hba(
> return -EINVAL;
>
> hba->transport = t;
> +
> /*
> * Get TCM subsystem api struct module reference to struct se_hba
> */
> - if (t->external_submod) {
> - if (!(t->sub_owner)) {
> - printk(KERN_ERR "Pointer to struct module does not"
> - " exist for %s\n", t->name);
> - hba->transport = NULL;
> - transport_core_put_sub(t);
> - return -EINVAL;
> - }
> + if (t->owner) {
> /*
> * Grab a struct module reference count for subsystem plugin
> */
> - if (!(try_module_get(t->sub_owner))) {
> - printk(KERN_ERR "try_module_get() failed for"
> - " t->sub_owner\n");
> + if (!try_module_get(t->owner)) {
> + printk(KERN_ERR "try_module_get() failed for %s\n",
> + t->owner->name);
> hba->transport = NULL;
> transport_core_put_sub(t);
> return -EINVAL;
> @@ -126,8 +120,8 @@ int se_core_add_hba(
> ret = t->attach_hba(hba, plugin_dep_id);
> if (ret < 0) {
> hba->transport = NULL;
> - if (t->external_submod)
> - module_put(t->sub_owner);
> + if (t->owner)
> + module_put(t->owner);
> transport_core_put_sub(t);
> return ret;
> }
> @@ -157,8 +151,8 @@ static int se_core_shutdown_hba(
> /*
> * Release TCM subsystem api struct module reference from struct se_hba
> */
> - if (t->external_submod)
> - module_put(t->sub_owner);
> + if (t->owner)
> + module_put(t->owner);
>
> return 0;
> }
> Index: lio-core-2.6/drivers/target/target_core_iblock.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/target_core_iblock.c 2010-11-08 15:38:27.891529681 +0100
> +++ lio-core-2.6/drivers/target/target_core_iblock.c 2010-11-08 15:48:47.868196356 +0100
> @@ -921,9 +921,9 @@ static void iblock_bio_done(struct bio *
>
> static struct se_subsystem_api iblock_template = {
> .name = "iblock",
> + .owner = THIS_MODULE,
> .type = IBLOCK,
> .transport_type = TRANSPORT_PLUGIN_VHBA_PDEV,
> - .external_submod = 1,
> .cdb_none = iblock_CDB_none,
> .cdb_read_non_SG = iblock_CDB_read_non_SG,
> .cdb_read_SG = iblock_CDB_read_SG,
> @@ -957,23 +957,14 @@ static struct se_subsystem_api iblock_te
> .get_device_type = iblock_get_device_type,
> .get_dma_length = iblock_get_dma_length,
> .get_blocks = iblock_get_blocks,
> - .write_pending = NULL,
> };
>
> -int __init iblock_module_init(void)
> +static int __init iblock_module_init(void)
> {
> - int ret;
> -
> - INIT_LIST_HEAD(&iblock_template.sub_api_list);
> -
> - ret = transport_subsystem_register(&iblock_template, THIS_MODULE);
> - if (ret < 0)
> - return ret;
> -
> - return 0;
> + return transport_subsystem_register(&iblock_template);
> }
>
> -void iblock_module_exit(void)
> +static void iblock_module_exit(void)
> {
> transport_subsystem_release(&iblock_template);
> }
> Index: lio-core-2.6/drivers/target/target_core_pscsi.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/target_core_pscsi.c 2010-11-08 15:38:27.901529680 +0100
> +++ lio-core-2.6/drivers/target/target_core_pscsi.c 2010-11-08 15:48:49.844863013 +0100
> @@ -1485,9 +1485,9 @@ static void pscsi_req_done(struct reques
>
> static struct se_subsystem_api pscsi_template = {
> .name = "pscsi",
> + .owner = THIS_MODULE,
> .type = PSCSI,
> .transport_type = TRANSPORT_PLUGIN_PHBA_PDEV,
> - .external_submod = 1,
> .cdb_none = pscsi_CDB_none,
> .cdb_read_non_SG = pscsi_CDB_read_non_SG,
> .cdb_read_SG = pscsi_CDB_read_SG,
> @@ -1516,23 +1516,14 @@ static struct se_subsystem_api pscsi_tem
> .get_device_rev = pscsi_get_device_rev,
> .get_device_type = pscsi_get_device_type,
> .get_dma_length = pscsi_get_dma_length,
> - .write_pending = NULL,
> };
>
> -int __init pscsi_module_init(void)
> +static int __init pscsi_module_init(void)
> {
> - int ret;
> -
> - INIT_LIST_HEAD(&pscsi_template.sub_api_list);
> -
> - ret = transport_subsystem_register(&pscsi_template, THIS_MODULE);
> - if (ret < 0)
> - return ret;
> -
> - return 0;
> + return transport_subsystem_register(&pscsi_template);
> }
>
> -void pscsi_module_exit(void)
> +static void pscsi_module_exit(void)
> {
> transport_subsystem_release(&pscsi_template);
> }
> Index: lio-core-2.6/drivers/target/target_core_rd.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/target_core_rd.c 2010-11-08 15:38:27.911529679 +0100
> +++ lio-core-2.6/drivers/target/target_core_rd.c 2010-11-08 15:49:00.321529680 +0100
> @@ -1283,7 +1283,6 @@ static struct se_subsystem_api rd_dr_tem
> .name = "rd_dr",
> .type = RAMDISK_DR,
> .transport_type = TRANSPORT_PLUGIN_VHBA_VDEV,
> - .external_submod = 0,
> .cdb_none = rd_CDB_none,
> .cdb_read_non_SG = rd_CDB_read_non_SG,
> .cdb_read_SG = rd_CDB_read_SG,
> @@ -1314,14 +1313,12 @@ static struct se_subsystem_api rd_dr_tem
> .get_dma_length = rd_get_dma_length,
> .get_blocks = rd_get_blocks,
> .do_se_mem_map = rd_DIRECT_do_se_mem_map,
> - .write_pending = NULL,
> };
>
> static struct se_subsystem_api rd_mcp_template = {
> .name = "rd_mcp",
> .type = RAMDISK_MCP,
> .transport_type = TRANSPORT_PLUGIN_VHBA_VDEV,
> - .external_submod = 0,
> .cdb_none = rd_CDB_none,
> .cdb_read_non_SG = rd_CDB_read_non_SG,
> .cdb_read_SG = rd_CDB_read_SG,
> @@ -1348,21 +1345,17 @@ static struct se_subsystem_api rd_mcp_te
> .get_device_rev = rd_get_device_rev,
> .get_device_type = rd_get_device_type,
> .get_dma_length = rd_get_dma_length,
> - .write_pending = NULL,
> };
>
> int __init rd_module_init(void)
> {
> int ret;
>
> - INIT_LIST_HEAD(&rd_dr_template.sub_api_list);
> - INIT_LIST_HEAD(&rd_mcp_template.sub_api_list);
> -
> - ret = transport_subsystem_register(&rd_dr_template, NULL);
> + ret = transport_subsystem_register(&rd_dr_template);
> if (ret < 0)
> return ret;
>
> - ret = transport_subsystem_register(&rd_mcp_template, NULL);
> + ret = transport_subsystem_register(&rd_mcp_template);
> if (ret < 0) {
> transport_subsystem_release(&rd_dr_template);
> return ret;
> Index: lio-core-2.6/drivers/target/target_core_stgt.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/target_core_stgt.c 2010-11-08 15:38:27.924863014 +0100
> +++ lio-core-2.6/drivers/target/target_core_stgt.c 2010-11-08 15:49:02.761529680 +0100
> @@ -833,9 +833,9 @@ static int stgt_transfer_response(struct
>
> static struct se_subsystem_api stgt_template = {
> .name = "stgt",
> + .owner = THIS_MODULE,
> .type = STGT,
> .transport_type = TRANSPORT_PLUGIN_VHBA_PDEV,
> - .external_submod = 1,
> .cdb_none = stgt_CDB_none,
> .cdb_read_non_SG = stgt_CDB_read_non_SG,
> .cdb_read_SG = stgt_CDB_read_SG,
> @@ -865,23 +865,14 @@ static struct se_subsystem_api stgt_temp
> .get_device_rev = stgt_get_device_rev,
> .get_device_type = stgt_get_device_type,
> .get_dma_length = stgt_get_dma_length,
> - .write_pending = NULL,
> };
>
> -int __init stgt_module_init(void)
> +static int __init stgt_module_init(void)
> {
> - int ret;
> -
> - INIT_LIST_HEAD(&stgt_template.sub_api_list);
> -
> - ret = transport_subsystem_register(&stgt_template, THIS_MODULE);
> - if (ret < 0)
> - return ret;
> -
> - return 0;
> + return transport_subsystem_register(&stgt_template);
> }
>
> -void stgt_module_exit(void)
> +static void stgt_module_exit(void)
> {
> transport_subsystem_release(&stgt_template);
> }
> Index: lio-core-2.6/drivers/target/target_core_transport.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/target_core_transport.c 2010-11-08 15:37:15.928196347 +0100
> +++ lio-core-2.6/drivers/target/target_core_transport.c 2010-11-08 15:44:43.708196346 +0100
> @@ -545,18 +545,11 @@ int transport_subsystem_check_init(void)
> }
>
> int transport_subsystem_register(
> - struct se_subsystem_api *sub_api,
> - struct module *sub_owner)
> + struct se_subsystem_api *sub_api)
> {
> struct se_subsystem_api *s;
> - /*
> - * Save struct module * for TFO [attach,detach]_hba() reference
> - * in se_core_add_hba()
> - */
> - if (sub_api->external_submod && (sub_owner != NULL))
> - sub_api->sub_owner = sub_owner;
> - else
> - sub_api->sub_owner = NULL;
> +
> + INIT_LIST_HEAD(&sub_api->sub_api_list);
>
> mutex_lock(&se_global->g_sub_api_mutex);
> list_for_each_entry(s, &se_global->g_sub_api_list, sub_api_list) {
> @@ -572,7 +565,7 @@ int transport_subsystem_register(
> mutex_unlock(&se_global->g_sub_api_mutex);
>
> printk(KERN_INFO "TCM: Registered subsystem plugin: %s struct module:"
> - " %p\n", sub_api->name, sub_api->sub_owner);
> + " %p\n", sub_api->name, sub_api->owner);
> return 0;
> }
> EXPORT_SYMBOL(transport_subsystem_register);
> Index: lio-core-2.6/include/target/target_core_transport.h
> ===================================================================
> --- lio-core-2.6.orig/include/target/target_core_transport.h 2010-11-08 15:42:48.694863012 +0100
> +++ lio-core-2.6/include/target/target_core_transport.h 2010-11-08 15:49:30.924863014 +0100
> @@ -138,8 +138,7 @@ extern int __iscsi_debug_dev(struct se_d
> extern unsigned char *transport_get_iqn_sn(void);
> extern void transport_init_queue_obj(struct se_queue_obj *);
> extern int transport_subsystem_check_init(void);
> -extern int transport_subsystem_register(struct se_subsystem_api *,
> - struct module *);
> +extern int transport_subsystem_register(struct se_subsystem_api *);
> extern void transport_subsystem_release(struct se_subsystem_api *);
> extern void transport_load_plugins(void);
> extern struct se_subsystem_api *transport_core_get_sub_by_name(const char *);
> @@ -323,13 +322,9 @@ struct se_subsystem_api {
> */
> u8 transport_type;
> /*
> - * For target_core_rd.c internal usage
> - */
> - int external_submod;
> - /*
> * struct module for struct se_hba references
> */
> - struct module *sub_owner;
> + struct module *owner;
> /*
> * Counter for struct se_hba reference
> */
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 6/9] target: remove dead blockdevice claim/release code
2010-11-08 15:56 ` [PATCH 6/9] target: remove dead blockdevice claim/release code Christoph Hellwig
@ 2010-11-08 22:35 ` Nicholas A. Bellinger
0 siblings, 0 replies; 23+ messages in thread
From: Nicholas A. Bellinger @ 2010-11-08 22:35 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linux-scsi
On Mon, 2010-11-08 at 10:56 -0500, Christoph Hellwig wrote:
> plain text document attachment (lio-cleanup-claim)
> This code is entirely unused - even the last reference to
> linux_blockdevice_release was unreachable at this point.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Committed as 6c52636e761. There is still one piece of lio-utils.git
code that depends on this, but I will get this fixed up and pushed into
lio-utils.git/master shortly.
Thanks!
--nab
>
> Index: lio-core-2.6/drivers/target/target_core_device.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/target_core_device.c 2010-11-08 15:52:26.154863014 +0100
> +++ lio-core-2.6/drivers/target/target_core_device.c 2010-11-08 15:57:14.058196347 +0100
> @@ -50,111 +50,6 @@
> #include "target_core_pr.h"
> #include "target_core_ua.h"
>
> -struct block_device *__linux_blockdevice_claim(
> - int major,
> - int minor,
> - void *claim_ptr,
> - int *ret)
> -{
> - dev_t dev;
> - struct block_device *bd;
> -
> - dev = MKDEV(major, minor);
> -
> - bd = bdget(dev);
> - if (!(bd)) {
> - *ret = -1;
> - return NULL;
> - }
> -
> - if (blkdev_get(bd, FMODE_WRITE|FMODE_READ) < 0) {
> - *ret = -1;
> - return NULL;
> - }
> - /*
> - * If no claim pointer was passed from claimee, use struct block_device.
> - */
> - if (!claim_ptr)
> - claim_ptr = (void *)bd;
> -
> - if (bd_claim(bd, claim_ptr) < 0) {
> - blkdev_put(bd, FMODE_WRITE|FMODE_READ);
> - *ret = 0;
> - return bd;
> - }
> -
> - *ret = 1;
> - return bd;
> -}
> -
> -struct block_device *linux_blockdevice_claim(
> - int major,
> - int minor,
> - void *claim_ptr)
> -{
> - dev_t dev;
> - struct block_device *bd;
> -
> - dev = MKDEV(major, minor);
> -
> - bd = bdget(dev);
> - if (!(bd))
> - return NULL;
> -
> - if (blkdev_get(bd, FMODE_WRITE|FMODE_READ) < 0)
> - return NULL;
> - /*
> - * If no claim pointer was passed from claimee, use struct block_device.
> - */
> - if (!claim_ptr)
> - claim_ptr = (void *)bd;
> -
> - if (bd_claim(bd, claim_ptr) < 0) {
> - blkdev_put(bd, FMODE_WRITE|FMODE_READ);
> - return NULL;
> - }
> -
> - return bd;
> -}
> -EXPORT_SYMBOL(linux_blockdevice_claim);
> -
> -int linux_blockdevice_release(int major, int minor, struct block_device *bd_p)
> -{
> - dev_t dev;
> - struct block_device *bd;
> -
> - if (!bd_p) {
> - dev = MKDEV(major, minor);
> -
> - bd = bdget(dev);
> - if (!(bd))
> - return -1;
> - } else
> - bd = bd_p;
> -
> - bd_release(bd);
> - blkdev_put(bd, FMODE_WRITE|FMODE_READ);
> -
> - return 0;
> -}
> -EXPORT_SYMBOL(linux_blockdevice_release);
> -
> -int linux_blockdevice_check(int major, int minor)
> -{
> - struct block_device *bd;
> -
> - bd = linux_blockdevice_claim(major, minor, NULL);
> - if (!(bd))
> - return -1;
> - /*
> - * Blockdevice was able to be claimed, now unclaim it and return success
> - */
> - linux_blockdevice_release(major, minor, NULL);
> -
> - return 0;
> -}
> -EXPORT_SYMBOL(linux_blockdevice_check);
> -
> extern int __transport_get_lun_for_cmd(
> struct se_cmd *se_cmd,
> u32 unpacked_lun)
> Index: lio-core-2.6/drivers/target/target_core_file.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/target_core_file.c 2010-11-08 15:54:21.721529679 +0100
> +++ lio-core-2.6/drivers/target/target_core_file.c 2010-11-08 15:55:27.531529681 +0100
> @@ -234,14 +234,7 @@ static struct se_device *fd_create_virtd
> dev_limits.max_cdb_len = TCM_MAX_COMMAND_SIZE;
> dev_limits.hw_queue_depth = FD_MAX_DEVICE_QUEUE_DEPTH;
> dev_limits.queue_depth = FD_DEVICE_QUEUE_DEPTH;
> - /*
> - * Pass dev_flags for linux_blockdevice_claim_bd or
> - * linux_blockdevice_claim() from the usage above.
> - *
> - * Note that transport_add_device_to_core_hba() will call
> - * linux_blockdevice_release() internally on failure to
> - * call bd_release() on the referenced struct block_device.
> - */
> +
> dev = transport_add_device_to_core_hba(hba, &fileio_template,
> se_dev, dev_flags, (void *)fd_dev,
> &dev_limits, "FILEIO", FD_VERSION);
> Index: lio-core-2.6/drivers/target/target_core_file.h
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/target_core_file.h 2010-11-08 15:52:03.078196347 +0100
> +++ lio-core-2.6/drivers/target/target_core_file.h 2010-11-08 15:56:30.278196346 +0100
> @@ -16,10 +16,6 @@
> #define FD_DATA_NONE 3
>
> extern struct se_global *se_global;
> -extern struct block_device *__linux_blockdevice_claim(int, int, void *, int *);
> -extern struct block_device *linux_blockdevice_claim(int, int, void *);
> -extern int linux_blockdevice_release(int, int, struct block_device *);
> -extern int linux_blockdevice_check(int, int);
>
> #define RRF_EMULATE_CDB 0x01
> #define RRF_GOT_LBA 0x02
> Index: lio-core-2.6/drivers/target/target_core_iblock.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/target_core_iblock.c 2010-11-08 15:54:21.734863014 +0100
> +++ lio-core-2.6/drivers/target/target_core_iblock.c 2010-11-08 16:03:22.868196349 +0100
> @@ -187,15 +187,7 @@ static struct se_device *iblock_create_v
> ib_dev->ibd_major = MAJOR(bd->bd_dev);
> ib_dev->ibd_minor = MINOR(bd->bd_dev);
> ib_dev->ibd_bd = bd;
> - ib_dev->ibd_flags |= IBDF_BDEV_EXCLUSIVE;
> - /*
> - * Pass dev_flags for linux_blockdevice_claim() or
> - * linux_blockdevice_claim() from the usage above.
> - *
> - * Note that transport_add_device_to_core_hba() will call
> - * linux_blockdevice_release() internally on failure to
> - * call bd_release() on the referenced struct block_device.
> - */
> +
> dev = transport_add_device_to_core_hba(hba,
> &iblock_template, se_dev, dev_flags, (void *)ib_dev,
> &dev_limits, "IBLOCK", IBLOCK_VERSION);
> @@ -251,25 +243,8 @@ static void iblock_free_device(void *p)
> {
> struct iblock_dev *ib_dev = p;
>
> - if (ib_dev->ibd_bd) {
> - printk(KERN_INFO "IBLOCK: Releasing Major:Minor - %d:%d\n",
> - ib_dev->ibd_major, ib_dev->ibd_minor);
> -
> - if (ib_dev->ibd_flags & IBDF_BDEV_EXCLUSIVE)
> - close_bdev_exclusive(ib_dev->ibd_bd,
> - FMODE_WRITE|FMODE_READ);
> - else
> - linux_blockdevice_release(ib_dev->ibd_major,
> - ib_dev->ibd_minor, ib_dev->ibd_bd);
> - ib_dev->ibd_bd = NULL;
> - }
> -
> - if (ib_dev->ibd_bio_set) {
> - DEBUG_IBLOCK("Calling bioset_free ib_dev->ibd_bio_set: %p\n",
> - ib_dev->ibd_bio_set);
> - bioset_free(ib_dev->ibd_bio_set);
> - }
> -
> + close_bdev_exclusive(ib_dev->ibd_bd, FMODE_WRITE|FMODE_READ);
> + bioset_free(ib_dev->ibd_bio_set);
> kfree(ib_dev);
> }
>
> Index: lio-core-2.6/drivers/target/target_core_iblock.h
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/target_core_iblock.h 2010-11-08 15:59:59.918196346 +0100
> +++ lio-core-2.6/drivers/target/target_core_iblock.h 2010-11-08 16:00:08.661529684 +0100
> @@ -23,8 +23,7 @@ struct iblock_req {
>
> #define IBDF_HAS_UDEV_PATH 0x01
> #define IBDF_HAS_FORCE 0x02
> -#define IBDF_BDEV_EXCLUSIVE 0x04
> -#define IBDF_BDEV_ISSUE_FLUSH 0x08
> +#define IBDF_BDEV_ISSUE_FLUSH 0x04
>
> struct iblock_dev {
> unsigned char ibd_udev_path[SE_UDEV_PATH_LEN];
> Index: lio-core-2.6/drivers/target/target_core_pscsi.h
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/target_core_pscsi.h 2010-11-08 15:53:09.088196347 +0100
> +++ lio-core-2.6/drivers/target/target_core_pscsi.h 2010-11-08 15:56:11.404863014 +0100
> @@ -20,9 +20,6 @@
> #define PS_TIMEOUT_OTHER (500*HZ)
>
> extern struct se_global *se_global;
> -extern struct block_device *linux_blockdevice_claim(int, int, void *);
> -extern int linux_blockdevice_release(int, int, struct block_device *);
> -extern int linux_blockdevice_check(int, int);
>
> #include <linux/device.h>
> #include <scsi/scsi_driver.h>
> Index: lio-core-2.6/drivers/target/target_core_stgt.h
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/target_core_stgt.h 2010-11-08 15:53:17.704863012 +0100
> +++ lio-core-2.6/drivers/target/target_core_stgt.h 2010-11-08 15:56:13.564863014 +0100
> @@ -12,9 +12,6 @@
> #define PS_TIMEOUT_OTHER (500*HZ)
>
> extern struct se_global *se_global;
> -extern struct block_device *linux_blockdevice_claim(int, int, void *);
> -extern int linux_blockdevice_release(int, int, struct block_device *);
> -extern int linux_blockdevice_check(int, int);
>
> #include <linux/device.h>
> #include <scsi/scsi_driver.h>
> Index: lio-core-2.6/include/target/target_core_device.h
> ===================================================================
> --- lio-core-2.6.orig/include/target/target_core_device.h 2010-11-08 15:52:18.101529681 +0100
> +++ lio-core-2.6/include/target/target_core_device.h 2010-11-08 15:56:17.911529680 +0100
> @@ -3,10 +3,6 @@
>
> extern struct se_global *se_global;
>
> -extern struct block_device *__linux_blockdevice_claim(int, int, void *, int *);
> -extern struct block_device *linux_blockdevice_claim(int, int, void *);
> -extern int linux_blockdevice_release(int, int, struct block_device *);
> -extern int linux_blockdevice_check(int, int);
> extern int transport_get_lun_for_cmd(struct se_cmd *, unsigned char *, u32);
> extern int transport_get_lun_for_tmr(struct se_cmd *, u32);
> extern struct se_dev_entry *core_get_se_deve_from_rtpi(
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 7/9] target: remove transport_generic_free_device
2010-11-08 15:56 ` [PATCH 7/9] target: remove transport_generic_free_device Christoph Hellwig
@ 2010-11-08 22:40 ` Nicholas A. Bellinger
0 siblings, 0 replies; 23+ messages in thread
From: Nicholas A. Bellinger @ 2010-11-08 22:40 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linux-scsi
On Mon, 2010-11-08 at 10:56 -0500, Christoph Hellwig wrote:
> plain text document attachment
> (lio-kill-transport_generic_free_device)
> It's simple enough to inline into the only caller.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Committed as c9975cf6a7f.
--nab
>
> Index: lio-core-2.6/drivers/target/target_core_device.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/target_core_device.c 2010-11-08 16:07:13.631529681 +0100
> +++ lio-core-2.6/drivers/target/target_core_device.c 2010-11-08 16:08:56.528196347 +0100
> @@ -34,6 +34,7 @@
> #include <linux/slab.h>
> #include <linux/spinlock.h>
> #include <linux/smp_lock.h>
> +#include <linux/kthread.h>
> #include <linux/in.h>
> #include <net/sock.h>
> #include <net/tcp.h>
> @@ -733,7 +734,11 @@ void se_release_device_for_hba(struct se
> (dev->dev_status & TRANSPORT_DEVICE_OFFLINE_DEACTIVATED))
> se_dev_stop(dev);
>
> - transport_generic_free_device(dev);
> + if (dev->dev_ptr) {
> + kthread_stop(dev->process_thread);
> + if (dev->transport->free_device)
> + dev->transport->free_device(dev->dev_ptr);
> + }
>
> spin_lock(&hba->device_lock);
> list_del(&dev->dev_list);
> Index: lio-core-2.6/drivers/target/target_core_transport.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/target_core_transport.c 2010-11-08 16:07:13.618196346 +0100
> +++ lio-core-2.6/drivers/target/target_core_transport.c 2010-11-08 16:08:26.438196370 +0100
> @@ -2367,22 +2367,6 @@ out:
> }
> EXPORT_SYMBOL(transport_add_device_to_core_hba);
>
> -/* transport_generic_free_device():
> - *
> - *
> - */
> -void transport_generic_free_device(struct se_device *dev)
> -{
> - if (!(dev->dev_ptr))
> - return;
> -
> - kthread_stop(dev->process_thread);
> -
> - if (TRANSPORT(dev)->free_device)
> - TRANSPORT(dev)->free_device(dev->dev_ptr);
> -}
> -EXPORT_SYMBOL(transport_generic_free_device);
> -
> static inline int transport_allocate_iovecs_for_cmd(
> struct se_cmd *cmd,
> u32 iov_count)
> Index: lio-core-2.6/include/target/target_core_transport.h
> ===================================================================
> --- lio-core-2.6.orig/include/target/target_core_transport.h 2010-11-08 16:08:08.554863013 +0100
> +++ lio-core-2.6/include/target/target_core_transport.h 2010-11-08 16:08:10.134863013 +0100
> @@ -190,7 +190,6 @@ extern struct se_device *transport_add_d
> struct se_subsystem_dev *, u32,
> void *, struct se_dev_limits *,
> const char *, const char *);
> -extern void transport_generic_free_device(struct se_device *);
> extern int transport_generic_allocate_iovecs(struct se_cmd *);
> extern void transport_device_setup_cmd(struct se_cmd *);
> extern int transport_check_alloc_task_attr(struct se_cmd *);
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 8/9] target: remove unused split_cdb_RW_* handlers
2010-11-08 15:56 ` [PATCH 8/9] target: remove unused split_cdb_RW_* handlers Christoph Hellwig
@ 2010-11-08 22:41 ` Nicholas A. Bellinger
0 siblings, 0 replies; 23+ messages in thread
From: Nicholas A. Bellinger @ 2010-11-08 22:41 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linux-scsi
On Mon, 2010-11-08 at 10:56 -0500, Christoph Hellwig wrote:
> plain text document attachment (lio-cleanup-cdb-split)
> Signed-off-by: Christoph Hellwig <hch@lst.de>
>
Commited as 4344aa17b7. Thanks!
--nab
> Index: lio-core-2.6/drivers/target/target_core_scdb.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/target_core_scdb.c 2010-11-08 16:18:26.328196347 +0100
> +++ lio-core-2.6/drivers/target/target_core_scdb.c 2010-11-08 16:18:42.911529680 +0100
> @@ -51,16 +51,6 @@ void split_cdb_XX_6(
> cdb[4] = *sectors & 0xff;
> }
>
> -void split_cdb_RW_6(
> - unsigned long long lba,
> - u32 *sectors,
> - unsigned char *cdb,
> - int rw)
> -{
> - cdb[0] = (rw) ? WRITE_6 : READ_6;
> - split_cdb_XX_6(lba, sectors, &cdb[0]);
> -}
> -
> /* split_cdb_XX_10():
> *
> * 32-bit LBA w/ 16-bit SECTORS
> @@ -74,16 +64,6 @@ void split_cdb_XX_10(
> put_unaligned_be16(*sectors, &cdb[7]);
> }
>
> -void split_cdb_RW_10(
> - unsigned long long lba,
> - u32 *sectors,
> - unsigned char *cdb,
> - int rw)
> -{
> - cdb[0] = (rw) ? WRITE_10 : READ_10;
> - split_cdb_XX_10(lba, sectors, &cdb[0]);
> -}
> -
> /* split_cdb_XX_12():
> *
> * 32-bit LBA w/ 32-bit SECTORS
> @@ -97,16 +77,6 @@ void split_cdb_XX_12(
> put_unaligned_be32(*sectors, &cdb[6]);
> }
>
> -void split_cdb_RW_12(
> - unsigned long long lba,
> - u32 *sectors,
> - unsigned char *cdb,
> - int rw)
> -{
> - cdb[0] = (rw) ? WRITE_12 : READ_12;
> - split_cdb_XX_12(lba, sectors, &cdb[0]);
> -}
> -
> /* split_cdb_XX_16():
> *
> * 64-bit LBA w/ 32-bit SECTORS
> @@ -120,16 +90,6 @@ void split_cdb_XX_16(
> put_unaligned_be32(*sectors, &cdb[10]);
> }
>
> -void split_cdb_RW_16(
> - unsigned long long lba,
> - u32 *sectors,
> - unsigned char *cdb,
> - int rw)
> -{
> - cdb[0] = (rw) ? WRITE_16 : READ_16;
> - split_cdb_XX_16(lba, sectors, &cdb[0]);
> -}
> -
> /*
> * split_cdb_XX_32():
> *
> @@ -143,16 +103,3 @@ void split_cdb_XX_32(
> put_unaligned_be64(lba, &cdb[12]);
> put_unaligned_be32(*sectors, &cdb[28]);
> }
> -
> -void split_cdb_RW_32(
> - unsigned long long lba,
> - u32 *sectors,
> - unsigned char *cdb,
> - int rw)
> -{
> - /*
> - * Set service action for VARIABLE_LENGTH_CMD
> - */
> - cdb[9] = (rw) ? WRITE_32 : READ_32;
> - split_cdb_XX_32(lba, sectors, &cdb[0]);
> -}
> Index: lio-core-2.6/drivers/target/target_core_scdb.h
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/target_core_scdb.h 2010-11-08 16:18:52.318196349 +0100
> +++ lio-core-2.6/drivers/target/target_core_scdb.h 2010-11-08 16:18:57.131529680 +0100
> @@ -2,14 +2,9 @@
> #define TARGET_CORE_SCDB_H
>
> extern void split_cdb_XX_6(unsigned long long, u32 *, unsigned char *);
> -extern void split_cdb_RW_6(unsigned long long, u32 *, unsigned char *, int);
> extern void split_cdb_XX_10(unsigned long long, u32 *, unsigned char *);
> -extern void split_cdb_RW_10(unsigned long long, u32 *, unsigned char *, int);
> extern void split_cdb_XX_12(unsigned long long, u32 *, unsigned char *);
> -extern void split_cdb_RW_12(unsigned long long, u32 *, unsigned char *, int);
> extern void split_cdb_XX_16(unsigned long long, u32 *, unsigned char *);
> -extern void split_cdb_RW_16(unsigned long long, u32 *, unsigned char *, int);
> extern void split_cdb_XX_32(unsigned long long, u32 *, unsigned char *);
> -extern void split_cdb_RW_32(unsigned long long, u32 *, unsigned char *, int);
>
> #endif /* TARGET_CORE_SCDB_H */
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 9/9] target: remove dead call to transport_emulate_control_cdb in rd driver
2010-11-08 15:56 ` [PATCH 9/9] target: remove dead call to transport_emulate_control_cdb in rd driver Christoph Hellwig
@ 2010-11-08 22:44 ` Nicholas A. Bellinger
0 siblings, 0 replies; 23+ messages in thread
From: Nicholas A. Bellinger @ 2010-11-08 22:44 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linux-scsi
On Mon, 2010-11-08 at 10:56 -0500, Christoph Hellwig wrote:
> plain text document attachment (lio-mark-target_core_transport-static)
> We'll never reach a non-pscsi backend for non-data CDBs these days.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
>
Woops, missed during the CDB emulation 'push-up'. Committed as
15ecfc43eb3.
Thanks!
--nab
> Index: lio-core-2.6/drivers/target/target_core_rd.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/target_core_rd.c 2010-11-08 16:31:38.968196346 +0100
> +++ lio-core-2.6/drivers/target/target_core_rd.c 2010-11-08 16:31:42.041529681 +0100
> @@ -972,9 +972,6 @@ static int rd_DIRECT_allocate_DMA(struct
> */
> static int rd_DIRECT_do_task(struct se_task *task)
> {
> - if (!(TASK_CMD(task)->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB))
> - return transport_emulate_control_cdb(task);
> -
> /*
> * At this point the locally allocated RD tables have been mapped
> * to struct se_mem elements in rd_DIRECT_do_se_mem_map().
> Index: lio-core-2.6/drivers/target/target_core_transport.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/target_core_transport.c 2010-11-08 16:31:58.868196346 +0100
> +++ lio-core-2.6/drivers/target/target_core_transport.c 2010-11-08 16:32:42.158196349 +0100
> @@ -209,6 +209,7 @@ static int transport_generic_write_pendi
> static int transport_processing_thread(void *);
> static int transport_new_cmd_obj(struct se_cmd *cmd,
> struct se_transform_info *ti, int post_execute);
> +static int transport_emulate_control_cdb(struct se_task *task);
>
> static char *transport_passthrough_get_fabric_name(void)
> {
> @@ -5462,7 +5463,7 @@ static int transport_generic_write_same(
> * Used by TCM subsystem plugins IBLOCK, FILEIO, and RAMDISK as a
> * generic non SCF_SCSI_DATA_SG_IO_CDB ops.
> */
> -int transport_emulate_control_cdb(struct se_task *task)
> +static int transport_emulate_control_cdb(struct se_task *task)
> {
> struct se_cmd *cmd = TASK_CMD(task);
> struct se_device *dev = SE_DEV(cmd);
> Index: lio-core-2.6/include/target/target_core_transport.h
> ===================================================================
> --- lio-core-2.6.orig/include/target/target_core_transport.h 2010-11-08 16:31:49.168196346 +0100
> +++ lio-core-2.6/include/target/target_core_transport.h 2010-11-08 16:31:51.141529681 +0100
> @@ -232,7 +232,6 @@ extern int transport_generic_emulate_mod
> extern int transport_generic_emulate_request_sense(struct se_cmd *,
> unsigned char *);
> extern int transport_get_sense_data(struct se_cmd *);
> -extern int transport_emulate_control_cdb(struct se_task *);
> extern struct se_cmd *transport_allocate_passthrough(unsigned char *, int, u32,
> void *, u32, u32, void *);
> extern void transport_passthrough_release(struct se_cmd *);
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 10/9] target: split CDB emulation out of target_core_transport.c
2010-11-08 17:19 ` [PATCH 10/9] target: split CDB emulation out of target_core_transport.c Christoph Hellwig
@ 2010-11-08 22:48 ` Nicholas A. Bellinger
2010-11-08 22:57 ` Christoph Hellwig
0 siblings, 1 reply; 23+ messages in thread
From: Nicholas A. Bellinger @ 2010-11-08 22:48 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linux-scsi
On Mon, 2010-11-08 at 12:19 -0500, Christoph Hellwig wrote:
> Split out the CDB emulation into it's own file, and refactor it along proper
> boundaries.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
>
I think this makes alot sense for the vast majority of the CDB emulation
code, but I think specifically for the handful of PR and ALUA CDB
emulation pieces it does make more sense conceptually (and for the sake
of comments) to keep this code in their respective source files.
Other than those two cases, I am happy to merge this code.
Thanks alot for this one hch!
--nab
> Index: lio-core-2.6/drivers/target/target_core_cdb.c
> ===================================================================
> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> +++ lio-core-2.6/drivers/target/target_core_cdb.c 2010-11-08 18:14:35.028196347 +0100
> @@ -0,0 +1,1128 @@
> +/*
> + * CDB emulation for non-READ/WRITE commands.
> + *
> + * Copyright (c) 2002, 2003, 2004, 2005 PyX Technologies, Inc.
> + * Copyright (c) 2005, 2006, 2007 SBE, Inc.
> + * Copyright (c) 2007-2010 Rising Tide Systems
> + * Copyright (c) 2008-2010 Linux-iSCSI.org
> + *
> + * Nicholas A. Bellinger <nab@kernel.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
> + */
> +
> +#include <asm/unaligned.h>
> +#include <scsi/scsi.h>
> +
> +#include <target/target_core_base.h>
> +#include <target/target_core_transport.h>
> +#include <target/target_core_fabric_ops.h>
> +#include "target_core_ua.h"
> +
> +static void
> +target_fill_alua_data(struct se_port *port, unsigned char *buf)
> +{
> + struct t10_alua_tg_pt_gp *tg_pt_gp;
> + struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem;
> +
> + /*
> + * Set SCCS for MAINTENANCE_IN + REPORT_TARGET_PORT_GROUPS.
> + */
> + buf[5] = 0x80;
> +
> + /*
> + * Set TPGS field for explict and/or implict ALUA access type
> + * and opteration.
> + *
> + * See spc4r17 section 6.4.2 Table 135
> + */
> + if (!port)
> + return;
> + tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem;
> + if (!tg_pt_gp_mem)
> + return;
> +
> + spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
> + tg_pt_gp = tg_pt_gp_mem->tg_pt_gp;
> + if (tg_pt_gp)
> + buf[5] |= tg_pt_gp->tg_pt_gp_alua_access_type;
> + spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
> +}
> +
> +static int
> +target_emulate_inquiry_std(struct se_cmd *cmd)
> +{
> + struct se_lun *lun = SE_LUN(cmd);
> + struct se_device *dev = SE_DEV(cmd);
> + unsigned char *buf = cmd->t_task->t_task_buf;
> +
> + /*
> + * Make sure we at least have 6 bytes of INQUIRY response
> + * payload going back for EVPD=0
> + */
> + if (cmd->data_length < 6) {
> + printk(KERN_ERR "SCSI Inquiry payload length: %u"
> + " too small for EVPD=0\n", cmd->data_length);
> + return -1;
> + }
> +
> + buf[0] = dev->transport->get_device_type(dev);
> + if (buf[0] == TYPE_TAPE)
> + buf[1] = 0x80;
> + buf[2] = dev->transport->get_device_rev(dev);
> +
> + /*
> + * Enable SCCS and TPGS fields for Emulated ALUA
> + */
> + if (T10_ALUA(dev->se_sub_dev)->alua_type == SPC3_ALUA_EMULATED)
> + target_fill_alua_data(lun->lun_sep, buf);
> +
> + if (cmd->data_length < 8) {
> + buf[4] = 1; /* Set additional length to 1 */
> + return 0;
> + }
> +
> + buf[7] = 0x32; /* Sync=1 and CmdQue=1 */
> +
> + /*
> + * Do not include vendor, product, reversion info in INQUIRY
> + * response payload for cdbs with a small allocation length.
> + */
> + if (cmd->data_length < 36) {
> + buf[4] = 3; /* Set additional length to 3 */
> + return 0;
> + }
> +
> + snprintf((unsigned char *)&buf[8], 8, "LIO-ORG");
> + snprintf((unsigned char *)&buf[16], 16, "%s",
> + &DEV_T10_WWN(dev)->model[0]);
> + snprintf((unsigned char *)&buf[32], 4, "%s",
> + &DEV_T10_WWN(dev)->revision[0]);
> + buf[4] = 31; /* Set additional length to 31 */
> + return 0;
> +}
> +
> +/* supported vital product data pages */
> +static int
> +target_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf)
> +{
> + buf[1] = 0x00;
> + if (cmd->data_length < 8)
> + return 0;
> +
> + buf[4] = 0x0;
> + /*
> + * Only report the INQUIRY EVPD=1 pages after a valid NAA
> + * Registered Extended LUN WWN has been set via ConfigFS
> + * during device creation/restart.
> + */
> + if (SE_DEV(cmd)->se_sub_dev->su_dev_flags &
> + SDF_EMULATED_VPD_UNIT_SERIAL) {
> + buf[3] = 3;
> + buf[5] = 0x80;
> + buf[6] = 0x83;
> + buf[7] = 0x86;
> + }
> +
> + return 0;
> +}
> +
> +/* unit serial number */
> +static int
> +target_emulate_evpd_80(struct se_cmd *cmd, unsigned char *buf)
> +{
> + struct se_device *dev = SE_DEV(cmd);
> + u16 len;
> +
> + buf[1] = 0x80;
> + if (dev->se_sub_dev->su_dev_flags &
> + SDF_EMULATED_VPD_UNIT_SERIAL) {
> + u32 unit_serial_len;
> +
> + unit_serial_len =
> + strlen(&DEV_T10_WWN(dev)->unit_serial[0]);
> + unit_serial_len++; /* For NULL Terminator */
> +
> + if (((len + 4) + unit_serial_len) > cmd->data_length) {
> + len += unit_serial_len;
> + buf[2] = ((len >> 8) & 0xff);
> + buf[3] = (len & 0xff);
> + return 0;
> + }
> + len += sprintf((unsigned char *)&buf[4], "%s",
> + &DEV_T10_WWN(dev)->unit_serial[0]);
> + len++; /* Extra Byte for NULL Terminator */
> + buf[3] = len;
> + }
> + return 0;
> +}
> +
> +/*
> + * Device identification VPD, for a complete list of
> + * DESIGNATOR TYPEs see spc4r17 Table 459.
> + */
> +static int
> +target_emulate_evpd_83(struct se_cmd *cmd, unsigned char *buf)
> +{
> + struct se_device *dev = SE_DEV(cmd);
> + struct se_lun *lun = SE_LUN(cmd);
> + struct se_port *port = NULL;
> + struct se_portal_group *tpg = NULL;
> + struct t10_alua_lu_gp_member *lu_gp_mem;
> + struct t10_alua_tg_pt_gp *tg_pt_gp;
> + struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem;
> + unsigned char binary, binary_new;
> + unsigned char *prod = &DEV_T10_WWN(dev)->model[0];
> + u32 prod_len;
> + u32 unit_serial_len, off = 0;
> + int i;
> + u16 len = 0, id_len;
> +
> + buf[1] = 0x83;
> + off = 4;
> +
> + /*
> + * NAA IEEE Registered Extended Assigned designator format, see
> + * spc4r17 section 7.7.3.6.5
> + *
> + * We depend upon a target_core_mod/ConfigFS provided
> + * /sys/kernel/config/target/core/$HBA/$DEV/wwn/vpd_unit_serial
> + * value in order to return the NAA id.
> + */
> + if (!(dev->se_sub_dev->su_dev_flags & SDF_EMULATED_VPD_UNIT_SERIAL))
> + goto check_t10_vend_desc;
> +
> + if (off + 20 > cmd->data_length)
> + goto check_t10_vend_desc;
> +
> + /* CODE SET == Binary */
> + buf[off++] = 0x1;
> +
> + /* Set ASSOICATION == addressed logical unit: 0)b */
> + buf[off] = 0x00;
> +
> + /* Identifier/Designator type == NAA identifier */
> + buf[off++] = 0x3;
> + off++;
> +
> + /* Identifier/Designator length */
> + buf[off++] = 0x10;
> +
> + /*
> + * Start NAA IEEE Registered Extended Identifier/Designator
> + */
> + buf[off++] = (0x6 << 4);
> +
> + /*
> + * Use OpenFabrics IEEE Company ID: 00 14 05
> + */
> + buf[off++] = 0x01;
> + buf[off++] = 0x40;
> + buf[off] = (0x5 << 4);
> +
> + /*
> + * Return ConfigFS Unit Serial Number information for
> + * VENDOR_SPECIFIC_IDENTIFIER and
> + * VENDOR_SPECIFIC_IDENTIFIER_EXTENTION
> + */
> + binary = transport_asciihex_to_binaryhex(
> + &DEV_T10_WWN(dev)->unit_serial[0]);
> + buf[off++] |= (binary & 0xf0) >> 4;
> + for (i = 0; i < 24; i += 2) {
> + binary_new = transport_asciihex_to_binaryhex(
> + &DEV_T10_WWN(dev)->unit_serial[i+2]);
> + buf[off] = (binary & 0x0f) << 4;
> + buf[off++] |= (binary_new & 0xf0) >> 4;
> + binary = binary_new;
> + }
> + len = 20;
> + off = (len + 4);
> +
> +check_t10_vend_desc:
> + /*
> + * T10 Vendor Identifier Page, see spc4r17 section 7.7.3.4
> + */
> + id_len = 8; /* For Vendor field */
> + prod_len = 4; /* For VPD Header */
> + prod_len += 8; /* For Vendor field */
> + prod_len += strlen(prod);
> + prod_len++; /* For : */
> +
> + if (dev->se_sub_dev->su_dev_flags &
> + SDF_EMULATED_VPD_UNIT_SERIAL) {
> + unit_serial_len =
> + strlen(&DEV_T10_WWN(dev)->unit_serial[0]);
> + unit_serial_len++; /* For NULL Terminator */
> +
> + if ((len + (id_len + 4) +
> + (prod_len + unit_serial_len)) >
> + cmd->data_length) {
> + len += (prod_len + unit_serial_len);
> + goto check_port;
> + }
> + id_len += sprintf((unsigned char *)&buf[off+12],
> + "%s:%s", prod,
> + &DEV_T10_WWN(dev)->unit_serial[0]);
> + }
> + buf[off] = 0x2; /* ASCII */
> + buf[off+1] = 0x1; /* T10 Vendor ID */
> + buf[off+2] = 0x0;
> + memcpy((unsigned char *)&buf[off+4], "LIO-ORG", 8);
> + /* Extra Byte for NULL Terminator */
> + id_len++;
> + /* Identifier Length */
> + buf[off+3] = id_len;
> + /* Header size for Designation descriptor */
> + len += (id_len + 4);
> + off += (id_len + 4);
> + /*
> + * struct se_port is only set for INQUIRY VPD=1 through $FABRIC_MOD
> + */
> +check_port:
> + port = lun->lun_sep;
> + if (port) {
> + struct t10_alua_lu_gp *lu_gp;
> + u32 padding, scsi_name_len;
> + u16 lu_gp_id = 0;
> + u16 tg_pt_gp_id = 0;
> + u16 tpgt;
> +
> + tpg = port->sep_tpg;
> + /*
> + * Relative target port identifer, see spc4r17
> + * section 7.7.3.7
> + *
> + * Get the PROTOCOL IDENTIFIER as defined by spc4r17
> + * section 7.5.1 Table 362
> + */
> + if (((len + 4) + 8) > cmd->data_length) {
> + len += 8;
> + goto check_tpgi;
> + }
> + buf[off] =
> + (TPG_TFO(tpg)->get_fabric_proto_ident(tpg) << 4);
> + buf[off++] |= 0x1; /* CODE SET == Binary */
> + buf[off] = 0x80; /* Set PIV=1 */
> + /* Set ASSOICATION == target port: 01b */
> + buf[off] |= 0x10;
> + /* DESIGNATOR TYPE == Relative target port identifer */
> + buf[off++] |= 0x4;
> + off++; /* Skip over Reserved */
> + buf[off++] = 4; /* DESIGNATOR LENGTH */
> + /* Skip over Obsolete field in RTPI payload
> + * in Table 472 */
> + off += 2;
> + buf[off++] = ((port->sep_rtpi >> 8) & 0xff);
> + buf[off++] = (port->sep_rtpi & 0xff);
> + len += 8; /* Header size + Designation descriptor */
> + /*
> + * Target port group identifier, see spc4r17
> + * section 7.7.3.8
> + *
> + * Get the PROTOCOL IDENTIFIER as defined by spc4r17
> + * section 7.5.1 Table 362
> + */
> +check_tpgi:
> + if (T10_ALUA(dev->se_sub_dev)->alua_type !=
> + SPC3_ALUA_EMULATED)
> + goto check_scsi_name;
> +
> + if (((len + 4) + 8) > cmd->data_length) {
> + len += 8;
> + goto check_lu_gp;
> + }
> + tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem;
> + if (!tg_pt_gp_mem)
> + goto check_lu_gp;
> +
> + spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
> + tg_pt_gp = tg_pt_gp_mem->tg_pt_gp;
> + if (!(tg_pt_gp)) {
> + spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
> + goto check_lu_gp;
> + }
> + tg_pt_gp_id = tg_pt_gp->tg_pt_gp_id;
> + spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
> +
> + buf[off] =
> + (TPG_TFO(tpg)->get_fabric_proto_ident(tpg) << 4);
> + buf[off++] |= 0x1; /* CODE SET == Binary */
> + buf[off] = 0x80; /* Set PIV=1 */
> + /* Set ASSOICATION == target port: 01b */
> + buf[off] |= 0x10;
> + /* DESIGNATOR TYPE == Target port group identifier */
> + buf[off++] |= 0x5;
> + off++; /* Skip over Reserved */
> + buf[off++] = 4; /* DESIGNATOR LENGTH */
> + off += 2; /* Skip over Reserved Field */
> + buf[off++] = ((tg_pt_gp_id >> 8) & 0xff);
> + buf[off++] = (tg_pt_gp_id & 0xff);
> + len += 8; /* Header size + Designation descriptor */
> + /*
> + * Logical Unit Group identifier, see spc4r17
> + * section 7.7.3.8
> + */
> +check_lu_gp:
> + if (((len + 4) + 8) > cmd->data_length) {
> + len += 8;
> + goto check_scsi_name;
> + }
> + lu_gp_mem = dev->dev_alua_lu_gp_mem;
> + if (!(lu_gp_mem))
> + goto check_scsi_name;
> +
> + spin_lock(&lu_gp_mem->lu_gp_mem_lock);
> + lu_gp = lu_gp_mem->lu_gp;
> + if (!(lu_gp)) {
> + spin_unlock(&lu_gp_mem->lu_gp_mem_lock);
> + goto check_scsi_name;
> + }
> + lu_gp_id = lu_gp->lu_gp_id;
> + spin_unlock(&lu_gp_mem->lu_gp_mem_lock);
> +
> + buf[off++] |= 0x1; /* CODE SET == Binary */
> + /* DESIGNATOR TYPE == Logical Unit Group identifier */
> + buf[off++] |= 0x6;
> + off++; /* Skip over Reserved */
> + buf[off++] = 4; /* DESIGNATOR LENGTH */
> + off += 2; /* Skip over Reserved Field */
> + buf[off++] = ((lu_gp_id >> 8) & 0xff);
> + buf[off++] = (lu_gp_id & 0xff);
> + len += 8; /* Header size + Designation descriptor */
> + /*
> + * SCSI name string designator, see spc4r17
> + * section 7.7.3.11
> + *
> + * Get the PROTOCOL IDENTIFIER as defined by spc4r17
> + * section 7.5.1 Table 362
> + */
> +check_scsi_name:
> + scsi_name_len = strlen(TPG_TFO(tpg)->tpg_get_wwn(tpg));
> + /* UTF-8 ",t,0x<16-bit TPGT>" + NULL Terminator */
> + scsi_name_len += 10;
> + /* Check for 4-byte padding */
> + padding = ((-scsi_name_len) & 3);
> + if (padding != 0)
> + scsi_name_len += padding;
> + /* Header size + Designation descriptor */
> + scsi_name_len += 4;
> +
> + if (((len + 4) + scsi_name_len) > cmd->data_length) {
> + len += scsi_name_len;
> + goto set_len;
> + }
> + buf[off] =
> + (TPG_TFO(tpg)->get_fabric_proto_ident(tpg) << 4);
> + buf[off++] |= 0x3; /* CODE SET == UTF-8 */
> + buf[off] = 0x80; /* Set PIV=1 */
> + /* Set ASSOICATION == target port: 01b */
> + buf[off] |= 0x10;
> + /* DESIGNATOR TYPE == SCSI name string */
> + buf[off++] |= 0x8;
> + off += 2; /* Skip over Reserved and length */
> + /*
> + * SCSI name string identifer containing, $FABRIC_MOD
> + * dependent information. For LIO-Target and iSCSI
> + * Target Port, this means "<iSCSI name>,t,0x<TPGT> in
> + * UTF-8 encoding.
> + */
> + tpgt = TPG_TFO(tpg)->tpg_get_tag(tpg);
> + scsi_name_len = sprintf(&buf[off], "%s,t,0x%04x",
> + TPG_TFO(tpg)->tpg_get_wwn(tpg), tpgt);
> + scsi_name_len += 1 /* Include NULL terminator */;
> + /*
> + * The null-terminated, null-padded (see 4.4.2) SCSI
> + * NAME STRING field contains a UTF-8 format string.
> + * The number of bytes in the SCSI NAME STRING field
> + * (i.e., the value in the DESIGNATOR LENGTH field)
> + * shall be no larger than 256 and shall be a multiple
> + * of four.
> + */
> + if (padding)
> + scsi_name_len += padding;
> +
> + buf[off-1] = scsi_name_len;
> + off += scsi_name_len;
> + /* Header size + Designation descriptor */
> + len += (scsi_name_len + 4);
> + }
> +set_len:
> + buf[2] = ((len >> 8) & 0xff);
> + buf[3] = (len & 0xff); /* Page Length for VPD 0x83 */
> + return 0;
> +}
> +
> +/* Extended INQUIRY Data VPD Page */
> +static int
> +target_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf)
> +{
> + if (cmd->data_length < 60)
> + return 0;
> +
> + buf[1] = 0x86;
> + buf[2] = 0x3c;
> + /* Set HEADSUP, ORDSUP, SIMPSUP */
> + buf[5] = 0x07;
> +
> + /* If WriteCache emulation is enabled, set V_SUP */
> + if (DEV_ATTRIB(SE_DEV(cmd))->emulate_write_cache > 0)
> + buf[6] = 0x01;
> + return 0;
> +}
> +
> +/* Block Limits VPD page */
> +static int
> +target_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf)
> +{
> + struct se_device *dev = SE_DEV(cmd);
> + int have_tp = 0;
> +
> + /*
> + * Following sbc3r22 section 6.5.3 Block Limits VPD page, when
> + * emulate_tpu=1 or emulate_tpws=1 we will be expect a
> + * different page length for Thin Provisioning.
> + */
> + if (DEV_ATTRIB(dev)->emulate_tpu || DEV_ATTRIB(dev)->emulate_tpws)
> + have_tp = 1;
> +
> + if (have_tp) {
> + if (cmd->data_length < (0x3c + 4)) {
> + printk(KERN_INFO "Received data_length: %u"
> + " too small for TPE=1 EVPD 0xb0\n",
> + cmd->data_length);
> + return -1;
> + }
> + } else {
> + if (cmd->data_length < (0x10 + 4)) {
> + printk(KERN_INFO "Received data_length: %u"
> + " too small for TPE=1 EVPD 0xb0\n",
> + cmd->data_length);
> + return -1;
> + }
> + }
> +
> + buf[0] = dev->transport->get_device_type(dev);
> + buf[1] = 0xb0;
> + buf[3] = have_tp ? 0x3c : 0x10;
> +
> + /*
> + * Set OPTIMAL TRANSFER LENGTH GRANULARITY
> + */
> + put_unaligned_be16(1, &buf[6]);
> +
> + /*
> + * Set MAXIMUM TRANSFER LENGTH
> + */
> + put_unaligned_be32(DEV_ATTRIB(dev)->max_sectors, &buf[8]);
> +
> + /*
> + * Set OPTIMAL TRANSFER LENGTH
> + */
> + put_unaligned_be32(DEV_ATTRIB(dev)->optimal_sectors, &buf[12]);
> +
> + if (!have_tp)
> + return 0;
> +
> + /*
> + * Set MAXIMUM UNMAP LBA COUNT
> + */
> + put_unaligned_be32(DEV_ATTRIB(dev)->max_unmap_lba_count, &buf[20]);
> +
> + /*
> + * Set MAXIMUM UNMAP BLOCK DESCRIPTOR COUNT
> + */
> + put_unaligned_be32(DEV_ATTRIB(dev)->max_unmap_block_desc_count,
> + &buf[24]);
> +
> + /*
> + * Set OPTIMAL UNMAP GRANULARITY
> + */
> + put_unaligned_be32(DEV_ATTRIB(dev)->unmap_granularity, &buf[28]);
> +
> + /*
> + * UNMAP GRANULARITY ALIGNMENT
> + */
> + put_unaligned_be32(DEV_ATTRIB(dev)->unmap_granularity_alignment,
> + &buf[32]);
> + if (DEV_ATTRIB(dev)->unmap_granularity_alignment != 0)
> + buf[32] |= 0x80; /* Set the UGAVALID bit */
> +
> + return 0;
> +}
> +
> +/* Thin Provisioning VPD */
> +static int
> +target_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf)
> +{
> + struct se_device *dev = SE_DEV(cmd);
> +
> + /*
> + * From sbc3r22 section 6.5.4 Thin Provisioning VPD page:
> + *
> + * The PAGE LENGTH field is defined in SPC-4. If the DP bit is set to
> + * zero, then the page length shall be set to 0004h. If the DP bit
> + * is set to one, then the page length shall be set to the value
> + * defined in table 162.
> + */
> + buf[0] = dev->transport->get_device_type(dev);
> + buf[1] = 0xb2;
> +
> + /*
> + * Set Hardcoded length mentioned above for DP=0
> + */
> + put_unaligned_be16(0x0004, &buf[2]);
> +
> + /*
> + * The THRESHOLD EXPONENT field indicates the threshold set size in
> + * LBAs as a power of 2 (i.e., the threshold set size is equal to
> + * 2(threshold exponent)).
> + *
> + * Note that this is currently set to 0x00 as mkp says it will be
> + * changing again. We can enable this once it has settled in T10
> + * and is actually used by Linux/SCSI ML code.
> + */
> + buf[4] = 0x00;
> +
> + /*
> + * A TPU bit set to one indicates that the device server supports
> + * the UNMAP command (see 5.25). A TPU bit set to zero indicates
> + * that the device server does not support the UNMAP command.
> + */
> + if (DEV_ATTRIB(dev)->emulate_tpu != 0)
> + buf[5] = 0x80;
> +
> + /*
> + * A TPWS bit set to one indicates that the device server supports
> + * the use of the WRITE SAME (16) command (see 5.42) to unmap LBAs.
> + * A TPWS bit set to zero indicates that the device server does not
> + * support the use of the WRITE SAME (16) command to unmap LBAs.
> + */
> + if (DEV_ATTRIB(dev)->emulate_tpws != 0)
> + buf[5] |= 0x40;
> +
> + return 0;
> +}
> +
> +static int
> +target_emulate_inquiry(struct se_cmd *cmd)
> +{
> + struct se_device *dev = SE_DEV(cmd);
> + unsigned char *buf = cmd->t_task->t_task_buf;
> + unsigned char *cdb = cmd->t_task->t_task_cdb;
> +
> + if (!(cdb[1] & 0x1))
> + return target_emulate_inquiry_std(cmd);
> +
> + /*
> + * Make sure we at least have 4 bytes of INQUIRY response
> + * payload for 0x00 going back for EVPD=1. Note that 0x80
> + * and 0x83 will check for enough payload data length and
> + * jump to set_len: label when there is not enough inquiry EVPD
> + * payload length left for the next outgoing EVPD metadata
> + */
> + if (cmd->data_length < 4) {
> + printk(KERN_ERR "SCSI Inquiry payload length: %u"
> + " too small for EVPD=1\n", cmd->data_length);
> + return -1;
> + }
> + buf[0] = dev->transport->get_device_type(dev);
> +
> + switch (cdb[2]) {
> + case 0x00:
> + return target_emulate_evpd_00(cmd, buf);
> + case 0x80:
> + return target_emulate_evpd_80(cmd, buf);
> + case 0x83:
> + return target_emulate_evpd_83(cmd, buf);
> + case 0x86:
> + return target_emulate_evpd_86(cmd, buf);
> + case 0xb0:
> + return target_emulate_evpd_b0(cmd, buf);
> + case 0xb2:
> + return target_emulate_evpd_b2(cmd, buf);
> + default:
> + printk(KERN_ERR "Unknown VPD Code: 0x%02x\n", cdb[2]);
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> +static int
> +target_emulate_readcapacity(struct se_cmd *cmd)
> +{
> + struct se_device *dev = SE_DEV(cmd);
> + unsigned char *buf = cmd->t_task->t_task_buf;
> + u32 blocks = dev->transport->get_blocks(dev);
> +
> + buf[0] = (blocks >> 24) & 0xff;
> + buf[1] = (blocks >> 16) & 0xff;
> + buf[2] = (blocks >> 8) & 0xff;
> + buf[3] = blocks & 0xff;
> + buf[4] = (DEV_ATTRIB(dev)->block_size >> 24) & 0xff;
> + buf[5] = (DEV_ATTRIB(dev)->block_size >> 16) & 0xff;
> + buf[6] = (DEV_ATTRIB(dev)->block_size >> 8) & 0xff;
> + buf[7] = DEV_ATTRIB(dev)->block_size & 0xff;
> + /*
> + * Set max 32-bit blocks to signal SERVICE ACTION READ_CAPACITY_16
> + */
> + if (DEV_ATTRIB(dev)->emulate_tpu || DEV_ATTRIB(dev)->emulate_tpws)
> + put_unaligned_be32(0xFFFFFFFF, &buf[0]);
> +
> + return 0;
> +}
> +
> +static int
> +target_emulate_readcapacity_16(struct se_cmd *cmd)
> +{
> + struct se_device *dev = SE_DEV(cmd);
> + unsigned char *buf = cmd->t_task->t_task_buf;
> + unsigned long long blocks = dev->transport->get_blocks(dev);
> +
> + buf[0] = (blocks >> 56) & 0xff;
> + buf[1] = (blocks >> 48) & 0xff;
> + buf[2] = (blocks >> 40) & 0xff;
> + buf[3] = (blocks >> 32) & 0xff;
> + buf[4] = (blocks >> 24) & 0xff;
> + buf[5] = (blocks >> 16) & 0xff;
> + buf[6] = (blocks >> 8) & 0xff;
> + buf[7] = blocks & 0xff;
> + buf[8] = (DEV_ATTRIB(dev)->block_size >> 24) & 0xff;
> + buf[9] = (DEV_ATTRIB(dev)->block_size >> 16) & 0xff;
> + buf[10] = (DEV_ATTRIB(dev)->block_size >> 8) & 0xff;
> + buf[11] = DEV_ATTRIB(dev)->block_size & 0xff;
> + /*
> + * Set Thin Provisioning Enable bit following sbc3r22 in section
> + * READ CAPACITY (16) byte 14 if emulate_tpu or emulate_tpws is enabled.
> + */
> + if (DEV_ATTRIB(dev)->emulate_tpu || DEV_ATTRIB(dev)->emulate_tpws)
> + buf[14] = 0x80;
> +
> + return 0;
> +}
> +
> +static int
> +target_modesense_rwrecovery(unsigned char *p)
> +{
> + p[0] = 0x01;
> + p[1] = 0x0a;
> +
> + return 12;
> +}
> +
> +static int
> +target_modesense_control(struct se_device *dev, unsigned char *p)
> +{
> + p[0] = 0x0a;
> + p[1] = 0x0a;
> + p[2] = 2;
> + /*
> + * From spc4r17, section 7.4.6 Control mode Page
> + *
> + * Unit Attention interlocks control (UN_INTLCK_CTRL) to code 00b
> + *
> + * 00b: The logical unit shall clear any unit attention condition
> + * reported in the same I_T_L_Q nexus transaction as a CHECK CONDITION
> + * status and shall not establish a unit attention condition when a com-
> + * mand is completed with BUSY, TASK SET FULL, or RESERVATION CONFLICT
> + * status.
> + *
> + * 10b: The logical unit shall not clear any unit attention condition
> + * reported in the same I_T_L_Q nexus transaction as a CHECK CONDITION
> + * status and shall not establish a unit attention condition when
> + * a command is completed with BUSY, TASK SET FULL, or RESERVATION
> + * CONFLICT status.
> + *
> + * 11b a The logical unit shall not clear any unit attention condition
> + * reported in the same I_T_L_Q nexus transaction as a CHECK CONDITION
> + * status and shall establish a unit attention condition for the
> + * initiator port associated with the I_T nexus on which the BUSY,
> + * TASK SET FULL, or RESERVATION CONFLICT status is being returned.
> + * Depending on the status, the additional sense code shall be set to
> + * PREVIOUS BUSY STATUS, PREVIOUS TASK SET FULL STATUS, or PREVIOUS
> + * RESERVATION CONFLICT STATUS. Until it is cleared by a REQUEST SENSE
> + * command, a unit attention condition shall be established only once
> + * for a BUSY, TASK SET FULL, or RESERVATION CONFLICT status regardless
> + * to the number of commands completed with one of those status codes.
> + */
> + p[4] = (DEV_ATTRIB(dev)->emulate_ua_intlck_ctrl == 2) ? 0x30 :
> + (DEV_ATTRIB(dev)->emulate_ua_intlck_ctrl == 1) ? 0x20 : 0x00;
> + /*
> + * From spc4r17, section 7.4.6 Control mode Page
> + *
> + * Task Aborted Status (TAS) bit set to zero.
> + *
> + * A task aborted status (TAS) bit set to zero specifies that aborted
> + * tasks shall be terminated by the device server without any response
> + * to the application client. A TAS bit set to one specifies that tasks
> + * aborted by the actions of an I_T nexus other than the I_T nexus on
> + * which the command was received shall be completed with TASK ABORTED
> + * status (see SAM-4).
> + */
> + p[5] = (DEV_ATTRIB(dev)->emulate_tas) ? 0x40 : 0x00;
> + p[8] = 0xff;
> + p[9] = 0xff;
> + p[11] = 30;
> +
> + return 12;
> +}
> +
> +static int
> +target_modesense_caching(struct se_device *dev, unsigned char *p)
> +{
> + p[0] = 0x08;
> + p[1] = 0x12;
> + if (DEV_ATTRIB(dev)->emulate_write_cache > 0)
> + p[2] = 0x04; /* Write Cache Enable */
> + p[12] = 0x20; /* Disabled Read Ahead */
> +
> + return 20;
> +}
> +
> +static void
> +target_modesense_write_protect(unsigned char *buf, int type)
> +{
> + /*
> + * I believe that the WP bit (bit 7) in the mode header is the same for
> + * all device types..
> + */
> + switch (type) {
> + case TYPE_DISK:
> + case TYPE_TAPE:
> + default:
> + buf[0] |= 0x80; /* WP bit */
> + break;
> + }
> +}
> +
> +static void
> +target_modesense_dpofua(unsigned char *buf, int type)
> +{
> + switch (type) {
> + case TYPE_DISK:
> + buf[0] |= 0x10; /* DPOFUA bit */
> + break;
> + default:
> + break;
> + }
> +}
> +
> +static int
> +target_emulate_modesense(struct se_cmd *cmd, int ten)
> +{
> + struct se_device *dev = SE_DEV(cmd);
> + char *cdb = cmd->t_task->t_task_cdb;
> + unsigned char *rbuf = cmd->t_task->t_task_buf;
> + int type = dev->transport->get_device_type(dev);
> + int offset = (ten) ? 8 : 4;
> + int length = 0;
> + unsigned char buf[SE_MODE_PAGE_BUF];
> +
> + memset(buf, 0, SE_MODE_PAGE_BUF);
> +
> + switch (cdb[2] & 0x3f) {
> + case 0x01:
> + length = target_modesense_rwrecovery(&buf[offset]);
> + break;
> + case 0x08:
> + length = target_modesense_caching(dev, &buf[offset]);
> + break;
> + case 0x0a:
> + length = target_modesense_control(dev, &buf[offset]);
> + break;
> + case 0x3f:
> + length = target_modesense_rwrecovery(&buf[offset]);
> + length += target_modesense_caching(dev, &buf[offset+length]);
> + length += target_modesense_control(dev, &buf[offset+length]);
> + break;
> + default:
> + printk(KERN_ERR "Got Unknown Mode Page: 0x%02x\n",
> + cdb[2] & 0x3f);
> + return PYX_TRANSPORT_UNKNOWN_MODE_PAGE;
> + }
> + offset += length;
> +
> + if (ten) {
> + offset -= 2;
> + buf[0] = (offset >> 8) & 0xff;
> + buf[1] = offset & 0xff;
> +
> + if ((SE_LUN(cmd)->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) ||
> + (cmd->se_deve &&
> + (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY)))
> + target_modesense_write_protect(&buf[3], type);
> +
> + if ((DEV_ATTRIB(dev)->emulate_write_cache > 0) &&
> + (DEV_ATTRIB(dev)->emulate_fua_write > 0))
> + target_modesense_dpofua(&buf[3], type);
> +
> + if ((offset + 2) > cmd->data_length)
> + offset = cmd->data_length;
> +
> + } else {
> + offset -= 1;
> + buf[0] = offset & 0xff;
> +
> + if ((SE_LUN(cmd)->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) ||
> + (cmd->se_deve &&
> + (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY)))
> + target_modesense_write_protect(&buf[2], type);
> +
> + if ((DEV_ATTRIB(dev)->emulate_write_cache > 0) &&
> + (DEV_ATTRIB(dev)->emulate_fua_write > 0))
> + target_modesense_dpofua(&buf[2], type);
> +
> + if ((offset + 1) > cmd->data_length)
> + offset = cmd->data_length;
> + }
> + memcpy(rbuf, buf, offset);
> +
> + return 0;
> +}
> +
> +static int
> +target_emulate_request_sense(struct se_cmd *cmd)
> +{
> + unsigned char *cdb = cmd->t_task->t_task_cdb;
> + unsigned char *buf = cmd->t_task->t_task_buf;
> + u8 ua_asc = 0, ua_ascq = 0;
> +
> + if (cdb[1] & 0x01) {
> + printk(KERN_ERR "REQUEST_SENSE description emulation not"
> + " supported\n");
> + return PYX_TRANSPORT_INVALID_CDB_FIELD;
> + }
> + if (!(core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq))) {
> + /*
> + * CURRENT ERROR, UNIT ATTENTION
> + */
> + buf[0] = 0x70;
> + buf[SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION;
> + /*
> + * Make sure request data length is enough for additional
> + * sense data.
> + */
> + if (cmd->data_length <= 18) {
> + buf[7] = 0x00;
> + return 0;
> + }
> + /*
> + * The Additional Sense Code (ASC) from the UNIT ATTENTION
> + */
> + buf[SPC_ASC_KEY_OFFSET] = ua_asc;
> + buf[SPC_ASCQ_KEY_OFFSET] = ua_ascq;
> + buf[7] = 0x0A;
> + } else {
> + /*
> + * CURRENT ERROR, NO SENSE
> + */
> + buf[0] = 0x70;
> + buf[SPC_SENSE_KEY_OFFSET] = NO_SENSE;
> + /*
> + * Make sure request data length is enough for additional
> + * sense data.
> + */
> + if (cmd->data_length <= 18) {
> + buf[7] = 0x00;
> + return 0;
> + }
> + /*
> + * NO ADDITIONAL SENSE INFORMATION
> + */
> + buf[SPC_ASC_KEY_OFFSET] = 0x00;
> + buf[7] = 0x0A;
> + }
> +
> + return 0;
> +}
> +
> +/*
> + * Used for TCM/IBLOCK and TCM/FILEIO for block/blk-lib.c level discard support.
> + * Note this is not used for TCM/pSCSI passthrough
> + */
> +static int
> +target_emulate_unmap(struct se_task *task)
> +{
> + struct se_cmd *cmd = TASK_CMD(task);
> + struct se_device *dev = SE_DEV(cmd);
> + unsigned char *buf = cmd->t_task->t_task_buf, *ptr = NULL;
> + unsigned char *cdb = &cmd->t_task->t_task_cdb[0];
> + sector_t lba;
> + unsigned int size = cmd->data_length, range;
> + int ret, offset;
> + unsigned short dl, bd_dl;
> +
> + /* First UNMAP block descriptor starts at 8 byte offset */
> + offset = 8;
> + size -= 8;
> + dl = get_unaligned_be16(&cdb[0]);
> + bd_dl = get_unaligned_be16(&cdb[2]);
> + ptr = &buf[offset];
> + printk(KERN_INFO "UNMAP: Sub: %s Using dl: %hu bd_dl: %hu size: %hu"
> + " ptr: %p\n", dev->transport->name, dl, bd_dl, size, ptr);
> +
> + while (size) {
> + lba = get_unaligned_be64(&ptr[0]);
> + range = get_unaligned_be32(&ptr[8]);
> + printk(KERN_INFO "UNMAP: Using lba: %llu and range: %u\n",
> + (unsigned long long)lba, range);
> +
> + ret = dev->transport->do_discard(dev, lba, range);
> + if (ret < 0) {
> + printk(KERN_ERR "blkdev_issue_discard() failed: %d\n",
> + ret);
> + return -1;
> + }
> +
> + ptr += 16;
> + size -= 16;
> + }
> +
> + task->task_scsi_status = GOOD;
> + transport_complete_task(task, 1);
> + return 0;
> +}
> +
> +/*
> + * Used for TCM/IBLOCK and TCM/FILEIO for block/blk-lib.c level discard support.
> + * Note this is not used for TCM/pSCSI passthrough
> + */
> +static int
> +target_emulate_write_same(struct se_task *task)
> +{
> + struct se_cmd *cmd = TASK_CMD(task);
> + struct se_device *dev = SE_DEV(cmd);
> + sector_t lba = cmd->t_task->t_task_lba;
> + unsigned int range;
> + int ret;
> +
> + range = (cmd->data_length / DEV_ATTRIB(dev)->block_size);
> +
> + printk(KERN_INFO "WRITE_SAME UNMAP: LBA: %llu Range: %u\n",
> + (unsigned long long)lba, range);
> +
> + ret = dev->transport->do_discard(dev, lba, range);
> + if (ret < 0) {
> + printk(KERN_INFO "blkdev_issue_discard() failed for WRITE_SAME\n");
> + return -1;
> + }
> +
> + task->task_scsi_status = GOOD;
> + transport_complete_task(task, 1);
> + return 0;
> +}
> +
> +int
> +transport_emulate_control_cdb(struct se_task *task)
> +{
> + struct se_cmd *cmd = TASK_CMD(task);
> + struct se_device *dev = SE_DEV(cmd);
> + unsigned short service_action;
> + int ret = 0;
> +
> + switch (cmd->t_task->t_task_cdb[0]) {
> + case INQUIRY:
> + ret = target_emulate_inquiry(cmd);
> + break;
> + case READ_CAPACITY:
> + ret = target_emulate_readcapacity(cmd);
> + break;
> + case MODE_SENSE:
> + ret = target_emulate_modesense(cmd, 0);
> + break;
> + case MODE_SENSE_10:
> + ret = target_emulate_modesense(cmd, 1);
> + break;
> + case SERVICE_ACTION_IN:
> + switch (cmd->t_task->t_task_cdb[1] & 0x1f) {
> + case SAI_READ_CAPACITY_16:
> + ret = target_emulate_readcapacity_16(cmd);
> + break;
> + default:
> + printk(KERN_ERR "Unsupported SA: 0x%02x\n",
> + cmd->t_task->t_task_cdb[1] & 0x1f);
> + return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
> + }
> + case REQUEST_SENSE:
> + ret = target_emulate_request_sense(cmd);
> + break;
> + case UNMAP:
> + if (!dev->transport->do_discard) {
> + printk(KERN_ERR "UNMAP emulation not supported for: %s\n",
> + dev->transport->name);
> + return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
> + }
> + ret = target_emulate_unmap(task);
> + break;
> + case WRITE_SAME_16:
> + if (!dev->transport->do_discard) {
> + printk(KERN_ERR "WRITE_SAME_16 emulation not supported"
> + " for: %s\n", dev->transport->name);
> + return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
> + }
> + ret = target_emulate_write_same(task);
> + break;
> + case VARIABLE_LENGTH_CMD:
> + service_action =
> + get_unaligned_be16(&cmd->t_task->t_task_cdb[8]);
> + switch (service_action) {
> + case WRITE_SAME_32:
> + if (!dev->transport->do_discard) {
> + printk(KERN_ERR "WRITE_SAME_32 SA emulation not"
> + " supported for: %s\n",
> + dev->transport->name);
> + return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
> + }
> + ret = target_emulate_write_same(task);
> + break;
> + default:
> + printk(KERN_ERR "Unsupported VARIABLE_LENGTH_CMD SA:"
> + " 0x%02x\n", service_action);
> + break;
> + }
> + break;
> + case SYNCHRONIZE_CACHE:
> + case 0x91: /* SYNCHRONIZE_CACHE_16: */
> + if (!dev->transport->do_sync_cache) {
> + printk(KERN_ERR
> + "SYNCHRONIZE_CACHE emulation not supported"
> + " for: %s\n", dev->transport->name);
> + return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
> + }
> + dev->transport->do_sync_cache(task);
> + break;
> + case ALLOW_MEDIUM_REMOVAL:
> + case ERASE:
> + case REZERO_UNIT:
> + case SEEK_10:
> + case SPACE:
> + case START_STOP:
> + case TEST_UNIT_READY:
> + case VERIFY:
> + case WRITE_FILEMARKS:
> + break;
> + default:
> + printk(KERN_ERR "Unsupported SCSI Opcode: 0x%02x for %s\n",
> + cmd->t_task->t_task_cdb[0], dev->transport->name);
> + return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
> + }
> +
> + if (ret < 0)
> + return ret;
> + task->task_scsi_status = GOOD;
> + transport_complete_task(task, 1);
> +
> + return PYX_TRANSPORT_SENT_TO_TRANSPORT;
> +}
> Index: lio-core-2.6/drivers/target/target_core_transport.c
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/target_core_transport.c 2010-11-08 17:06:49.144863013 +0100
> +++ lio-core-2.6/drivers/target/target_core_transport.c 2010-11-08 18:13:15.068196347 +0100
> @@ -4405,871 +4405,6 @@ unsigned char transport_asciihex_to_bina
> }
> EXPORT_SYMBOL(transport_asciihex_to_binaryhex);
>
> -extern int transport_generic_emulate_inquiry(
> - struct se_cmd *cmd,
> - unsigned char type,
> - unsigned char *prod,
> - unsigned char *version)
> -{
> - struct se_device *dev = SE_DEV(cmd);
> - struct se_lun *lun = SE_LUN(cmd);
> - struct se_port *port = NULL;
> - struct se_portal_group *tpg = NULL;
> - struct t10_alua_lu_gp_member *lu_gp_mem;
> - struct t10_alua_tg_pt_gp *tg_pt_gp;
> - struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem;
> - unsigned char *buf = (unsigned char *) T_TASK(cmd)->t_task_buf;
> - unsigned char *cdb = T_TASK(cmd)->t_task_cdb;
> - unsigned char binary, binary_new;
> - u32 prod_len;
> - u32 unit_serial_len, off = 0;
> - int i;
> - u16 len = 0, id_len;
> -
> - if (!(cdb[1] & 0x1)) {
> - /*
> - * Make sure we at least have 6 bytes of INQUIRY response
> - * payload going back for EVPD=0
> - */
> - if (cmd->data_length < 6) {
> - printk(KERN_ERR "SCSI Inquiry payload length: %u"
> - " too small for EVPD=0\n", cmd->data_length);
> - return -1;
> - }
> - buf[0] = type;
> -
> - if (type == TYPE_TAPE)
> - buf[1] = 0x80;
> - buf[2] = TRANSPORT(dev)->get_device_rev(dev);
> - /*
> - * Enable SCCS and TPGS fields for Emulated ALUA
> - */
> - if (T10_ALUA(dev->se_sub_dev)->alua_type ==
> - SPC3_ALUA_EMULATED) {
> - /*
> - * Set SCCS for MAINTENANCE_IN +
> - * REPORT_TARGET_PORT_GROUPS
> - */
> - buf[5] = 0x80;
> - /*
> - * Set TPGS field for explict and/or implict ALUA
> - * access type and opteration.
> - *
> - * See spc4r17 section 6.4.2 Table 135
> - */
> - port = lun->lun_sep;
> - if (!(port))
> - goto after_tpgs;
> - tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem;
> - if (!(tg_pt_gp_mem))
> - goto after_tpgs;
> -
> - spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
> - tg_pt_gp = tg_pt_gp_mem->tg_pt_gp;
> - if (!(tg_pt_gp)) {
> - spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
> - goto after_tpgs;
> - }
> - buf[5] |= tg_pt_gp->tg_pt_gp_alua_access_type;
> - spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
> - }
> -after_tpgs:
> - if (cmd->data_length < 8) {
> - buf[4] = 1; /* Set additional length to 1 */
> - return 0;
> - }
> -
> - buf[7] = 0x32; /* Sync=1 and CmdQue=1 */
> - /*
> - * Do not include vendor, product, reversion info in INQUIRY
> - * response payload for cdbs with a small allocation length.
> - */
> - if (cmd->data_length < 36) {
> - buf[4] = 3; /* Set additional length to 3 */
> - return 0;
> - }
> -
> - snprintf((unsigned char *)&buf[8], 8, "LIO-ORG");
> - snprintf((unsigned char *)&buf[16], 16, "%s", prod);
> - snprintf((unsigned char *)&buf[32], 4, "%s", version);
> - buf[4] = 31; /* Set additional length to 31 */
> - return 0;
> - }
> - /*
> - * Make sure we at least have 4 bytes of INQUIRY response
> - * payload for 0x00 going back for EVPD=1. Note that 0x80
> - * and 0x83 will check for enough payload data length and
> - * jump to set_len: label when there is not enough inquiry EVPD
> - * payload length left for the next outgoing EVPD metadata
> - */
> - if (cmd->data_length < 4) {
> - printk(KERN_ERR "SCSI Inquiry payload length: %u"
> - " too small for EVPD=1\n", cmd->data_length);
> - return -1;
> - }
> - buf[0] = type;
> -
> - switch (cdb[2]) {
> - case 0x00: /* supported vital product data pages */
> - buf[1] = 0x00;
> - if (cmd->data_length < 8)
> - return 0;
> - buf[4] = 0x0;
> - /*
> - * Only report the INQUIRY EVPD=1 pages after a valid NAA
> - * Registered Extended LUN WWN has been set via ConfigFS
> - * during device creation/restart.
> - */
> - if (dev->se_sub_dev->su_dev_flags &
> - SDF_EMULATED_VPD_UNIT_SERIAL) {
> - buf[3] = 3;
> - buf[5] = 0x80;
> - buf[6] = 0x83;
> - buf[7] = 0x86;
> - len = 3;
> - }
> - break;
> - case 0x80: /* unit serial number */
> - buf[1] = 0x80;
> - if (dev->se_sub_dev->su_dev_flags &
> - SDF_EMULATED_VPD_UNIT_SERIAL) {
> -
> - unit_serial_len =
> - strlen(&DEV_T10_WWN(dev)->unit_serial[0]);
> - unit_serial_len++; /* For NULL Terminator */
> -
> - if (((len + 4) + unit_serial_len) > cmd->data_length) {
> - len += unit_serial_len;
> - goto set_len;
> - }
> - len += sprintf((unsigned char *)&buf[4], "%s",
> - &DEV_T10_WWN(dev)->unit_serial[0]);
> - len++; /* Extra Byte for NULL Terminator */
> - buf[3] = len;
> - }
> - break;
> - case 0x83:
> - /*
> - * Device identification VPD, for a complete list of
> - * DESIGNATOR TYPEs see spc4r17 Table 459.
> - */
> - buf[1] = 0x83;
> - off = 4;
> - /*
> - * NAA IEEE Registered Extended Assigned designator format,
> - * see spc4r17 section 7.7.3.6.5
> - *
> - * We depend upon a target_core_mod/ConfigFS provided
> - * /sys/kernel/config/target/core/$HBA/$DEV/wwn/vpd_unit_serial
> - * value in order to return the NAA id.
> - */
> - if (!(dev->se_sub_dev->su_dev_flags &
> - SDF_EMULATED_VPD_UNIT_SERIAL))
> - goto check_t10_vend_desc;
> - if ((off + 20) > cmd->data_length)
> - goto check_t10_vend_desc;
> - /* CODE SET == Binary */
> - buf[off++] = 0x1;
> - /* Set ASSOICATION == addressed logical unit: 0)b */
> - buf[off] = 0x00;
> - /* Identifier/Designator type == NAA identifier */
> - buf[off++] = 0x3;
> - off++;
> - /* Identifier/Designator length */
> - buf[off++] = 0x10;
> - /*
> - * Start NAA IEEE Registered Extended Identifier/Designator
> - */
> - buf[off++] = (0x6 << 4);
> - /*
> - * Use OpenFabrics IEEE Company ID: 00 14 05
> - */
> - buf[off++] = 0x01;
> - buf[off++] = 0x40;
> - buf[off] = (0x5 << 4);
> - /*
> - * Return ConfigFS Unit Serial Number information for
> - * VENDOR_SPECIFIC_IDENTIFIER and
> - * VENDOR_SPECIFIC_IDENTIFIER_EXTENTION
> - */
> - binary = transport_asciihex_to_binaryhex(
> - &DEV_T10_WWN(dev)->unit_serial[0]);
> - buf[off++] |= (binary & 0xf0) >> 4;
> - for (i = 0; i < 24; i += 2) {
> - binary_new = transport_asciihex_to_binaryhex(
> - &DEV_T10_WWN(dev)->unit_serial[i+2]);
> - buf[off] = (binary & 0x0f) << 4;
> - buf[off++] |= (binary_new & 0xf0) >> 4;
> - binary = binary_new;
> - }
> - len = 20;
> - off = (len + 4);
> -check_t10_vend_desc:
> - /*
> - * T10 Vendor Identifier Page, see spc4r17 section 7.7.3.4
> - */
> - id_len = 8; /* For Vendor field */
> - prod_len = 4; /* For VPD Header */
> - prod_len += 8; /* For Vendor field */
> - prod_len += strlen(prod);
> - prod_len++; /* For : */
> -
> - if (dev->se_sub_dev->su_dev_flags &
> - SDF_EMULATED_VPD_UNIT_SERIAL) {
> - unit_serial_len =
> - strlen(&DEV_T10_WWN(dev)->unit_serial[0]);
> - unit_serial_len++; /* For NULL Terminator */
> -
> - if ((len + (id_len + 4) +
> - (prod_len + unit_serial_len)) >
> - cmd->data_length) {
> - len += (prod_len + unit_serial_len);
> - goto check_port;
> - }
> - id_len += sprintf((unsigned char *)&buf[off+12],
> - "%s:%s", prod,
> - &DEV_T10_WWN(dev)->unit_serial[0]);
> - }
> - buf[off] = 0x2; /* ASCII */
> - buf[off+1] = 0x1; /* T10 Vendor ID */
> - buf[off+2] = 0x0;
> - memcpy((unsigned char *)&buf[off+4], "LIO-ORG", 8);
> - /* Extra Byte for NULL Terminator */
> - id_len++;
> - /* Identifier Length */
> - buf[off+3] = id_len;
> - /* Header size for Designation descriptor */
> - len += (id_len + 4);
> - off += (id_len + 4);
> - /*
> - * struct se_port is only set for INQUIRY VPD=1 through $FABRIC_MOD
> - */
> -check_port:
> - port = lun->lun_sep;
> - if (port) {
> - struct t10_alua_lu_gp *lu_gp;
> - u32 padding, scsi_name_len;
> - u16 lu_gp_id = 0;
> - u16 tg_pt_gp_id = 0;
> - u16 tpgt;
> -
> - tpg = port->sep_tpg;
> - /*
> - * Relative target port identifer, see spc4r17
> - * section 7.7.3.7
> - *
> - * Get the PROTOCOL IDENTIFIER as defined by spc4r17
> - * section 7.5.1 Table 362
> - */
> - if (((len + 4) + 8) > cmd->data_length) {
> - len += 8;
> - goto check_tpgi;
> - }
> - buf[off] =
> - (TPG_TFO(tpg)->get_fabric_proto_ident(tpg) << 4);
> - buf[off++] |= 0x1; /* CODE SET == Binary */
> - buf[off] = 0x80; /* Set PIV=1 */
> - /* Set ASSOICATION == target port: 01b */
> - buf[off] |= 0x10;
> - /* DESIGNATOR TYPE == Relative target port identifer */
> - buf[off++] |= 0x4;
> - off++; /* Skip over Reserved */
> - buf[off++] = 4; /* DESIGNATOR LENGTH */
> - /* Skip over Obsolete field in RTPI payload
> - * in Table 472 */
> - off += 2;
> - buf[off++] = ((port->sep_rtpi >> 8) & 0xff);
> - buf[off++] = (port->sep_rtpi & 0xff);
> - len += 8; /* Header size + Designation descriptor */
> - /*
> - * Target port group identifier, see spc4r17
> - * section 7.7.3.8
> - *
> - * Get the PROTOCOL IDENTIFIER as defined by spc4r17
> - * section 7.5.1 Table 362
> - */
> -check_tpgi:
> - if (T10_ALUA(dev->se_sub_dev)->alua_type !=
> - SPC3_ALUA_EMULATED)
> - goto check_scsi_name;
> -
> - if (((len + 4) + 8) > cmd->data_length) {
> - len += 8;
> - goto check_lu_gp;
> - }
> - tg_pt_gp_mem = port->sep_alua_tg_pt_gp_mem;
> - if (!(tg_pt_gp_mem))
> - goto check_lu_gp;
> -
> - spin_lock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
> - tg_pt_gp = tg_pt_gp_mem->tg_pt_gp;
> - if (!(tg_pt_gp)) {
> - spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
> - goto check_lu_gp;
> - }
> - tg_pt_gp_id = tg_pt_gp->tg_pt_gp_id;
> - spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock);
> -
> - buf[off] =
> - (TPG_TFO(tpg)->get_fabric_proto_ident(tpg) << 4);
> - buf[off++] |= 0x1; /* CODE SET == Binary */
> - buf[off] = 0x80; /* Set PIV=1 */
> - /* Set ASSOICATION == target port: 01b */
> - buf[off] |= 0x10;
> - /* DESIGNATOR TYPE == Target port group identifier */
> - buf[off++] |= 0x5;
> - off++; /* Skip over Reserved */
> - buf[off++] = 4; /* DESIGNATOR LENGTH */
> - off += 2; /* Skip over Reserved Field */
> - buf[off++] = ((tg_pt_gp_id >> 8) & 0xff);
> - buf[off++] = (tg_pt_gp_id & 0xff);
> - len += 8; /* Header size + Designation descriptor */
> - /*
> - * Logical Unit Group identifier, see spc4r17
> - * section 7.7.3.8
> - */
> -check_lu_gp:
> - if (((len + 4) + 8) > cmd->data_length) {
> - len += 8;
> - goto check_scsi_name;
> - }
> - lu_gp_mem = dev->dev_alua_lu_gp_mem;
> - if (!(lu_gp_mem))
> - goto check_scsi_name;
> -
> - spin_lock(&lu_gp_mem->lu_gp_mem_lock);
> - lu_gp = lu_gp_mem->lu_gp;
> - if (!(lu_gp)) {
> - spin_unlock(&lu_gp_mem->lu_gp_mem_lock);
> - goto check_scsi_name;
> - }
> - lu_gp_id = lu_gp->lu_gp_id;
> - spin_unlock(&lu_gp_mem->lu_gp_mem_lock);
> -
> - buf[off++] |= 0x1; /* CODE SET == Binary */
> - /* DESIGNATOR TYPE == Logical Unit Group identifier */
> - buf[off++] |= 0x6;
> - off++; /* Skip over Reserved */
> - buf[off++] = 4; /* DESIGNATOR LENGTH */
> - off += 2; /* Skip over Reserved Field */
> - buf[off++] = ((lu_gp_id >> 8) & 0xff);
> - buf[off++] = (lu_gp_id & 0xff);
> - len += 8; /* Header size + Designation descriptor */
> - /*
> - * SCSI name string designator, see spc4r17
> - * section 7.7.3.11
> - *
> - * Get the PROTOCOL IDENTIFIER as defined by spc4r17
> - * section 7.5.1 Table 362
> - */
> -check_scsi_name:
> - scsi_name_len = strlen(TPG_TFO(tpg)->tpg_get_wwn(tpg));
> - /* UTF-8 ",t,0x<16-bit TPGT>" + NULL Terminator */
> - scsi_name_len += 10;
> - /* Check for 4-byte padding */
> - padding = ((-scsi_name_len) & 3);
> - if (padding != 0)
> - scsi_name_len += padding;
> - /* Header size + Designation descriptor */
> - scsi_name_len += 4;
> -
> - if (((len + 4) + scsi_name_len) > cmd->data_length) {
> - len += scsi_name_len;
> - goto set_len;
> - }
> - buf[off] =
> - (TPG_TFO(tpg)->get_fabric_proto_ident(tpg) << 4);
> - buf[off++] |= 0x3; /* CODE SET == UTF-8 */
> - buf[off] = 0x80; /* Set PIV=1 */
> - /* Set ASSOICATION == target port: 01b */
> - buf[off] |= 0x10;
> - /* DESIGNATOR TYPE == SCSI name string */
> - buf[off++] |= 0x8;
> - off += 2; /* Skip over Reserved and length */
> - /*
> - * SCSI name string identifer containing, $FABRIC_MOD
> - * dependent information. For LIO-Target and iSCSI
> - * Target Port, this means "<iSCSI name>,t,0x<TPGT> in
> - * UTF-8 encoding.
> - */
> - tpgt = TPG_TFO(tpg)->tpg_get_tag(tpg);
> - scsi_name_len = sprintf(&buf[off], "%s,t,0x%04x",
> - TPG_TFO(tpg)->tpg_get_wwn(tpg), tpgt);
> - scsi_name_len += 1 /* Include NULL terminator */;
> - /*
> - * The null-terminated, null-padded (see 4.4.2) SCSI
> - * NAME STRING field contains a UTF-8 format string.
> - * The number of bytes in the SCSI NAME STRING field
> - * (i.e., the value in the DESIGNATOR LENGTH field)
> - * shall be no larger than 256 and shall be a multiple
> - * of four.
> - */
> - if (padding)
> - scsi_name_len += padding;
> -
> - buf[off-1] = scsi_name_len;
> - off += scsi_name_len;
> - /* Header size + Designation descriptor */
> - len += (scsi_name_len + 4);
> - }
> -set_len:
> - buf[2] = ((len >> 8) & 0xff);
> - buf[3] = (len & 0xff); /* Page Length for VPD 0x83 */
> - break;
> - case 0x86: /* Extended INQUIRY Data VPD Page */
> - /*
> - * This page uses a hardcoded value of 60
> - */
> - if (cmd->data_length < 60)
> - return 0;
> -
> - buf[1] = 0x86;
> - buf[2] = 0x3c;
> - /* Set HEADSUP, ORDSUP, SIMPSUP */
> - buf[5] = 0x07;
> - /* If WriteCache emulation is enabled, set V_SUP */
> - if (DEV_ATTRIB(dev)->emulate_write_cache > 0)
> - buf[6] = 0x01;
> -
> - break;
> - case 0xb0: /* Block Limits VPD page */
> - /*
> - * Following sbc3r22 section 6.5.3 Block Limits VPD page,
> - * when emulate_tpu=1 or emulate_tpws=1 we will be expect
> - * a different page length for Thin Provisioning.
> - */
> - if (!(DEV_ATTRIB(dev)->emulate_tpu) &&
> - !(DEV_ATTRIB(dev)->emulate_tpws)) {
> - if (cmd->data_length < (0x10 + 4)) {
> - printk(KERN_INFO "Received data_length: %u"
> - " too small for TPE=1 EVPD 0xb0\n",
> - cmd->data_length);
> - return -1;
> - }
> - buf[0] = TRANSPORT(dev)->get_device_type(dev);
> - buf[1] = 0xb0;
> - buf[3] = 0x10; /* Set hardcoded TPE=0 length */
> - /*
> - * Set OPTIMAL TRANSFER LENGTH GRANULARITY
> - */
> - put_unaligned_be16(1, &buf[6]);
> - /*
> - * Set MAXIMUM TRANSFER LENGTH
> - */
> - put_unaligned_be32(DEV_ATTRIB(dev)->max_sectors,
> - &buf[8]);
> - /*
> - * Set OPTIMAL TRANSFER LENGTH
> - */
> - put_unaligned_be32(DEV_ATTRIB(dev)->optimal_sectors,
> - &buf[12]);
> - break;
> - }
> -
> - if (cmd->data_length < (0x3c + 4)) {
> - printk(KERN_INFO "Received data_length: %u"
> - " too small for TPE=1 EVPD 0xb0\n",
> - cmd->data_length);
> - return -1;
> - }
> - buf[0] = TRANSPORT(dev)->get_device_type(dev);
> - buf[1] = 0xb0;
> - buf[3] = 0x3c; /* Set hardcoded TPE=1 length */
> - /*
> - * Set OPTIMAL TRANSFER LENGTH GRANULARITY
> - * Note that this follows what scsi_debug.c reports to SCSI ML
> - */
> - put_unaligned_be16(1, &buf[6]);
> - /*
> - * Set MAXIMUM TRANSFER LENGTH
> - */
> - put_unaligned_be32(DEV_ATTRIB(dev)->max_sectors, &buf[8]);
> - /*
> - * Set OPTIMAL TRANSFER LENGTH
> - */
> - put_unaligned_be32(DEV_ATTRIB(dev)->optimal_sectors, &buf[12]);
> - /*
> - * Set MAXIMUM UNMAP LBA COUNT
> - */
> - put_unaligned_be32(DEV_ATTRIB(dev)->max_unmap_lba_count,
> - &buf[20]);
> - /*
> - * Set MAXIMUM UNMAP BLOCK DESCRIPTOR COUNT
> - */
> - put_unaligned_be32(DEV_ATTRIB(dev)->max_unmap_block_desc_count,
> - &buf[24]);
> - /*
> - * Set OPTIMAL UNMAP GRANULARITY
> - */
> - put_unaligned_be32(DEV_ATTRIB(dev)->unmap_granularity,
> - &buf[28]);
> - /*
> - * UNMAP GRANULARITY ALIGNMENT
> - */
> - put_unaligned_be32(DEV_ATTRIB(dev)->unmap_granularity_alignment,
> - &buf[32]);
> - if (DEV_ATTRIB(dev)->unmap_granularity_alignment != 0)
> - buf[32] |= 0x80; /* Set the UGAVALID bit */
> - break;
> - case 0xb2: /* Thin Provisioning VPD */
> - /*
> - * From sbc3r22 section 6.5.4 Thin Provisioning VPD page:
> - *
> - * The PAGE LENGTH field is defined in SPC-4. If the DP bit is
> - * set to zero, then the page length shall be set to 0004h. If the
> - * DP bit is set to one, then the page length shall be set to the value
> - * defined in table 162.
> - */
> - buf[0] = TRANSPORT(dev)->get_device_type(dev);
> - buf[1] = 0xb2;
> - /*
> - * Set Hardcoded length mentioned above for DP=0
> - */
> - put_unaligned_be16(0x0004, &buf[2]);
> - /*
> - * The THRESHOLD EXPONENT field indicates the threshold set size in LBAs
> - * as a power of 2 (i.e., the threshold set size is equal to 2(threshold exponent)).
> - *
> - * Note that this is currently set to 0x00 as mkp says it will be
> - * changing again. We can enable this once it has settled in T10
> - * and is actually used by Linux/SCSI ML code.
> - */
> - buf[4] = 0x00;
> - /*
> - * A TPU bit set to one indicates that the device server supports
> - * the UNMAP command (see 5.25). A TPU bit set to zero indicates
> - * that the device server does not support the UNMAP command.
> - */
> - if (DEV_ATTRIB(dev)->emulate_tpu != 0)
> - buf[5] = 0x80;
> - /*
> - * A TPWS bit set to one indicates that the device server supports
> - * the use of the WRITE SAME (16) command (see 5.42) to unmap LBAs.
> - * A TPWS bit set to zero indicates that the device server does not
> - * support the use of the WRITE SAME (16) command to unmap LBAs.
> - */
> - if (DEV_ATTRIB(dev)->emulate_tpws != 0)
> - buf[5] |= 0x40;
> - break;
> - default:
> - printk(KERN_ERR "Unknown VPD Code: 0x%02x\n", cdb[2]);
> - return -1;
> - }
> -
> - return 0;
> -}
> -EXPORT_SYMBOL(transport_generic_emulate_inquiry);
> -
> -int transport_generic_emulate_readcapacity(
> - struct se_cmd *cmd,
> - u32 blocks)
> -{
> - struct se_device *dev = SE_DEV(cmd);
> - unsigned char *buf = (unsigned char *) T_TASK(cmd)->t_task_buf;
> -
> - buf[0] = (blocks >> 24) & 0xff;
> - buf[1] = (blocks >> 16) & 0xff;
> - buf[2] = (blocks >> 8) & 0xff;
> - buf[3] = blocks & 0xff;
> - buf[4] = (DEV_ATTRIB(dev)->block_size >> 24) & 0xff;
> - buf[5] = (DEV_ATTRIB(dev)->block_size >> 16) & 0xff;
> - buf[6] = (DEV_ATTRIB(dev)->block_size >> 8) & 0xff;
> - buf[7] = DEV_ATTRIB(dev)->block_size & 0xff;
> - /*
> - * Set max 32-bit blocks to signal SERVICE ACTION READ_CAPACITY_16
> - */
> - if (DEV_ATTRIB(dev)->emulate_tpu || DEV_ATTRIB(dev)->emulate_tpws)
> - put_unaligned_be32(0xFFFFFFFF, &buf[0]);
> -
> - return 0;
> -}
> -EXPORT_SYMBOL(transport_generic_emulate_readcapacity);
> -
> -int transport_generic_emulate_readcapacity_16(
> - struct se_cmd *cmd,
> - unsigned long long blocks)
> -{
> - struct se_device *dev = SE_DEV(cmd);
> - unsigned char *buf = (unsigned char *) T_TASK(cmd)->t_task_buf;
> -
> - buf[0] = (blocks >> 56) & 0xff;
> - buf[1] = (blocks >> 48) & 0xff;
> - buf[2] = (blocks >> 40) & 0xff;
> - buf[3] = (blocks >> 32) & 0xff;
> - buf[4] = (blocks >> 24) & 0xff;
> - buf[5] = (blocks >> 16) & 0xff;
> - buf[6] = (blocks >> 8) & 0xff;
> - buf[7] = blocks & 0xff;
> - buf[8] = (DEV_ATTRIB(dev)->block_size >> 24) & 0xff;
> - buf[9] = (DEV_ATTRIB(dev)->block_size >> 16) & 0xff;
> - buf[10] = (DEV_ATTRIB(dev)->block_size >> 8) & 0xff;
> - buf[11] = DEV_ATTRIB(dev)->block_size & 0xff;
> - /*
> - * Set Thin Provisioning Enable bit following sbc3r22 in section
> - * READ CAPACITY (16) byte 14 if emulate_tpu or emulate_tpws is enabled.
> - */
> - if (DEV_ATTRIB(dev)->emulate_tpu || DEV_ATTRIB(dev)->emulate_tpws)
> - buf[14] = 0x80;
> -
> - return 0;
> -}
> -EXPORT_SYMBOL(transport_generic_emulate_readcapacity_16);
> -
> -static int transport_modesense_rwrecovery(unsigned char *p)
> -{
> - p[0] = 0x01;
> - p[1] = 0x0a;
> -
> - return 12;
> -}
> -
> -static int transport_modesense_control(struct se_device *dev, unsigned char *p)
> -{
> - p[0] = 0x0a;
> - p[1] = 0x0a;
> - p[2] = 2;
> - /*
> - * From spc4r17, section 7.4.6 Control mode Page
> - *
> - * Unit Attention interlocks control (UN_INTLCK_CTRL) to code 00b
> - *
> - * 00b: The logical unit shall clear any unit attention condition
> - * reported in the same I_T_L_Q nexus transaction as a CHECK CONDITION
> - * status and shall not establish a unit attention condition when a com-
> - * mand is completed with BUSY, TASK SET FULL, or RESERVATION CONFLICT
> - * status.
> - *
> - * 10b: The logical unit shall not clear any unit attention condition
> - * reported in the same I_T_L_Q nexus transaction as a CHECK CONDITION
> - * status and shall not establish a unit attention condition when
> - * a command is completed with BUSY, TASK SET FULL, or RESERVATION
> - * CONFLICT status.
> - *
> - * 11b a The logical unit shall not clear any unit attention condition
> - * reported in the same I_T_L_Q nexus transaction as a CHECK CONDITION
> - * status and shall establish a unit attention condition for the
> - * initiator port associated with the I_T nexus on which the BUSY,
> - * TASK SET FULL, or RESERVATION CONFLICT status is being returned.
> - * Depending on the status, the additional sense code shall be set to
> - * PREVIOUS BUSY STATUS, PREVIOUS TASK SET FULL STATUS, or PREVIOUS
> - * RESERVATION CONFLICT STATUS. Until it is cleared by a REQUEST SENSE
> - * command, a unit attention condition shall be established only once
> - * for a BUSY, TASK SET FULL, or RESERVATION CONFLICT status regardless
> - * to the number of commands completed with one of those status codes.
> - */
> - p[4] = (DEV_ATTRIB(dev)->emulate_ua_intlck_ctrl == 2) ? 0x30 :
> - (DEV_ATTRIB(dev)->emulate_ua_intlck_ctrl == 1) ? 0x20 : 0x00;
> - /*
> - * From spc4r17, section 7.4.6 Control mode Page
> - *
> - * Task Aborted Status (TAS) bit set to zero.
> - *
> - * A task aborted status (TAS) bit set to zero specifies that aborted
> - * tasks shall be terminated by the device server without any response
> - * to the application client. A TAS bit set to one specifies that tasks
> - * aborted by the actions of an I_T nexus other than the I_T nexus on
> - * which the command was received shall be completed with TASK ABORTED
> - * status (see SAM-4).
> - */
> - p[5] = (DEV_ATTRIB(dev)->emulate_tas) ? 0x40 : 0x00;
> - p[8] = 0xff;
> - p[9] = 0xff;
> - p[11] = 30;
> -
> - return 12;
> -}
> -
> -static int transport_modesense_caching(struct se_device *dev, unsigned char *p)
> -{
> - p[0] = 0x08;
> - p[1] = 0x12;
> - if (DEV_ATTRIB(dev)->emulate_write_cache > 0)
> - p[2] = 0x04; /* Write Cache Enable */
> - p[12] = 0x20; /* Disabled Read Ahead */
> -
> - return 20;
> -}
> -
> -#if 0
> -static int transport_modesense_devicecaps(unsigned char *p)
> -{
> - p[0] = 0x2a;
> - p[1] = 0x0a;
> -
> - return 12;
> -}
> -#endif
> -
> -static void transport_modesense_write_protect(
> - unsigned char *buf,
> - int type)
> -{
> - /*
> - * I believe that the WP bit (bit 7) in the mode header is the same for
> - * all device types..
> - */
> - switch (type) {
> - case TYPE_DISK:
> - case TYPE_TAPE:
> - default:
> - buf[0] |= 0x80; /* WP bit */
> - break;
> - }
> -}
> -
> -static void transport_modesense_dpofua(
> - unsigned char *buf,
> - int type)
> -{
> - switch (type) {
> - case TYPE_DISK:
> - buf[0] |= 0x10; /* DPOFUA bit */
> - break;
> - default:
> - break;
> - }
> -}
> -
> -int transport_generic_emulate_modesense(
> - struct se_cmd *cmd,
> - unsigned char *cdb,
> - unsigned char *rbuf,
> - int ten,
> - int type)
> -{
> - struct se_device *dev = SE_DEV(cmd);
> - int offset = (ten) ? 8 : 4;
> - int length = 0;
> - unsigned char buf[SE_MODE_PAGE_BUF];
> -
> - memset(buf, 0, SE_MODE_PAGE_BUF);
> -
> - switch (cdb[2] & 0x3f) {
> - case 0x01:
> - length = transport_modesense_rwrecovery(&buf[offset]);
> - break;
> - case 0x08:
> - length = transport_modesense_caching(dev, &buf[offset]);
> - break;
> - case 0x0a:
> - length = transport_modesense_control(dev, &buf[offset]);
> - break;
> -#if 0
> - case 0x2a:
> - length = transport_modesense_devicecaps(&buf[offset]);
> - break;
> -#endif
> - case 0x3f:
> - length = transport_modesense_rwrecovery(&buf[offset]);
> - length += transport_modesense_caching(dev, &buf[offset+length]);
> - length += transport_modesense_control(dev, &buf[offset+length]);
> -#if 0
> - length += transport_modesense_devicecaps(&buf[offset+length]);
> -#endif
> - break;
> - default:
> - printk(KERN_ERR "Got Unknown Mode Page: 0x%02x\n",
> - cdb[2] & 0x3f);
> - return PYX_TRANSPORT_UNKNOWN_MODE_PAGE;
> - }
> - offset += length;
> -
> - if (ten) {
> - offset -= 2;
> - buf[0] = (offset >> 8) & 0xff;
> - buf[1] = offset & 0xff;
> -
> - if ((SE_LUN(cmd)->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) ||
> - (cmd->se_deve &&
> - (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY)))
> - transport_modesense_write_protect(&buf[3], type);
> -
> - if ((DEV_ATTRIB(dev)->emulate_write_cache > 0) &&
> - (DEV_ATTRIB(dev)->emulate_fua_write > 0))
> - transport_modesense_dpofua(&buf[3], type);
> -
> - if ((offset + 2) > cmd->data_length)
> - offset = cmd->data_length;
> -
> - } else {
> - offset -= 1;
> - buf[0] = offset & 0xff;
> -
> - if ((SE_LUN(cmd)->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) ||
> - (cmd->se_deve &&
> - (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY)))
> - transport_modesense_write_protect(&buf[2], type);
> -
> - if ((DEV_ATTRIB(dev)->emulate_write_cache > 0) &&
> - (DEV_ATTRIB(dev)->emulate_fua_write > 0))
> - transport_modesense_dpofua(&buf[2], type);
> -
> - if ((offset + 1) > cmd->data_length)
> - offset = cmd->data_length;
> - }
> - memcpy(rbuf, buf, offset);
> -
> - return 0;
> -}
> -EXPORT_SYMBOL(transport_generic_emulate_modesense);
> -
> -int transport_generic_emulate_request_sense(
> - struct se_cmd *cmd,
> - unsigned char *cdb)
> -{
> - unsigned char *buf = (unsigned char *) T_TASK(cmd)->t_task_buf;
> - u8 ua_asc = 0, ua_ascq = 0;
> -
> - if (cdb[1] & 0x01) {
> - printk(KERN_ERR "REQUEST_SENSE description emulation not"
> - " supported\n");
> - return PYX_TRANSPORT_INVALID_CDB_FIELD;
> - }
> - if (!(core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq))) {
> - /*
> - * CURRENT ERROR, UNIT ATTENTION
> - */
> - buf[0] = 0x70;
> - buf[SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION;
> - /*
> - * Make sure request data length is enough for additional
> - * sense data.
> - */
> - if (cmd->data_length <= 18) {
> - buf[7] = 0x00;
> - return 0;
> - }
> - /*
> - * The Additional Sense Code (ASC) from the UNIT ATTENTION
> - */
> - buf[SPC_ASC_KEY_OFFSET] = ua_asc;
> - buf[SPC_ASCQ_KEY_OFFSET] = ua_ascq;
> - buf[7] = 0x0A;
> - } else {
> - /*
> - * CURRENT ERROR, NO SENSE
> - */
> - buf[0] = 0x70;
> - buf[SPC_SENSE_KEY_OFFSET] = NO_SENSE;
> - /*
> - * Make sure request data length is enough for additional
> - * sense data.
> - */
> - if (cmd->data_length <= 18) {
> - buf[7] = 0x00;
> - return 0;
> - }
> - /*
> - * NO ADDITIONAL SENSE INFORMATION
> - */
> - buf[SPC_ASC_KEY_OFFSET] = 0x00;
> - buf[7] = 0x0A;
> - }
> -
> - return 0;
> -}
> -EXPORT_SYMBOL(transport_generic_emulate_request_sense);
> -
> static void transport_xor_callback(struct se_cmd *cmd)
> {
> unsigned char *buf, *addr;
> @@ -5385,215 +4520,6 @@ int transport_get_sense_data(struct se_c
> return -1;
> }
>
> -/*
> - * Used for TCM/IBLOCK and TCM/FILEIO for block/blk-lib.c level discard support.
> - * Note this is not used for TCM/pSCSI passthrough
> - */
> -static int transport_generic_unmap(struct se_task *task)
> -{
> - struct se_cmd *cmd = TASK_CMD(task);
> - struct se_device *dev = SE_DEV(cmd);
> - unsigned char *buf = T_TASK(cmd)->t_task_buf, *ptr = NULL;
> - unsigned char *cdb = &T_TASK(cmd)->t_task_cdb[0];
> - sector_t lba;
> - unsigned int size = cmd->data_length, range;
> - int ret, offset = 8; /* First UNMAP block descriptor starts at 8 byte offset */
> - unsigned short dl, bd_dl;
> -
> - /* Skip over UNMAP header */
> - size -= 8;
> - dl = get_unaligned_be16(&cdb[0]);
> - bd_dl = get_unaligned_be16(&cdb[2]);
> - ptr = &buf[offset];
> - printk(KERN_INFO "UNMAP: Sub: %s Using dl: %hu bd_dl: %hu size: %hu"
> - " ptr: %p\n", TRANSPORT(dev)->name, dl, bd_dl, size, ptr);
> -
> - while (size) {
> - lba = get_unaligned_be64(&ptr[0]);
> - range = get_unaligned_be32(&ptr[8]);
> - printk(KERN_INFO "UNMAP: Using lba: %llu and range: %u\n",
> - (unsigned long long)lba, range);
> -
> - ret = TRANSPORT(dev)->do_discard(dev, lba, range);
> - if (ret < 0) {
> - printk(KERN_ERR "blkdev_issue_discard() failed: %d\n", ret);
> - return -1;
> - }
> -
> - ptr += 16;
> - size -= 16;
> - }
> -
> - task->task_scsi_status = GOOD;
> - transport_complete_task(task, 1);
> - return 0;
> -}
> -
> -/*
> - * Used for TCM/IBLOCK and TCM/FILEIO for block/blk-lib.c level discard support.
> - * Note this is not used for TCM/pSCSI passthrough
> - */
> -static int transport_generic_write_same(struct se_task *task)
> -{
> - struct se_cmd *cmd = TASK_CMD(task);
> - struct se_device *dev = SE_DEV(cmd);
> - sector_t lba;
> - unsigned int range;
> - int ret;
> -
> - lba = T_TASK(cmd)->t_task_lba;
> - range = (cmd->data_length / DEV_ATTRIB(dev)->block_size);
> -
> - printk(KERN_INFO "WRITE_SAME UNMAP: LBA: %llu Range: %u\n",
> - (unsigned long long)lba, range);
> -
> - ret = TRANSPORT(dev)->do_discard(dev, lba, range);
> - if (ret < 0) {
> - printk(KERN_INFO "blkdev_issue_discard() failed for WRITE_SAME\n");
> - return -1;
> - }
> -
> - task->task_scsi_status = GOOD;
> - transport_complete_task(task, 1);
> - return 0;
> -}
> -
> -/*
> - * Used by TCM subsystem plugins IBLOCK, FILEIO, and RAMDISK as a
> - * generic non SCF_SCSI_DATA_SG_IO_CDB ops.
> - */
> -int transport_emulate_control_cdb(struct se_task *task)
> -{
> - struct se_cmd *cmd = TASK_CMD(task);
> - struct se_device *dev = SE_DEV(cmd);
> - sector_t blocks_long;
> - unsigned int blocks;
> - int ret;
> - unsigned short service_action;
> -
> - switch (T_TASK(cmd)->t_task_cdb[0]) {
> - case INQUIRY:
> - ret = transport_generic_emulate_inquiry(cmd,
> - TRANSPORT(dev)->get_device_type(dev),
> - &DEV_T10_WWN(dev)->model[0],
> - &DEV_T10_WWN(dev)->revision[0]);
> - if (ret < 0)
> - return ret;
> - break;
> - case READ_CAPACITY:
> - blocks = TRANSPORT(dev)->get_blocks(dev);
> - ret = transport_generic_emulate_readcapacity(cmd,
> - blocks);
> - if (ret < 0)
> - return ret;
> - break;
> - case MODE_SENSE:
> - ret = transport_generic_emulate_modesense(TASK_CMD(task),
> - T_TASK(cmd)->t_task_cdb,
> - T_TASK(cmd)->t_task_buf, 0,
> - TRANSPORT(dev)->get_device_type(dev));
> - if (ret < 0)
> - return ret;
> - break;
> - case MODE_SENSE_10:
> - ret = transport_generic_emulate_modesense(TASK_CMD(task),
> - T_TASK(cmd)->t_task_cdb,
> - T_TASK(cmd)->t_task_buf, 1,
> - TRANSPORT(dev)->get_device_type(dev));
> - if (ret < 0)
> - return ret;
> - break;
> - case SERVICE_ACTION_IN:
> - switch (T_TASK(cmd)->t_task_cdb[1] & 0x1f) {
> - case SAI_READ_CAPACITY_16:
> - blocks_long = TRANSPORT(dev)->get_blocks(dev);
> - ret = transport_generic_emulate_readcapacity_16(cmd,
> - blocks_long);
> - if (ret < 0)
> - return ret;
> - break;
> - default:
> - printk(KERN_ERR "Unsupported SA: 0x%02x\n",
> - T_TASK(cmd)->t_task_cdb[1] & 0x1f);
> - return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
> - }
> - case REQUEST_SENSE:
> - ret = transport_generic_emulate_request_sense(cmd,
> - T_TASK(cmd)->t_task_cdb);
> - if (ret < 0)
> - return ret;
> - break;
> - case UNMAP:
> - if (!(TRANSPORT(dev)->do_discard)) {
> - printk(KERN_ERR "UNMAP emulation not supported for: %s\n",
> - TRANSPORT(dev)->name);
> - return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
> - }
> - ret = transport_generic_unmap(task);
> - if (ret < 0)
> - return ret;
> - break;
> - case WRITE_SAME_16:
> - if (!(TRANSPORT(dev)->do_discard)) {
> - printk(KERN_ERR "WRITE_SAME_16 emulation not supported"
> - " for: %s\n", TRANSPORT(dev)->name);
> - return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
> - }
> - ret = transport_generic_write_same(task);
> - if (ret < 0)
> - return ret;
> - break;
> - case VARIABLE_LENGTH_CMD:
> - service_action = get_unaligned_be16(&T_TASK(cmd)->t_task_cdb[8]);
> - switch (service_action) {
> - case WRITE_SAME_32:
> - if (!(TRANSPORT(dev)->do_discard)) {
> - printk(KERN_ERR "WRITE_SAME_32 SA emulation not"
> - " supported for: %s\n", TRANSPORT(dev)->name);
> - return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
> - }
> - ret = transport_generic_write_same(task);
> - if (ret < 0)
> - return ret;
> - break;
> - default:
> - printk(KERN_ERR "Unsupported VARIABLE_LENGTH_CMD SA:"
> - " 0x%02x\n", service_action);
> - break;
> - }
> - break;
> - case SYNCHRONIZE_CACHE:
> - case 0x91: /* SYNCHRONIZE_CACHE_16: */
> - if (!(TRANSPORT(dev)->do_sync_cache)) {
> - printk(KERN_ERR "SYNCHRONIZE_CACHE emulation not supported"
> - " for: %s\n", TRANSPORT(dev)->name);
> - return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
> - }
> - TRANSPORT(dev)->do_sync_cache(task);
> - break;
> - case ALLOW_MEDIUM_REMOVAL:
> - case ERASE:
> - case REZERO_UNIT:
> - case SEEK_10:
> - case SPACE:
> - case START_STOP:
> - case TEST_UNIT_READY:
> - case VERIFY:
> - case WRITE_FILEMARKS:
> - break;
> - default:
> - printk(KERN_ERR "Unsupported SCSI Opcode: 0x%02x for %s\n",
> - T_TASK(cmd)->t_task_cdb[0], TRANSPORT(dev)->name);
> - return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE;
> - }
> -
> - task->task_scsi_status = GOOD;
> - transport_complete_task(task, 1);
> -
> - return PYX_TRANSPORT_SENT_TO_TRANSPORT;
> -}
> -EXPORT_SYMBOL(transport_emulate_control_cdb);
> -
> static inline void transport_dev_get_mem_buf(
> struct se_device *dev,
> struct se_cmd *cmd)
> Index: lio-core-2.6/include/target/target_core_transport.h
> ===================================================================
> --- lio-core-2.6.orig/include/target/target_core_transport.h 2010-11-08 17:06:49.151529680 +0100
> +++ lio-core-2.6/include/target/target_core_transport.h 2010-11-08 17:06:49.221529679 +0100
> @@ -221,16 +221,6 @@ extern void transport_stop_task_timer(st
> extern void transport_stop_all_task_timers(struct se_cmd *);
> extern int transport_execute_tasks(struct se_cmd *);
> extern unsigned char transport_asciihex_to_binaryhex(unsigned char val[2]);
> -extern int transport_generic_emulate_inquiry(struct se_cmd *, unsigned char,
> - unsigned char *, unsigned char *);
> -extern int transport_generic_emulate_readcapacity(struct se_cmd *, u32);
> -extern int transport_generic_emulate_readcapacity_16(struct se_cmd *,
> - unsigned long long);
> -extern int transport_generic_emulate_modesense(struct se_cmd *,
> - unsigned char *,
> - unsigned char *, int, int);
> -extern int transport_generic_emulate_request_sense(struct se_cmd *,
> - unsigned char *);
> extern int transport_get_sense_data(struct se_cmd *);
> extern int transport_emulate_control_cdb(struct se_task *);
> extern struct se_cmd *transport_allocate_passthrough(unsigned char *, int, u32,
> Index: lio-core-2.6/drivers/target/Kbuild
> ===================================================================
> --- lio-core-2.6.orig/drivers/target/Kbuild 2010-11-08 17:07:01.288196347 +0100
> +++ lio-core-2.6/drivers/target/Kbuild 2010-11-08 17:07:18.058196348 +0100
> @@ -11,6 +11,7 @@ target_core_mod-y := target_core_config
> target_core_tmr.o \
> target_core_tpg.o \
> target_core_transport.o \
> + target_core_cdb.o \
> target_core_ua.o \
> target_core_rd.o \
> target_core_mib.o
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 10/9] target: split CDB emulation out of target_core_transport.c
2010-11-08 22:48 ` Nicholas A. Bellinger
@ 2010-11-08 22:57 ` Christoph Hellwig
0 siblings, 0 replies; 23+ messages in thread
From: Christoph Hellwig @ 2010-11-08 22:57 UTC (permalink / raw)
To: Nicholas A. Bellinger; +Cc: Christoph Hellwig, linux-scsi
On Mon, Nov 08, 2010 at 02:48:45PM -0800, Nicholas A. Bellinger wrote:
> On Mon, 2010-11-08 at 12:19 -0500, Christoph Hellwig wrote:
> > Split out the CDB emulation into it's own file, and refactor it along proper
> > boundaries.
> >
> > Signed-off-by: Christoph Hellwig <hch@lst.de>
> >
>
> I think this makes alot sense for the vast majority of the CDB emulation
> code, but I think specifically for the handful of PR and ALUA CDB
> emulation pieces it does make more sense conceptually (and for the sake
> of comments) to keep this code in their respective source files.
>
> Other than those two cases, I am happy to merge this code.
Currently all the code is in target_core_transport.c, so splitting it
out is a good first stuff. Further splitting out PR and ALUA helpers
and moving them to the specific source files seems like a good idea,
though.
Btw, I just noticed this only applies without patch 9 applies. You
should be able to rebase it yourself, if not I'm happy to resend it.
^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2010-11-08 22:57 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-11-08 15:56 [PATCH 0/9] target core review feedback Christoph Hellwig
2010-11-08 15:56 ` [PATCH 1/9] target: remove never changing indirections in se_cmd Christoph Hellwig
2010-11-08 21:57 ` Nicholas A. Bellinger
2010-11-08 15:56 ` [PATCH 2/9] target: remove activate_device/deactivate_device methods Christoph Hellwig
2010-11-08 22:00 ` Nicholas A. Bellinger
2010-11-08 15:56 ` [PATCH 3/9] From: Christoph Hellwig <hch@lst.de> Sujbect: target: remove SHUTDOWN_SIGS Christoph Hellwig
2010-11-08 22:21 ` [PATCH 3/9] " Nicholas A. Bellinger
2010-11-08 22:31 ` Christoph Hellwig
2010-11-08 15:56 ` [PATCH 4/9] target: remove transport_generic_map_buffers_to_tasks Christoph Hellwig
2010-11-08 22:29 ` Nicholas A. Bellinger
2010-11-08 15:56 ` [PATCH 5/9] target: clean up transport_subsystem_register Christoph Hellwig
2010-11-08 22:32 ` Nicholas A. Bellinger
2010-11-08 15:56 ` [PATCH 6/9] target: remove dead blockdevice claim/release code Christoph Hellwig
2010-11-08 22:35 ` Nicholas A. Bellinger
2010-11-08 15:56 ` [PATCH 7/9] target: remove transport_generic_free_device Christoph Hellwig
2010-11-08 22:40 ` Nicholas A. Bellinger
2010-11-08 15:56 ` [PATCH 8/9] target: remove unused split_cdb_RW_* handlers Christoph Hellwig
2010-11-08 22:41 ` Nicholas A. Bellinger
2010-11-08 15:56 ` [PATCH 9/9] target: remove dead call to transport_emulate_control_cdb in rd driver Christoph Hellwig
2010-11-08 22:44 ` Nicholas A. Bellinger
2010-11-08 17:19 ` [PATCH 10/9] target: split CDB emulation out of target_core_transport.c Christoph Hellwig
2010-11-08 22:48 ` Nicholas A. Bellinger
2010-11-08 22:57 ` Christoph Hellwig
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox