1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 24 * Copyright 2016 Nexenta Systems, Inc. All rights reserved. 25 * Copyright (c) 2013 by Delphix. All rights reserved. 26 */ 27 28 #ifndef _STMF_H 29 #define _STMF_H 30 31 #include <sys/stmf_defines.h> 32 33 #ifdef __cplusplus 34 extern "C" { 35 #endif 36 37 typedef enum stmf_struct_id { 38 STMF_STRUCT_LU_PROVIDER = 1, 39 STMF_STRUCT_PORT_PROVIDER, 40 STMF_STRUCT_STMF_LOCAL_PORT, 41 STMF_STRUCT_STMF_LU, 42 STMF_STRUCT_SCSI_SESSION, 43 STMF_STRUCT_SCSI_TASK, 44 STMF_STRUCT_DATA_BUF, 45 STMF_STRUCT_DBUF_STORE, 46 STMF_MAX_STRUCT_IDS 47 } stmf_struct_id_t; 48 49 /* 50 * Provider callback commands 51 */ 52 #define STMF_PROVIDER_DATA_UPDATED 0x01 53 54 /* 55 * Provider callback flags 56 */ 57 #define STMF_PCB_STMF_ONLINING 0x0001 58 #define STMF_PCB_PREG_COMPLETE 0x0002 59 60 typedef void *data_seg_handle_t; 61 #define STMF_MAX_LU_CACHE_NTASKS 16 62 63 #define STMF_NO_HANDLE 0xffffffff 64 65 #define COMPANY_ID_NONE 0xFFFFFFFF 66 #define COMPANY_ID_SUN 0x00144F 67 68 /* 69 * The scatter/gather list buffer format is used in 2 different 70 * contexts within stmf: 71 * 1) supplied by the port provider that the LU provider uses to exchange 72 * data with the backing store. 73 * 2) supplied by the LU provider that the port provider uses exchange 74 * data with the host initiator. 75 * The second format is optionally supported by the port provided as 76 * indicated by the command task flags. 77 */ 78 79 typedef struct stmf_sglist_ent { 80 uint32_t seg_length; 81 uint8_t *seg_addr; 82 } stmf_sglist_ent_t; 83 84 typedef struct stmf_data_buf { 85 void *db_stmf_private; 86 void *db_port_private; 87 void *db_lu_private; 88 uint32_t db_buf_size; /* Total size of this buffer */ 89 uint32_t db_data_size; /* Intended xfer size of this buffer */ 90 uint32_t db_relative_offset; 91 uint16_t db_sglist_length; 92 uint16_t db_flags; /* Direction, auto status etc */ 93 stmf_status_t db_xfer_status; 94 uint8_t db_handle; /* To track parallel buffers */ 95 hrtime_t db_xfer_start_timestamp; 96 stmf_sglist_ent_t db_sglist[1]; /* PP scatter/gather list */ 97 } stmf_data_buf_t; 98 99 /* 100 * db_flags 101 */ 102 #define DB_DIRECTION_TO_RPORT 0x0001 103 #define DB_DIRECTION_FROM_RPORT 0x0002 104 #define DB_SEND_STATUS_GOOD 0x0004 105 #define DB_STATUS_GOOD_SENT 0x0008 106 #define DB_DONT_CACHE 0x0010 107 #define DB_DONT_REUSE 0x0020 108 #define DB_LU_DATA_BUF 0x0040 109 #define DB_LPORT_XFER_ACTIVE 0x8000 110 111 typedef struct scsi_task { 112 void *task_stmf_private; 113 void *task_port_private; 114 115 void *task_lu_private; 116 struct stmf_scsi_session *task_session; 117 struct stmf_local_port *task_lport; 118 struct stmf_lu *task_lu; 119 void *task_lu_itl_handle; /* Assigned by LU */ 120 121 /* CMD information from initiator */ 122 uint8_t task_lun_no[8]; 123 uint8_t task_flags; /* See def. for task flags */ 124 uint8_t task_priority; /* As per SAM-3 */ 125 uint8_t task_mgmt_function; /* If this is a TM request */ 126 uint8_t task_max_nbufs; 127 uint8_t task_cur_nbufs; 128 uint8_t task_csn_size; /* cmd seq no size in bits */ 129 uint16_t task_additional_flags; 130 uint32_t task_cmd_seq_no; 131 uint32_t task_expected_xfer_length; 132 uint32_t task_timeout; /* In seconds */ 133 uint16_t task_ext_id; 134 uint16_t task_cdb_length; 135 uint8_t *task_cdb; 136 137 /* Fields to manage data phase */ 138 uint32_t task_cmd_xfer_length; /* xfer len based on CDB */ 139 uint32_t task_nbytes_transferred; 140 uint32_t task_max_xfer_len; /* largest xfer allowed */ 141 uint32_t task_1st_xfer_len; /* 1st xfer hint */ 142 uint32_t task_copy_threshold; /* copy reduction threshold */ 143 144 145 /* Status Phase */ 146 stmf_status_t task_completion_status; 147 uint32_t task_resid; 148 uint8_t task_status_ctrl; /* See def. for status ctrl */ 149 uint8_t task_scsi_status; 150 uint16_t task_sense_length; 151 uint8_t *task_sense_data; 152 153 /* Misc. task data */ 154 void *task_extended_cmd; 155 156 } scsi_task_t; 157 158 /* 159 * Maximum expected transfer length. Can also be used when the transfer 160 * length is unknown when the task is allocated (e.g. SAS) 161 */ 162 163 #define TASK_MAX_XFER_LENGTH 0xFFFFFFFF 164 165 /* 166 * task_flags definitions. 167 */ 168 /* 169 * If TF_INITIAL_BURST is set, the dbuf passed with new_task() contains 170 * data from initial burst. Otherwise its just a buffer which the port 171 * passed to the LU. 172 */ 173 #define TF_INITIAL_BURST 0x80 174 /* Both READ_DATA and WRITE_DATA can be set for bidirectional xfers */ 175 #define TF_READ_DATA 0x40 176 #define TF_WRITE_DATA 0x20 177 #define TF_ATTR_MASK 0x07 178 #define TF_ATTR_UNTAGGED 0x0 179 #define TF_ATTR_SIMPLE_QUEUE 0x1 180 #define TF_ATTR_ORDERED_QUEUE 0x2 181 #define TF_ATTR_HEAD_OF_QUEUE 0x3 182 #define TF_ATTR_ACA 0x4 183 184 /* 185 * Task Management flags. 186 */ 187 #define TM_NONE 0x00 188 #define TM_ABORT_TASK 0x01 189 #define TM_ABORT_TASK_SET 0x02 190 #define TM_CLEAR_ACA 0x03 191 #define TM_CLEAR_TASK_SET 0x04 192 #define TM_LUN_RESET 0x05 193 #define TM_TARGET_WARM_RESET 0x06 194 #define TM_TARGET_COLD_RESET 0x07 195 #define TM_TASK_REASSIGN 0x08 196 #define TM_TARGET_RESET 0x09 197 #define TM_QUERY_TASK 0x0A 198 199 /* 200 * additional flags 201 */ 202 #define TASK_AF_ENABLE_COMP_CONF 0x01 203 #define TASK_AF_PORT_LOAD_HIGH 0x02 204 #define TASK_AF_NO_EXPECTED_XFER_LENGTH 0x04 205 /* 206 * PP sets this flag if it can process dbufs created by the LU. 207 */ 208 #define TASK_AF_ACCEPT_LU_DBUF 0x08 209 210 /* 211 * Indicating a PPPT task 212 */ 213 #define TASK_AF_PPPT_TASK 0x10 214 215 /* 216 * scsi_task_t extension identifiers 217 */ 218 #define STMF_TASK_EXT_NONE 0 219 220 /* 221 * max_nbufs 222 */ 223 #define STMF_BUFS_MAX 255 224 225 /* 226 * Task status ctrl 227 */ 228 #define TASK_SCTRL_OVER 1 229 #define TASK_SCTRL_UNDER 2 230 231 /* 232 * The flags used by I/O flow. 233 */ 234 #define STMF_IOF_LU_DONE 0x0001 235 #define STMF_IOF_LPORT_DONE 0x0002 236 #define STMF_IOF_STATS_ONLY 0x0004 237 238 /* 239 * struct allocation flags 240 */ 241 #define AF_FORCE_NOSLEEP 0x0001 242 #define AF_DONTZERO 0x0002 243 244 typedef struct stmf_state_change_info { 245 uint64_t st_rflags; /* Reason behind this change */ 246 char *st_additional_info; 247 } stmf_state_change_info_t; 248 249 typedef struct stmf_change_status { 250 stmf_status_t st_completion_status; 251 char *st_additional_info; 252 } stmf_change_status_t; 253 254 /* 255 * conditions causing or affecting the change. 256 */ 257 #define STMF_RFLAG_USER_REQUEST 0x0001 258 #define STMF_RFLAG_FATAL_ERROR 0x0002 259 #define STMF_RFLAG_STAY_OFFLINED 0x0004 260 #define STMF_RFLAG_RESET 0x0008 261 #define STMF_RFLAG_COLLECT_DEBUG_DUMP 0x0010 262 #define STMF_RFLAG_LU_ABORT 0x0020 263 #define STMF_RFLAG_LPORT_ABORT 0x0040 264 265 #define STMF_CHANGE_INFO_LEN 160 266 267 /* 268 * cmds to stmf_abort entry point 269 */ 270 #define STMF_QUEUE_TASK_ABORT 1 271 #define STMF_REQUEUE_TASK_ABORT_LPORT 2 272 #define STMF_REQUEUE_TASK_ABORT_LU 3 273 #define STMF_QUEUE_ABORT_LU 4 274 275 /* 276 * cmds to be used by stmf ctl 277 */ 278 #define STMF_CMD_LU_OP 0x0100 279 #define STMF_CMD_LPORT_OP 0x0200 280 #define STMF_CMD_MASK 0x00ff 281 #define STMF_CMD_ONLINE 0x0001 282 #define STMF_CMD_OFFLINE 0x0002 283 #define STMF_CMD_GET_STATUS 0x0003 284 #define STMF_CMD_ONLINE_COMPLETE 0x0004 285 #define STMF_CMD_OFFLINE_COMPLETE 0x0005 286 #define STMF_ACK_ONLINE_COMPLETE 0x0006 287 #define STMF_ACK_OFFLINE_COMPLETE 0x0007 288 289 #define STMF_CMD_LU_ONLINE (STMF_CMD_LU_OP | STMF_CMD_ONLINE) 290 #define STMF_CMD_LU_OFFLINE (STMF_CMD_LU_OP | STMF_CMD_OFFLINE) 291 #define STMF_CMD_LPORT_ONLINE (STMF_CMD_LPORT_OP | STMF_CMD_ONLINE) 292 #define STMF_CMD_LPORT_OFFLINE (STMF_CMD_LPORT_OP | STMF_CMD_OFFLINE) 293 #define STMF_CMD_GET_LU_STATUS (STMF_CMD_LU_OP | STMF_CMD_GET_STATUS) 294 #define STMF_CMD_GET_LPORT_STATUS \ 295 (STMF_CMD_LPORT_OP | STMF_CMD_GET_STATUS) 296 #define STMF_CMD_LU_ONLINE_COMPLETE \ 297 (STMF_CMD_LU_OP | STMF_CMD_ONLINE_COMPLETE) 298 #define STMF_CMD_LPORT_ONLINE_COMPLETE \ 299 (STMF_CMD_LPORT_OP | STMF_CMD_ONLINE_COMPLETE) 300 #define STMF_ACK_LU_ONLINE_COMPLETE \ 301 (STMF_CMD_LU_OP | STMF_ACK_ONLINE_COMPLETE) 302 #define STMF_ACK_LPORT_ONLINE_COMPLETE \ 303 (STMF_CMD_LPORT_OP | STMF_ACK_ONLINE_COMPLETE) 304 #define STMF_CMD_LU_OFFLINE_COMPLETE \ 305 (STMF_CMD_LU_OP | STMF_CMD_OFFLINE_COMPLETE) 306 #define STMF_CMD_LPORT_OFFLINE_COMPLETE \ 307 (STMF_CMD_LPORT_OP | STMF_CMD_OFFLINE_COMPLETE) 308 #define STMF_ACK_LU_OFFLINE_COMPLETE \ 309 (STMF_CMD_LU_OP | STMF_ACK_OFFLINE_COMPLETE) 310 #define STMF_ACK_LPORT_OFFLINE_COMPLETE \ 311 (STMF_CMD_LPORT_OP | STMF_ACK_OFFLINE_COMPLETE) 312 /* 313 * For LPORTs and LUs to create their own ctl cmds which dont 314 * conflict with stmf ctl cmds. 315 */ 316 #define STMF_LPORT_CTL_CMDS 0x1000 317 #define STMF_LU_CTL_CMDS 0x2000 318 319 /* 320 * Commands for various info routines. 321 */ 322 /* Command classifiers */ 323 #define SI_LPORT 0x1000000 324 #define SI_STMF 0x2000000 325 #define SI_LU 0x4000000 326 #define SI_LPORT_FC 0x0000000 327 #define SI_LPORT_ISCSI 0x0010000 328 #define SI_LPORT_SAS 0x0020000 329 #define SI_STMF_LU 0x0010000 330 #define SI_STMF_LPORT 0x0020000 331 332 #define SI_GET_CLASS(v) ((v) & 0xFF000000) 333 #define SI_GET_SUBCLASS(v) ((v) & 0x00FF0000) 334 335 /* Commands for LPORT info routines */ 336 /* XXX - Implement these. */ 337 #if 0 338 #define SI_LPORT_FC_PORTINFO (SI_LPORT | SI_LPORT_FC | 1) 339 #define SI_RPORT_FC_PORTINFO (SI_LPORT | SI_LPORT_FC | 2) 340 #endif 341 342 /* 343 * Events 344 */ 345 #define STMF_EVENT_ALL ((int)-1) 346 #define LPORT_EVENT_INITIAL_LUN_MAPPED 0 347 348 /* 349 * This needs to go into common/ddi/sunddi.h 350 */ 351 #define DDI_NT_STMF "ddi_scsi_target:framework" 352 #define DDI_NT_STMF_LP "ddi_scsi_target:lu_provider" 353 #define DDI_NT_STMF_PP "ddi_scsi_target:port_provider" 354 355 /* 356 * VPD page bits. 357 */ 358 #define STMF_VPD_LU_ID 0x01 359 #define STMF_VPD_TARGET_ID 0x02 360 #define STMF_VPD_TP_GROUP 0x04 361 #define STMF_VPD_RELATIVE_TP_ID 0x08 362 363 /* 364 * Common macros to simplify coding 365 */ 366 #define STMF_SEC2TICK(x_sec) (drv_usectohz((x_sec) * 1000000)) 367 368 void stmf_trace(caddr_t ident, const char *fmt, ...); 369 void *stmf_alloc(stmf_struct_id_t sid, int additional_size, int alloc_flags); 370 void stmf_free(void *struct_ptr); 371 struct scsi_task *stmf_task_alloc(struct stmf_local_port *lport, 372 struct stmf_scsi_session *ss, uint8_t *lun, uint16_t cdb_length, 373 uint16_t ext_id); 374 void stmf_post_task(scsi_task_t *task, stmf_data_buf_t *dbuf); 375 stmf_data_buf_t *stmf_alloc_dbuf(scsi_task_t *task, uint32_t size, 376 uint32_t *pminsize, uint32_t flags); 377 void stmf_free_dbuf(scsi_task_t *task, stmf_data_buf_t *dbuf); 378 stmf_status_t stmf_setup_dbuf(scsi_task_t *task, stmf_data_buf_t *dbuf, 379 uint32_t flags); 380 void stmf_teardown_dbuf(scsi_task_t *task, stmf_data_buf_t *dbuf); 381 stmf_status_t stmf_xfer_data(scsi_task_t *task, stmf_data_buf_t *dbuf, 382 uint32_t ioflags); 383 stmf_status_t stmf_send_scsi_status(scsi_task_t *task, uint32_t ioflags); 384 void stmf_data_xfer_done(scsi_task_t *task, stmf_data_buf_t *dbuf, 385 uint32_t iof); 386 void stmf_send_status_done(scsi_task_t *task, stmf_status_t s, uint32_t iof); 387 void stmf_task_lu_done(scsi_task_t *task); 388 void stmf_abort(int abort_cmd, scsi_task_t *task, stmf_status_t s, void *arg); 389 void stmf_task_lu_aborted(scsi_task_t *task, stmf_status_t s, uint32_t iof); 390 void stmf_task_lport_aborted_unlocked(scsi_task_t *task, stmf_status_t s, 391 uint32_t iof); 392 stmf_status_t stmf_task_poll_lu(scsi_task_t *task, uint32_t timeout); 393 stmf_status_t stmf_task_poll_lport(scsi_task_t *task, uint32_t timeout); 394 stmf_status_t stmf_ctl(int cmd, void *obj, void *arg); 395 stmf_status_t stmf_register_itl_handle(struct stmf_lu *lu, uint8_t *lun, 396 struct stmf_scsi_session *ss, uint64_t session_id, void *itl_handle); 397 stmf_status_t stmf_deregister_all_lu_itl_handles(struct stmf_lu *lu); 398 stmf_status_t stmf_get_itl_handle(struct stmf_lu *lu, uint8_t *lun, 399 struct stmf_scsi_session *ss, uint64_t session_id, void **itl_handle_retp); 400 stmf_data_buf_t *stmf_handle_to_buf(scsi_task_t *task, uint8_t h); 401 stmf_status_t stmf_lu_add_event(struct stmf_lu *lu, int eventid); 402 stmf_status_t stmf_lu_remove_event(struct stmf_lu *lu, int eventid); 403 stmf_status_t stmf_lport_add_event(struct stmf_local_port *lport, int eventid); 404 stmf_status_t stmf_lport_remove_event(struct stmf_local_port *lport, 405 int eventid); 406 void stmf_wwn_to_devid_desc(struct scsi_devid_desc *sdid, uint8_t *wwn, 407 uint8_t protocol_id); 408 stmf_status_t stmf_scsilib_uniq_lu_id(uint32_t company_id, 409 struct scsi_devid_desc *lu_id); 410 stmf_status_t stmf_scsilib_uniq_lu_id2(uint32_t company_id, uint32_t host_id, 411 struct scsi_devid_desc *lu_id); 412 void stmf_scsilib_send_status(scsi_task_t *task, uint8_t st, uint32_t saa); 413 uint32_t stmf_scsilib_prepare_vpd_page83(scsi_task_t *task, uint8_t *page, 414 uint32_t page_len, uint8_t byte0, uint32_t vpd_mask); 415 uint16_t stmf_scsilib_get_lport_rtid(struct scsi_devid_desc *devid); 416 struct scsi_devid_desc *stmf_scsilib_get_devid_desc(uint16_t rtpid); 417 void stmf_scsilib_handle_report_tpgs(scsi_task_t *task, stmf_data_buf_t *dbuf); 418 void stmf_scsilib_handle_task_mgmt(scsi_task_t *task); 419 420 struct stmf_remote_port *stmf_scsilib_devid_to_remote_port( 421 struct scsi_devid_desc *); 422 boolean_t stmf_scsilib_tptid_validate(struct scsi_transport_id *, 423 uint32_t, uint16_t *); 424 boolean_t stmf_scsilib_tptid_compare(struct scsi_transport_id *, 425 struct scsi_transport_id *); 426 struct stmf_remote_port *stmf_remote_port_alloc(uint16_t); 427 void stmf_remote_port_free(struct stmf_remote_port *); 428 struct stmf_lu *stmf_check_and_hold_lu(struct scsi_task *task, uint8_t *guid); 429 void stmf_release_lu(struct stmf_lu *lu); 430 int stmf_is_task_being_aborted(struct scsi_task *task); 431 #ifdef __cplusplus 432 } 433 #endif 434 435 #endif /* _STMF_H */ 436