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 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 23 */ 24 #ifndef _STMF_IMPL_H 25 #define _STMF_IMPL_H 26 27 #include <sys/stmf_defines.h> 28 #include <sys/stmf_ioctl.h> 29 30 #ifdef __cplusplus 31 extern "C" { 32 #endif 33 34 typedef uint32_t stmf_event_handle_t; 35 #define STMF_MAX_NUM_EVENTS (sizeof (stmf_event_handle_t) * 8) 36 #define STMF_EVENT_ADD(h, e) (atomic_or_32(&(h), \ 37 ((uint32_t)1) << (e))) 38 #define STMF_EVENT_REMOVE(h, e) (atomic_and_32(&(h), \ 39 ~(((uint32_t)1) << (e)))) 40 #define STMF_EVENT_ENABLED(h, e) (((h) & ((uint32_t)1) << (e)) != 0) 41 #define STMF_EVENT_CLEAR_ALL(h) ((h) = 0) 42 #define STMF_EVENT_ALLOC_HANDLE(h) ((h) = 0) 43 #define STMF_EVENT_FREE_HANDLE(h) ((h) = 0) 44 45 #define STMF_TGT_NAME_LEN 256 46 #define STMF_GUID_INPUT 32 47 48 #define STMF_UPDATE_KSTAT_IO(kip, dbuf) \ 49 if (dbuf->db_flags & DB_DIRECTION_TO_RPORT) { \ 50 kip->reads++; \ 51 kip->nread += dbuf->db_data_size; \ 52 } else { \ 53 kip->writes++; \ 54 kip->nwritten += dbuf->db_data_size; \ 55 } 56 57 struct stmf_i_scsi_task; 58 struct stmf_itl_data; 59 60 typedef struct stmf_i_lu_provider { 61 stmf_lu_provider_t *ilp_lp; 62 uint32_t ilp_alloc_size; 63 uint32_t ilp_nlus; /* # LUNs being exported */ 64 uint32_t ilp_cb_in_progress:1, 65 ilp_rsvd:31; 66 struct stmf_i_lu_provider *ilp_next; 67 struct stmf_pp_data *ilp_ppd; 68 } stmf_i_lu_provider_t; 69 70 typedef struct stmf_i_lu { 71 stmf_lu_t *ilu_lu; 72 uint32_t ilu_alloc_size; 73 uint32_t ilu_flags; 74 uint32_t ilu_ref_cnt; 75 uint8_t ilu_state; 76 uint8_t ilu_prev_state; 77 uint8_t ilu_access; 78 uint8_t ilu_alua; 79 stmf_event_handle_t ilu_event_hdl; 80 struct stmf_i_lu *ilu_next; 81 struct stmf_i_lu *ilu_prev; 82 char *ilu_alias; 83 char ilu_ascii_hex_guid[STMF_GUID_INPUT + 1]; 84 kmutex_t ilu_task_lock; 85 uint32_t ilu_task_cntr1; 86 uint32_t ilu_task_cntr2; 87 uint32_t *ilu_cur_task_cntr; 88 uint32_t ilu_ntasks; /* # of tasks in the ilu_task list */ 89 uint32_t ilu_ntasks_free; /* # of tasks that are free */ 90 uint32_t ilu_ntasks_min_free; /* # minimal free tasks */ 91 uint32_t rsvd1; 92 uint32_t ilu_proxy_registered; 93 uint64_t ilu_reg_msgid; 94 struct stmf_i_scsi_task *ilu_tasks; 95 struct stmf_i_scsi_task *ilu_free_tasks; 96 struct stmf_itl_data *ilu_itl_list; 97 kstat_t *ilu_kstat_info; 98 kstat_t *ilu_kstat_io; 99 kmutex_t ilu_kstat_lock; 100 101 /* point to the luid entry in stmf_state.stmf_luid_list */ 102 void *ilu_luid; 103 } stmf_i_lu_t; 104 105 /* 106 * ilu_flags 107 */ 108 #define ILU_STALL_DEREGISTER 0x0001 109 #define ILU_RESET_ACTIVE 0x0002 110 111 typedef struct stmf_i_port_provider { 112 stmf_port_provider_t *ipp_pp; 113 uint32_t ipp_alloc_size; 114 uint32_t ipp_npps; 115 uint32_t ipp_cb_in_progress:1, 116 ipp_rsvd:31; 117 struct stmf_i_port_provider *ipp_next; 118 struct stmf_pp_data *ipp_ppd; 119 } stmf_i_port_provider_t; 120 121 #define MAX_ILPORT 0x10000 122 123 typedef struct stmf_i_local_port { 124 stmf_local_port_t *ilport_lport; 125 uint32_t ilport_alloc_size; 126 uint32_t ilport_nsessions; 127 struct stmf_i_scsi_session *ilport_ss_list; 128 krwlock_t ilport_lock; 129 struct stmf_i_local_port *ilport_next; 130 struct stmf_i_local_port *ilport_prev; 131 uint8_t ilport_state; 132 uint8_t ilport_prev_state; 133 uint8_t ilport_standby; 134 uint8_t ilport_alua; 135 uint16_t ilport_rtpid; /* relative tpid */ 136 uint16_t ilport_proxy_registered; 137 uint64_t ilport_reg_msgid; 138 uint8_t ilport_no_standby_lu; 139 uint32_t ilport_unexpected_comp; 140 stmf_event_handle_t ilport_event_hdl; 141 clock_t ilport_last_online_clock; 142 clock_t ilport_avg_interval; 143 uint32_t ilport_online_times; 144 uint32_t ilport_flags; 145 kstat_t *ilport_kstat_info; 146 kstat_t *ilport_kstat_io; 147 kmutex_t ilport_kstat_lock; 148 char ilport_kstat_tgt_name[STMF_TGT_NAME_LEN]; 149 /* which target group this port belongs to in stmf_state.stmf_tg_list */ 150 void *ilport_tg; 151 id_t ilport_instance; 152 /* XXX Need something to track all the remote ports also */ 153 } stmf_i_local_port_t; 154 155 #define STMF_AVG_ONLINE_INTERVAL (30 * drv_usectohz(1000000)) 156 157 #define MAX_IRPORT 0x10000 158 159 typedef struct stmf_i_remote_port { 160 struct scsi_devid_desc *irport_id; 161 kmutex_t irport_mutex; 162 int irport_refcnt; 163 id_t irport_instance; 164 avl_node_t irport_ln; 165 } stmf_i_remote_port_t; 166 167 typedef struct stmf_i_itl_kstat { 168 char iitl_kstat_nm[KSTAT_STRLEN]; 169 char iitl_kstat_lport[STMF_TGT_NAME_LEN]; 170 char iitl_kstat_guid[STMF_GUID_INPUT + 1]; 171 char *iitl_kstat_strbuf; 172 int iitl_kstat_strbuflen; 173 kstat_t *iitl_kstat_info; 174 kstat_t *iitl_kstat_taskq; 175 kstat_t *iitl_kstat_lu_xfer; 176 kstat_t *iitl_kstat_lport_xfer; 177 avl_node_t iitl_kstat_ln; 178 } stmf_i_itl_kstat_t; 179 180 /* 181 * ilport flags 182 */ 183 #define ILPORT_FORCED_OFFLINE 0x01 184 #define ILPORT_SS_GOT_INITIAL_LUNS 0x02 185 186 typedef struct stmf_i_scsi_session { 187 stmf_scsi_session_t *iss_ss; 188 uint32_t iss_alloc_size; 189 uint32_t iss_flags; 190 stmf_i_remote_port_t *iss_irport; 191 struct stmf_i_scsi_session *iss_next; 192 /* 193 * Ideally we should maintain 2 maps. One would indicate a new map 194 * which will become available only upon receipt of a REPORT LUN 195 * cmd. 196 */ 197 struct stmf_lun_map *iss_sm; 198 /* 199 * which host group the host of this session belongs to in 200 * stmf_state.stmf_hg_list 201 */ 202 void *iss_hg; 203 krwlock_t *iss_lockp; 204 time_t iss_creation_time; 205 } stmf_i_scsi_session_t; 206 207 /* 208 * iss flags 209 */ 210 #define ISS_LUN_INVENTORY_CHANGED 0x0001 211 #define ISS_RESET_ACTIVE 0x0002 212 #define ISS_BEING_CREATED 0x0004 213 #define ISS_GOT_INITIAL_LUNS 0x0008 214 #define ISS_EVENT_ACTIVE 0x0010 215 #define ISS_NULL_TPTID 0x0020 216 217 #define ITASK_MAX_NCMDS 14 218 #define ITASK_DEFAULT_POLL_TIMEOUT 0 219 220 #define ITASK_TASK_AUDIT_DEPTH 32 /* Must be a power of 2 */ 221 222 typedef enum { 223 TE_UNDEFINED, 224 TE_TASK_START, 225 TE_XFER_START, 226 TE_XFER_DONE, 227 TE_SEND_STATUS, 228 TE_SEND_STATUS_DONE, 229 TE_TASK_FREE, 230 TE_TASK_ABORT, 231 TE_TASK_LPORT_ABORTED, 232 TE_TASK_LU_ABORTED, 233 TE_PROCESS_CMD 234 } task_audit_event_t; 235 236 #define CMD_OR_IOF_NA 0xffffffff 237 238 typedef struct stmf_task_audit_rec { 239 task_audit_event_t ta_event; 240 uint32_t ta_cmd_or_iof; 241 uint32_t ta_itask_flags; 242 stmf_data_buf_t *ta_dbuf; 243 timespec_t ta_timestamp; 244 } stmf_task_audit_rec_t; 245 246 struct stmf_worker; 247 typedef struct stmf_i_scsi_task { 248 scsi_task_t *itask_task; 249 uint32_t itask_alloc_size; 250 uint32_t itask_flags; 251 uint64_t itask_proxy_msg_id; 252 stmf_data_buf_t *itask_proxy_dbuf; 253 struct stmf_worker *itask_worker; 254 uint32_t *itask_ilu_task_cntr; 255 struct stmf_i_scsi_task *itask_worker_next; 256 struct stmf_i_scsi_task *itask_lu_next; 257 struct stmf_i_scsi_task *itask_lu_prev; 258 struct stmf_i_scsi_task *itask_lu_free_next; 259 struct stmf_i_scsi_task *itask_abort_next; 260 struct stmf_itl_data *itask_itl_datap; 261 clock_t itask_start_time; /* abort and normal */ 262 /* For now we only support 4 parallel buffers. Should be enough. */ 263 stmf_data_buf_t *itask_dbufs[4]; 264 clock_t itask_poll_timeout; 265 uint8_t itask_cmd_stack[ITASK_MAX_NCMDS]; 266 uint8_t itask_ncmds; 267 uint8_t itask_allocated_buf_map; 268 uint16_t itask_cdb_buf_size; 269 270 /* Task profile data */ 271 hrtime_t itask_start_timestamp; 272 hrtime_t itask_done_timestamp; 273 hrtime_t itask_waitq_enter_timestamp; 274 hrtime_t itask_waitq_time; 275 hrtime_t itask_lu_read_time; 276 hrtime_t itask_lu_write_time; 277 hrtime_t itask_lport_read_time; 278 hrtime_t itask_lport_write_time; 279 uint64_t itask_read_xfer; 280 uint64_t itask_write_xfer; 281 kmutex_t itask_audit_mutex; 282 uint8_t itask_audit_index; 283 stmf_task_audit_rec_t itask_audit_records[ITASK_TASK_AUDIT_DEPTH]; 284 } stmf_i_scsi_task_t; 285 286 #define ITASK_DEFAULT_ABORT_TIMEOUT 5 287 288 /* 289 * itask_flags 290 */ 291 #define ITASK_IN_FREE_LIST 0x0001 292 #define ITASK_IN_TRANSITION 0x0002 293 #define ITASK_IN_WORKER_QUEUE 0x0004 294 #define ITASK_BEING_ABORTED 0x0008 295 #define ITASK_BEING_COMPLETED 0x0010 296 #define ITASK_KNOWN_TO_TGT_PORT 0x0020 297 #define ITASK_KNOWN_TO_LU 0x0040 298 #define ITASK_LU_ABORT_CALLED 0x0080 299 #define ITASK_TGT_PORT_ABORT_CALLED 0x0100 300 #define ITASK_DEFAULT_HANDLING 0x0200 301 #define ITASK_CAUSING_LU_RESET 0x0400 302 #define ITASK_CAUSING_TARGET_RESET 0x0800 303 #define ITASK_KSTAT_IN_RUNQ 0x1000 304 #define ITASK_PROXY_TASK 0x2000 305 306 /* 307 * itask cmds. 308 */ 309 #define ITASK_CMD_MASK 0x1F 310 #define ITASK_CMD_BUF_NDX(cmd) (((uint8_t)(cmd)) >> 5) 311 #define ITASK_CMD_NEW_TASK 0x1 312 #define ITASK_CMD_DATA_XFER_DONE 0x2 313 #define ITASK_CMD_STATUS_DONE 0x3 314 #define ITASK_CMD_ABORT 0x4 315 #define ITASK_CMD_SEND_STATUS 0x5 316 #define ITASK_CMD_POLL 0x10 317 #define ITASK_CMD_POLL_LU (ITASK_CMD_POLL | 1) 318 #define ITASK_CMD_POLL_LPORT (ITASK_CMD_POLL | 2) 319 320 /* 321 * struct maintained on a per itl basis when the lu registers ITL handle. 322 */ 323 typedef struct stmf_itl_data { 324 uint32_t itl_counter; 325 uint8_t itl_flags; 326 uint8_t itl_hdlrm_reason; 327 uint16_t itl_lun; 328 char *itl_kstat_strbuf; 329 int itl_kstat_strbuflen; 330 kstat_t *itl_kstat_info; 331 kstat_t *itl_kstat_taskq; 332 kstat_t *itl_kstat_lu_xfer; 333 kstat_t *itl_kstat_lport_xfer; 334 void *itl_handle; 335 struct stmf_i_lu *itl_ilu; 336 struct stmf_i_scsi_session *itl_session; 337 struct stmf_itl_data *itl_next; 338 } stmf_itl_data_t; 339 340 /* 341 * itl flags 342 */ 343 #define STMF_ITL_BEING_TERMINATED 0x01 344 345 /* 346 * data structures to maintain provider private data. 347 */ 348 typedef struct stmf_pp_data { 349 struct stmf_pp_data *ppd_next; 350 void *ppd_provider; 351 nvlist_t *ppd_nv; 352 uint32_t ppd_lu_provider:1, 353 ppd_port_provider:1, 354 ppd_rsvd:30; 355 uint32_t ppd_alloc_size; 356 uint64_t ppd_token; 357 char ppd_name[8]; 358 } stmf_pp_data_t; 359 360 typedef struct stmf_worker { 361 kthread_t *worker_tid; 362 stmf_i_scsi_task_t *worker_task_head; 363 stmf_i_scsi_task_t *worker_task_tail; 364 stmf_i_scsi_task_t *worker_wait_head; 365 stmf_i_scsi_task_t *worker_wait_tail; 366 kmutex_t worker_lock; 367 kcondvar_t worker_cv; 368 uint32_t worker_flags; 369 uint32_t worker_queue_depth; /* ntasks cur queued */ 370 uint32_t worker_max_qdepth_pu; /* maxqd / unit time */ 371 uint32_t worker_max_sys_qdepth_pu; /* for all workers */ 372 uint32_t worker_ref_count; /* # IOs referencing */ 373 hrtime_t worker_signal_timestamp; 374 } stmf_worker_t; 375 376 /* 377 * worker flags 378 */ 379 #define STMF_WORKER_STARTED 1 380 #define STMF_WORKER_ACTIVE 2 381 #define STMF_WORKER_TERMINATE 4 382 383 /* 384 * data struct for managing transfers. 385 */ 386 typedef struct stmf_xfer_data { 387 uint32_t alloc_size; /* Including this struct */ 388 uint32_t size_done; 389 uint32_t size_left; 390 uint8_t buf[4]; 391 } stmf_xfer_data_t; 392 393 /* 394 * Define frequently used macros 395 */ 396 #define TASK_TO_ITASK(x_task) \ 397 ((stmf_i_scsi_task_t *)(x_task)->task_stmf_private) 398 399 void stmf_dlun_init(); 400 stmf_status_t stmf_dlun_fini(); 401 void stmf_worker_init(); 402 stmf_status_t stmf_worker_fini(); 403 void stmf_task_free(scsi_task_t *task); 404 void stmf_do_task_abort(scsi_task_t *task); 405 void stmf_do_itl_dereg(stmf_lu_t *lu, stmf_itl_data_t *itl, 406 uint8_t hdlrm_reason); 407 void stmf_generate_lu_event(stmf_i_lu_t *ilu, int eventid, 408 void *arg, uint32_t flags); 409 void stmf_generate_lport_event(stmf_i_local_port_t *ilport, int eventid, 410 void *arg, uint32_t flags); 411 412 #ifdef __cplusplus 413 } 414 #endif 415 416 #endif /* _STMF_IMPL_H */ 417