| 1 |
|
| 2 | #ifndef TARGET_CORE_FABRIC_H
|
| 3 | #define TARGET_CORE_FABRIC_H
|
| 4 |
|
| 5 | #include <linux/configfs.h>
|
| 6 | #include <linux/types.h>
|
| 7 | #include <target/target_core_base.h>
|
| 8 |
|
| 9 | struct target_core_fabric_ops {
|
| 10 | struct module *module;
|
| 11 | |
| 12 | * XXX: Special case for iscsi/iSCSI...
|
| 13 | * If non-null, fabric_alias is used for matching target/$fabric
|
| 14 | * ConfigFS paths. If null, fabric_name is used for this (see below).
|
| 15 |
|
| 16 | const char *fabric_alias;
|
| 17 | |
| 18 | * fabric_name is used for matching target/$fabric ConfigFS paths
|
| 19 | * without a fabric_alias (see above). It's also used for the ALUA state
|
| 20 | * path and is stored on disk with PR state.
|
| 21 |
|
| 22 | const char *fabric_name;
|
| 23 | size_t node_acl_size;
|
| 24 | |
| 25 | * Limits number of scatterlist entries per SCF_SCSI_DATA_CDB payload.
|
| 26 | * Setting this value tells target-core to enforce this limit, and
|
| 27 | * report as INQUIRY EVPD=b0 MAXIMUM TRANSFER LENGTH.
|
| 28 | *
|
| 29 | * target-core will currently reset se_cmd->data_length to this
|
| 30 | * maximum size, and set UNDERFLOW residual count if length exceeds
|
| 31 | * this limit.
|
| 32 | *
|
| 33 | * XXX: Not all initiator hosts honor this block-limit EVPD
|
| 34 | * XXX: Currently assumes single PAGE_SIZE per scatterlist entry
|
| 35 |
|
| 36 | u32 max_data_sg_nents;
|
| 37 | char *(*tpg_get_wwn)(struct se_portal_group *);
|
| 38 | u16 (*tpg_get_tag)(struct se_portal_group *);
|
| 39 | u32 (*tpg_get_default_depth)(struct se_portal_group *);
|
| 40 | int (*tpg_check_demo_mode)(struct se_portal_group *);
|
| 41 | int (*tpg_check_demo_mode_cache)(struct se_portal_group *);
|
| 42 | int (*tpg_check_demo_mode_write_protect)(struct se_portal_group *);
|
| 43 | int (*tpg_check_prod_mode_write_protect)(struct se_portal_group *);
|
| 44 | |
| 45 | * Optionally used by fabrics to allow demo-mode login, but not
|
| 46 | * expose any TPG LUNs, and return 'not connected' in standard
|
| 47 | * inquiry response
|
| 48 |
|
| 49 | int (*tpg_check_demo_mode_login_only)(struct se_portal_group *);
|
| 50 | |
| 51 | * Optionally used as a configfs tunable to determine when
|
| 52 | * target-core should signal the PROTECT=1 feature bit for
|
| 53 | * backends that don't support T10-PI, so that either fabric
|
| 54 | * HW offload or target-core emulation performs the associated
|
| 55 | * WRITE_STRIP and READ_INSERT operations.
|
| 56 |
|
| 57 | int (*tpg_check_prot_fabric_only)(struct se_portal_group *);
|
| 58 | u32 (*tpg_get_inst_index)(struct se_portal_group *);
|
| 59 | |
| 60 | * Optional to release struct se_cmd and fabric dependent allocated
|
| 61 | * I/O descriptor after command execution has finished.
|
| 62 | *
|
| 63 | * Returning 1 will signal a descriptor has been released.
|
| 64 | * Returning 0 will signal a descriptor has not been released.
|
| 65 |
|
| 66 | int (*check_stop_free)(struct se_cmd *);
|
| 67 | void (*release_cmd)(struct se_cmd *);
|
| 68 | void (*close_session)(struct se_session *);
|
| 69 | u32 (*sess_get_index)(struct se_session *);
|
| 70 | |
| 71 | * Used only for SCSI fabrics that contain multi-value TransportIDs
|
| 72 | * (like iSCSI). All other SCSI fabrics should set this to NULL.
|
| 73 |
|
| 74 | u32 (*sess_get_initiator_sid)(struct se_session *,
|
| 75 | unsigned char *, u32);
|
| 76 | int (*write_pending)(struct se_cmd *);
|
| 77 | void (*set_default_node_attributes)(struct se_node_acl *);
|
| 78 | int (*get_cmd_state)(struct se_cmd *);
|
| 79 | int (*queue_data_in)(struct se_cmd *);
|
| 80 | int (*queue_status)(struct se_cmd *);
|
| 81 | void (*queue_tm_rsp)(struct se_cmd *);
|
| 82 | void (*aborted_task)(struct se_cmd *);
|
| 83 | |
| 84 | * fabric module calls for target_core_fabric_configfs.c
|
| 85 |
|
| 86 | struct se_wwn *(*fabric_make_wwn)(struct target_fabric_configfs *,
|
| 87 | struct config_group *, const char *);
|
| 88 | void (*fabric_drop_wwn)(struct se_wwn *);
|
| 89 | void (*add_wwn_groups)(struct se_wwn *);
|
| 90 | struct se_portal_group *(*fabric_make_tpg)(struct se_wwn *,
|
| 91 | const char *);
|
| 92 | int (*fabric_enable_tpg)(struct se_portal_group *se_tpg, bool enable);
|
| 93 | void (*fabric_drop_tpg)(struct se_portal_group *);
|
| 94 | int (*fabric_post_link)(struct se_portal_group *,
|
| 95 | struct se_lun *);
|
| 96 | void (*fabric_pre_unlink)(struct se_portal_group *,
|
| 97 | struct se_lun *);
|
| 98 | void (*fabric_post_unlink)(struct se_portal_group *se_tpg,
|
| 99 | struct se_lun *lun);
|
| 100 | struct se_tpg_np *(*fabric_make_np)(struct se_portal_group *,
|
| 101 | struct config_group *, const char *);
|
| 102 | void (*fabric_drop_np)(struct se_tpg_np *);
|
| 103 | int (*fabric_init_nodeacl)(struct se_node_acl *, const char *);
|
| 104 |
|
| 105 | struct configfs_attribute **tfc_discovery_attrs;
|
| 106 | struct configfs_attribute **tfc_wwn_attrs;
|
| 107 | struct configfs_attribute **tfc_tpg_base_attrs;
|
| 108 | struct configfs_attribute **tfc_tpg_np_base_attrs;
|
| 109 | struct configfs_attribute **tfc_tpg_attrib_attrs;
|
| 110 | struct configfs_attribute **tfc_tpg_auth_attrs;
|
| 111 | struct configfs_attribute **tfc_tpg_param_attrs;
|
| 112 | struct configfs_attribute **tfc_tpg_nacl_base_attrs;
|
| 113 | struct configfs_attribute **tfc_tpg_nacl_attrib_attrs;
|
| 114 | struct configfs_attribute **tfc_tpg_nacl_auth_attrs;
|
| 115 | struct configfs_attribute **tfc_tpg_nacl_param_attrs;
|
| 116 |
|
| 117 | |
| 118 | * Set this member variable if the SCSI transport protocol
|
| 119 | * (e.g. iSCSI) requires that the Data-Out buffer is transferred in
|
| 120 | * its entirety before a command is aborted.
|
| 121 |
|
| 122 | unsigned int write_pending_must_be_called:1;
|
| 123 | |
| 124 | * Set this if the driver does not require calling queue_data_in
|
| 125 | * queue_status and check_stop_free from a worker thread when
|
| 126 | * completing successful commands.
|
| 127 |
|
| 128 | unsigned int direct_compl_supp:1;
|
| 129 | |
| 130 | * Set this if the driver supports submitting commands to the backend
|
| 131 | * from target_submit/target_submit_cmd.
|
| 132 |
|
| 133 | unsigned int direct_submit_supp:1;
|
| 134 |
|
| 135 | u8 default_submit_type;
|
| 136 |
|
| 137 | u8 default_compl_type;
|
| 138 | };
|
| 139 |
|
| 140 | int target_register_template(const struct target_core_fabric_ops *fo);
|
| 141 | void target_unregister_template(const struct target_core_fabric_ops *fo);
|
| 142 |
|
| 143 | int target_depend_item(struct config_item *item);
|
| 144 | void target_undepend_item(struct config_item *item);
|
| 145 |
|
| 146 | struct se_session *target_setup_session(struct se_portal_group *,
|
| 147 | unsigned int, unsigned int, enum target_prot_op prot_op,
|
| 148 | const char *, void *,
|
| 149 | int (*callback)(struct se_portal_group *,
|
| 150 | struct se_session *, void *));
|
| 151 | void target_remove_session(struct se_session *);
|
| 152 |
|
| 153 | void target_stop_cmd_counter(struct target_cmd_counter *cmd_cnt);
|
| 154 | void target_wait_for_cmds(struct target_cmd_counter *cmd_cnt);
|
| 155 | struct target_cmd_counter *target_alloc_cmd_counter(void);
|
| 156 | void target_free_cmd_counter(struct target_cmd_counter *cmd_cnt);
|
| 157 |
|
| 158 | void transport_init_session(struct se_session *se_sess);
|
| 159 | struct se_session *transport_alloc_session(enum target_prot_op);
|
| 160 | int transport_alloc_session_tags(struct se_session *, unsigned int,
|
| 161 | unsigned int);
|
| 162 | void __transport_register_session(struct se_portal_group *,
|
| 163 | struct se_node_acl *, struct se_session *, void *);
|
| 164 | void transport_register_session(struct se_portal_group *,
|
| 165 | struct se_node_acl *, struct se_session *, void *);
|
| 166 | ssize_t target_show_dynamic_sessions(struct se_portal_group *, char *);
|
| 167 | void transport_free_session(struct se_session *);
|
| 168 | void target_spc2_release(struct se_node_acl *nacl);
|
| 169 | void target_put_nacl(struct se_node_acl *);
|
| 170 | void transport_deregister_session_configfs(struct se_session *);
|
| 171 | void transport_deregister_session(struct se_session *);
|
| 172 |
|
| 173 |
|
| 174 | void __target_init_cmd(struct se_cmd *cmd,
|
| 175 | const struct target_core_fabric_ops *tfo,
|
| 176 | struct se_session *sess, u32 data_length, int data_direction,
|
| 177 | int task_attr, unsigned char *sense_buffer, u64 unpacked_lun,
|
| 178 | struct target_cmd_counter *cmd_cnt);
|
| 179 | int target_init_cmd(struct se_cmd *se_cmd, struct se_session *se_sess,
|
| 180 | unsigned char *sense, u64 unpacked_lun, u32 data_length,
|
| 181 | int task_attr, int data_dir, int flags);
|
| 182 | int target_submit_prep(struct se_cmd *se_cmd, unsigned char *cdb,
|
| 183 | struct scatterlist *sgl, u32 sgl_count,
|
| 184 | struct scatterlist *sgl_bidi, u32 sgl_bidi_count,
|
| 185 | struct scatterlist *sgl_prot, u32 sgl_prot_count, gfp_t gfp);
|
| 186 | int target_submit(struct se_cmd *se_cmd);
|
| 187 | sense_reason_t transport_lookup_cmd_lun(struct se_cmd *);
|
| 188 | sense_reason_t target_cmd_init_cdb(struct se_cmd *se_cmd, unsigned char *cdb,
|
| 189 | gfp_t gfp);
|
| 190 | sense_reason_t target_cmd_parse_cdb(struct se_cmd *);
|
| 191 | void target_submit_cmd(struct se_cmd *, struct se_session *, unsigned char *,
|
| 192 | unsigned char *, u64, u32, int, int, int);
|
| 193 |
|
| 194 | int target_submit_tmr(struct se_cmd *se_cmd, struct se_session *se_sess,
|
| 195 | unsigned char *sense, u64 unpacked_lun,
|
| 196 | void *fabric_tmr_ptr, unsigned char tm_type,
|
| 197 | gfp_t, u64, int);
|
| 198 | sense_reason_t transport_generic_new_cmd(struct se_cmd *);
|
| 199 |
|
| 200 | void target_put_cmd_and_wait(struct se_cmd *cmd);
|
| 201 | void target_execute_cmd(struct se_cmd *cmd);
|
| 202 |
|
| 203 | int transport_generic_free_cmd(struct se_cmd *, int);
|
| 204 |
|
| 205 | bool transport_wait_for_tasks(struct se_cmd *);
|
| 206 | int transport_send_check_condition_and_sense(struct se_cmd *,
|
| 207 | sense_reason_t, int);
|
| 208 | int target_send_busy(struct se_cmd *cmd);
|
| 209 | int target_get_sess_cmd(struct se_cmd *, bool);
|
| 210 | int target_put_sess_cmd(struct se_cmd *);
|
| 211 | void target_stop_session(struct se_session *se_sess);
|
| 212 | void target_wait_for_sess_cmds(struct se_session *);
|
| 213 | void target_show_cmd(const char *pfx, struct se_cmd *cmd);
|
| 214 |
|
| 215 | int core_tmr_alloc_req(struct se_cmd *, void *, u8, gfp_t);
|
| 216 | void core_tmr_release_req(struct se_tmr_req *);
|
| 217 | int transport_generic_handle_tmr(struct se_cmd *);
|
| 218 | void transport_generic_request_failure(struct se_cmd *, sense_reason_t);
|
| 219 | int transport_lookup_tmr_lun(struct se_cmd *);
|
| 220 | void core_allocate_nexus_loss_ua(struct se_node_acl *acl);
|
| 221 |
|
| 222 | struct se_node_acl *core_tpg_get_initiator_node_acl(struct se_portal_group *tpg,
|
| 223 | unsigned char *);
|
| 224 | bool target_tpg_has_node_acl(struct se_portal_group *tpg,
|
| 225 | const char *);
|
| 226 | struct se_node_acl *core_tpg_check_initiator_node_acl(struct se_portal_group *,
|
| 227 | unsigned char *);
|
| 228 | int core_tpg_set_initiator_node_queue_depth(struct se_node_acl *, u32);
|
| 229 | int core_tpg_set_initiator_node_tag(struct se_portal_group *,
|
| 230 | struct se_node_acl *, const char *);
|
| 231 | int core_tpg_register(struct se_wwn *, struct se_portal_group *, int);
|
| 232 | int core_tpg_deregister(struct se_portal_group *);
|
| 233 |
|
| 234 | int target_alloc_sgl(struct scatterlist **sgl, unsigned int *nents,
|
| 235 | u32 length, bool zero_page, bool chainable);
|
| 236 | void target_free_sgl(struct scatterlist *sgl, int nents);
|
| 237 |
|
| 238 | |
| 239 | * The LIO target core uses DMA_TO_DEVICE to mean that data is going
|
| 240 | * to the target (eg handling a WRITE) and DMA_FROM_DEVICE to mean
|
| 241 | * that data is coming from the target (eg handling a READ). However,
|
| 242 | * this is just the opposite of what we have to tell the DMA mapping
|
| 243 | * layer -- eg when handling a READ, the HBA will have to DMA the data
|
| 244 | * out of memory so it can send it to the initiator, which means we
|
| 245 | * need to use DMA_TO_DEVICE when we map the data.
|
| 246 |
|
| 247 | static inline enum dma_data_direction
|
| 248 | target_reverse_dma_direction(struct se_cmd *se_cmd)
|
| 249 | {
|
| 250 | if (se_cmd->se_cmd_flags & SCF_BIDI)
|
| 251 | return DMA_BIDIRECTIONAL;
|
| 252 |
|
| 253 | switch (se_cmd->data_direction) {
|
| 254 | case DMA_TO_DEVICE:
|
| 255 | return DMA_FROM_DEVICE;
|
| 256 | case DMA_FROM_DEVICE:
|
| 257 | return DMA_TO_DEVICE;
|
| 258 | case DMA_NONE:
|
| 259 | default:
|
| 260 | return DMA_NONE;
|
| 261 | }
|
| 262 | }
|
| 263 |
|
| 264 | #endif
|