/* * include/scst_user.h * * Copyright (C) 2007 - 2018 Vladislav Bolkhovitin * Copyright (C) 2007 - 2018 Western Digital Corporation * * Contains constants and data structures for scst_user module. * See http://scst.sourceforge.net/doc/scst_user_spec.txt or * scst_user_spec.txt for description. * * 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, version 2 * of the License. * * 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. */ #ifndef __SCST_USER_H #define __SCST_USER_H #ifdef INSIDE_KERNEL_TREE #include #else #include #endif #define DEV_USER_NAME "scst_user" #define DEV_USER_PATH "/dev/" #define DEV_USER_VERSION_NAME SCST_VERSION_NAME #define DEV_USER_VERSION \ DEV_USER_VERSION_NAME DEV_USER_INTF_VER SCST_CONST_VERSION #define SCST_USER_PARSE_STANDARD 0 #define SCST_USER_PARSE_CALL 1 #define SCST_USER_PARSE_EXCEPTION 2 #define SCST_USER_MAX_PARSE_OPT SCST_USER_PARSE_EXCEPTION #define SCST_USER_ON_FREE_CMD_CALL 0 #define SCST_USER_ON_FREE_CMD_IGNORE 1 #define SCST_USER_MAX_ON_FREE_CMD_OPT SCST_USER_ON_FREE_CMD_IGNORE #define SCST_USER_MEM_NO_REUSE 0 #define SCST_USER_MEM_REUSE_READ 1 #define SCST_USER_MEM_REUSE_WRITE 2 #define SCST_USER_MEM_REUSE_ALL 3 #define SCST_USER_MAX_MEM_REUSE_OPT SCST_USER_MEM_REUSE_ALL #define SCST_USER_PARTIAL_TRANSFERS_NOT_SUPPORTED 0 #define SCST_USER_PARTIAL_TRANSFERS_SUPPORTED_ORDERED 1 #define SCST_USER_PARTIAL_TRANSFERS_SUPPORTED 2 #define SCST_USER_MAX_PARTIAL_TRANSFERS_OPT \ SCST_USER_PARTIAL_TRANSFERS_SUPPORTED #ifndef __KERNEL__ #define aligned_u64 uint64_t __attribute__((aligned(8))) #endif #ifndef aligned_i64 #define aligned_i64 int64_t __attribute__((aligned(8))) #endif /************************************************************* ** Private ucmd states *************************************************************/ #define UCMD_STATE_NEW 0 #define UCMD_STATE_PARSING 1 #define UCMD_STATE_BUF_ALLOCING 2 #define UCMD_STATE_EXECING 3 #define UCMD_STATE_ON_FREEING 4 #define UCMD_STATE_ON_CACHE_FREEING 5 #define UCMD_STATE_EXT_COPY_REMAPPING 6 #define UCMD_STATE_ON_FREE_SKIPPED 7 #define UCMD_STATE_TM_RECEIVED_EXECING 8 #define UCMD_STATE_TM_DONE_EXECING 9 #define UCMD_STATE_ATTACH_SESS 0x20 #define UCMD_STATE_DETACH_SESS 0x21 struct scst_user_opt { uint8_t parse_type; uint8_t on_free_cmd_type; uint8_t memory_reuse_type; uint8_t partial_transfers_type; int32_t partial_len; /* SCSI control mode page parameters, see SPC */ uint8_t tst; uint8_t tmf_only; uint8_t queue_alg; uint8_t qerr; uint8_t tas; uint8_t swp; uint8_t d_sense; uint8_t has_own_order_mgmt; uint8_t ext_copy_remap_supported; }; struct scst_user_dev_desc { aligned_u64 version_str; aligned_u64 license_str; uint8_t type; uint8_t sgv_shared; uint8_t sgv_disable_clustered_pool; int32_t sgv_single_alloc_pages; int32_t sgv_purge_interval; struct scst_user_opt opt; uint32_t block_size; uint8_t enable_pr_cmds_notifications; char name[SCST_MAX_NAME]; char sgv_name[SCST_MAX_NAME]; }; struct scst_user_sess { aligned_u64 sess_h; aligned_u64 lun; uint16_t threads_num; uint8_t rd_only; uint16_t scsi_transport_version; uint16_t phys_transport_version; char initiator_name[SCST_MAX_EXTERNAL_NAME]; char target_name[SCST_MAX_EXTERNAL_NAME]; }; struct scst_user_scsi_cmd_parse { aligned_u64 sess_h; uint8_t cdb[SCST_MAX_CDB_SIZE]; uint16_t cdb_len; aligned_i64 lba; aligned_i64 data_len; int32_t bufflen; int32_t out_bufflen; int32_t timeout; uint32_t op_flags; uint8_t queue_type; uint8_t data_direction; uint8_t expected_values_set; uint8_t expected_data_direction; int32_t expected_transfer_len; int32_t expected_out_transfer_len; uint32_t sn; }; struct scst_user_scsi_cmd_alloc_mem { aligned_u64 sess_h; uint8_t cdb[SCST_MAX_CDB_SIZE]; uint16_t cdb_len; int32_t alloc_len; uint8_t queue_type; uint8_t data_direction; uint32_t sn; }; struct scst_user_scsi_cmd_exec { aligned_u64 sess_h; uint8_t cdb[SCST_MAX_CDB_SIZE]; uint16_t cdb_len; aligned_i64 lba; aligned_i64 data_len; int32_t bufflen; int32_t alloc_len; aligned_u64 pbuf; uint8_t queue_type; uint8_t data_direction; uint8_t partial; int32_t timeout; aligned_u64 p_out_buf; int32_t out_bufflen; uint32_t sn; uint32_t parent_cmd_h; int32_t parent_cmd_data_len; uint32_t partial_offset; }; struct scst_user_scsi_on_free_cmd { aligned_u64 pbuf; int32_t resp_data_len; uint8_t buffer_cached; uint8_t aborted; uint8_t status; uint8_t delivery_status; }; struct scst_user_on_cached_mem_free { aligned_u64 pbuf; }; struct scst_user_tm { aligned_u64 sess_h; uint32_t fn; uint32_t cmd_h_to_abort; uint32_t cmd_sn; uint8_t cmd_sn_set; }; struct scst_user_ext_copy_data_descr { aligned_u64 src_lba; aligned_u64 dst_lba; int32_t data_len; /* in bytes */ }; struct scst_user_ext_copy_remap { aligned_u64 sess_h; aligned_u64 src_sess_h; aligned_u64 dst_sess_h; struct scst_user_ext_copy_data_descr data_descr; }; struct scst_user_get_cmd { uint32_t cmd_h; uint32_t subcode; union { aligned_u64 preply; 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; struct scst_user_ext_copy_remap remap_cmd; }; }; /* Be careful adding new members here, this structure is allocated on stack! */ struct scst_user_scsi_cmd_reply_parse { uint8_t status; union { struct { uint8_t queue_type; uint8_t data_direction; uint16_t cdb_len; aligned_i64 lba; aligned_i64 data_len; int32_t bufflen; uint32_t op_flags; int32_t out_bufflen; }; struct { uint8_t sense_len; aligned_u64 psense_buffer; }; }; }; /* Be careful adding new members here, this structure is allocated on stack! */ struct scst_user_scsi_cmd_reply_alloc_mem { aligned_u64 pbuf; }; /* * Same as struct scst_data_descriptor, but suitable to pass kernel/user * space boundary */ struct scst_user_data_descriptor { aligned_u64 usdd_lba; aligned_u64 usdd_blocks; }; /* Be careful adding new members here, this structure is allocated on stack! */ struct scst_user_scsi_cmd_reply_exec { int32_t resp_data_len; aligned_u64 pbuf; #define SCST_EXEC_REPLY_BACKGROUND 0 #define SCST_EXEC_REPLY_COMPLETED 1 #define SCST_EXEC_REPLY_DO_WRITE_SAME 2 uint8_t reply_type; uint8_t status; union { struct { uint8_t sense_len; aligned_u64 psense_buffer; }; struct { uint16_t ws_descriptors_len; aligned_u64 ws_descriptors; }; }; }; /* Be careful adding new members here, this structure is allocated on stack! */ struct scst_user_ext_copy_reply_remap { aligned_u64 remap_descriptors; uint16_t remap_descriptors_len; uint8_t status; uint8_t sense_len; aligned_u64 psense_buffer; }; /* Be careful adding new members here, this structure is allocated on stack! */ 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; struct scst_user_ext_copy_reply_remap remap_reply; }; }; /* Be careful adding new members here, this structure is allocated on stack! */ struct scst_user_get_ext_cdb { uint32_t cmd_h; aligned_u64 ext_cdb_buffer; }; /* Be careful adding new members here, this structure is allocated on stack! */ struct scst_user_prealloc_buffer_in { aligned_u64 pbuf; uint32_t bufflen; uint8_t for_clust_pool; }; /* Be careful adding new members here, this structure is allocated on stack! */ struct scst_user_prealloc_buffer_out { uint32_t cmd_h; }; /* Be careful adding new members here, this structure is allocated on stack! */ union scst_user_prealloc_buffer { struct scst_user_prealloc_buffer_in in; struct scst_user_prealloc_buffer_out out; }; struct scst_user_get_multi { aligned_u64 preplies; /* in */ int16_t replies_cnt; /* in */ int16_t replies_done; /* out */ int16_t cmds_cnt; /* in/out */ int16_t pad; struct scst_user_get_cmd cmds[0]; /* out */ }; #define SCST_USER_REGISTER_DEVICE _IOW('u', 1, struct scst_user_dev_desc) #define SCST_USER_UNREGISTER_DEVICE _IO('u', 2) #define SCST_USER_SET_OPTIONS _IOW('u', 3, struct scst_user_opt) #define SCST_USER_GET_OPTIONS _IOR('u', 4, struct scst_user_opt) #define SCST_USER_REPLY_AND_GET_CMD _IOWR('u', 5, struct scst_user_get_cmd) #define SCST_USER_REPLY_CMD _IOW('u', 6, struct scst_user_reply_cmd) #define SCST_USER_FLUSH_CACHE _IO('u', 7) #define SCST_USER_DEVICE_CAPACITY_CHANGED _IO('u', 8) #define SCST_USER_GET_EXTENDED_CDB _IOWR('u', 9, struct scst_user_get_ext_cdb) #define SCST_USER_PREALLOC_BUFFER _IOWR('u', 10, union scst_user_prealloc_buffer) #define SCST_USER_REPLY_AND_GET_MULTI _IOWR('u', 11, struct scst_user_get_multi) /* Values for scst_user_get_cmd.subcode */ #define SCST_USER_ATTACH_SESS \ _IOR('s', UCMD_STATE_ATTACH_SESS, struct scst_user_sess) #define SCST_USER_DETACH_SESS \ _IOR('s', UCMD_STATE_DETACH_SESS, struct scst_user_sess) #define SCST_USER_PARSE \ _IOWR('s', UCMD_STATE_PARSING, struct scst_user_scsi_cmd_parse) #define SCST_USER_ALLOC_MEM \ _IOWR('s', UCMD_STATE_BUF_ALLOCING, struct scst_user_scsi_cmd_alloc_mem) #define SCST_USER_EXEC \ _IOWR('s', UCMD_STATE_EXECING, struct scst_user_scsi_cmd_exec) #define SCST_USER_ON_FREE_CMD \ _IOR('s', UCMD_STATE_ON_FREEING, struct scst_user_scsi_on_free_cmd) #define SCST_USER_ON_CACHED_MEM_FREE \ _IOR('s', UCMD_STATE_ON_CACHE_FREEING, \ struct scst_user_on_cached_mem_free) #define SCST_USER_TASK_MGMT_RECEIVED \ _IOWR('s', UCMD_STATE_TM_RECEIVED_EXECING, struct scst_user_tm) #define SCST_USER_TASK_MGMT_DONE \ _IOWR('s', UCMD_STATE_TM_DONE_EXECING, struct scst_user_tm) #define SCST_USER_EXT_COPY_REMAP \ _IOWR('s', UCMD_STATE_EXT_COPY_REMAPPING, struct scst_user_ext_copy_remap) #endif /* __SCST_USER_H */