diff options
Diffstat (limited to 'include/target')
| -rw-r--r-- | include/target/iscsi/iscsi_transport.h | 104 | ||||
| -rw-r--r-- | include/target/target_core_backend.h | 82 | ||||
| -rw-r--r-- | include/target/target_core_base.h | 499 | ||||
| -rw-r--r-- | include/target/target_core_configfs.h | 2 | ||||
| -rw-r--r-- | include/target/target_core_fabric.h | 80 | ||||
| -rw-r--r-- | include/target/target_core_fabric_configfs.h | 11 |
6 files changed, 463 insertions, 315 deletions
diff --git a/include/target/iscsi/iscsi_transport.h b/include/target/iscsi/iscsi_transport.h new file mode 100644 index 00000000000..daef9daa500 --- /dev/null +++ b/include/target/iscsi/iscsi_transport.h @@ -0,0 +1,104 @@ +#include <linux/module.h> +#include <linux/list.h> +#include "../../../drivers/target/iscsi/iscsi_target_core.h" + +struct iscsit_transport { +#define ISCSIT_TRANSPORT_NAME 16 + char name[ISCSIT_TRANSPORT_NAME]; + int transport_type; + int priv_size; + struct module *owner; + struct list_head t_node; + int (*iscsit_setup_np)(struct iscsi_np *, struct __kernel_sockaddr_storage *); + int (*iscsit_accept_np)(struct iscsi_np *, struct iscsi_conn *); + void (*iscsit_free_np)(struct iscsi_np *); + void (*iscsit_wait_conn)(struct iscsi_conn *); + void (*iscsit_free_conn)(struct iscsi_conn *); + int (*iscsit_get_login_rx)(struct iscsi_conn *, struct iscsi_login *); + int (*iscsit_put_login_tx)(struct iscsi_conn *, struct iscsi_login *, u32); + int (*iscsit_immediate_queue)(struct iscsi_conn *, struct iscsi_cmd *, int); + int (*iscsit_response_queue)(struct iscsi_conn *, struct iscsi_cmd *, int); + int (*iscsit_get_dataout)(struct iscsi_conn *, struct iscsi_cmd *, bool); + int (*iscsit_queue_data_in)(struct iscsi_conn *, struct iscsi_cmd *); + int (*iscsit_queue_status)(struct iscsi_conn *, struct iscsi_cmd *); + void (*iscsit_aborted_task)(struct iscsi_conn *, struct iscsi_cmd *); + enum target_prot_op (*iscsit_get_sup_prot_ops)(struct iscsi_conn *); +}; + +static inline void *iscsit_priv_cmd(struct iscsi_cmd *cmd) +{ + return (void *)(cmd + 1); +} + +/* + * From iscsi_target_transport.c + */ + +extern int iscsit_register_transport(struct iscsit_transport *); +extern void iscsit_unregister_transport(struct iscsit_transport *); +extern struct iscsit_transport *iscsit_get_transport(int); +extern void iscsit_put_transport(struct iscsit_transport *); + +/* + * From iscsi_target.c + */ +extern int iscsit_setup_scsi_cmd(struct iscsi_conn *, struct iscsi_cmd *, + unsigned char *); +extern void iscsit_set_unsoliticed_dataout(struct iscsi_cmd *); +extern int iscsit_process_scsi_cmd(struct iscsi_conn *, struct iscsi_cmd *, + struct iscsi_scsi_req *); +extern int iscsit_check_dataout_hdr(struct iscsi_conn *, unsigned char *, + struct iscsi_cmd **); +extern int iscsit_check_dataout_payload(struct iscsi_cmd *, struct iscsi_data *, + bool); +extern int iscsit_setup_nop_out(struct iscsi_conn *, struct iscsi_cmd *, + struct iscsi_nopout *); +extern int iscsit_process_nop_out(struct iscsi_conn *, struct iscsi_cmd *, + struct iscsi_nopout *); +extern int iscsit_handle_logout_cmd(struct iscsi_conn *, struct iscsi_cmd *, + unsigned char *); +extern int iscsit_handle_task_mgt_cmd(struct iscsi_conn *, struct iscsi_cmd *, + unsigned char *); +extern int iscsit_setup_text_cmd(struct iscsi_conn *, struct iscsi_cmd *, + struct iscsi_text *); +extern int iscsit_process_text_cmd(struct iscsi_conn *, struct iscsi_cmd *, + struct iscsi_text *); +extern void iscsit_build_rsp_pdu(struct iscsi_cmd *, struct iscsi_conn *, + bool, struct iscsi_scsi_rsp *); +extern void iscsit_build_nopin_rsp(struct iscsi_cmd *, struct iscsi_conn *, + struct iscsi_nopin *, bool); +extern void iscsit_build_task_mgt_rsp(struct iscsi_cmd *, struct iscsi_conn *, + struct iscsi_tm_rsp *); +extern int iscsit_build_text_rsp(struct iscsi_cmd *, struct iscsi_conn *, + struct iscsi_text_rsp *, + enum iscsit_transport_type); +extern void iscsit_build_reject(struct iscsi_cmd *, struct iscsi_conn *, + struct iscsi_reject *); +extern int iscsit_build_logout_rsp(struct iscsi_cmd *, struct iscsi_conn *, + struct iscsi_logout_rsp *); +extern int iscsit_logout_post_handler(struct iscsi_cmd *, struct iscsi_conn *); +/* + * From iscsi_target_device.c + */ +extern void iscsit_increment_maxcmdsn(struct iscsi_cmd *, struct iscsi_session *); +/* + * From iscsi_target_erl0.c + */ +extern void iscsit_cause_connection_reinstatement(struct iscsi_conn *, int); +/* + * From iscsi_target_erl1.c + */ +extern void iscsit_stop_dataout_timer(struct iscsi_cmd *); + +/* + * From iscsi_target_tmr.c + */ +extern int iscsit_tmr_post_handler(struct iscsi_cmd *, struct iscsi_conn *); + +/* + * From iscsi_target_util.c + */ +extern struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *, int); +extern int iscsit_sequence_cmd(struct iscsi_conn *, struct iscsi_cmd *, + unsigned char *, __be32); +extern void iscsit_release_cmd(struct iscsi_cmd *); diff --git a/include/target/target_core_backend.h b/include/target/target_core_backend.h index 2d7db85e93a..9adc1bca117 100644 --- a/include/target/target_core_backend.h +++ b/include/target/target_core_backend.h @@ -9,45 +9,77 @@ struct se_subsystem_api { struct list_head sub_api_list; char name[16]; + char inquiry_prod[16]; + char inquiry_rev[4]; struct module *owner; u8 transport_type; - unsigned int fua_write_emulated : 1; - unsigned int write_cache_emulated : 1; - int (*attach_hba)(struct se_hba *, u32); void (*detach_hba)(struct se_hba *); int (*pmode_enable_hba)(struct se_hba *, unsigned long); - void *(*allocate_virtdevice)(struct se_hba *, const char *); - struct se_device *(*create_virtdevice)(struct se_hba *, - struct se_subsystem_dev *, void *); - void (*free_device)(void *); - int (*transport_complete)(struct se_cmd *cmd, struct scatterlist *); - int (*execute_cmd)(struct se_cmd *, struct scatterlist *, u32, - enum dma_data_direction); - int (*do_discard)(struct se_device *, sector_t, u32); - void (*do_sync_cache)(struct se_cmd *); - ssize_t (*check_configfs_dev_params)(struct se_hba *, - struct se_subsystem_dev *); - ssize_t (*set_configfs_dev_params)(struct se_hba *, - struct se_subsystem_dev *, const char *, ssize_t); - ssize_t (*show_configfs_dev_params)(struct se_hba *, - struct se_subsystem_dev *, char *); - u32 (*get_device_rev)(struct se_device *); + + struct se_device *(*alloc_device)(struct se_hba *, const char *); + int (*configure_device)(struct se_device *); + void (*free_device)(struct se_device *device); + + ssize_t (*set_configfs_dev_params)(struct se_device *, + const char *, ssize_t); + ssize_t (*show_configfs_dev_params)(struct se_device *, char *); + + void (*transport_complete)(struct se_cmd *cmd, + struct scatterlist *, + unsigned char *); + + sense_reason_t (*parse_cdb)(struct se_cmd *cmd); u32 (*get_device_type)(struct se_device *); sector_t (*get_blocks)(struct se_device *); + sector_t (*get_alignment_offset_lbas)(struct se_device *); + /* lbppbe = logical blocks per physical block exponent. see SBC-3 */ + unsigned int (*get_lbppbe)(struct se_device *); + unsigned int (*get_io_min)(struct se_device *); + unsigned int (*get_io_opt)(struct se_device *); unsigned char *(*get_sense_buffer)(struct se_cmd *); + bool (*get_write_cache)(struct se_device *); + int (*init_prot)(struct se_device *); + int (*format_prot)(struct se_device *); + void (*free_prot)(struct se_device *); +}; + +struct sbc_ops { + sense_reason_t (*execute_rw)(struct se_cmd *cmd, struct scatterlist *, + u32, enum dma_data_direction); + sense_reason_t (*execute_sync_cache)(struct se_cmd *cmd); + sense_reason_t (*execute_write_same)(struct se_cmd *cmd); + sense_reason_t (*execute_write_same_unmap)(struct se_cmd *cmd); + sense_reason_t (*execute_unmap)(struct se_cmd *cmd); }; int transport_subsystem_register(struct se_subsystem_api *); void transport_subsystem_release(struct se_subsystem_api *); -struct se_device *transport_add_device_to_core_hba(struct se_hba *, - struct se_subsystem_api *, struct se_subsystem_dev *, u32, - void *, struct se_dev_limits *, const char *, const char *); - void target_complete_cmd(struct se_cmd *, u8); +void target_complete_cmd_with_length(struct se_cmd *, u8, int); + +sense_reason_t spc_parse_cdb(struct se_cmd *cmd, unsigned int *size); +sense_reason_t spc_emulate_report_luns(struct se_cmd *cmd); +sense_reason_t spc_emulate_inquiry_std(struct se_cmd *, unsigned char *); +sense_reason_t spc_emulate_evpd_83(struct se_cmd *, unsigned char *); + +sense_reason_t sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops); +u32 sbc_get_device_rev(struct se_device *dev); +u32 sbc_get_device_type(struct se_device *dev); +sector_t sbc_get_write_same_sectors(struct se_cmd *cmd); +sense_reason_t sbc_execute_unmap(struct se_cmd *cmd, + sense_reason_t (*do_unmap_fn)(struct se_cmd *cmd, void *priv, + sector_t lba, sector_t nolb), + void *priv); +void sbc_dif_generate(struct se_cmd *); +sense_reason_t sbc_dif_verify_write(struct se_cmd *, sector_t, unsigned int, + unsigned int, struct scatterlist *, int); +sense_reason_t sbc_dif_verify_read(struct se_cmd *, sector_t, unsigned int, + unsigned int, struct scatterlist *, int); +sense_reason_t sbc_dif_read_strip(struct se_cmd *); void transport_set_vpd_proto_id(struct t10_vpd *, unsigned char *); int transport_set_vpd_assoc(struct t10_vpd *, unsigned char *); @@ -57,6 +89,10 @@ int transport_set_vpd_ident(struct t10_vpd *, unsigned char *); /* core helpers also used by command snooping in pscsi */ void *transport_kmap_data_sg(struct se_cmd *); void transport_kunmap_data_sg(struct se_cmd *); +/* core helpers also used by xcopy during internal command setup */ +int target_alloc_sgl(struct scatterlist **, unsigned int *, u32, bool); +sense_reason_t transport_generic_map_mem_to_cmd(struct se_cmd *, + struct scatterlist *, u32, struct scatterlist *, u32); void array_free(void *array, int n); diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index dc35d8660aa..9ec9864ecf3 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -5,11 +5,12 @@ #include <linux/configfs.h> #include <linux/dma-mapping.h> #include <linux/blkdev.h> +#include <linux/percpu_ida.h> #include <scsi/scsi_cmnd.h> #include <net/sock.h> #include <net/tcp.h> -#define TARGET_CORE_MOD_VERSION "v4.1.0-rc2-ml" +#define TARGET_CORE_MOD_VERSION "v4.1.0" #define TARGET_CORE_VERSION TARGET_CORE_MOD_VERSION /* Maximum Number of LUNs per Target Portal Group */ @@ -36,6 +37,9 @@ /* Used by transport_send_check_condition_and_sense() */ #define SPC_SENSE_KEY_OFFSET 2 #define SPC_ADD_SENSE_LEN_OFFSET 7 +#define SPC_DESC_TYPE_OFFSET 8 +#define SPC_ADDITIONAL_DESC_LEN_OFFSET 9 +#define SPC_VALIDITY_OFFSET 10 #define SPC_ASC_KEY_OFFSET 12 #define SPC_ASCQ_KEY_OFFSET 13 #define TRANSPORT_IQN_LEN 224 @@ -44,7 +48,7 @@ /* Used by core_alua_store_tg_pt_gp_info() and target_core_alua_tg_pt_gp_show_attr_members() */ #define TG_PT_GROUP_NAME_BUF 256 /* Used to parse VPD into struct t10_vpd */ -#define VPD_TMP_BUF_SIZE 128 +#define VPD_TMP_BUF_SIZE 254 /* Used by transport_generic_cmd_sequencer() */ #define READ_BLOCK_LEN 6 #define READ_CAP_LEN 8 @@ -62,20 +66,6 @@ #define PYX_TRANSPORT_STATUS_INTERVAL 5 /* In seconds */ -/* - * struct se_subsystem_dev->su_dev_flags -*/ -#define SDF_FIRMWARE_VPD_UNIT_SERIAL 0x00000001 -#define SDF_EMULATED_VPD_UNIT_SERIAL 0x00000002 -#define SDF_USING_UDEV_PATH 0x00000004 -#define SDF_USING_ALIAS 0x00000008 - -/* - * struct se_device->dev_flags - */ -#define DF_SPC2_RESERVATIONS 0x00000001 -#define DF_SPC2_RESERVATIONS_WITH_ISID 0x00000002 - /* struct se_dev_attrib sanity values */ /* Default max_unmap_lba_count */ #define DA_MAX_UNMAP_LBA_COUNT 0 @@ -85,8 +75,12 @@ #define DA_UNMAP_GRANULARITY_DEFAULT 0 /* Default unmap_granularity_alignment */ #define DA_UNMAP_GRANULARITY_ALIGNMENT_DEFAULT 0 +/* Default max_write_same_len, disabled by default */ +#define DA_MAX_WRITE_SAME_LEN 0 /* Default max transfer length */ #define DA_FABRIC_MAX_SECTORS 8192 +/* Use a model alias based on the configfs backend device name */ +#define DA_EMULATE_MODEL_ALIAS 0 /* Emulation for Direct Page Out */ #define DA_EMULATE_DPO 0 /* Emulation for Forced Unit Access WRITEs */ @@ -106,8 +100,10 @@ * block/blk-lib.c:blkdev_issue_discard() */ #define DA_EMULATE_TPWS 0 -/* No Emulation for PSCSI by default */ -#define DA_EMULATE_RESERVATIONS 0 +/* Emulation for CompareAndWrite (AtomicTestandSet) by default */ +#define DA_EMULATE_CAW 1 +/* Emulation for 3rd Party Copy (ExtendedCopy) by default */ +#define DA_EMULATE_3PC 1 /* No Emulation for PSCSI by default */ #define DA_EMULATE_ALUA 0 /* Enforce SCSI Initiator Port TransportID with 'ISID' for PR */ @@ -119,8 +115,9 @@ /* Queue Algorithm Modifier default for restricted reordering in control mode page */ #define DA_EMULATE_REST_REORD 0 -#define SE_INQUIRY_BUF 512 +#define SE_INQUIRY_BUF 1024 #define SE_MODE_PAGE_BUF 512 +#define SE_SENSE_BUF 96 /* struct se_hba->hba_flags */ enum hba_flags_table { @@ -145,12 +142,9 @@ enum transport_state_table { TRANSPORT_NO_STATE = 0, TRANSPORT_NEW_CMD = 1, TRANSPORT_WRITE_PENDING = 3, - TRANSPORT_PROCESS_WRITE = 4, TRANSPORT_PROCESSING = 5, TRANSPORT_COMPLETE = 6, - TRANSPORT_PROCESS_TMR = 9, TRANSPORT_ISTATE_PROCESSING = 11, - TRANSPORT_NEW_CMD_MAP = 16, TRANSPORT_COMPLETE_QF_WP = 18, TRANSPORT_COMPLETE_QF_OK = 19, }; @@ -160,25 +154,21 @@ enum se_cmd_flags_table { SCF_SUPPORTED_SAM_OPCODE = 0x00000001, SCF_TRANSPORT_TASK_SENSE = 0x00000002, SCF_EMULATED_TASK_SENSE = 0x00000004, - SCF_SCSI_DATA_SG_IO_CDB = 0x00000008, - SCF_SCSI_CONTROL_SG_IO_CDB = 0x00000010, - SCF_SCSI_NON_DATA_CDB = 0x00000020, - SCF_SCSI_TMR_CDB = 0x00000040, - SCF_SCSI_CDB_EXCEPTION = 0x00000080, - SCF_SCSI_RESERVATION_CONFLICT = 0x00000100, - SCF_FUA = 0x00000200, - SCF_SE_LUN_CMD = 0x00000800, - SCF_SE_ALLOW_EOO = 0x00001000, - SCF_BIDI = 0x00002000, - SCF_SENT_CHECK_CONDITION = 0x00004000, - SCF_OVERFLOW_BIT = 0x00008000, - SCF_UNDERFLOW_BIT = 0x00010000, - SCF_SENT_DELAYED_TAS = 0x00020000, - SCF_ALUA_NON_OPTIMIZED = 0x00040000, - SCF_DELAYED_CMD_FROM_SAM_ATTR = 0x00080000, - SCF_UNUSED = 0x00100000, - SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC = 0x00200000, - SCF_ACK_KREF = 0x00400000, + SCF_SCSI_DATA_CDB = 0x00000008, + SCF_SCSI_TMR_CDB = 0x00000010, + SCF_FUA = 0x00000080, + SCF_SE_LUN_CMD = 0x00000100, + SCF_BIDI = 0x00000400, + SCF_SENT_CHECK_CONDITION = 0x00000800, + SCF_OVERFLOW_BIT = 0x00001000, + SCF_UNDERFLOW_BIT = 0x00002000, + SCF_SEND_DELAYED_TAS = 0x00004000, + SCF_ALUA_NON_OPTIMIZED = 0x00008000, + SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC = 0x00020000, + SCF_ACK_KREF = 0x00040000, + SCF_COMPARE_AND_WRITE = 0x00080000, + SCF_COMPARE_AND_WRITE_POST = 0x00100000, + SCF_CMD_XCOPY_PASSTHROUGH = 0x00200000, }; /* struct se_dev_entry->lun_flags and struct se_lun->lun_access */ @@ -189,37 +179,39 @@ enum transport_lunflags_table { TRANSPORT_LUNFLAGS_READ_WRITE = 0x04, }; -/* struct se_device->dev_status */ -enum transport_device_status_table { - TRANSPORT_DEVICE_ACTIVATED = 0x01, - TRANSPORT_DEVICE_DEACTIVATED = 0x02, - TRANSPORT_DEVICE_QUEUE_FULL = 0x04, - TRANSPORT_DEVICE_SHUTDOWN = 0x08, - TRANSPORT_DEVICE_OFFLINE_ACTIVATED = 0x10, - TRANSPORT_DEVICE_OFFLINE_DEACTIVATED = 0x20, -}; - /* - * Used by transport_send_check_condition_and_sense() and se_cmd->scsi_sense_reason + * Used by transport_send_check_condition_and_sense() * to signal which ASC/ASCQ sense payload should be built. */ +typedef unsigned __bitwise__ sense_reason_t; + enum tcm_sense_reason_table { - TCM_NON_EXISTENT_LUN = 0x01, - TCM_UNSUPPORTED_SCSI_OPCODE = 0x02, - TCM_INCORRECT_AMOUNT_OF_DATA = 0x03, - TCM_UNEXPECTED_UNSOLICITED_DATA = 0x04, - TCM_SERVICE_CRC_ERROR = 0x05, - TCM_SNACK_REJECTED = 0x06, - TCM_SECTOR_COUNT_TOO_MANY = 0x07, - TCM_INVALID_CDB_FIELD = 0x08, - TCM_INVALID_PARAMETER_LIST = 0x09, - TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE = 0x0a, - TCM_UNKNOWN_MODE_PAGE = 0x0b, - TCM_WRITE_PROTECTED = 0x0c, - TCM_CHECK_CONDITION_ABORT_CMD = 0x0d, - TCM_CHECK_CONDITION_UNIT_ATTENTION = 0x0e, - TCM_CHECK_CONDITION_NOT_READY = 0x0f, - TCM_RESERVATION_CONFLICT = 0x10, +#define R(x) (__force sense_reason_t )(x) + TCM_NO_SENSE = R(0x00), + TCM_NON_EXISTENT_LUN = R(0x01), + TCM_UNSUPPORTED_SCSI_OPCODE = R(0x02), + TCM_INCORRECT_AMOUNT_OF_DATA = R(0x03), + TCM_UNEXPECTED_UNSOLICITED_DATA = R(0x04), + TCM_SERVICE_CRC_ERROR = R(0x05), + TCM_SNACK_REJECTED = R(0x06), + TCM_SECTOR_COUNT_TOO_MANY = R(0x07), + TCM_INVALID_CDB_FIELD = R(0x08), + TCM_INVALID_PARAMETER_LIST = R(0x09), + TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE = R(0x0a), + TCM_UNKNOWN_MODE_PAGE = R(0x0b), + TCM_WRITE_PROTECTED = R(0x0c), + TCM_CHECK_CONDITION_ABORT_CMD = R(0x0d), + TCM_CHECK_CONDITION_UNIT_ATTENTION = R(0x0e), + TCM_CHECK_CONDITION_NOT_READY = R(0x0f), + TCM_RESERVATION_CONFLICT = R(0x10), + TCM_ADDRESS_OUT_OF_RANGE = R(0x11), + TCM_OUT_OF_RESOURCES = R(0x12), + TCM_PARAMETER_LIST_LENGTH_ERROR = R(0x13), + TCM_MISCOMPARE_VERIFY = R(0x14), + TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED = R(0x15), + TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED = R(0x16), + TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED = R(0x17), +#undef R }; enum target_sc_flags_table { @@ -237,46 +229,19 @@ enum tcm_tmreq_table { TMR_LUN_RESET = 5, TMR_TARGET_WARM_RESET = 6, TMR_TARGET_COLD_RESET = 7, - TMR_FABRIC_TMR = 255, }; /* fabric independent task management response values */ enum tcm_tmrsp_table { - TMR_FUNCTION_COMPLETE = 0, - TMR_TASK_DOES_NOT_EXIST = 1, - TMR_LUN_DOES_NOT_EXIST = 2, - TMR_TASK_STILL_ALLEGIANT = 3, - TMR_TASK_FAILOVER_NOT_SUPPORTED = 4, - TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED = 5, - TMR_FUNCTION_AUTHORIZATION_FAILED = 6, - TMR_FUNCTION_REJECTED = 255, -}; - -struct se_obj { - atomic_t obj_access_count; + TMR_FUNCTION_FAILED = 0, + TMR_FUNCTION_COMPLETE = 1, + TMR_TASK_DOES_NOT_EXIST = 2, + TMR_LUN_DOES_NOT_EXIST = 3, + TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED = 4, + TMR_FUNCTION_REJECTED = 5, }; /* - * Used by TCM Core internally to signal if ALUA emulation is enabled or - * disabled, or running in with TCM/pSCSI passthrough mode - */ -typedef enum { - SPC_ALUA_PASSTHROUGH, - SPC2_ALUA_DISABLED, - SPC3_ALUA_EMULATED -} t10_alua_index_t; - -/* - * Used by TCM Core internally to signal if SAM Task Attribute emulation - * is enabled or disabled, or running in with TCM/pSCSI passthrough mode - */ -typedef enum { - SAM_TASK_ATTR_PASSTHROUGH, - SAM_TASK_ATTR_UNTAGGED, - SAM_TASK_ATTR_EMULATED -} t10_task_attr_index_t; - -/* * Used for target SCSI statistics */ typedef enum { @@ -288,18 +253,34 @@ typedef enum { struct se_cmd; +struct t10_alua_lba_map_member { + struct list_head lba_map_mem_list; + int lba_map_mem_alua_state; + int lba_map_mem_alua_pg_id; +}; + +struct t10_alua_lba_map { + u64 lba_map_first_lba; + u64 lba_map_last_lba; + struct list_head lba_map_list; + struct list_head lba_map_mem_list; +}; + struct t10_alua { - t10_alua_index_t alua_type; /* ALUA Target Port Group ID */ u16 alua_tg_pt_gps_counter; u32 alua_tg_pt_gps_count; + /* Referrals support */ + spinlock_t lba_map_lock; + u32 lba_map_segment_size; + u32 lba_map_segment_multiplier; + struct list_head lba_map_list; spinlock_t tg_pt_gps_lock; - struct se_subsystem_dev *t10_sub_dev; + struct se_device *t10_dev; /* Used for default ALUA Target Port Group */ struct t10_alua_tg_pt_gp *default_tg_pt_gp; /* Used for default ALUA Target Port Group ConfigFS group */ struct config_group alua_tg_pt_gps_group; - int (*alua_state_check)(struct se_cmd *, unsigned char *, u8 *); struct list_head tg_pt_gps_list; }; @@ -326,25 +307,29 @@ struct t10_alua_lu_gp_member { struct t10_alua_tg_pt_gp { u16 tg_pt_gp_id; int tg_pt_gp_valid_id; + int tg_pt_gp_alua_supported_states; + int tg_pt_gp_alua_pending_state; + int tg_pt_gp_alua_previous_state; int tg_pt_gp_alua_access_status; int tg_pt_gp_alua_access_type; int tg_pt_gp_nonop_delay_msecs; int tg_pt_gp_trans_delay_msecs; - int tg_pt_gp_implict_trans_secs; + int tg_pt_gp_implicit_trans_secs; int tg_pt_gp_pref; int tg_pt_gp_write_metadata; - /* Used by struct t10_alua_tg_pt_gp->tg_pt_gp_md_buf_len */ -#define ALUA_MD_BUF_LEN 1024 - u32 tg_pt_gp_md_buf_len; u32 tg_pt_gp_members; atomic_t tg_pt_gp_alua_access_state; atomic_t tg_pt_gp_ref_cnt; spinlock_t tg_pt_gp_lock; struct mutex tg_pt_gp_md_mutex; - struct se_subsystem_dev *tg_pt_gp_su_dev; + struct se_device *tg_pt_gp_dev; struct config_group tg_pt_gp_group; struct list_head tg_pt_gp_list; struct list_head tg_pt_gp_mem_list; + struct se_port *tg_pt_gp_alua_port; + struct se_node_acl *tg_pt_gp_alua_nacl; + struct delayed_work tg_pt_gp_transition_work; + struct completion *tg_pt_gp_transition_complete; }; struct t10_alua_tg_pt_gp_member { @@ -372,23 +357,11 @@ struct t10_wwn { char revision[4]; char unit_serial[INQUIRY_VPD_SERIAL_LEN]; spinlock_t t10_vpd_lock; - struct se_subsystem_dev *t10_sub_dev; + struct se_device *t10_dev; struct config_group t10_wwn_group; struct list_head t10_vpd_list; }; - -/* - * Used by TCM Core internally to signal if >= SPC-3 persistent reservations - * emulation is enabled or disabled, or running in with TCM/pSCSI passthrough - * mode - */ -typedef enum { - SPC_PASSTHROUGH, - SPC2_RESERVATIONS, - SPC3_PERSISTENT_RESERVATIONS -} t10_reservations_index_t; - struct t10_pr_registration { /* Used for fabrics that contain WWN+ISID */ #define PR_REG_ISID_LEN 16 @@ -401,8 +374,6 @@ struct t10_pr_registration { /* Used during APTPL metadata reading */ #define PR_APTPL_MAX_TPORT_LEN 256 unsigned char pr_tport[PR_APTPL_MAX_TPORT_LEN]; - /* For writing out live meta data */ - unsigned char *pr_aptpl_buf; u16 pr_aptpl_rpti; u16 pr_reg_tpgt; /* Reservation effects all target ports */ @@ -430,29 +401,14 @@ struct t10_pr_registration { struct list_head pr_reg_atp_mem_list; }; -/* - * This set of function pointer ops is set based upon SPC3_PERSISTENT_RESERVATIONS, - * SPC2_RESERVATIONS or SPC_PASSTHROUGH in drivers/target/target_core_pr.c: - * core_setup_reservations() - */ -struct t10_reservation_ops { - int (*t10_reservation_check)(struct se_cmd *, u32 *); - int (*t10_seq_non_holder)(struct se_cmd *, unsigned char *, u32); - int (*t10_pr_register)(struct se_cmd *); - int (*t10_pr_clear)(struct se_cmd *); -}; - struct t10_reservation { /* Reservation effects all target ports */ int pr_all_tg_pt; /* Activate Persistence across Target Power Loss enabled * for SCSI device */ int pr_aptpl_active; - /* Used by struct t10_reservation->pr_aptpl_buf_len */ #define PR_APTPL_BUF_LEN 8192 - u32 pr_aptpl_buf_len; u32 pr_generation; - t10_reservations_index_t res_type; spinlock_t registration_lock; spinlock_t aptpl_reg_lock; /* @@ -468,14 +424,6 @@ struct t10_reservation { struct se_node_acl *pr_res_holder; struct list_head registration_list; struct list_head aptpl_reg_list; - struct t10_reservation_ops pr_ops; -}; - -struct se_queue_obj { - atomic_t queue_cnt; - spinlock_t cmd_queue_lock; - struct list_head qobj_list; - wait_queue_head_t thread_wq; }; struct se_tmr_req { @@ -486,22 +434,51 @@ struct se_tmr_req { int call_transport; /* Reference to ITT that Task Mgmt should be performed */ u32 ref_task_tag; - /* 64-bit encoded SAM LUN from $FABRIC_MOD TMR header */ - u64 ref_task_lun; void *fabric_tmr_ptr; struct se_cmd *task_cmd; - struct se_cmd *ref_cmd; struct se_device *tmr_dev; struct se_lun *tmr_lun; struct list_head tmr_list; }; +enum target_prot_op { + TARGET_PROT_NORMAL = 0, + TARGET_PROT_DIN_INSERT = (1 << 0), + TARGET_PROT_DOUT_INSERT = (1 << 1), + TARGET_PROT_DIN_STRIP = (1 << 2), + TARGET_PROT_DOUT_STRIP = (1 << 3), + TARGET_PROT_DIN_PASS = (1 << 4), + TARGET_PROT_DOUT_PASS = (1 << 5), +}; + +#define TARGET_PROT_ALL TARGET_PROT_DIN_INSERT | TARGET_PROT_DOUT_INSERT | \ + TARGET_PROT_DIN_STRIP | TARGET_PROT_DOUT_STRIP | \ + TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS + +enum target_prot_type { + TARGET_DIF_TYPE0_PROT, + TARGET_DIF_TYPE1_PROT, + TARGET_DIF_TYPE2_PROT, + TARGET_DIF_TYPE3_PROT, +}; + +enum target_core_dif_check { + TARGET_DIF_CHECK_GUARD = 0x1 << 0, + TARGET_DIF_CHECK_APPTAG = 0x1 << 1, + TARGET_DIF_CHECK_REFTAG = 0x1 << 2, +}; + +struct se_dif_v1_tuple { + __be16 guard_tag; + __be16 app_tag; + __be32 ref_tag; +}; + struct se_cmd { /* SAM response code being sent to initiator */ u8 scsi_status; u8 scsi_asc; u8 scsi_ascq; - u8 scsi_sense_reason; u16 scsi_sense_length; /* Delay for ALUA Active/NonOptimized state access in milliseconds */ int alua_nonop_delay; @@ -509,10 +486,10 @@ struct se_cmd { enum dma_data_direction data_direction; /* For SAM Task Attribute */ int sam_task_attr; + /* Used for se_sess->sess_tag_pool */ + unsigned int map_tag; /* Transport protocol dependent state, see transport_state_table */ enum transport_state_table t_state; - /* Used to signal cmd->se_tfo->check_release_cmd() usage per cmd */ - unsigned check_release:1; unsigned cmd_wait_set:1; unsigned unknown_data_length:1; /* See se_cmd_flags_table */ @@ -520,8 +497,6 @@ struct se_cmd { u32 se_ordered_id; /* Total size in bytes associated with command */ u32 data_length; - /* SCSI Presented Data Transfer Length */ - u32 cmd_spdtl; u32 residual_count; u32 orig_fe_lun; /* Persistent Reservation key */ @@ -529,7 +504,6 @@ struct se_cmd { /* Used for sense data */ void *sense_buffer; struct list_head se_delayed_node; - struct list_head se_lun_node; struct list_head se_qf_node; struct se_device *se_dev; struct se_dev_entry *se_deve; @@ -537,45 +511,41 @@ struct se_cmd { /* Only used for internal passthrough and legacy TCM fabric modules */ struct se_session *se_sess; struct se_tmr_req *se_tmr_req; - struct list_head se_queue_node; struct list_head se_cmd_list; struct completion cmd_wait_comp; struct kref cmd_kref; struct target_core_fabric_ops *se_tfo; - int (*execute_cmd)(struct se_cmd *); - void (*transport_complete_callback)(struct se_cmd *); + sense_reason_t (*execute_cmd)(struct se_cmd *); + sense_reason_t (*execute_rw)(struct se_cmd *, struct scatterlist *, + u32, enum dma_data_direction); + sense_reason_t (*transport_complete_callback)(struct se_cmd *); unsigned char *t_task_cdb; unsigned char __t_task_cdb[TCM_MAX_COMMAND_SIZE]; unsigned long long t_task_lba; - atomic_t t_fe_count; + unsigned int t_task_nolb; unsigned int transport_state; #define CMD_T_ABORTED (1 << 0) #define CMD_T_ACTIVE (1 << 1) #define CMD_T_COMPLETE (1 << 2) -#define CMD_T_QUEUED (1 << 3) #define CMD_T_SENT (1 << 4) #define CMD_T_STOP (1 << 5) -#define CMD_T_FAILED (1 << 6) -#define CMD_T_LUN_STOP (1 << 7) -#define CMD_T_LUN_FE_STOP (1 << 8) -#define CMD_T_DEV_ACTIVE (1 << 9) -#define CMD_T_REQUEST_STOP (1 << 10) -#define CMD_T_BUSY (1 << 11) +#define CMD_T_DEV_ACTIVE (1 << 7) +#define CMD_T_REQUEST_STOP (1 << 8) +#define CMD_T_BUSY (1 << 9) spinlock_t t_state_lock; struct completion t_transport_stop_comp; - struct completion transport_lun_fe_stop_comp; - struct completion transport_lun_stop_comp; struct work_struct work; struct scatterlist *t_data_sg; + struct scatterlist *t_data_sg_orig; unsigned int t_data_nents; + unsigned int t_data_nents_orig; void *t_data_vmap; struct scatterlist *t_bidi_data_sg; unsigned int t_bidi_data_nents; - struct list_head execute_list; struct list_head state_list; bool state_active; @@ -584,13 +554,27 @@ struct se_cmd { /* backend private data */ void *priv; + + /* Used for lun->lun_ref counting */ + int lun_ref_active; + + /* DIF related members */ + enum target_prot_op prot_op; + enum target_prot_type prot_type; + u8 prot_checks; + u32 prot_length; + u32 reftag_seed; + struct scatterlist *t_prot_sg; + unsigned int t_prot_nents; + sense_reason_t pi_err; + sector_t bad_sector; + bool prot_pto; }; struct se_ua { u8 ua_asc; u8 ua_ascq; struct se_node_acl *ua_nacl; - struct list_head ua_dev_list; struct list_head ua_nacl_list; }; @@ -601,10 +585,8 @@ struct se_node_acl { bool acl_stop:1; u32 queue_depth; u32 acl_index; - u64 num_cmds; - u64 read_bytes; - u64 write_bytes; - spinlock_t stats_lock; +#define MAX_ACL_TAG_SIZE 64 + char acl_tag[MAX_ACL_TAG_SIZE]; /* Used for PR SPEC_I_PT=1 and REGISTER_AND_MOVE */ atomic_t acl_pr_ref_count; struct se_dev_entry **device_list; @@ -627,6 +609,7 @@ struct se_node_acl { struct se_session { unsigned sess_tearing_down:1; u64 sess_bin_isid; + enum target_prot_op sup_prot_ops; struct se_node_acl *se_node_acl; struct se_portal_group *se_tpg; void *fabric_sess_ptr; @@ -636,6 +619,8 @@ struct se_session { struct list_head sess_wait_list; spinlock_t sess_cmd_lock; struct kref sess_kref; + void *sess_cmd_map; + struct percpu_ida sess_tag_pool; }; struct se_device; @@ -662,12 +647,8 @@ struct se_dev_entry { bool def_pr_registered; /* See transport_lunflags_table */ u32 lun_flags; - u32 deve_cmds; u32 mapped_lun; - u32 average_bytes; - u32 last_byte_count; u32 total_cmds; - u32 total_bytes; u64 pr_res_key; u64 creation_time; u32 attach_count; @@ -683,16 +664,8 @@ struct se_dev_entry { struct list_head ua_list; }; -struct se_dev_limits { - /* Max supported HW queue depth */ - u32 hw_queue_depth; - /* Max supported virtual queue depth */ - u32 queue_depth; - /* From include/linux/blkdev.h for the other HW/SW limits. */ - struct queue_limits limits; -}; - struct se_dev_attrib { + int emulate_model_alias; int emulate_dpo; int emulate_fua_write; int emulate_fua_read; @@ -701,8 +674,11 @@ struct se_dev_attrib { int emulate_tas; int emulate_tpu; int emulate_tpws; - int emulate_reservations; - int emulate_alua; + int emulate_caw; + int emulate_3pc; + int pi_prot_format; + enum target_prot_type pi_prot_type; + enum target_prot_type hw_pi_prot_type; int enforce_pr_isids; int is_nonrot; int emulate_rest_reord; @@ -717,10 +693,40 @@ struct se_dev_attrib { u32 max_unmap_block_desc_count; u32 unmap_granularity; u32 unmap_granularity_alignment; - struct se_subsystem_dev *da_sub_dev; + u32 max_write_same_len; + u32 max_bytes_per_io; + struct se_device *da_dev; struct config_group da_group; }; +struct se_port_stat_grps { + struct config_group stat_group; + struct config_group scsi_port_group; + struct config_group scsi_tgt_port_group; + struct config_group scsi_transport_group; +}; + +struct se_lun { +#define SE_LUN_LINK_MAGIC 0xffff7771 + u32 lun_link_magic; + /* See transport_lun_status_table */ + enum transport_lun_status_table lun_status; + u32 lun_access; + u32 lun_flags; + u32 unpacked_lun; + atomic_t lun_acl_count; + spinlock_t lun_acl_lock; + spinlock_t lun_sep_lock; + struct completion lun_shutdown_comp; + struct list_head lun_acl_list; + struct se_device *lun_se_dev; + struct se_port *lun_sep; + struct config_group lun_group; + struct se_port_stat_grps port_stat_grps; + struct completion lun_ref_comp; + struct percpu_ref lun_ref; +}; + struct se_dev_stat_grps { struct config_group stat_group; struct config_group scsi_dev_group; @@ -728,72 +734,47 @@ struct se_dev_stat_grps { struct config_group scsi_lu_group; }; -struct se_subsystem_dev { -/* Used for struct se_subsystem_dev-->se_dev_alias, must be less than PAGE_SIZE */ -#define SE_DEV_ALIAS_LEN 512 - unsigned char se_dev_alias[SE_DEV_ALIAS_LEN]; -/* Used for struct se_subsystem_dev->se_dev_udev_path[], must be less than PAGE_SIZE */ -#define SE_UDEV_PATH_LEN 512 - unsigned char se_dev_udev_path[SE_UDEV_PATH_LEN]; - u32 su_dev_flags; - struct se_hba *se_dev_hba; - struct se_device *se_dev_ptr; - struct se_dev_attrib se_dev_attrib; - /* T10 Asymmetric Logical Unit Assignment for Target Ports */ - struct t10_alua t10_alua; - /* T10 Inquiry and VPD WWN Information */ - struct t10_wwn t10_wwn; - /* T10 SPC-2 + SPC-3 Reservations */ - struct t10_reservation t10_pr; - spinlock_t se_dev_lock; - void *se_dev_su_ptr; - struct config_group se_dev_group; - /* For T10 Reservations */ - struct config_group se_dev_pr_group; - /* For target_core_stat.c groups */ - struct se_dev_stat_grps dev_stat_grps; -}; - struct se_device { +#define SE_DEV_LINK_MAGIC 0xfeeddeef + u32 dev_link_magic; /* RELATIVE TARGET PORT IDENTIFER Counter */ u16 dev_rpti_counter; /* Used for SAM Task Attribute ordering */ u32 dev_cur_ordered_id; u32 dev_flags; +#define DF_CONFIGURED 0x00000001 +#define DF_FIRMWARE_VPD_UNIT_SERIAL 0x00000002 +#define DF_EMULATED_VPD_UNIT_SERIAL 0x00000004 +#define DF_USING_UDEV_PATH 0x00000008 +#define DF_USING_ALIAS 0x00000010 u32 dev_port_count; - /* See transport_device_status_table */ - u32 dev_status; /* Physical device queue depth */ u32 queue_depth; /* Used for SPC-2 reservations enforce of ISIDs */ u64 dev_res_bin_isid; - t10_task_attr_index_t dev_task_attr_type; /* Pointer to transport specific device structure */ - void *dev_ptr; u32 dev_index; u64 creation_time; - u32 num_resets; - u64 num_cmds; - u64 read_bytes; - u64 write_bytes; - spinlock_t stats_lock; + atomic_long_t num_resets; + atomic_long_t num_cmds; + atomic_long_t read_bytes; + atomic_long_t write_bytes; /* Active commands on this virtual SE device */ atomic_t simple_cmds; atomic_t dev_ordered_id; - atomic_t execute_tasks; atomic_t dev_ordered_sync; atomic_t dev_qf_count; - struct se_obj dev_obj; - struct se_obj dev_access_obj; - struct se_obj dev_export_obj; - struct se_queue_obj dev_queue_obj; + int export_count; spinlock_t delayed_cmd_lock; spinlock_t execute_task_lock; spinlock_t dev_reservation_lock; - spinlock_t dev_status_lock; + unsigned int dev_reservation_flags; +#define DRF_SPC2_RESERVATIONS 0x00000001 +#define DRF_SPC2_RESERVATIONS_WITH_ISID 0x00000002 spinlock_t se_port_lock; spinlock_t se_tmr_lock; spinlock_t qf_cmd_lock; + struct semaphore caw_sem; /* Used for legacy SPC-2 reservationsa */ struct se_node_acl *dev_reserved_node_acl; /* Used for ALUA Logical Unit Group membership */ @@ -802,20 +783,35 @@ struct se_device { struct t10_pr_registration *dev_pr_res_holder; struct list_head dev_sep_list; struct list_head dev_tmr_list; - /* Pointer to descriptor for processing thread */ - struct task_struct *process_thread; + struct workqueue_struct *tmr_wq; struct work_struct qf_work_queue; struct list_head delayed_cmd_list; - struct list_head execute_list; struct list_head state_list; struct list_head qf_cmd_list; + struct list_head g_dev_node; /* Pointer to associated SE HBA */ struct se_hba *se_hba; - struct se_subsystem_dev *se_sub_dev; + /* T10 Inquiry and VPD WWN Information */ + struct t10_wwn t10_wwn; + /* T10 Asymmetric Logical Unit Assignment for Target Ports */ + struct t10_alua t10_alua; + /* T10 SPC-2 + SPC-3 Reservations */ + struct t10_reservation t10_pr; + struct se_dev_attrib dev_attrib; + struct config_group dev_group; + struct config_group dev_pr_group; + struct se_dev_stat_grps dev_stat_grps; +#define SE_DEV_ALIAS_LEN 512 /* must be less than PAGE_SIZE */ + unsigned char dev_alias[SE_DEV_ALIAS_LEN]; +#define SE_UDEV_PATH_LEN 512 /* must be less than PAGE_SIZE */ + unsigned char udev_path[SE_UDEV_PATH_LEN]; /* Pointer to template of function pointers for transport */ struct se_subsystem_api *transport; /* Linked list for struct se_hba struct se_device list */ struct list_head dev_list; + struct se_lun xcopy_lun; + /* Protection Information */ + int prot_length; }; struct se_hba { @@ -828,8 +824,6 @@ struct se_hba { u32 hba_index; /* Pointer to transport specific host structure. */ void *hba_ptr; - /* Linked list for struct se_device */ - struct list_head hba_dev_list; struct list_head hba_node; spinlock_t device_lock; struct config_group hba_group; @@ -837,32 +831,6 @@ struct se_hba { struct se_subsystem_api *transport; }; -struct se_port_stat_grps { - struct config_group stat_group; - struct config_group scsi_port_group; - struct config_group scsi_tgt_port_group; - struct config_group scsi_transport_group; -}; - -struct se_lun { - /* See transport_lun_status_table */ - enum transport_lun_status_table lun_status; - u32 lun_access; - u32 lun_flags; - u32 unpacked_lun; - atomic_t lun_acl_count; - spinlock_t lun_acl_lock; - spinlock_t lun_cmd_lock; - spinlock_t lun_sep_lock; - struct completion lun_shutdown_comp; - struct list_head lun_cmd_list; - struct list_head lun_acl_list; - struct se_device *lun_se_dev; - struct se_port *lun_sep; - struct config_group lun_group; - struct se_port_stat_grps port_stat_grps; -}; - struct scsi_port_stats { u64 cmd_pdus; u64 tx_data_octets; @@ -919,11 +887,12 @@ struct se_portal_group { struct target_core_fabric_ops *se_tpg_tfo; struct se_wwn *se_tpg_wwn; struct config_group tpg_group; - struct config_group *tpg_default_groups[6]; + struct config_group *tpg_default_groups[7]; struct config_group tpg_lun_group; struct config_group tpg_np_group; struct config_group tpg_acl_group; struct config_group tpg_attrib_group; + struct config_group tpg_auth_group; struct config_group tpg_param_group; }; diff --git a/include/target/target_core_configfs.h b/include/target/target_core_configfs.h index 612509592ff..e0801386e4d 100644 --- a/include/target/target_core_configfs.h +++ b/include/target/target_core_configfs.h @@ -23,6 +23,7 @@ struct target_fabric_configfs_template { struct config_item_type tfc_tpg_np_cit; struct config_item_type tfc_tpg_np_base_cit; struct config_item_type tfc_tpg_attrib_cit; + struct config_item_type tfc_tpg_auth_cit; struct config_item_type tfc_tpg_param_cit; struct config_item_type tfc_tpg_nacl_cit; struct config_item_type tfc_tpg_nacl_base_cit; @@ -53,4 +54,3 @@ struct target_fabric_configfs { struct target_fabric_configfs_template tf_cit_tmpl; }; -#define TF_CIT_TMPL(tf) (&(tf)->tf_cit_tmpl) diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h index c78a23333c4..22a4e98eec8 100644 --- a/include/target/target_core_fabric.h +++ b/include/target/target_core_fabric.h @@ -33,12 +33,6 @@ struct target_core_fabric_ops { struct se_node_acl *); u32 (*tpg_get_inst_index)(struct se_portal_group *); /* - * Optional function pointer for TCM to perform command map - * from TCM processing thread context, for those struct se_cmd - * initially allocated in interrupt context. - */ - int (*new_cmd_map)(struct se_cmd *); - /* * Optional to release struct se_cmd and fabric dependent allocated * I/O descriptor in transport_cmd_check_stop(). * @@ -67,9 +61,8 @@ struct target_core_fabric_ops { int (*get_cmd_state)(struct se_cmd *); int (*queue_data_in)(struct se_cmd *); int (*queue_status)(struct se_cmd *); - int (*queue_tm_rsp)(struct se_cmd *); - u16 (*set_fabric_sense_len)(struct se_cmd *, u32); - u16 (*get_fabric_sense_len)(void); + void (*queue_tm_rsp)(struct se_cmd *); + void (*aborted_task)(struct se_cmd *); /* * fabric module calls for target_core_fabric_configfs.c */ @@ -91,7 +84,11 @@ struct target_core_fabric_ops { void (*fabric_drop_nodeacl)(struct se_node_acl *); }; -struct se_session *transport_init_session(void); +struct se_session *transport_init_session(enum target_prot_op); +int transport_alloc_session_tags(struct se_session *, unsigned int, + unsigned int); +struct se_session *transport_init_session_tags(unsigned int, unsigned int, + enum target_prot_op); void __transport_register_session(struct se_portal_group *, struct se_node_acl *, struct se_session *, void *); void transport_register_session(struct se_portal_group *, @@ -106,42 +103,45 @@ void transport_deregister_session(struct se_session *); void transport_init_se_cmd(struct se_cmd *, struct target_core_fabric_ops *, struct se_session *, u32, int, int, unsigned char *); -int transport_lookup_cmd_lun(struct se_cmd *, u32); -int target_setup_cmd_from_cdb(struct se_cmd *, unsigned char *); -void target_submit_cmd(struct se_cmd *, struct se_session *, unsigned char *, +sense_reason_t transport_lookup_cmd_lun(struct se_cmd *, u32); +sense_reason_t target_setup_cmd_from_cdb(struct se_cmd *, unsigned char *); +int target_submit_cmd_map_sgls(struct se_cmd *, struct se_session *, + unsigned char *, unsigned char *, u32, u32, int, int, int, + struct scatterlist *, u32, struct scatterlist *, u32, + struct scatterlist *, u32); +int target_submit_cmd(struct se_cmd *, struct se_session *, unsigned char *, unsigned char *, u32, u32, int, int, int); int target_submit_tmr(struct se_cmd *se_cmd, struct se_session *se_sess, unsigned char *sense, u32 unpacked_lun, void *fabric_tmr_ptr, unsigned char tm_type, gfp_t, unsigned int, int); int transport_handle_cdb_direct(struct se_cmd *); -int transport_generic_handle_cdb_map(struct se_cmd *); -int transport_generic_handle_data(struct se_cmd *); -int transport_generic_map_mem_to_cmd(struct se_cmd *cmd, - struct scatterlist *, u32, struct scatterlist *, u32); -int transport_generic_new_cmd(struct se_cmd *); +sense_reason_t transport_generic_new_cmd(struct se_cmd *); -void transport_generic_process_write(struct se_cmd *); +void target_execute_cmd(struct se_cmd *cmd); -void transport_generic_free_cmd(struct se_cmd *, int); +int transport_generic_free_cmd(struct se_cmd *, int); bool transport_wait_for_tasks(struct se_cmd *); int transport_check_aborted_status(struct se_cmd *, int); -int transport_send_check_condition_and_sense(struct se_cmd *, u8, int); - -void target_get_sess_cmd(struct se_session *, struct se_cmd *, bool); +int transport_send_check_condition_and_sense(struct se_cmd *, + sense_reason_t, int); +int target_get_sess_cmd(struct se_session *, struct se_cmd *, bool); int target_put_sess_cmd(struct se_session *, struct se_cmd *); -void target_splice_sess_cmd_list(struct se_session *); -void target_wait_for_sess_cmds(struct se_session *, int); +void target_sess_cmd_list_set_waiting(struct se_session *); +void target_wait_for_sess_cmds(struct se_session *); int core_alua_check_nonop_delay(struct se_cmd *); int core_tmr_alloc_req(struct se_cmd *, void *, u8, gfp_t); void core_tmr_release_req(struct se_tmr_req *); int transport_generic_handle_tmr(struct se_cmd *); -void transport_generic_request_failure(struct se_cmd *); +void transport_generic_request_failure(struct se_cmd *, sense_reason_t); +void __target_execute_cmd(struct se_cmd *); int transport_lookup_tmr_lun(struct se_cmd *, u32); +struct se_node_acl *core_tpg_get_initiator_node_acl(struct se_portal_group *tpg, + unsigned char *); struct se_node_acl *core_tpg_check_initiator_node_acl(struct se_portal_group *, unsigned char *); void core_tpg_clear_object_luns(struct se_portal_group *); @@ -151,6 +151,8 @@ int core_tpg_del_initiator_node_acl(struct se_portal_group *, struct se_node_acl *, int); int core_tpg_set_initiator_node_queue_depth(struct se_portal_group *, unsigned char *, u32, int); +int core_tpg_set_initiator_node_tag(struct se_portal_group *, + struct se_node_acl *, const char *); int core_tpg_register(struct target_core_fabric_ops *, struct se_wwn *, struct se_portal_group *, void *, int); int core_tpg_deregister(struct se_portal_group *); @@ -182,4 +184,30 @@ u32 iscsi_get_pr_transport_id_len(struct se_portal_group *, struct se_node_acl * char *iscsi_parse_pr_out_transport_id(struct se_portal_group *, const char *, u32 *, char **); +/* + * The LIO target core uses DMA_TO_DEVICE to mean that data is going + * to the target (eg handling a WRITE) and DMA_FROM_DEVICE to mean + * that data is coming from the target (eg handling a READ). However, + * this is just the opposite of what we have to tell the DMA mapping + * layer -- eg when handling a READ, the HBA will have to DMA the data + * out of memory so it can send it to the initiator, which means we + * need to use DMA_TO_DEVICE when we map the data. + */ +static inline enum dma_data_direction +target_reverse_dma_direction(struct se_cmd *se_cmd) +{ + if (se_cmd->se_cmd_flags & SCF_BIDI) + return DMA_BIDIRECTIONAL; + + switch (se_cmd->data_direction) { + case DMA_TO_DEVICE: + return DMA_FROM_DEVICE; + case DMA_FROM_DEVICE: + return DMA_TO_DEVICE; + case DMA_NONE: + default: + return DMA_NONE; + } +} + #endif /* TARGET_CORE_FABRICH */ diff --git a/include/target/target_core_fabric_configfs.h b/include/target/target_core_fabric_configfs.h index a26fb7586a0..b32a14905cf 100644 --- a/include/target/target_core_fabric_configfs.h +++ b/include/target/target_core_fabric_configfs.h @@ -62,6 +62,17 @@ static struct target_fabric_tpg_attrib_attribute _fabric##_tpg_attrib_##_name = _fabric##_tpg_attrib_show_##_name, \ _fabric##_tpg_attrib_store_##_name); +CONFIGFS_EATTR_STRUCT(target_fabric_tpg_auth, se_portal_group); +#define TF_TPG_AUTH_ATTR(_fabric, _name, _mode) \ +static struct target_fabric_tpg_auth_attribute _fabric##_tpg_auth_##_name = \ + __CONFIGFS_EATTR(_name, _mode, \ + _fabric##_tpg_auth_show_##_name, \ + _fabric##_tpg_auth_store_##_name); + +#define TF_TPG_AUTH_ATTR_RO(_fabric, _name) \ +static struct target_fabric_tpg_auth_attribute _fabric##_tpg_auth_##_name = \ + __CONFIGFS_EATTR_RO(_name, \ + _fabric##_tpg_auth_show_##_name); CONFIGFS_EATTR_STRUCT(target_fabric_tpg_param, se_portal_group); #define TF_TPG_PARAM_ATTR(_fabric, _name, _mode) \ |
