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 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _SYS_SCSI_IMPL_TRANSPORT_H 27 #define _SYS_SCSI_IMPL_TRANSPORT_H 28 29 30 /* 31 * Include the loadable module wrapper. 32 */ 33 #include <sys/modctl.h> 34 #include <sys/note.h> 35 36 #ifdef __cplusplus 37 extern "C" { 38 #endif 39 40 #ifdef _KERNEL 41 42 /* 43 * SCSI transport structures 44 * 45 * As each Host Adapter makes itself known to the system, 46 * it will create and register with the library the structure 47 * described below. This is so that the library knows how to route 48 * packets, resource control requests, and capability requests 49 * for any particular host adapter. The 'a_hba_tran' field of a 50 * scsi_address structure made known to a Target driver will 51 * point to one of these transport structures. 52 */ 53 54 typedef struct scsi_hba_tran scsi_hba_tran_t; 55 56 struct scsi_hba_tran { 57 /* 58 * Ptr to the device info structure for this particular HBA. 59 */ 60 dev_info_t *tran_hba_dip; 61 62 /* 63 * Private fields for use by the HBA itself. 64 */ 65 void *tran_hba_private; /* HBA softstate */ 66 void *tran_tgt_private; /* target-specific info */ 67 68 /* 69 * Only used to refer to a particular scsi device 70 * if the entire scsi_hba_tran structure is "cloned" 71 * per target device, otherwise NULL. 72 */ 73 struct scsi_device *tran_sd; 74 75 /* 76 * Vectors to point to specific HBA entry points 77 */ 78 79 int (*tran_tgt_init)( 80 dev_info_t *hba_dip, 81 dev_info_t *tgt_dip, 82 scsi_hba_tran_t *hba_tran, 83 struct scsi_device *sd); 84 85 int (*tran_tgt_probe)( 86 struct scsi_device *sd, 87 int (*callback)( 88 void)); 89 void (*tran_tgt_free)( 90 dev_info_t *hba_dip, 91 dev_info_t *tgt_dip, 92 scsi_hba_tran_t *hba_tran, 93 struct scsi_device *sd); 94 95 int (*tran_start)( 96 struct scsi_address *ap, 97 struct scsi_pkt *pkt); 98 99 int (*tran_reset)( 100 struct scsi_address *ap, 101 int level); 102 103 int (*tran_abort)( 104 struct scsi_address *ap, 105 struct scsi_pkt *pkt); 106 107 int (*tran_getcap)( 108 struct scsi_address *ap, 109 char *cap, 110 int whom); 111 112 int (*tran_setcap)( 113 struct scsi_address *ap, 114 char *cap, 115 int value, 116 int whom); 117 118 struct scsi_pkt *(*tran_init_pkt)( 119 struct scsi_address *ap, 120 struct scsi_pkt *pkt, 121 struct buf *bp, 122 int cmdlen, 123 int statuslen, 124 int tgtlen, 125 int flags, 126 int (*callback)( 127 caddr_t arg), 128 caddr_t callback_arg); 129 130 void (*tran_destroy_pkt)( 131 struct scsi_address *ap, 132 struct scsi_pkt *pkt); 133 134 void (*tran_dmafree)( 135 struct scsi_address *ap, 136 struct scsi_pkt *pkt); 137 138 void (*tran_sync_pkt)( 139 struct scsi_address *ap, 140 struct scsi_pkt *pkt); 141 142 int (*tran_reset_notify)( 143 struct scsi_address *ap, 144 int flag, 145 void (*callback)(caddr_t), 146 caddr_t arg); 147 148 int (*tran_get_bus_addr)( 149 struct scsi_device *devp, 150 char *name, 151 int len); 152 153 int (*tran_get_name)( 154 struct scsi_device *devp, 155 char *name, 156 int len); 157 158 int (*tran_clear_aca)( 159 struct scsi_address *ap); 160 161 int (*tran_clear_task_set)( 162 struct scsi_address *ap); 163 164 int (*tran_terminate_task)( 165 struct scsi_address *ap, 166 struct scsi_pkt *pkt); 167 168 int (*tran_get_eventcookie)( 169 dev_info_t *hba_dip, 170 dev_info_t *tgt_dip, 171 char *name, 172 ddi_eventcookie_t *eventp); 173 174 int (*tran_add_eventcall)( 175 dev_info_t *hba_dip, 176 dev_info_t *tgt_dip, 177 ddi_eventcookie_t event, 178 void (*callback)( 179 dev_info_t *tgt_dip, 180 ddi_eventcookie_t event, 181 void *arg, 182 void *bus_impldata), 183 void *arg, 184 ddi_callback_id_t *cb_id); 185 186 int (*tran_remove_eventcall)(dev_info_t *devi, 187 ddi_callback_id_t cb_id); 188 189 int (*tran_post_event)( 190 dev_info_t *hba_dip, 191 dev_info_t *tgt_dip, 192 ddi_eventcookie_t event, 193 void *bus_impldata); 194 195 int (*tran_quiesce)( 196 dev_info_t *hba_dip); 197 198 int (*tran_unquiesce)( 199 dev_info_t *hba_dip); 200 201 int (*tran_bus_reset)( 202 dev_info_t *hba_dip, 203 int level); 204 205 /* 206 * Implementation-private specifics. 207 * No HBA should refer to any of the fields below. 208 * This information can and will change. 209 */ 210 int tran_hba_flags; /* flag options */ 211 212 uint_t tran_obs1; 213 uchar_t tran_obs2; 214 uchar_t tran_obs3; 215 216 /* 217 * open_lock: protect tran_minor_isopen 218 * open_flag: bit field indicating which minor nodes are open. 219 * 0 = closed, 1 = shared open, all bits 1 = excl open. 220 * 221 * XXX Unused if hba driver chooses to implement own 222 * xxopen(9e) entry point 223 */ 224 kmutex_t tran_open_lock; 225 uint64_t tran_open_flag; 226 227 /* 228 * bus_config vectors - ON Consolidation Private 229 * These interfaces are subject to change. 230 */ 231 int (*tran_bus_config)( 232 dev_info_t *hba_dip, 233 uint_t flag, 234 ddi_bus_config_op_t op, 235 void *arg, 236 dev_info_t **tgt_dipp); 237 238 int (*tran_bus_unconfig)( 239 dev_info_t *hba_dip, 240 uint_t flag, 241 ddi_bus_config_op_t op, 242 void *arg); 243 244 int (*tran_bus_power)( 245 dev_info_t *dip, 246 void *impl_arg, 247 pm_bus_power_op_t op, 248 void *arg, 249 void *result); 250 251 /* 252 * Inter-Connect type of trasnport as defined in 253 * usr/src/uts/common/sys/scsi/impl/services.h 254 */ 255 int tran_interconnect_type; 256 257 /* tran_setup_pkt(9E) related scsi_pkt fields */ 258 int (*tran_pkt_constructor)( 259 struct scsi_pkt *pkt, 260 scsi_hba_tran_t *tran, 261 int kmflag); 262 void (*tran_pkt_destructor)( 263 struct scsi_pkt *pkt, 264 scsi_hba_tran_t *tran); 265 kmem_cache_t *tran_pkt_cache_ptr; 266 uint_t tran_hba_len; 267 int (*tran_setup_pkt)( 268 struct scsi_pkt *pkt, 269 int (*callback)( 270 caddr_t arg), 271 caddr_t callback_arg); 272 void (*tran_teardown_pkt)( 273 struct scsi_pkt *pkt); 274 ddi_dma_attr_t tran_dma_attr; 275 276 void *tran_extension; 277 /* 278 * An fm_capable HBA driver can set tran_fm_capable prior to 279 * scsi_hba_attach_setup(). If not set, SCSA provides a default 280 * implementation. 281 */ 282 int tran_fm_capable; 283 284 #ifdef SCSI_SIZE_CLEAN_VERIFY 285 /* 286 * Must be last: Building a driver with-and-without 287 * -DSCSI_SIZE_CLEAN_VERIFY, and checking driver modules for 288 * differences with a tools like 'wsdiff' allows a developer to verify 289 * that their driver has no dependencies on scsi*(9S) size. 290 */ 291 int _pad[8]; 292 #endif /* SCSI_SIZE_CLEAN_VERIFY */ 293 }; 294 size_t scsi_hba_tran_size(); /* private */ 295 296 297 #ifdef __lock_lint 298 _NOTE(SCHEME_PROTECTS_DATA("stable data", 299 scsi_hba_tran::tran_sd 300 scsi_hba_tran::tran_hba_dip 301 scsi_hba_tran::tran_hba_flags 302 scsi_hba_tran::tran_open_flag 303 scsi_hba_tran::tran_pkt_cache_ptr)) 304 /* 305 * we only modify the dma atributes (like dma_attr_granular) upon 306 * attach and in response to a setcap. It is also up to the target 307 * driver to not have any outstanding I/Os when it is changing the 308 * capabilities of the transport. 309 */ 310 _NOTE(SCHEME_PROTECTS_DATA("serialized by target driver", \ 311 scsi_hba_tran::tran_dma_attr.dma_attr_granular)) 312 #endif 313 314 /* 315 * Prototypes for SCSI HBA interface functions 316 * 317 * All these functions are public interfaces, with the 318 * exception of scsi_initialize_hba_interface() and 319 * scsi_uninitialize_hba_interface(), called by the 320 * scsi module _init() and _fini(), respectively. 321 */ 322 323 extern void scsi_initialize_hba_interface(void); 324 325 #ifdef NO_SCSI_FINI_YET 326 extern void scsi_uninitialize_hba_interface(void); 327 #endif /* NO_SCSI_FINI_YET */ 328 329 extern int scsi_hba_init( 330 struct modlinkage *modlp); 331 332 extern void scsi_hba_fini( 333 struct modlinkage *modlp); 334 335 extern int scsi_hba_attach( 336 dev_info_t *hba_dip, 337 ddi_dma_lim_t *hba_lim, 338 scsi_hba_tran_t *hba_tran, 339 int flags, 340 void *hba_options); 341 342 extern int scsi_hba_attach_setup( 343 dev_info_t *hba_dip, 344 ddi_dma_attr_t *hba_dma_attr, 345 scsi_hba_tran_t *hba_tran, 346 int flags); 347 348 extern int scsi_hba_detach( 349 dev_info_t *hba_dip); 350 351 extern scsi_hba_tran_t *scsi_hba_tran_alloc( 352 dev_info_t *hba_dip, 353 int flags); 354 355 extern int scsi_tran_ext_alloc( 356 scsi_hba_tran_t *hba_tran, 357 size_t length, 358 int flags); 359 360 extern void scsi_tran_ext_free( 361 scsi_hba_tran_t *hba_tran, 362 size_t length); 363 364 extern void scsi_hba_tran_free( 365 scsi_hba_tran_t *hba_tran); 366 367 extern int scsi_hba_probe( 368 struct scsi_device *sd, 369 int (*callback)(void)); 370 371 char *scsi_get_device_type_string( 372 char *prop_name, 373 dev_info_t *hba_dip, 374 struct scsi_device *devp); 375 376 extern int scsi_get_device_type_scsi_options( 377 dev_info_t *hba_dip, 378 struct scsi_device *devp, 379 int default_scsi_options); 380 381 extern struct scsi_pkt *scsi_hba_pkt_alloc( 382 dev_info_t *hba_dip, 383 struct scsi_address *ap, 384 int cmdlen, 385 int statuslen, 386 int tgtlen, 387 int hbalen, 388 int (*callback)(caddr_t), 389 caddr_t arg); 390 391 extern void scsi_hba_pkt_free( 392 struct scsi_address *ap, 393 struct scsi_pkt *pkt); 394 395 396 extern int scsi_hba_lookup_capstr( 397 char *capstr); 398 399 extern int scsi_hba_in_panic(void); 400 401 extern int scsi_hba_open( 402 dev_t *devp, 403 int flags, 404 int otyp, 405 cred_t *credp); 406 407 extern int scsi_hba_close( 408 dev_t dev, 409 int flag, 410 int otyp, 411 cred_t *credp); 412 413 extern int scsi_hba_ioctl( 414 dev_t dev, 415 int cmd, 416 intptr_t arg, 417 int mode, 418 cred_t *credp, 419 int *rvalp); 420 421 extern void scsi_hba_nodename_compatible_get( 422 struct scsi_inquiry *inq, 423 char *binding_set, 424 int dtype_node, 425 char *compat0, 426 char **nodenamep, 427 char ***compatiblep, 428 int *ncompatiblep); 429 430 extern void scsi_hba_nodename_compatible_free( 431 char *nodename, 432 char **compatible); 433 434 435 extern int scsi_hba_prop_update_inqstring( 436 struct scsi_device *devp, 437 char *name, 438 char *data, 439 size_t len); 440 441 /* 442 * Flags for scsi_hba_attach 443 */ 444 #define SCSI_HBA_TRAN_CLONE 0x01 /* clone scsi_hba_tran_t */ 445 /* structure per target */ 446 #define SCSI_HBA_TRAN_ALLOC 0x02 /* set if scsi_hba_tran_alloc */ 447 /* is called */ 448 #define SCSI_HBA_TRAN_CDB 0x04 /* allocate cdb */ 449 #define SCSI_HBA_TRAN_SCB 0x08 /* allocate sense */ 450 #define SCSI_HBA_TRAN_FMSCSA 0x10 /* using common ddi_fm_* */ 451 452 /* 453 * Flags for scsi_hba allocation functions 454 */ 455 #define SCSI_HBA_CANSLEEP 0x01 /* can sleep */ 456 457 /* 458 * For minor nodes created by the SCSA framework, minor numbers are 459 * formed by left-shifting instance by INST_MINOR_SHIFT and OR in a 460 * number less than 64. 461 * 462 * - Numbers 0 - 31 are reserved by the framework, part of the range are 463 * in use, as defined below. 464 * 465 * - Numbers 32 - 63 are available for HBA driver use. 466 */ 467 #define INST_MINOR_SHIFT 6 468 #define TRAN_MINOR_MASK ((1 << INST_MINOR_SHIFT) - 1) 469 #define TRAN_OPEN_EXCL (uint64_t)-1 470 471 #define DEVCTL_MINOR 0 472 #define SCSI_MINOR 1 473 474 #define INST2DEVCTL(x) (((x) << INST_MINOR_SHIFT) | DEVCTL_MINOR) 475 #define INST2SCSI(x) (((x) << INST_MINOR_SHIFT) | SCSI_MINOR) 476 #define MINOR2INST(x) ((x) >> INST_MINOR_SHIFT) 477 478 #endif /* _KERNEL */ 479 480 481 #ifdef __cplusplus 482 } 483 #endif 484 485 #endif /* _SYS_SCSI_IMPL_TRANSPORT_H */ 486