1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright (c) 2017, Joyent, Inc. 14 */ 15 16 #ifndef _SMRT_H 17 #define _SMRT_H 18 19 #include <sys/types.h> 20 #include <sys/pci.h> 21 #include <sys/param.h> 22 #include <sys/errno.h> 23 #include <sys/conf.h> 24 #include <sys/map.h> 25 #include <sys/modctl.h> 26 #include <sys/kmem.h> 27 #include <sys/cmn_err.h> 28 #include <sys/stat.h> 29 #include <sys/scsi/scsi.h> 30 #include <sys/scsi/impl/spc3_types.h> 31 #include <sys/devops.h> 32 #include <sys/ddi.h> 33 #include <sys/sunddi.h> 34 #include <sys/sdt.h> 35 #include <sys/policy.h> 36 #include <sys/ctype.h> 37 38 #if !defined(_LITTLE_ENDIAN) || !defined(_BIT_FIELDS_LTOH) 39 /* 40 * This driver contains a number of multi-byte bit fields and other structs 41 * that are only correct on a system with the same ordering as x86. 42 */ 43 #error "smrt: driver works only on little endian systems" 44 #endif 45 46 #ifdef __cplusplus 47 extern "C" { 48 #endif 49 50 /* 51 * Some structures are statically sized based on the expected number of logical 52 * drives and controllers in the system. These definitions are used throughout 53 * other driver-specific header files, and must appear prior to their 54 * inclusion. 55 */ 56 #define SMRT_MAX_LOGDRV 64 /* Maximum number of logical drives */ 57 #define SMRT_MAX_PHYSDEV 128 /* Maximum number of physical devices */ 58 59 #include <sys/scsi/adapters/smrt/smrt_ciss.h> 60 #include <sys/scsi/adapters/smrt/smrt_scsi.h> 61 62 #ifdef __cplusplus 63 extern "C" { 64 #endif 65 66 extern ddi_device_acc_attr_t smrt_dev_attributes; 67 68 typedef enum smrt_init_level { 69 SMRT_INITLEVEL_BASIC = (0x1 << 0), 70 SMRT_INITLEVEL_I2O_MAPPED = (0x1 << 1), 71 SMRT_INITLEVEL_CFGTBL_MAPPED = (0x1 << 2), 72 SMRT_INITLEVEL_PERIODIC = (0x1 << 3), 73 SMRT_INITLEVEL_INT_ALLOC = (0x1 << 4), 74 SMRT_INITLEVEL_INT_ADDED = (0x1 << 5), 75 SMRT_INITLEVEL_INT_ENABLED = (0x1 << 6), 76 SMRT_INITLEVEL_SCSA = (0x1 << 7), 77 SMRT_INITLEVEL_MUTEX = (0x1 << 8), 78 SMRT_INITLEVEL_TASKQ = (0x1 << 9), 79 SMRT_INITLEVEL_ASYNC_EVENT = (0x1 << 10), 80 } smrt_init_level_t; 81 82 /* 83 * Commands issued to the controller carry a (generally 32-bit, though with 84 * two reserved signalling bits) identifying tag number. In order to avoid 85 * having the controller confuse us by double-reporting the completion of a 86 * particular tag, we try to reuse them as infrequently as possible. In 87 * practice, this means looping through a range of values. The minimum and 88 * maximum value are defined below. A single command tag value is set aside 89 * for polled commands sent prior to full initialisation of the driver. 90 */ 91 #define SMRT_PRE_TAG_NUMBER 0x00000bad 92 #define SMRT_MIN_TAG_NUMBER 0x00001000 93 #define SMRT_MAX_TAG_NUMBER 0x0fffffff 94 95 /* 96 * Character strings that represent the names of the iports used for both 97 * physical and virtual volumes. 98 */ 99 #define SMRT_IPORT_PHYS "p0" 100 #define SMRT_IPORT_VIRT "v0" 101 102 /* 103 * Definitions to support waiting for the controller to converge on a 104 * particular state: ready or not ready. These are used with 105 * smrt_ctlr_wait_for_state(). 106 */ 107 #define SMRT_WAIT_DELAY_SECONDS 120 108 typedef enum smrt_wait_state { 109 SMRT_WAIT_STATE_READY = 1, 110 SMRT_WAIT_STATE_UNREADY 111 } smrt_wait_state_t; 112 113 typedef enum smrt_ctlr_mode { 114 SMRT_CTLR_MODE_UNKNOWN = 0, 115 SMRT_CTLR_MODE_SIMPLE 116 } smrt_ctlr_mode_t; 117 118 /* 119 * In addition to Logical Volumes, we also expose the controller at a 120 * pseudo target address on the SCSI bus we are essentially pretending to be. 121 */ 122 #define SMRT_CONTROLLER_TARGET 128 123 124 /* 125 * When waiting for volume discovery to complete, we wait for a maximum 126 * duration (in seconds) before giving up. 127 */ 128 #define SMRT_DISCOVER_TIMEOUT 30 129 130 /* 131 * The maintenance routine which checks for controller lockup and aborts 132 * commands that have passed their timeout runs periodically. The time is 133 * expressed in seconds. 134 */ 135 #define SMRT_PERIODIC_RATE 5 136 137 /* 138 * At times, we need to check if the controller is still responding. To do 139 * that, we send a Nop message to the controller and make sure it completes 140 * successfully. So that we don't wait forever, we set a timeout (in seconds). 141 */ 142 #define SMRT_PING_CHECK_TIMEOUT 60 143 144 /* 145 * When detaching the device, we may need to have an asynchronous event 146 * cancellation be issued. While this should be relatively smooth, we don't 147 * want to wait forever for it. As such we set a timeout in seconds. 148 */ 149 #define SMRT_ASYNC_CANCEL_TIMEOUT 60 150 151 /* 152 * HP PCI vendor ID and Generation 9 device ID. Used to identify generations of 153 * supported controllers. 154 */ 155 #define SMRT_VENDOR_HP 0x103c 156 #define SMRT_DEVICE_GEN9 0x3238 157 158 typedef enum smrt_controller_status { 159 /* 160 * An attempt is being made to detach the controller instance. 161 */ 162 SMRT_CTLR_STATUS_DETACHING = (0x1 << 0), 163 164 /* 165 * The controller is believed to be functioning correctly. The driver 166 * is to allow command submission, process interrupts, and perform 167 * periodic background maintenance. 168 */ 169 SMRT_CTLR_STATUS_RUNNING = (0x1 << 1), 170 171 /* 172 * The controller is currently being reset. 173 */ 174 SMRT_CTLR_STATUS_RESETTING = (0x1 << 2), 175 176 /* 177 * Our async event notification command is currently in need of help 178 * from the broader driver. This will be set by smrt_event_complete() 179 * to indicate that the command is not being processed due to a 180 * controller reset or because another fatal error occurred. The 181 * periodic will have to pick up and recover this for us. It is only 182 * safe for the driver to manipulate the event command outside of 183 * smrt_event_complete() if this flag is set. 184 */ 185 SMRT_CTLR_ASYNC_INTERVENTION = (0x1 << 3), 186 187 /* 188 * See the theory statement on discovery and resets in smrt_ciss.c for 189 * an explanation of these values. 190 */ 191 SMRT_CTLR_DISCOVERY_REQUESTED = (0x1 << 4), 192 SMRT_CTLR_DISCOVERY_RUNNING = (0x1 << 5), 193 SMRT_CTLR_DISCOVERY_PERIODIC = (0x1 << 6), 194 SMRT_CTLR_DISCOVERY_REQUIRED = (0x1 << 7), 195 } smrt_controller_status_t; 196 197 #define SMRT_CTLR_DISCOVERY_MASK (SMRT_CTLR_DISCOVERY_REQUESTED | \ 198 SMRT_CTLR_DISCOVERY_RUNNING | SMRT_CTLR_DISCOVERY_PERIODIC) 199 200 typedef struct smrt_stats { 201 uint64_t smrts_tran_aborts; 202 uint64_t smrts_tran_resets; 203 uint64_t smrts_tran_starts; 204 uint64_t smrts_ctlr_resets; 205 unsigned smrts_max_inflight; 206 uint64_t smrts_unclaimed_interrupts; 207 uint64_t smrts_claimed_interrupts; 208 uint64_t smrts_ignored_scsi_cmds; 209 uint64_t smrts_events_received; 210 uint64_t smrts_events_errors; 211 uint64_t smrts_events_intervened; 212 uint64_t smrts_discovery_tq_errors; 213 } smrt_stats_t; 214 215 typedef struct smrt_versions { 216 uint8_t smrtv_hardware_version; 217 218 /* 219 * These strings must be large enough to hold the 4 byte version string 220 * retrieved from an IDENTIFY CONTROLLER response, as well as the 221 * terminating NUL byte: 222 */ 223 char smrtv_firmware_rev[5]; 224 char smrtv_recovery_rev[5]; 225 char smrtv_bootblock_rev[5]; 226 } smrt_versions_t; 227 228 typedef struct smrt smrt_t; 229 typedef struct smrt_command smrt_command_t; 230 typedef struct smrt_command_internal smrt_command_internal_t; 231 typedef struct smrt_command_scsa smrt_command_scsa_t; 232 typedef struct smrt_pkt smrt_pkt_t; 233 234 /* 235 * Per-Controller Structure 236 */ 237 struct smrt { 238 dev_info_t *smrt_dip; 239 int smrt_instance; 240 smrt_controller_status_t smrt_status; 241 smrt_stats_t smrt_stats; 242 243 /* 244 * Controller configuration discovered during initialisation. 245 */ 246 uint32_t smrt_host_support; 247 uint32_t smrt_bus_support; 248 uint32_t smrt_maxcmds; 249 uint32_t smrt_sg_cnt; 250 smrt_versions_t smrt_versions; 251 uint16_t smrt_pci_vendor; 252 uint16_t smrt_pci_device; 253 254 /* 255 * iport specific data 256 */ 257 dev_info_t *smrt_virt_iport; 258 dev_info_t *smrt_phys_iport; 259 scsi_hba_tgtmap_t *smrt_virt_tgtmap; 260 scsi_hba_tgtmap_t *smrt_phys_tgtmap; 261 262 /* 263 * The transport mode of the controller. 264 */ 265 smrt_ctlr_mode_t smrt_ctlr_mode; 266 267 /* 268 * The current initialisation level of the driver. Bits in this field 269 * are set during initialisation and unset during cleanup of the 270 * allocated resources. 271 */ 272 smrt_init_level_t smrt_init_level; 273 274 /* 275 * Essentially everything is protected by "smrt_mutex". When the 276 * completion queue is updated, threads sleeping on "smrt_cv_finishq" 277 * are awoken. 278 */ 279 kmutex_t smrt_mutex; 280 kcondvar_t smrt_cv_finishq; 281 282 /* 283 * List of enumerated logical volumes (smrt_volume_t). 284 */ 285 list_t smrt_volumes; 286 287 /* 288 * List of enumerated physical devices (smrt_physical_t). 289 */ 290 list_t smrt_physicals; 291 292 /* 293 * List of attached SCSA target drivers (smrt_target_t). 294 */ 295 list_t smrt_targets; 296 297 /* 298 * Controller Heartbeat Tracking 299 */ 300 uint32_t smrt_last_heartbeat; 301 hrtime_t smrt_last_heartbeat_time; 302 303 hrtime_t smrt_last_interrupt_claimed; 304 hrtime_t smrt_last_interrupt_unclaimed; 305 hrtime_t smrt_last_reset_start; 306 hrtime_t smrt_last_reset_finish; 307 308 /* 309 * Command object tracking. These lists, and all commands within the 310 * lists, are protected by "smrt_mutex". 311 */ 312 uint32_t smrt_next_tag; 313 avl_tree_t smrt_inflight; 314 list_t smrt_commands; /* List of all commands. */ 315 list_t smrt_finishq; /* List of completed commands. */ 316 list_t smrt_abortq; /* List of commands to abort. */ 317 318 /* 319 * Discovery coordination 320 */ 321 ddi_taskq_t *smrt_discover_taskq; 322 hrtime_t smrt_last_phys_discovery; 323 hrtime_t smrt_last_log_discovery; 324 uint64_t smrt_discover_gen; 325 326 /* 327 * Controller interrupt handler registration. 328 */ 329 int smrt_interrupt_type; 330 int smrt_interrupt_cap; 331 uint_t smrt_interrupt_pri; 332 ddi_intr_handle_t smrt_interrupts[1]; 333 int smrt_ninterrupts; 334 335 ddi_periodic_t smrt_periodic; 336 337 scsi_hba_tran_t *smrt_hba_tran; 338 339 ddi_dma_attr_t smrt_dma_attr; 340 341 /* 342 * Access to the I2O Registers: 343 */ 344 unsigned smrt_i2o_bar; 345 caddr_t smrt_i2o_space; 346 ddi_acc_handle_t smrt_i2o_handle; 347 348 /* 349 * Access to the Configuration Table: 350 */ 351 unsigned smrt_ct_bar; 352 uint32_t smrt_ct_baseaddr; 353 CfgTable_t *smrt_ct; 354 ddi_acc_handle_t smrt_ct_handle; 355 356 /* 357 * Asynchronous Event State 358 */ 359 uint32_t smrt_event_count; 360 smrt_command_t *smrt_event_cmd; 361 smrt_command_t *smrt_event_cancel_cmd; 362 kcondvar_t smrt_event_queue; 363 }; 364 365 /* 366 * Logical Volume Structure 367 */ 368 typedef enum smrt_volume_flags { 369 SMRT_VOL_FLAG_WWN = (0x1 << 0), 370 } smrt_volume_flags_t; 371 372 typedef struct smrt_volume { 373 LUNAddr_t smlv_addr; 374 smrt_volume_flags_t smlv_flags; 375 376 uint8_t smlv_wwn[16]; 377 uint64_t smlv_gen; 378 379 smrt_t *smlv_ctlr; 380 list_node_t smlv_link; 381 382 /* 383 * List of SCSA targets currently attached to this Logical Volume: 384 */ 385 list_t smlv_targets; 386 } smrt_volume_t; 387 388 typedef struct smrt_physical { 389 LUNAddr_t smpt_addr; 390 uint64_t smpt_wwn; 391 uint8_t smpt_dtype; 392 uint16_t smpt_bmic; 393 uint64_t smpt_gen; 394 boolean_t smpt_supported; 395 boolean_t smpt_visible; 396 boolean_t smpt_unsup_warn; 397 list_node_t smpt_link; 398 list_t smpt_targets; 399 smrt_t *smpt_ctlr; 400 smrt_identify_physical_drive_t *smpt_info; 401 } smrt_physical_t; 402 403 /* 404 * Per-Target Structure 405 */ 406 typedef struct smrt_target { 407 struct scsi_device *smtg_scsi_dev; 408 409 boolean_t smtg_physical; 410 411 /* 412 * This is only used when performing discovery during panic, as we need 413 * a mechanism to determine if the set of drives has shifted. 414 */ 415 boolean_t smtg_gone; 416 417 /* 418 * Linkage back to the device that this target represents. This may be 419 * either a smrt_volume_t or a smrt_physical_t. We keep a pointer to the 420 * address, as that's the one thing we generally care about. 421 */ 422 union { 423 smrt_physical_t *smtg_phys; 424 smrt_volume_t *smtg_vol; 425 } smtg_lun; 426 list_node_t smtg_link_lun; 427 LUNAddr_t *smtg_addr; 428 429 /* 430 * Linkage back to the controller: 431 */ 432 smrt_t *smtg_ctlr; 433 list_node_t smtg_link_ctlr; 434 } smrt_target_t; 435 436 /* 437 * DMA Resource Tracking Structure 438 */ 439 typedef enum smrt_dma_level { 440 SMRT_DMALEVEL_HANDLE_ALLOC = (0x1 << 0), 441 SMRT_DMALEVEL_MEMORY_ALLOC = (0x1 << 1), 442 SMRT_DMALEVEL_HANDLE_BOUND = (0x1 << 2), 443 } smrt_dma_level_t; 444 445 typedef struct smrt_dma { 446 smrt_dma_level_t smdma_level; 447 size_t smdma_real_size; 448 ddi_dma_handle_t smdma_dma_handle; 449 ddi_acc_handle_t smdma_acc_handle; 450 ddi_dma_cookie_t smdma_dma_cookies[1]; 451 uint_t smdma_dma_ncookies; 452 } smrt_dma_t; 453 454 455 typedef enum smrt_command_status { 456 /* 457 * When a command is submitted to the controller, it is marked USED 458 * to avoid accidental reuse of the command without reinitialising 459 * critical fields. The submitted command is also marked INFLIGHT 460 * to reflect its inclusion in the "smrt_inflight" AVL tree. When 461 * the command is completed by the controller, INFLIGHT is unset. 462 */ 463 SMRT_CMD_STATUS_USED = (0x1 << 0), 464 SMRT_CMD_STATUS_INFLIGHT = (0x1 << 1), 465 466 /* 467 * This flag is set during abort queue processing to record that this 468 * command was aborted in response to an expired timeout, and not some 469 * other cancellation. If the controller is able to abort the command, 470 * we use this flag to let the SCSI framework know that the command 471 * timed out. 472 */ 473 SMRT_CMD_STATUS_TIMEOUT = (0x1 << 2), 474 475 /* 476 * The controller set the error bit when completing this command. 477 * Details of the particular fault may be read from the error 478 * information written by the controller. 479 */ 480 SMRT_CMD_STATUS_ERROR = (0x1 << 3), 481 482 /* 483 * This command has been abandoned by the original submitter. This 484 * could happen if the command did not complete in a timely fashion. 485 * When it reaches the finish queue it will be freed without further 486 * processing. 487 */ 488 SMRT_CMD_STATUS_ABANDONED = (0x1 << 4), 489 490 /* 491 * This command has made it through the completion queue and had final 492 * processing performed. 493 */ 494 SMRT_CMD_STATUS_COMPLETE = (0x1 << 5), 495 496 /* 497 * A polled message will be ignored by the regular processing of the 498 * completion queue. The blocking function doing the polling is 499 * responsible for watching the command on which it has set the POLLED 500 * flag. Regular completion queue processing (which might happen in 501 * the polling function, or it might happen in the interrupt handler) 502 * will set POLL_COMPLETE once it is out of the finish queue 503 * altogether. 504 */ 505 SMRT_CMD_STATUS_POLLED = (0x1 << 6), 506 SMRT_CMD_STATUS_POLL_COMPLETE = (0x1 << 7), 507 508 /* 509 * An abort message has been sent to the controller in an attempt to 510 * cancel this command. 511 */ 512 SMRT_CMD_STATUS_ABORT_SENT = (0x1 << 8), 513 514 /* 515 * This command has been passed to our tran_start(9E) handler. 516 */ 517 SMRT_CMD_STATUS_TRAN_START = (0x1 << 9), 518 519 /* 520 * This command was for a SCSI command that we are explicitly avoiding 521 * sending to the controller. 522 */ 523 SMRT_CMD_STATUS_TRAN_IGNORED = (0x1 << 10), 524 525 /* 526 * This command has been submitted once, and subsequently passed to 527 * smrt_command_reuse(). 528 */ 529 SMRT_CMD_STATUS_REUSED = (0x1 << 11), 530 531 /* 532 * A controller reset has been issued, so a response for this command 533 * is not expected. If one arrives before the controller reset has 534 * taken effect, it likely cannot be trusted. 535 */ 536 SMRT_CMD_STATUS_RESET_SENT = (0x1 << 12), 537 538 /* 539 * Certain commands related to discovery and pinging need to be run 540 * during the context after a reset has occurred, but before the 541 * controller is considered. Such commands can use this flag to bypass 542 * the normal smrt_submit() check. 543 */ 544 SMRT_CMD_IGNORE_RUNNING = (0x1 << 13), 545 } smrt_command_status_t; 546 547 typedef enum smrt_command_type { 548 SMRT_CMDTYPE_INTERNAL = 1, 549 SMRT_CMDTYPE_EVENT, 550 SMRT_CMDTYPE_ABORTQ, 551 SMRT_CMDTYPE_SCSA, 552 SMRT_CMDTYPE_PREINIT, 553 } smrt_command_type_t; 554 555 struct smrt_command { 556 uint32_t smcm_tag; 557 smrt_command_type_t smcm_type; 558 smrt_command_status_t smcm_status; 559 560 smrt_t *smcm_ctlr; 561 smrt_target_t *smcm_target; 562 563 list_node_t smcm_link; /* Linkage for allocated list. */ 564 list_node_t smcm_link_finish; /* Linkage for completion list. */ 565 list_node_t smcm_link_abort; /* Linkage for abort list. */ 566 avl_node_t smcm_node; /* Inflight AVL membership. */ 567 568 hrtime_t smcm_time_submit; 569 hrtime_t smcm_time_complete; 570 571 hrtime_t smcm_expiry; 572 573 /* 574 * The time at which an abort message was sent to try and terminate 575 * this command, as well as the tag of the abort message itself: 576 */ 577 hrtime_t smcm_abort_time; 578 uint32_t smcm_abort_tag; 579 580 /* 581 * Ancillary data objects. Only one of these will be allocated for any 582 * given command, but we nonetheless resist the temptation to use a 583 * union of pointers in order to make incorrect usage obvious. 584 */ 585 smrt_command_scsa_t *smcm_scsa; 586 smrt_command_internal_t *smcm_internal; 587 588 /* 589 * Physical allocation tracking for the actual command to send to the 590 * controller. 591 */ 592 smrt_dma_t smcm_contig; 593 594 CommandList_t *smcm_va_cmd; 595 uint32_t smcm_pa_cmd; 596 597 ErrorInfo_t *smcm_va_err; 598 uint32_t smcm_pa_err; 599 }; 600 601 /* 602 * Commands issued internally to the driver (as opposed to by the HBA 603 * framework) generally require a buffer in which to assemble the command body, 604 * and for receiving the response from the controller. The following object 605 * tracks this (optional) extra buffer. 606 */ 607 struct smrt_command_internal { 608 smrt_dma_t smcmi_contig; 609 610 void *smcmi_va; 611 uint32_t smcmi_pa; 612 size_t smcmi_len; 613 }; 614 615 /* 616 * Commands issued via the SCSI framework have a number of additional 617 * properties. 618 */ 619 struct smrt_command_scsa { 620 struct scsi_pkt *smcms_pkt; 621 smrt_command_t *smcms_command; 622 }; 623 624 625 /* 626 * CISS transport routines. 627 */ 628 void smrt_periodic(void *); 629 void smrt_lockup_check(smrt_t *); 630 int smrt_submit(smrt_t *, smrt_command_t *); 631 void smrt_submit_simple(smrt_t *, smrt_command_t *); 632 int smrt_retrieve(smrt_t *); 633 void smrt_retrieve_simple(smrt_t *); 634 int smrt_poll_for(smrt_t *, smrt_command_t *); 635 int smrt_preinit_command_simple(smrt_t *, smrt_command_t *); 636 637 /* 638 * Interrupt service routines. 639 */ 640 int smrt_interrupts_setup(smrt_t *); 641 int smrt_interrupts_enable(smrt_t *); 642 void smrt_interrupts_teardown(smrt_t *); 643 uint32_t smrt_isr_hw_simple(caddr_t, caddr_t); 644 645 /* 646 * Interrupt enable/disable routines. 647 */ 648 void smrt_intr_set(smrt_t *, boolean_t); 649 650 /* 651 * Controller initialisation routines. 652 */ 653 int smrt_ctlr_init(smrt_t *); 654 void smrt_ctlr_teardown(smrt_t *); 655 int smrt_ctlr_reset(smrt_t *); 656 int smrt_ctlr_wait_for_state(smrt_t *, smrt_wait_state_t); 657 int smrt_ctlr_init_simple(smrt_t *); 658 void smrt_ctlr_teardown_simple(smrt_t *); 659 int smrt_cfgtbl_flush(smrt_t *); 660 int smrt_cfgtbl_transport_has_support(smrt_t *, int); 661 void smrt_cfgtbl_transport_set(smrt_t *, int); 662 int smrt_cfgtbl_transport_confirm(smrt_t *, int); 663 uint32_t smrt_ctlr_get_cmdsoutmax(smrt_t *); 664 uint32_t smrt_ctlr_get_maxsgelements(smrt_t *); 665 666 /* 667 * Device enumeration and lookup routines. 668 */ 669 void smrt_discover_request(smrt_t *); 670 671 int smrt_logvol_discover(smrt_t *, uint16_t, uint64_t); 672 void smrt_logvol_teardown(smrt_t *); 673 smrt_volume_t *smrt_logvol_lookup_by_id(smrt_t *, unsigned long); 674 void smrt_logvol_tgtmap_activate(void *, char *, scsi_tgtmap_tgt_type_t, 675 void **); 676 boolean_t smrt_logvol_tgtmap_deactivate(void *, char *, scsi_tgtmap_tgt_type_t, 677 void *, scsi_tgtmap_deact_rsn_t); 678 679 int smrt_phys_discover(smrt_t *, uint16_t, uint64_t); 680 smrt_physical_t *smrt_phys_lookup_by_ua(smrt_t *, const char *); 681 void smrt_phys_teardown(smrt_t *); 682 void smrt_phys_tgtmap_activate(void *, char *, scsi_tgtmap_tgt_type_t, 683 void **); 684 boolean_t smrt_phys_tgtmap_deactivate(void *, char *, scsi_tgtmap_tgt_type_t, 685 void *, scsi_tgtmap_deact_rsn_t); 686 687 /* 688 * SCSI framework routines. 689 */ 690 int smrt_ctrl_hba_setup(smrt_t *); 691 void smrt_ctrl_hba_teardown(smrt_t *); 692 693 int smrt_logvol_hba_setup(smrt_t *, dev_info_t *); 694 void smrt_logvol_hba_teardown(smrt_t *, dev_info_t *); 695 int smrt_phys_hba_setup(smrt_t *, dev_info_t *); 696 void smrt_phys_hba_teardown(smrt_t *, dev_info_t *); 697 698 void smrt_hba_complete(smrt_command_t *); 699 700 void smrt_process_finishq(smrt_t *); 701 void smrt_process_abortq(smrt_t *); 702 703 /* 704 * Command block management. 705 */ 706 smrt_command_t *smrt_command_alloc(smrt_t *, smrt_command_type_t, 707 int); 708 smrt_command_t *smrt_command_alloc_preinit(smrt_t *, size_t, int); 709 int smrt_command_attach_internal(smrt_t *, smrt_command_t *, size_t, 710 int); 711 void smrt_command_free(smrt_command_t *); 712 smrt_command_t *smrt_lookup_inflight(smrt_t *, uint32_t); 713 void smrt_command_reuse(smrt_command_t *); 714 715 /* 716 * Device message construction routines. 717 */ 718 void smrt_write_lun_addr_phys(LUNAddr_t *, boolean_t, unsigned, unsigned); 719 void smrt_write_controller_lun_addr(LUNAddr_t *); 720 uint16_t smrt_lun_addr_to_bmic(PhysDevAddr_t *); 721 void smrt_write_message_abort_one(smrt_command_t *, uint32_t); 722 void smrt_write_message_abort_all(smrt_command_t *, LUNAddr_t *); 723 void smrt_write_message_nop(smrt_command_t *, int); 724 void smrt_write_message_event_notify(smrt_command_t *); 725 726 /* 727 * Device management routines. 728 */ 729 int smrt_device_setup(smrt_t *); 730 void smrt_device_teardown(smrt_t *); 731 uint32_t smrt_get32(smrt_t *, offset_t); 732 void smrt_put32(smrt_t *, offset_t, uint32_t); 733 734 /* 735 * SATA related routines. 736 */ 737 int smrt_sata_determine_wwn(smrt_t *, PhysDevAddr_t *, uint64_t *, uint16_t); 738 739 /* 740 * Asynchronous Event Notification 741 */ 742 int smrt_event_init(smrt_t *); 743 void smrt_event_fini(smrt_t *); 744 void smrt_event_complete(smrt_command_t *); 745 746 #ifdef __cplusplus 747 } 748 #endif 749 750 #endif /* _SMRT_H */ 751