+++ /dev/null
- SCST USER SPACE DEVICE HANDLER MODULE.
-
- USER SPACE INTERFACE DESCRIPTION.
-
- Version 1.0.0
-
-
- I. Description.
-
-SCST user space device handler module scst_user is a device handler for
-SCST, which provides a way to implement in the user space complete, full
-feature virtual SCSI devices in the SCST environment.
-
-This document assumes that the reader is familiar with the SCST
-architecture and the states through which SCSI commands go during
-processing in SCST. Module scst_user basically only provides hooks to
-them. Their description could be found on the SCST web page on
-http://scst.st.net.
-
-
- II. User space API.
-
-Module scst_user provides /dev/scst_user character device with the
-following system calls available:
-
- - open() - allows to open the device and get a file handle, which
- will be used in all subsequent actions until close() is called
-
- - close() - closes file handle returned by open()
-
- - poll() - allows to wait until some pending command from SCST to
- process is available.
-
- - ioctl() - main call, which allows commands interchange with the SCST
- core.
-
-Device /dev/scst_user could be opened in blocking or non-blocking mode
-using O_NONBLOCK flag. In the blocking mode ioctl()
-SCST_USER_REPLY_GET_CMD function blocks until there is a new subcommand
-to process. In the non-blocking mode if there are no pending subcommands
-SCST_USER_REPLY_GET_CMD function returns immediately with EAGAIN error
-code, and the user space device handler can use poll() call to get
-notification about new subcommands arrival. The blocking mode is the
-default.
-
-The module scst_user API is defined in scst_user.h file.
-
-
- III. IOCTL() functions.
-
-There are following IOCTL functions available. All of them has one
-argument. They all, except SCST_USER_REGISTER_DEVICE return 0 for
-success or -1 in case of error, and errno is set appropriately.
-
-
- 1. SCST_USER_REGISTER_DEVICE
-
-SCST_USER_REGISTER_DEVICE - registers new virtual user space device. The
-argument is:
-
-struct scst_user_dev_desc
-{
- uint8_t version;
- uint8_t type;
- uint8_t has_own_order_mgmt;
- struct scst_user_opt opt;
- uint32_t block_size;
- char name[SCST_MAX_NAME];
-},
-
-where:
-
- - version - is a protocol version, shall be DEV_USER_VERSION
-
- - type - SCSI type of the device
-
- - has_own_order_mgmt - set it in non-zero, if device implements own
- ORDERED commands management, i.e. guarantees commands execution order
- requirements, specified by SAM.
-
- - opt - device options, see SCST_USER_SET_OPTIONS/SCST_USER_GET_OPTIONS below
-
- - block_size - block size, shall be divisible by 512 for block devices
-
- - name - name of the device
-
-SCST_USER_REGISTER_DEVICE returns registered device's handler or -1
-in case of error, and errno is set appropriately.
-
-In order to unregister the device just call close() on its file descriptor.
-
-
- 3. SCST_USER_SET_OPTIONS/SCST_USER_GET_OPTIONS
-
-SCST_USER_SET_OPTIONS/SCST_USER_GET_OPTIONS allows to set or get
-correspondingly various options that control various aspects of SCSI
-commands processing.
-
-The argument is:
-
-struct scst_user_opt
-{
- uint8_t parse_type;
- uint8_t on_free_cmd_type;
- uint8_t memory_reuse_type;
- uint8_t partial_transfers_type;
- uint32_t partial_len;
-
- uint8_t tst;
- uint8_t queue_alg;
- uint8_t tas;
- uint8_t swp;
-},
-
-where:
-
- - parse_type - defines how the user space handler wants to process
- PARSE subcommand. Possible values are:
-
- * SCST_USER_PARSE_STANDARD - tells SCST use standard internal parser
- for this SCSI device type.
-
- * SCST_USER_PARSE_CALL - tells SCST generate SCST_USER_PARSE for all
- SCSI commands
-
- * SCST_USER_PARSE_EXCEPTION - tells SCST generate SCST_USER_PARSE
- for unknown SCSI commands or SCSI commands that produce errors in
- the standard parser.
-
- - on_free_cmd_type - defines how the user space handler wants to
- process ON_FREE_CMD subcommand. Possible values are:
-
- * SCST_USER_ON_FREE_CMD_CALL - tells SCST generate
- SCST_USER_ON_FREE_CMD for all SCSI commands
-
- * SCST_USER_ON_FREE_CMD_IGNORE - tells SCST do nothing on this event.
-
- - memory_reuse_type - defines how memory allocated by the user space
- handler for a SCSI commands data buffers is then reused by the SCST
- core as data buffer for subsequent commands. Possible values are:
-
- * SCST_USER_MEM_NO_REUSE - no memory reuse is possible, for each
- commands the user space handler will each time allocate a dedicated
- data buffer
-
- * SCST_USER_MEM_REUSE_READ - memory reuse by only READ-type commands
- (i.e. which involve data transfer from target to initiator) is
- allowed. For all WRITE-type commands (i.e. which involves data
- transfer from initiator to target) the user space handler will
- each time allocate a dedicated data buffer
-
- * SCST_USER_MEM_REUSE_WRITE - memory reuse by only WRITE-type
- commands is allowed. For all WRITE-type commands the user space
- handler will each time allocate a dedicated data buffer
-
- * SCST_USER_MEM_REUSE_ALL - unlimited memory reuse is possible.
-
- - partial_transfers_type - defines if the user space handler supports
- partial data transfers, when a SCSI command, which required big data
- transfer, is broken on several subcommands with smaller data
- transfers. This allows to improve performance by simultaneous data
- transfers from/to remote initiator and to/from the underlying storage
- device as well as lower allocation memory requirements for each
- (sub)command. All subcommands will have the same unique value in
- "parent_cmd_h" field and SCST_USER_SUBCOMMAND flag in "partial" field
- of struct scst_user_scsi_cmd_exec. The final subcommand will also
- have in that field SCST_USER_SUBCOMMAND_FINAL flag. All the
- subcommands will have the original unmodified CDB. Possible values
- are:
-
- * SCST_USER_PARTIAL_TRANSFERS_NOT_SUPPORTED - the partial data
- transfers are not supported
-
- * SCST_USER_PARTIAL_TRANSFERS_SUPPORTED_ORDERED - the partial data
- transfers are supported, but all the subcommands must come in order
- of data chunks. Could be used, e.g., for tape devices.
-
- * SCST_USER_PARTIAL_TRANSFERS_SUPPORTED - the partial data transfers
- are supported without limitations.
-
- - tst, queue_alg, tas and swp - set values for TST, QUEUE ALGORITHM MODIFIER,
- TAS and SWP fields from control mode page correspondingly, see SPC.
-
-Flags parse_type and on_free_cmd_type are designed to improve
-performance by eliminating context switches to the user space handler,
-when processing of the corresponding events isn't needed.
-
-Flag memory_reuse_type is designed to improve performance by eliminating
-memory allocation, preparation and then freeing each time for each
-commands, if the same memory will be allocated again and again. See
-SCST_USER_ALLOC_MEM description below for more info.
-
-SCST_USER_SET_OPTIONS should not be used from the same and the only
-thread, which also handles incoming commands, otherwise there could be a
-"deadlock", when SCST_USER_SET_OPTIONS waits for active commands finish,
-but nobody handles them. This "deadlock" will be resolved only when
-initiator, which sent those commands, aborts them after timeout.
-
-
- 4. SCST_USER_REPLY_AND_GET_CMD
-
-SCST_USER_REPLY_AND_GET_CMD allows at one call reply on the current
-subcommand from SCST and get the next one. If 0 is returned by ioctl(),
-SCST_USER_REPLY_AND_GET_CMD returns a SCST subcommand in the argument,
-which is defined as the following:
-
-struct scst_user_get_cmd
-{
- uint64_t preply;
- uint32_t cmd_h;
- uint32_t subcode;
- union {
- struct scst_user_sess sess;
- struct scst_user_scsi_cmd_parse parse_cmd;
- struct scst_user_scsi_cmd_alloc_mem alloc_cmd;
- struct scst_user_scsi_cmd_exec exec_cmd;
- struct scst_user_scsi_on_free_cmd on_free_cmd;
- struct scst_user_on_cached_mem_free on_cached_mem_free;
- struct scst_user_tm tm_cmd;
- };
-},
-
-where:
-
- - preply - pointer to the reply data or, if 0, there is no reply. See
- SCST_USER_REPLY_CMD for description of struct scst_user_reply_cmd
- fields
-
- - cmd_h - command handle used to identify the command in the reply.
-
- - subcode - subcommand code, see 4.1 below
-
-Union contains command's specific payload.
-
-For all received subcommands the user space device handler shall call
-SCST_USER_REPLY_AND_GET_CMD or SCST_USER_REPLY_CMD function to tell SCST
-that the subcommand's processing is finished, although some subcommands
-don't return a value.
-
-
- 4.1. Possible subcommands:
-
-
- 4.1.1. SCST_USER_ATTACH_SESS
-
-SCST_USER_ATTACH_SESS notifies the user space handler that a new
-initiator's session is about to be attached to the device. Payload
-contains struct scst_user_sess, which is defined as the following:
-
-struct scst_user_sess
-{
- uint64_t sess_h;
- uint64_t lun;
- uint16_t threads_num;
- uint8_t rd_only;
- char initiator_name[SCST_MAX_NAME];
-},
-
-where:
-
- - sess_h - session's handle, may not be 0
-
- - lun - assigned LUN for this device in this session
-
- - threads_num - specifies amount of additional threads, requested by
- the corresponding target driver
-
- - rd_only - if true, this device is read only in this session
-
- - initiator_name - name of the remote initiator, which initiated this
- session
-
-When SCST_USER_ATTACH_SESS is returned, it is guaranteed that there are
-no other commands are being executed or pending.
-
-After SCST_USER_ATTACH_SESS function completed, the user space device
-handler shall reply using "result" field of the corresponding reply
-command.
-
-
- 4.1.2. SCST_USER_DETACH_SESS
-
-SCST_USER_DETACH_SESS notifies the user space handler that the
-corresponding initiator is about to be detached from the particular
-device. Payload contains struct scst_user_sess, where only handle field
-is valid.
-
-When SCST_USER_DETACH_SESS is returned, it is guaranteed that there are
-no other commands are being executed or pending.
-
-This command doesn't reply any return value, although
-SCST_USER_REPLY_AND_GET_CMD or SCST_USER_REPLY_CMD function must be
-called.
-
-
- 4.1.3. SCST_USER_PARSE
-
-SCST_USER_PARSE returns SCSI command on PARSE state of the SCST
-processing. The PARSE state is intended to check validity of the
-command, determine data transfer type and the necessary data buffer
-size. This subcommand is returned only if SCST_USER_SET_OPTIONS
-parse_type isn't set to SCST_USER_PARSE_STANDARD. In this case the
-standard SCST internal parser for this SCSI device type will do all the
-job.
-
-Payload contains struct scst_user_scsi_cmd_parse, which is defined as
-the following:
-
-struct scst_user_scsi_cmd_parse
-{
- uint64_t sess_h;
-
- uint8_t cdb[SCST_MAX_CDB_SIZE];
- int32_t cdb_len;
-
- uint32_t timeout;
- int32_t bufflen;
-
- uint8_t queue_type;
- uint8_t data_direction;
-
- uint8_t expected_values_set;
- uint8_t expected_data_direction;
- int32_t expected_transfer_len;
-
- uint32_t sn;
-},
-
-where:
-
- - sess_h - corresponding session handler
-
- - cdb - SCSI CDB
-
- - cdb_len - SCSI CDB length
-
- - timeout - CDB execution timeout
-
- - bufflen - command's buffer length
-
- - queue_type - SCSI task attribute (queue type)
-
- - data_direction - command's data flow direction, one of SCST_DATA_*
- constants
-
- - expected_values_set - true if expected_data_direction and
- expected_transfer_len contain valid values
-
- - expected_data_direction - remote initiator supplied command's data
- flow direction
-
- - expected_transfer_len - remote initiator supplied transfer length
-
- - sn - command's SN, which might be used for task management
-
-In the PARSE state of SCSI commands processing the user space device
-handler shall check and provide SCST values for command data buffer
-length, data flow direction and timeout, which it shall reply using the
-corresponding reply command.
-
-In case of any error the error reporting should be deferred until
-SCST_USER_EXEC subcommand, where the appropriate SAM status and sense
-shall be set.
-
-
- 4.4.4. SCST_USER_ALLOC_MEM
-
-SCST_USER_ALLOC_MEM returns SCSI command on memory allocation state of
-the SCST processing. On this state the user space device handler shall
-allocate the command's data buffer with bufflen length and then return
-it to SCST using the corresponding reply command. Then SCST internally
-will convert it in SG vector in order to use it itself and by target
-drivers.
-
-If the memory reuse type is disabled (i.e. set to SCST_USER_MEM_NO_REUSE)
-there are no special requirements for buffer memory or its alignment, it
-could be just what malloc() returned. If the memory reuse type is enabled,
-the buffer shall be page size aligned, for example using memalign()
-function.
-
-Payload contains struct scst_user_scsi_cmd_alloc_mem, which is defined
-as the following:
-
-struct scst_user_scsi_cmd_alloc_mem
-{
- uint64_t sess_h;
-
- uint8_t cdb[SCST_MAX_CDB_SIZE];
- int32_t cdb_len;
-
- int32_t alloc_len;
-
- uint8_t queue_type;
- uint8_t data_direction;
-
- uint32_t sn;
-},
-
-where:
-
- - sess_h - corresponding session handler
-
- - cdb - SCSI CDB
-
- - cdb_len - SCSI CDB length
-
- - alloc_len - command's buffer length
-
- - queue_type - SCSI task attribute (queue type )
-
- - data_direction - command's data flow direction, one of SCST_DATA_*
- constants
-
- - sn - command's SN, which might be used for task management
-
-Memory allocation, preparation and freeing are ones of the most
-complicated and expensive operations during SCSI commands processing.
-Module scst_user provides a way to almost completely eliminate those
-operations by reusing once allocated memory for subsequent SCSI
-commands. It is controlled by memory_reuse_type option, which could be
-set by SCST_USER_SET_OPTIONS function. If any type memory reusage is
-enabled, then SCST will use its internal SGV cache in order to cache
-allocated and fully built SG vectors for subsequent commands of this
-type, so for them SCST_USER_ALLOC_MEM subfunction will not be called and
-in SCST_USER_EXEC pbuf pointer will point to that reused buffer.
-
-SGV cache is a backend cache made on top of Linux kernel SLAB cache. It
-caches SG vectors with power of 2 data sizes: 4K, 8K, ..., 4M. So, if
-there is a 5K SCSI command coming, then the user space handler will be
-asked for 8K allocation, from which only 5K will be used for this
-particular SCSI command. Then that SG vector will be cached and
-subsequently reused for all SCSI commands between 4K and 8K. For a 1M
-SCSI command the user space handler will be asked for another buffer
-(while the previous 5K one will be kept), which will not be then reused
-for 5K SCSI commands, since 1M and 5K vectors belong to different cache
-data sizes, it will be reused only for commands between 512K and 1M.
-Then, after some time of inactivity or when the system is under memory
-pressure, the cache entries will be freed and the user space handler
-will be notified using SCST_USER_ON_CACHED_MEM_FREE.
-
-Since SGV cache caches SG vectors with power of 2 data sizes, alloc_len
-field could be up to 2 times more, than actually required by the SCSI
-command.
-
-The memory reuse could be used in both SCSI tagged and untagged queuing
-environments. In the SCSI tagged queuing environment the SGV cache will
-take care that several commands don't use the same buffer simultaneously
-by asking the user space handler to allocate a new data buffer, when all
-cached ones are busy.
-
-Some important notes:
-
-1. If the user space handler needs to call fork(), it must call
-madvise() with MADV_DONTFORK flag for all allocated data buffers,
-otherwise parent or child process could loose the connection with them,
-which could lead to data corruption. See http://lwn.net/Articles/171941/
-for details.
-
-2. The interface assumes that all allocated memory by the user space
-handler is DMA'able by the target hardware. This is almost always true
-for most modern systems, except if the target hardware isn't capable of
-using 64-bit address space and the system has >4GB of memory or the
-memory addresses are in address space, which is unavailable with 32-bit
-addresses.
-
-In case of any error the error reporting should be deferred until
-SCST_USER_EXEC subcommand, where the appropriate SAM status and sense
-should be set.
-
-
- 4.4.5. SCST_USER_EXEC
-
-SCST_USER_EXEC returns SCSI command on execution state of the SCST
-processing. The user space handler should execute the SCSI command and
-reply using the corresponding reply command.
-
-In some cases for performance reasons for READ-type SCSI commands
-SCST_USER_ALLOC_MEM subcommand isn't returned before SCST_USER_EXEC.
-Thus, if pbuf pointer is 0 and the SCSI command needs data transfer,
-the user space handler should be prepared to allocate the data buffer
-with size alloc_len, which could be up to 2 times more, than actually
-required by the SCSI command. But field bufflen will contain the correct
-value. All the memory reusage rules, described for SCST_USER_ALLOC_MEM,
-apply to SCST_USER_EXEC as well.
-
-Payload contains struct scst_user_scsi_cmd_exec, which is defined as the
-following:
-
-struct scst_user_scsi_cmd_exec
-{
- uint64_t sess_h;
-
- uint8_t cdb[SCST_MAX_CDB_SIZE];
- int32_t cdb_len;
-
- int32_t data_len;
- int32_t bufflen;
- int32_t alloc_len;
- uint64_t pbuf;
- uint8_t queue_type;
- uint8_t data_direction;
- uint8_t partial;
- uint32_t timeout;
-
- uint32_t sn;
-
- uint32_t parent_cmd_h;
- int32_t parent_cmd_data_len;
- uint32_t partial_offset;
-},
-
-where:
-
- - sess_h - corresponding session handler
-
- - cdb - SCSI CDB
-
- - cdb_len - SCSI CDB length
-
- - data_len - command's data length. Could be different from bufflen for
- commands like VERIFY, which transfer different amount of data, than
- process, or even none of them
-
- - bufflen - command's buffer length
-
- - alloc_len - command's buffer length, which should be allocated, if pbuf
- is 0 and the command requires data transfer
-
- - pbuf - pointer to command's data buffer or 0 for SCSI commands
- without data transfer.
-
- - queue_type - SCSI task attribute (queue type)
-
- - data_direction - command's data flow direction, one of SCST_DATA_*
- constants
-
- - partial - specifies, if the command is a partial subcommand, could
- have the following OR'ed flags:
-
- * SCST_USER_SUBCOMMAND - set if the command is a partial subcommand
-
- * SCST_USER_SUBCOMMAND_FINAL - set if the subcommand is a final one
-
- - timeout - CDB execution timeout
-
- - sn - command's SN, which might be used for task management
-
- - parent_cmd_h - has the same unique value for all partial data
- transfers subcommands of one original (parent) command
-
- - parent_cmd_data_len - for partial data transfers subcommand has the
- size of the overall data transfer of the original (parent) command
-
- - partial_offset - has offset of the subcommand in the original
- (parent) command
-
-It is guaranteed that only commands of the same queue_type per session
-can be returned simultaneously.
-
-In case of any error it should be reported via appropriate SAM status
-and sense. If it happens for a subcommand of a partial data transfers
-command, all other subcommands of this command, which already passed the
-the user space handler or will be passed in the future, will be aborted
-by scst_user, the user space handler should ignore them.
-
-
- 4.4.6. SCST_USER_ON_FREE_CMD
-
-SCST_USER_ON_FREE_CMD returns SCSI command when the command is about to
-be freed. At this stage, the user space device handler could do any
-necessary cleanups, for instance, free allocated for data buffer memory.
-
-NOTE! If the memory reusage is enabled, then the data buffer must not be
-freed, it will be reused by subsequent SCSI commands. The buffer must be
-freed only on SCST_USER_ON_CACHED_MEM_FREE event.
-
-Payload contains struct scst_user_scsi_on_free_cmd, which is defined
-as the following:
-
-struct scst_user_scsi_on_free_cmd
-{
- uint64_t pbuf;
- int32_t resp_data_len;
- uint8_t buffer_cached;
- uint8_t aborted;
- uint8_t status;
- uint8_t delivery_status;
-},
-
-where:
-
- - pbuf - pointer to command's data buffer or 0 for SCSI commands
- without data transfer.
-
- - resp_data_len - length of the response data
-
- - buffer_cached - true, if memory reusage is enabled for this command
-
- - aborted - true, if command was aborted
-
- - status - SAM status of the commands execution
-
- - delivery_status - status of cmd's status/data delivery to remote
- initiator. Can be:
-
- * SCST_CMD_DELIVERY_SUCCESS - delivery succeeded
-
- * SCST_CMD_DELIVERY_FAILED - delivery failed
-
-The user space handler should reply using the corresponding reply
-command. No error code is needed.
-
-
- 4.4.7. SCST_USER_ON_CACHED_MEM_FREE
-
-SCST_USER_ON_CACHED_MEM_FREE subcommand is returned, when SGV cache
-decided that this buffer isn't needed anymore. This happens after some
-time of inactivity or when the system is under memory pressure.
-
-Payload contains struct scst_user_on_cached_mem_free, which is defined
-as the following:
-
-struct scst_user_scsi_cmd_alloc_mem
-{
- uint64_t pbuf;
-},
-
-where:
-
- - pbuf - pointer to buffer, which should be freed
-
-
- 4.4.8. SCST_USER_TASK_MGMT
-
-SCST_USER_TASK_MGMT subcommand returns a task management functions.
-Payload contains struct scst_user_tm, which is defined as the following:
-
-struct scst_user_tm
-{
- uint64_t sess_h;
- uint32_t fn;
- uint32_t cmd_h_to_abort;
- uint32_t cmd_sn;
- uint8_t cmd_sn_set;
-},
-
-where:
-
- - sess_h - corresponding session handler
-
- - fn - task management function, see below
-
- - cmd_h_to_abort - handle of command to abort. Valid only if fn is
- SCST_ABORT_TASK
-
- - cmd_sn - if cmd_sn_set is set, contains maximum commands SN, which
- this task management function affects. See iSCSI RFC 3720 10.5.1 for
- more details.
-
- - cmd_sn_set - specifies if cmd_sn is valid
-
-After TM function is completed, the user space device handler shall
-reply using "result" field of the corresponding reply command. It isn't
-necessary to wait for aborted command(s) finished, the result of TM
-function shall be returned immediately. SCST core will take care that
-the reply to the TM function isn't sent before all affection SCSI
-commands finished.
-
-Possible values of "fn" field:
-
- - SCST_ABORT_TASK - cmd_h_to_abort shall be aborted
-
- - SCST_ABORT_TASK_SET - task set on the device shall be aborted
-
- - SCST_CLEAR_ACA - ACA status shall be cleared
-
- - SCST_CLEAR_TASK_SET - task set on the device shall be cleared
-
- - SCST_LUN_RESET, SCST_TARGET_RESET - reset of the device shall be done
-
- - SCST_NEXUS_LOSS_SESS - notifies about nexus loss event for the session
-
- - SCST_ABORT_ALL_TASKS_SESS - all tasks in the session shall be aborted
-
- - SCST_NEXUS_LOSS - notifies about global nexus loss event
-
- - SCST_ABORT_ALL_TASKS - all tasks shall be aborted
-
-Possible return values are:
-
- - SCST_MGMT_STATUS_SUCCESS - success
-
- - SCST_MGMT_STATUS_TASK_NOT_EXIST - task does not exist
-
- - SCST_MGMT_STATUS_LUN_NOT_EXIST - LUN does not exist
-
- - SCST_MGMT_STATUS_FN_NOT_SUPPORTED - task management function not
- supported
-
- - SCST_MGMT_STATUS_REJECTED - task management function was rejected
-
- - SCST_MGMT_STATUS_FAILED - task management function failed
-
-
-
- 5. SCST_USER_REPLY_CMD
-
-SCST_USER_REPLY_CMD IOCTL function allows the user space handler to
-return the result of a command's execution. Its argument is defined as:
-
-struct scst_user_reply_cmd
-{
- uint32_t cmd_h;
- uint32_t subcode;
- union {
- int32_t result;
- struct scst_user_scsi_cmd_reply_parse parse_reply;
- struct scst_user_scsi_cmd_reply_alloc_mem alloc_reply;
- struct scst_user_scsi_cmd_reply_exec exec_reply;
- };
-},
-
-where:
-
- - cmd_h - command handle used to identify the command in the reply.
-
- - subcode - subcommand code, see 4.1
-
-Union contains the subcommand's specific payload:
-
- - result - subcommand's result code
-
-
-struct scst_user_scsi_cmd_reply_parse
-{
- uint8_t queue_type;
- uint8_t data_direction;
- int32_t data_len;
- int32_t bufflen;
-},
-
-where:
-
- - queue_type - SCSI task attribute (queue type )
-
- - data_direction - command's data flow direction, one of SCST_DATA_* constants
-
- - data_len - command's data length
-
- - bufflen - command's buffer length
-
-
-struct scst_user_scsi_cmd_reply_alloc_mem
-{
- uint64_t pbuf;
-},
-
-where:
-
- - pbuf - pointer to command's data buffer
-
-
-struct scst_user_scsi_cmd_reply_exec
-{
- int32_t resp_data_len;
- uint64_t pbuf;
-
- uint8_t reply_type;
-
- uint8_t status;
- uint8_t sense_len;
- aligned_u64 psense_buffer;
-},
-
-where:
-
- - resp_data_len - length of the response data
-
- - pbuf - pointer to command's data buffer. Used only when in the
- original SCST_USER_EXEC subcommand pbuf field is 0
-
- - reply_type - could be one of the following constants:
-
- * SCST_EXEC_REPLY_BACKGROUND - tells SCST send to the remote
- initiator GOOD status, but the command not yet completed by the
- user space handler, it is being executed in the background. When
- it will be completed, the user space handler will call
- SCST_USER_REPLY_CMD again with reply_type
- SCST_EXEC_REPLY_COMPLETED.
-
- * SCST_EXEC_REPLY_COMPLETED - the user space handler completed the command
-
- - status - SAM status of the commands execution
-
- - sense_len - length of sense data in psense_buffer, if any
-
- - psense_buffer - pointed to sense buffer
-
-
- IV. Commands processing flow example.
-
-As the example consider a simple synchronous VTL, which serves one
-virtual SCSI tape device and can process only one command at time from
-any initiator.
-
-At the beginning the VTL opens using open() call /dev/scst_user in the
-default blocking mode.
-
-Then it using SCST_USER_REGISTER_DEVICE ioctl() function registers the
-tape device. Since only one command at time is supported, the allocated
-command's data memory could be reused for both READ-type (i.e. which
-involve data transfer from target to initiator) and WRITE-type (i.e.
-which involve data transfer from initiator to target) commands. So the
-device is configured with parse_type SCST_USER_PARSE_STANDARD,
-on_free_cmd_type SCST_USER_ON_FREE_CMD_IGNORE, memory_reuse_type
-SCST_USER_MEM_REUSE_ALL and partial_transfers_type
-SCST_USER_PARTIAL_TRANSFERS_NOT_SUPPORTED.
-
-Then it prepares struct scst_user_get_cmd with reply set to 0, calls
-SCST_USER_REPLY_AND_GET_CMD ioctl() and waits until some initiator
-connects to its tape device. On that event the VTL receives
-SCST_USER_ATTACH_SESS subcommand. Since the VTL doesn't use any
-initiator specific data, it can do nothing on that subcommand, so it
-prepares scst_user_reply_cmd structure, where:
-
- - cmd_h set to returned by SCST_USER_REPLY_AND_GET_CMD ioctl() cmd_h
-
- - subcode set to SCST_USER_ATTACH_SESS
-
- - result set to 0
-
-Then it prepares struct scst_user_get_cmd with reply set to the prepared
-scst_user_reply_cmd structure, calls SCST_USER_REPLY_AND_GET_CMD ioctl()
-and waits for some SCSI command arrives from the initiator.
-
-If the received SCSI command is READ-type one, SCST does the necessary
-preparations, then the VTL receives SCST_USER_EXEC subcommand, where
-bufflen and data_len are set correctly, but memory for buffer isn't
-allocated, so pbuf field is 0. The VTL then allocates the data buffer
-with size alloc_len, e.g. using malloc(). Then the VTL reads the data
-from disk in it, e.g. using O_DIRECT read() function, then prepares
-scst_user_reply_cmd structure, where:
-
- - cmd_h set to returned by SCST_USER_REPLY_AND_GET_CMD ioctl() cmd_h
-
- - subcode set to SCST_USER_EXEC
-
- - exec_reply.resp_data_len set to length of the read data
-
- - exec_reply.pbuf set to the data buffer, where the data were read
-
- - exec_reply.reply_type set to SCST_EXEC_REPLY_COMPLETED
-
- - exec_reply.status set to the SAM defined status of the
- operation
-
- - exec_reply.sense_len set and exec_reply.psense_buffer filled with
- sense data, if necessary
-
-Then it prepares struct scst_user_get_cmd with reply set to the prepared
-scst_user_reply_cmd structure, calls SCST_USER_REPLY_AND_GET_CMD ioctl()
-and waits for the next SCSI command arrives from the initiator. That's
-all for this SCSI command. For the next one the used data buffer will be
-reused.
-
-For WRITE-type SCSI commands the processing is the same, but
-SCST_USER_ALLOC_MEM will be returned before SCST_USER_EXEC, since the
-data transfer from the initiator precedes the commands execution.
-
-In case, if the first command requires 4K data buffer, but the second
-one - 1M, for it the VTL also will be asked to allocate the buffer.
-Then, if no more 4K commands come for some time, for it
-SCST_USER_ON_CACHED_MEM_FREE subcommand will be returned to the VTL in
-order to ask it to free that buffer.
-
-Vladislav Bolkhovitin