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) 1990, 2010, Oracle and/or its affiliates. All rights reserved. 23 * Copyright 2014 Garrett D'Amore <garrett@damore.org> 24 * Copyright 2022 RackTop Systems, Inc. 25 */ 26 27 #ifndef _SYS_SCSI_IMPL_TRANSPORT_H 28 #define _SYS_SCSI_IMPL_TRANSPORT_H 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 * Opaque handles to address maps 44 */ 45 typedef struct __scsi_iportmap scsi_hba_iportmap_t; 46 typedef struct __scsi_tgtmap scsi_hba_tgtmap_t; 47 48 /* 49 * SCSI transport structures 50 * 51 * As each Host Adapter makes itself known to the system, 52 * it will create and register with the library the structure 53 * described below. This is so that the library knows how to route 54 * packets, resource control requests, and capability requests 55 * for any particular host adapter. The 'a_hba_tran' field of a 56 * scsi_address structure made known to a Target driver will 57 * point to one of these transport structures. 58 */ 59 60 typedef struct scsi_hba_tran scsi_hba_tran_t; 61 62 struct scsi_hba_tran { 63 /* 64 * Ptr to the device info structure for this particular HBA. If a SCSA 65 * HBA driver separates initiator port function from HBA function, 66 * this field still refers to the HBA and is used to manage DMA. 67 */ 68 dev_info_t *tran_hba_dip; 69 70 /* 71 * Private fields for use by the HBA itself. 72 */ 73 void *tran_hba_private; /* HBA softstate */ 74 75 /* 76 * The following two fields are only used in the deprecated 77 * SCSI_HBA_TRAN_CLONE case. Use SCSI_HBA_ADDR_COMPLEX instead. 78 */ 79 void *tran_tgt_private; 80 struct scsi_device *tran_sd; 81 82 /* 83 * Vectors to point to specific HBA entry points 84 */ 85 int (*tran_tgt_init)( 86 dev_info_t *hba_dip, 87 dev_info_t *tgt_dip, 88 scsi_hba_tran_t *tran, 89 struct scsi_device *sd); 90 91 int (*tran_tgt_probe)( 92 struct scsi_device *sd, 93 int (*callback)( 94 void)); 95 void (*tran_tgt_free)( 96 dev_info_t *hba_dip, 97 dev_info_t *tgt_dip, 98 scsi_hba_tran_t *tran, 99 struct scsi_device *sd); 100 101 int (*tran_start)( 102 struct scsi_address *ap, 103 struct scsi_pkt *pkt); 104 105 int (*tran_reset)( 106 struct scsi_address *ap, 107 int level); 108 109 int (*tran_abort)( 110 struct scsi_address *ap, 111 struct scsi_pkt *pkt); 112 113 int (*tran_getcap)( 114 struct scsi_address *ap, 115 char *cap, 116 int whom); 117 118 int (*tran_setcap)( 119 struct scsi_address *ap, 120 char *cap, 121 int value, 122 int whom); 123 124 struct scsi_pkt *(*tran_init_pkt)( 125 struct scsi_address *ap, 126 struct scsi_pkt *pkt, 127 struct buf *bp, 128 int cmdlen, 129 int statuslen, 130 int tgtlen, 131 int flags, 132 int (*callback)( 133 caddr_t arg), 134 caddr_t callback_arg); 135 136 void (*tran_destroy_pkt)( 137 struct scsi_address *ap, 138 struct scsi_pkt *pkt); 139 140 void (*tran_dmafree)( 141 struct scsi_address *ap, 142 struct scsi_pkt *pkt); 143 144 void (*tran_sync_pkt)( 145 struct scsi_address *ap, 146 struct scsi_pkt *pkt); 147 148 int (*tran_reset_notify)( 149 struct scsi_address *ap, 150 int flag, 151 void (*callback)(caddr_t), 152 caddr_t arg); 153 154 int (*tran_get_bus_addr)( 155 struct scsi_device *sd, 156 char *name, 157 int len); 158 159 int (*tran_get_name)( 160 struct scsi_device *sd, 161 char *name, 162 int len); 163 164 int (*tran_clear_aca)( 165 struct scsi_address *ap); 166 167 int (*tran_clear_task_set)( 168 struct scsi_address *ap); 169 170 int (*tran_terminate_task)( 171 struct scsi_address *ap, 172 struct scsi_pkt *pkt); 173 174 int (*tran_get_eventcookie)( 175 dev_info_t *hba_dip, 176 dev_info_t *tgt_dip, 177 char *name, 178 ddi_eventcookie_t *eventp); 179 180 int (*tran_add_eventcall)( 181 dev_info_t *hba_dip, 182 dev_info_t *tgt_dip, 183 ddi_eventcookie_t event, 184 void (*callback)( 185 dev_info_t *tgt_dip, 186 ddi_eventcookie_t event, 187 void *arg, 188 void *bus_impldata), 189 void *arg, 190 ddi_callback_id_t *cb_id); 191 192 int (*tran_remove_eventcall)(dev_info_t *devi, 193 ddi_callback_id_t cb_id); 194 195 int (*tran_post_event)( 196 dev_info_t *hba_dip, 197 dev_info_t *tgt_dip, 198 ddi_eventcookie_t event, 199 void *bus_impldata); 200 201 int (*tran_quiesce)( 202 dev_info_t *hba_dip); 203 204 int (*tran_unquiesce)( 205 dev_info_t *hba_dip); 206 207 int (*tran_bus_reset)( 208 dev_info_t *hba_dip, 209 int level); 210 211 /* 212 * Implementation-private specifics. 213 * No HBA should refer to any of the fields below. 214 * This information can and will change. 215 */ 216 int tran_hba_flags; /* flag options */ 217 218 uint_t tran_obs1; 219 uchar_t tran_obs2; 220 uchar_t tran_obs3; 221 222 /* 223 * open_lock: protect tran_minor_isopen 224 * open_flag: bit field indicating which minor nodes are open. 225 * 0 = closed, 1 = shared open, all bits 1 = excl open. 226 * 227 * NOTE: Unused if HBA driver implements its own open(9e) entry point. 228 */ 229 kmutex_t tran_open_lock; 230 uint64_t tran_open_flag; 231 232 /* 233 * bus_config vectors - ON Consolidation Private 234 * These interfaces are subject to change. 235 */ 236 int (*tran_bus_config)( 237 dev_info_t *hba_dip, 238 uint_t flag, 239 ddi_bus_config_op_t op, 240 void *arg, 241 dev_info_t **tgt_dipp); 242 243 int (*tran_bus_unconfig)( 244 dev_info_t *hba_dip, 245 uint_t flag, 246 ddi_bus_config_op_t op, 247 void *arg); 248 249 int (*tran_bus_power)( 250 dev_info_t *dip, 251 void *impl_arg, 252 pm_bus_power_op_t op, 253 void *arg, 254 void *result); 255 256 /* 257 * Inter-Connect type of transport as defined in 258 * usr/src/uts/common/sys/scsi/impl/services.h 259 */ 260 int tran_interconnect_type; 261 262 /* tran_setup_pkt(9E) related scsi_pkt fields */ 263 int (*tran_pkt_constructor)( 264 struct scsi_pkt *pkt, 265 scsi_hba_tran_t *tran, 266 int kmflag); 267 void (*tran_pkt_destructor)( 268 struct scsi_pkt *pkt, 269 scsi_hba_tran_t *tran); 270 kmem_cache_t *tran_pkt_cache_ptr; 271 uint_t tran_hba_len; 272 int (*tran_setup_pkt)( 273 struct scsi_pkt *pkt, 274 int (*callback)( 275 caddr_t arg), 276 caddr_t callback_arg); 277 void (*tran_teardown_pkt)( 278 struct scsi_pkt *pkt); 279 ddi_dma_attr_t tran_dma_attr; 280 281 void *tran_extension; 282 283 /* 284 * An fm_capable HBA driver can set tran_fm_capable prior to 285 * scsi_hba_attach_setup(). If not set, SCSA provides a default 286 * implementation. 287 */ 288 int tran_fm_capable; 289 290 /* 291 * Ptr to the device info structure for initiator port. If a SCSA HBA 292 * driver separates initiator port function from HBA function, this 293 * field still refers to the initiator port. 294 */ 295 dev_info_t *tran_iport_dip; 296 297 /* 298 * map of initiator ports below HBA 299 */ 300 scsi_hba_iportmap_t *tran_iportmap; 301 302 /* 303 * map of targets below initiator 304 */ 305 scsi_hba_tgtmap_t *tran_tgtmap; 306 307 #ifdef SCSI_SIZE_CLEAN_VERIFY 308 /* 309 * Must be last: Building a driver with-and-without 310 * -DSCSI_SIZE_CLEAN_VERIFY, and checking driver modules for 311 * differences with a tools like 'wsdiff' allows a developer to verify 312 * that their driver has no dependencies on scsi*(9S) size. 313 */ 314 int _pad[8]; 315 #endif /* SCSI_SIZE_CLEAN_VERIFY */ 316 }; 317 size_t scsi_hba_tran_size(); /* private */ 318 319 #ifdef __lock_lint 320 _NOTE(SCHEME_PROTECTS_DATA("stable data", 321 scsi_hba_tran::tran_sd 322 scsi_hba_tran::tran_hba_dip 323 scsi_hba_tran::tran_hba_flags 324 scsi_hba_tran::tran_open_flag 325 scsi_hba_tran::tran_pkt_cache_ptr)) 326 /* 327 * we only modify the dma attributes (like dma_attr_granular) upon 328 * attach and in response to a setcap. It is also up to the target 329 * driver to not have any outstanding I/Os when it is changing the 330 * capabilities of the transport. 331 */ 332 _NOTE(SCHEME_PROTECTS_DATA("serialized by target driver", \ 333 scsi_hba_tran::tran_dma_attr.dma_attr_granular)) 334 #endif 335 336 /* 337 * Prototypes for SCSI HBA interface functions 338 * 339 * All these functions are public interfaces, with the 340 * exception of: 341 * interface called by 342 * scsi_initialize_hba_interface() _init() of scsi module 343 * scsi_uninitialize_hba_interface() _fini() of scsi module 344 */ 345 346 void scsi_initialize_hba_interface(void); 347 348 #ifdef NO_SCSI_FINI_YET 349 void scsi_uninitialize_hba_interface(void); 350 #endif /* NO_SCSI_FINI_YET */ 351 352 int scsi_hba_init( 353 struct modlinkage *modlp); 354 355 void scsi_hba_fini( 356 struct modlinkage *modlp); 357 358 int scsi_hba_attach_setup( 359 dev_info_t *hba_dip, 360 ddi_dma_attr_t *hba_dma_attr, 361 scsi_hba_tran_t *tran, 362 int flags); 363 364 int scsi_hba_detach( 365 dev_info_t *hba_dip); 366 367 scsi_hba_tran_t *scsi_hba_tran_alloc( 368 dev_info_t *hba_dip, 369 int flags); 370 371 int scsi_tran_ext_alloc( 372 scsi_hba_tran_t *tran, 373 size_t length, 374 int flags); 375 376 void scsi_tran_ext_free( 377 scsi_hba_tran_t *tran, 378 size_t length); 379 380 void scsi_hba_tran_free( 381 scsi_hba_tran_t *tran); 382 383 int scsi_hba_probe( 384 struct scsi_device *sd, 385 int (*callback)(void)); 386 387 int scsi_hba_probe_pi( 388 struct scsi_device *sd, 389 int (*callback)(void), 390 int pi); 391 392 int scsi_hba_ua_get_reportdev( 393 struct scsi_device *sd, 394 char *ba, 395 int len); 396 397 int scsi_hba_ua_get( 398 struct scsi_device *sd, 399 char *ua, 400 int len); 401 402 char *scsi_get_device_type_string( 403 char *prop_name, 404 dev_info_t *hba_dip, 405 struct scsi_device *sd); 406 407 int scsi_get_scsi_maxluns( 408 struct scsi_device *sd); 409 410 int scsi_get_scsi_options( 411 struct scsi_device *sd, 412 int default_scsi_options); 413 414 int scsi_get_device_type_scsi_options( 415 dev_info_t *hba_dip, 416 struct scsi_device *sd, 417 int default_scsi_options); 418 419 struct scsi_pkt *scsi_hba_pkt_alloc( 420 dev_info_t *hba_dip, 421 struct scsi_address *ap, 422 int cmdlen, 423 int statuslen, 424 int tgtlen, 425 int hbalen, 426 int (*callback)(caddr_t), 427 caddr_t arg); 428 429 void scsi_hba_pkt_free( 430 struct scsi_address *ap, 431 struct scsi_pkt *pkt); 432 433 434 int scsi_hba_lookup_capstr( 435 char *capstr); 436 437 int scsi_hba_in_panic(void); 438 439 int scsi_hba_open( 440 dev_t *devp, 441 int flags, 442 int otyp, 443 cred_t *credp); 444 445 int scsi_hba_close( 446 dev_t dev, 447 int flag, 448 int otyp, 449 cred_t *credp); 450 451 int scsi_hba_ioctl( 452 dev_t dev, 453 int cmd, 454 intptr_t arg, 455 int mode, 456 cred_t *credp, 457 int *rvalp); 458 459 void scsi_hba_nodename_compatible_get( 460 struct scsi_inquiry *inq, 461 char *binding_set, 462 int dtype_node, 463 char *compat0, 464 char **nodenamep, 465 char ***compatiblep, 466 int *ncompatiblep); 467 468 void scsi_hba_nodename_compatible_free( 469 char *nodename, 470 char **compatible); 471 472 int scsi_device_prop_update_inqstring( 473 struct scsi_device *sd, 474 char *name, 475 char *data, 476 size_t len); 477 478 void scsi_hba_pkt_comp( 479 struct scsi_pkt *pkt); 480 481 int scsi_device_identity( 482 struct scsi_device *sd, 483 int (*callback)(void)); 484 485 char *scsi_hba_iport_unit_address( 486 dev_info_t *dip); 487 488 int scsi_hba_iport_register( 489 dev_info_t *dip, 490 char *port); 491 492 int scsi_hba_iport_exist( 493 dev_info_t *dip); 494 495 dev_info_t *scsi_hba_iport_find( 496 dev_info_t *pdip, 497 char *portnm); 498 499 500 /* 501 * Flags for scsi_hba_attach 502 * 503 * SCSI_HBA_ADDR_SPI The host adapter driver wants the 504 * scsi_address(9S) structure to be maintained 505 * in legacy SPI 'a_target'/'a_lun' form (default). 506 * 507 * SCSI_HBA_ADDR_COMPLEX The host adapter has a complex unit-address 508 * space, and the HBA driver wants to maintain 509 * per-scsi_device(9S) HBA private data using 510 * scsi_address_device(9F) and 511 * scsi_device_hba_private_[gs]et(9F). The HBA 512 * driver must maintain a private representation 513 * of the scsi_device(9S) unit-address - typically 514 * established during tran_tgt_init(9F) based on 515 * property values. 516 * 517 * SCSI_HBA_TRAN_PHCI The host adapter is an mpxio/scsi_vhci pHCI. 518 * The framework should take care of 519 * mdi_phci_register() stuff. 520 * 521 * SCSI_HBA_HBA The host adapter node (associated with a PCI 522 * function) is just an HBA, all SCSI initiator 523 * port function is provided by separate 'iport' 524 * children of the host adapter node. These iport 525 * children bind to the same driver as the host 526 * adapter node. Both nodes are managed by the 527 * same driver. The driver can distinguish context 528 * by calling scsi_hba_iport_unit_address(). 529 * 530 * ::SCSI_HBA_TRAN_CLONE Deprecated: use SCSI_HBA_ADDR_COMPLEX instead. 531 * SCSI_HBA_TRAN_CLONE was a KLUDGE to address 532 * limitations of the scsi_address(9S) structure 533 * via duplication of scsi_hba_tran(9S) and 534 * use of tran_tgt_private. 535 * 536 */ 537 #define SCSI_HBA_TRAN_CLONE 0x01 /* Deprecated */ 538 #define SCSI_HBA_TRAN_PHCI 0x02 /* treat HBA as mpxio 'pHCI' */ 539 #define SCSI_HBA_TRAN_CDB 0x04 /* allocate cdb */ 540 #define SCSI_HBA_TRAN_SCB 0x08 /* allocate sense */ 541 #define SCSI_HBA_HBA 0x10 /* all HBA children are iports */ 542 543 #define SCSI_HBA_ADDR_SPI 0x20 /* scsi_address in SPI form */ 544 #define SCSI_HBA_ADDR_COMPLEX 0x40 /* scsi_address is COMPLEX */ 545 546 /* upper bits used to record SCSA configuration state */ 547 #define SCSI_HBA_SCSA_PHCI 0x10000 /* need mdi_phci_unregister */ 548 #define SCSI_HBA_SCSA_TA 0x20000 /* scsi_hba_tran_alloc used */ 549 #define SCSI_HBA_SCSA_FM 0x40000 /* using common ddi_fm_* */ 550 551 /* 552 * Flags for scsi_hba allocation functions 553 */ 554 #define SCSI_HBA_CANSLEEP 0x01 /* can sleep */ 555 556 /* 557 * Support extra flavors for SCSA children 558 */ 559 #define SCSA_FLAVOR_SCSI_DEVICE NDI_FLAVOR_VANILLA 560 #define SCSA_FLAVOR_SMP 1 561 #define SCSA_FLAVOR_IPORT 2 562 #define SCSA_NFLAVORS 3 563 564 /* 565 * Maximum number of iport nodes under PCI function 566 */ 567 #define SCSI_HBA_MAX_IPORTS 32 568 569 /* 570 * SCSI iport map interfaces 571 */ 572 int scsi_hba_iportmap_create( 573 dev_info_t *hba_dip, 574 int csync_usec, 575 int stable_usec, 576 scsi_hba_iportmap_t **iportmapp); 577 578 int scsi_hba_iportmap_iport_add( 579 scsi_hba_iportmap_t *iportmap, 580 char *iport_addr, 581 void *iport_priv); 582 583 int scsi_hba_iportmap_iport_remove( 584 scsi_hba_iportmap_t *iportmap, 585 char *iport_addr); 586 587 void scsi_hba_iportmap_destroy(scsi_hba_iportmap_t *iportmap); 588 589 /* 590 * SCSI target map interfaces 591 */ 592 typedef enum { 593 SCSI_TM_FULLSET = 0, 594 SCSI_TM_PERADDR 595 } scsi_tgtmap_mode_t; 596 597 typedef enum { 598 SCSI_TGT_SCSI_DEVICE = 0, 599 SCSI_TGT_SMP_DEVICE, 600 SCSI_TGT_NTYPES 601 } scsi_tgtmap_tgt_type_t; 602 603 typedef enum { 604 SCSI_TGT_DEACT_RSN_GONE = 0, 605 SCSI_TGT_DEACT_RSN_CFG_FAIL, 606 SCSI_TGT_DEACT_RSN_UNSTBL 607 } scsi_tgtmap_deact_rsn_t; 608 609 typedef void (*scsi_tgt_activate_cb_t)( 610 void *tgtmap_priv, 611 char *tgt_addr, 612 scsi_tgtmap_tgt_type_t tgt_type, 613 void **tgt_privp); 614 typedef boolean_t (*scsi_tgt_deactivate_cb_t)( 615 void *tgtmap_priv, 616 char *tgt_addr, 617 scsi_tgtmap_tgt_type_t tgt_type, 618 void *tgt_priv, 619 scsi_tgtmap_deact_rsn_t tgt_deact_rsn); 620 int scsi_hba_tgtmap_create( 621 dev_info_t *iport_dip, 622 scsi_tgtmap_mode_t rpt_mode, 623 int csync_usec, 624 int stable_usec, 625 void *tgtmap_priv, 626 scsi_tgt_activate_cb_t activate_cb, 627 scsi_tgt_deactivate_cb_t deactivate_cb, 628 scsi_hba_tgtmap_t **tgtmapp); 629 630 int scsi_hba_tgtmap_set_begin(scsi_hba_tgtmap_t *tgtmap); 631 632 int scsi_hba_tgtmap_set_add( 633 scsi_hba_tgtmap_t *tgtmap, 634 scsi_tgtmap_tgt_type_t tgt_type, 635 char *tgt_addr, 636 void *tgt_priv); 637 638 int scsi_hba_tgtmap_set_end( 639 scsi_hba_tgtmap_t *tgtmap, 640 uint_t flags); 641 642 int scsi_hba_tgtmap_set_flush(scsi_hba_tgtmap_t *tgtmap); 643 644 int scsi_hba_tgtmap_tgt_add( 645 scsi_hba_tgtmap_t *tgtmap, 646 scsi_tgtmap_tgt_type_t tgt_type, 647 char *tgt_addr, 648 void *tgt_priv); 649 650 int scsi_hba_tgtmap_tgt_remove( 651 scsi_hba_tgtmap_t *tgtmap, 652 scsi_tgtmap_tgt_type_t tgt_type, 653 char *tgt_addr); 654 655 void scsi_hba_tgtmap_destroy(scsi_hba_tgtmap_t *tgt_map); 656 657 void scsi_hba_tgtmap_scan_luns(scsi_hba_tgtmap_t *tgt_map, 658 char *tgt_addr); 659 660 661 /* 662 * For minor nodes created by the SCSA framework, minor numbers are 663 * formed by left-shifting instance by INST_MINOR_SHIFT and OR in a 664 * number less than 64. 665 * 666 * - Numbers 0 - 31 are reserved by the framework, part of the range are 667 * in use, as defined below. 668 * 669 * - Numbers 32 - 63 are available for HBA driver use. 670 */ 671 #define INST_MINOR_SHIFT 6 672 #define TRAN_MINOR_MASK ((1 << INST_MINOR_SHIFT) - 1) 673 #define TRAN_OPEN_EXCL (uint64_t)-1 674 675 #define DEVCTL_MINOR 0 676 #define SCSI_MINOR 1 677 678 #define INST2DEVCTL(x) (((x) << INST_MINOR_SHIFT) | DEVCTL_MINOR) 679 #define INST2SCSI(x) (((x) << INST_MINOR_SHIFT) | SCSI_MINOR) 680 #define MINOR2INST(x) ((x) >> INST_MINOR_SHIFT) 681 682 #define SCSI_HBA_PROP_RECEPTACLE_LABEL "receptacle-label" 683 684 #endif /* _KERNEL */ 685 686 #ifdef __cplusplus 687 } 688 #endif 689 690 #endif /* _SYS_SCSI_IMPL_TRANSPORT_H */ 691