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) 2001, 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 /* 26 * Copyright 2014 Nexenta Systems, Inc. All rights reserved. 27 * Copyright 2024 RackTop Systems, Inc. 28 */ 29 30 #ifndef _SYS_SCSI_ADAPTERS_SCSI_VHCI_H 31 #define _SYS_SCSI_ADAPTERS_SCSI_VHCI_H 32 33 /* 34 * Multiplexed I/O SCSI vHCI global include 35 */ 36 #include <sys/note.h> 37 #include <sys/taskq.h> 38 #include <sys/mhd.h> 39 #include <sys/sunmdi.h> 40 #include <sys/mdi_impldefs.h> 41 #include <sys/scsi/adapters/mpapi_impl.h> 42 #include <sys/scsi/adapters/mpapi_scsi_vhci.h> 43 44 #ifdef __cplusplus 45 extern "C" { 46 #endif 47 48 #if !defined(_BIT_FIELDS_LTOH) && !defined(_BIT_FIELDS_HTOL) 49 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined 50 #endif /* _BIT_FIELDS_LTOH */ 51 52 #ifdef _KERNEL 53 54 #ifdef UNDEFINED 55 #undef UNDEFINED 56 #endif 57 #define UNDEFINED -1 58 59 #define VHCI_STATE_OPEN 0x00000001 60 61 62 #define VH_SLEEP 0x0 63 #define VH_NOSLEEP 0x1 64 65 /* 66 * HBA interface macros 67 */ 68 69 #define TRAN2HBAPRIVATE(tran) ((struct scsi_vhci *)(tran)->tran_hba_private) 70 #define VHCI_INIT_WAIT_TIMEOUT 60000000 71 #define VHCI_FOWATCH_INTERVAL 1000000 /* in usecs */ 72 #define VHCI_EXTFO_TIMEOUT (3 * 60 * NANOSEC) /* 3 minutes in nsec */ 73 74 #define SCBP_C(pkt) ((*(pkt)->pkt_scbp) & STATUS_MASK) 75 76 int vhci_do_scsi_cmd(struct scsi_pkt *); 77 /*PRINTFLIKE3*/ 78 void vhci_log(int, dev_info_t *, const char *, ...); 79 80 size_t vhci_get_blocksize(dev_info_t *); 81 82 /* 83 * debugging stuff 84 */ 85 86 #ifdef DEBUG 87 88 #ifndef VHCI_DEBUG_DEFAULT_VAL 89 #define VHCI_DEBUG_DEFAULT_VAL 0 90 #endif /* VHCI_DEBUG_DEFAULT_VAL */ 91 92 extern int vhci_debug; 93 94 #include <sys/debug.h> 95 96 #define VHCI_DEBUG(level, stmnt) \ 97 if (vhci_debug >= (level)) vhci_log stmnt 98 99 #else /* !DEBUG */ 100 101 #define VHCI_DEBUG(level, stmnt) 102 103 #endif /* !DEBUG */ 104 105 106 107 #define VHCI_PKT_PRIV_SIZE 2 108 109 #define ADDR2VHCI(ap) ((struct scsi_vhci *) \ 110 ((ap)->a_hba_tran->tran_hba_private)) 111 #define ADDR2VLUN(ap) (scsi_vhci_lun_t *) \ 112 (scsi_device_hba_private_get(scsi_address_device(ap))) 113 #define ADDR2DIP(ap) ((dev_info_t *)(scsi_address_device(ap)->sd_dev)) 114 115 #define HBAPKT2VHCIPKT(pkt) (pkt->pkt_private) 116 #define TGTPKT2VHCIPKT(pkt) (pkt->pkt_ha_private) 117 #define VHCIPKT2HBAPKT(pkt) (pkt->pkt_hba_pkt) 118 #define VHCIPKT2TGTPKT(pkt) (pkt->pkt_tgt_pkt) 119 120 #define VHCI_DECR_PATH_CMDCOUNT(svp) { \ 121 mutex_enter(&(svp)->svp_mutex); \ 122 (svp)->svp_cmds--; \ 123 if ((svp)->svp_cmds == 0) \ 124 cv_broadcast(&(svp)->svp_cv); \ 125 mutex_exit(&(svp)->svp_mutex); \ 126 } 127 128 #define VHCI_INCR_PATH_CMDCOUNT(svp) { \ 129 mutex_enter(&(svp)->svp_mutex); \ 130 (svp)->svp_cmds++; \ 131 mutex_exit(&(svp)->svp_mutex); \ 132 } 133 134 /* 135 * When a LUN is HELD it results in new IOs being returned to the target 136 * driver layer with TRAN_BUSY. Should be used while performing 137 * operations that require prevention of any new IOs to the LUN and 138 * the LUN should be HELD for the duration of such operations. 139 * f can be VH_SLEEP or VH_NOSLEEP. 140 * h is set to 1 to indicate LUN was successfully HELD. 141 * h is set to 0 when f is VH_NOSLEEP and LUN is already HELD. 142 * 143 * Application examples: 144 * 145 * 1) SCSI-II RESERVE: HOLD LUN until it is quiesced and the load balancing 146 * policy is switched to NONE before proceeding with RESERVE handling. 147 * 148 * 2) Failover: HOLD LUN before initiating failover. 149 * 150 * 3) When an externally initiated failover is detected, HOLD LUN until all 151 * path states have been refreshed to reflect the new value. 152 * 153 */ 154 #define VHCI_HOLD_LUN(vlun, f, h) { \ 155 int sleep = (f); \ 156 mutex_enter(&(vlun)->svl_mutex); \ 157 if ((vlun)->svl_transient == 1) { \ 158 if (sleep == VH_SLEEP) { \ 159 while ((vlun)->svl_transient == 1) \ 160 cv_wait(&(vlun)->svl_cv, &(vlun)->svl_mutex); \ 161 (vlun)->svl_transient = 1; \ 162 (h) = 1; \ 163 } else { \ 164 (h) = 0; \ 165 } \ 166 } else { \ 167 (vlun)->svl_transient = 1; \ 168 (h) = 1; \ 169 } \ 170 sleep = (h); \ 171 mutex_exit(&(vlun)->svl_mutex); \ 172 } 173 174 #define VHCI_RELEASE_LUN(vlun) { \ 175 mutex_enter(&(vlun)->svl_mutex); \ 176 (vlun)->svl_transient = 0; \ 177 cv_broadcast(&(vlun)->svl_cv); \ 178 mutex_exit(&(vlun)->svl_mutex); \ 179 } 180 181 #define VHCI_LUN_IS_HELD(vlun) ((vlun)->svl_transient == 1) 182 183 /* 184 * vhci_pkt states 185 */ 186 #define VHCI_PKT_IDLE 0x01 187 #define VHCI_PKT_ISSUED 0x02 188 #define VHCI_PKT_ABORTING 0x04 189 #define VHCI_PKT_STALE_BINDING 0x08 190 /* 191 * Set the first time taskq is dispatched from scsi_start for 192 * a packet. To ensure vhci_scsi_start recognizes that the scsi_pkt 193 * is being issued from the taskq and not target driver. 194 */ 195 #define VHCI_PKT_THRU_TASKQ 0x20 196 /* 197 * Set the first time failover is being triggered. To ensure 198 * failover won't be triggered again when the packet is being 199 * retried by target driver. 200 */ 201 #define VHCI_PKT_IN_FAILOVER 0x40 202 203 #define VHCI_PKT_TIMEOUT 30 /* seconds */ 204 #define VHCI_PKT_RETRY_CNT 2 205 #define VHCI_POLL_TIMEOUT 60 /* seconds */ 206 207 /* 208 * define extended scsi cmd pkt 209 */ 210 #define EXTCMDS_STATUS_SIZE (sizeof (struct scsi_arq_status)) 211 212 #define CFLAG_NOWAIT 0x1000 /* don't sleep */ 213 #define CFLAG_DMA_PARTIAL 0x2000 /* Support Partial DMA */ 214 215 /* 216 * Maximum size of SCSI cdb in SCSI command 217 */ 218 #define VHCI_SCSI_CDB_SIZE 16 219 #define VHCI_SCSI_SCB_SIZE (sizeof (struct scsi_arq_status)) 220 221 /* 222 * OSD specific definitions 223 */ 224 #define VHCI_SCSI_OSD_CDB_SIZE 224 225 #define VHCI_SCSI_OSD_PKT_FLAGS 0x100000 226 227 /* 228 * flag to determine failover support 229 */ 230 #define SCSI_NO_FAILOVER 0x0 231 #define SCSI_IMPLICIT_FAILOVER 0x1 232 #define SCSI_EXPLICIT_FAILOVER 0x2 233 #define SCSI_BOTH_FAILOVER \ 234 (SCSI_IMPLICIT_FAILOVER | SCSI_EXPLICIT_FAILOVER) 235 236 struct scsi_vhci_swarg; 237 238 #define VHCI_NUM_RESV_KEYS 8 239 240 typedef struct vhci_prin_readkeys { 241 uint32_t generation; 242 uint32_t length; 243 mhioc_resv_key_t keylist[VHCI_NUM_RESV_KEYS]; 244 } vhci_prin_readkeys_t; 245 246 #define VHCI_PROUT_SIZE \ 247 ((sizeof (vhci_prout_t) - 2 * (MHIOC_RESV_KEY_SIZE) * sizeof (char))) 248 249 typedef struct vhci_prout { 250 /* PGR register parameters start */ 251 uchar_t res_key[MHIOC_RESV_KEY_SIZE]; 252 uchar_t service_key[MHIOC_RESV_KEY_SIZE]; 253 uint32_t scope_address; 254 255 #if defined(_BIT_FIELDS_LTOH) 256 uchar_t aptpl:1, 257 reserved:7; 258 #else 259 uchar_t reserved:7, 260 aptpl:1; 261 #endif /* _BIT_FIELDS_LTOH */ 262 263 uchar_t reserved_1; 264 uint16_t ext_len; 265 /* PGR register parameters end */ 266 267 /* Update VHCI_PROUT_SIZE if new fields are added here */ 268 269 uchar_t active_res_key[MHIOC_RESV_KEY_SIZE]; 270 uchar_t active_service_key[MHIOC_RESV_KEY_SIZE]; 271 } vhci_prout_t; 272 273 #define VHCI_PROUT_REGISTER 0x0 274 #define VHCI_PROUT_RESERVE 0x1 275 #define VHCI_PROUT_RELEASE 0x2 276 #define VHCI_PROUT_CLEAR 0x3 277 #define VHCI_PROUT_PREEMPT 0x4 278 #define VHCI_PROUT_P_AND_A 0x5 279 #define VHCI_PROUT_R_AND_IGNORE 0x6 280 281 struct vhci_pkt { 282 struct scsi_pkt *vpkt_tgt_pkt; 283 mdi_pathinfo_t *vpkt_path; /* path pkt bound to */ 284 285 /* 286 * pHCI packet that does the actual work. 287 */ 288 struct scsi_pkt *vpkt_hba_pkt; 289 290 uint_t vpkt_state; 291 uint_t vpkt_flags; 292 293 /* 294 * copy of vhci_scsi_init_pkt args. Used when we invoke 295 * scsi_init_pkt() of the pHCI corresponding to the path that we 296 * bind to 297 */ 298 int vpkt_tgt_init_cdblen; 299 int vpkt_tgt_init_scblen; 300 int vpkt_tgt_init_pkt_flags; 301 struct buf *vpkt_tgt_init_bp; 302 303 /* 304 * Pointer to original struct vhci_pkt for cmd send by ssd. 305 * Saved when the command is being retried internally. 306 */ 307 struct vhci_pkt *vpkt_org_vpkt; 308 }; 309 310 typedef struct scsi_vhci_lun { 311 kmutex_t svl_mutex; 312 kcondvar_t svl_cv; 313 314 /* 315 * following three fields are under svl_mutex protection 316 */ 317 int svl_transient; 318 319 /* 320 * to prevent unnecessary failover when a device is 321 * is discovered across a passive path and active path 322 * is still comng up 323 */ 324 int svl_waiting_for_activepath; 325 hrtime_t svl_wfa_time; 326 327 /* 328 * to keep the failover status in order to return the 329 * failure status to target driver when targer driver 330 * retries the command which originally triggered the 331 * failover. 332 */ 333 int svl_failover_status; 334 335 /* 336 * for RESERVE/RELEASE support 337 */ 338 client_lb_t svl_lb_policy_save; 339 340 /* 341 * Failover ops and ops name selected for the lun. 342 */ 343 struct scsi_failover_ops *svl_fops; 344 char *svl_fops_name; 345 346 void *svl_fops_ctpriv; 347 348 struct scsi_vhci_lun *svl_hash_next; 349 char *svl_lun_wwn; 350 351 /* 352 * currently active pathclass 353 */ 354 char *svl_active_pclass; 355 356 dev_info_t *svl_dip; 357 uint32_t svl_flags; /* protected by svl_mutex */ 358 359 /* 360 * When SCSI-II reservations are active we set the following pip 361 * to point to the path holding the reservation. As long as 362 * the reservation is active this svl_resrv_pip is bound for the 363 * transport directly. We bypass calling mdi_select_path to return 364 * a pip. 365 * The following pip is only valid when VLUN_RESERVE_ACTIVE_FLG 366 * is set. This pip should not be accessed if this flag is reset. 367 */ 368 mdi_pathinfo_t *svl_resrv_pip; 369 370 /* 371 * following fields are for PGR support 372 */ 373 taskq_t *svl_taskq; 374 ksema_t svl_pgr_sema; /* PGR serialization */ 375 vhci_prin_readkeys_t svl_prin; /* PGR in data */ 376 vhci_prout_t svl_prout; /* PGR out data */ 377 uchar_t svl_cdb[CDB_GROUP4]; 378 int svl_time; /* pkt_time */ 379 uint32_t svl_bcount; /* amount of data */ 380 int svl_pgr_active; /* registrations active */ 381 mdi_pathinfo_t *svl_first_path; 382 383 /* external failover */ 384 int svl_efo_update_path; 385 struct scsi_vhci_swarg *svl_swarg; 386 387 uint32_t svl_support_lun_reset; /* Lun reset support */ 388 int svl_not_supported; 389 int svl_xlf_capable; /* XLF implementation */ 390 int svl_sector_size; 391 int svl_setcap_done; 392 uint16_t svl_fo_support; /* failover mode */ 393 } scsi_vhci_lun_t; 394 395 #define VLUN_TASK_D_ALIVE_FLG 0x01 396 397 /* 398 * This flag is used to monitor the state of SCSI-II RESERVATION on the 399 * lun. A SCSI-II RESERVE cmd may be accepted by the target on the inactive 400 * path. This would then cause a subsequent IO to cause the paths to be 401 * updated and be returned with a reservation conflict. By monitoring this 402 * flag, and sending a reset to the target when needed to clear the reservation, 403 * one can avoid this conflict. 404 */ 405 #define VLUN_RESERVE_ACTIVE_FLG 0x04 406 407 /* 408 * This flag is set when a SCSI-II RESERVE cmd is received by scsi_vhci 409 * and cleared when the pkt completes in vhci_intr. It ensures that the 410 * lun remains quiesced for the duration of this pkt. This is different 411 * from VHCI_HOLD_LUN as this pertains to IOs only. 412 */ 413 #define VLUN_QUIESCED_FLG 0x08 414 415 /* 416 * This flag is set to tell vhci_update_pathstates to call back 417 * into vhci_mpapi_update_tpg_acc_state. 418 */ 419 #define VLUN_UPDATE_TPG 0x10 420 421 /* 422 * Various reset recovery depth. 423 */ 424 425 #define VHCI_DEPTH_ALL 3 426 #define VHCI_DEPTH_TARGET 2 427 #define VHCI_DEPTH_LUN 1 /* For the sake completeness */ 428 #define TRUE (1) 429 #define FALSE (0) 430 431 /* 432 * this is stashed away in the client private area of 433 * pathinfo 434 */ 435 typedef struct scsi_vhci_priv { 436 kmutex_t svp_mutex; 437 kcondvar_t svp_cv; 438 struct scsi_vhci_lun *svp_svl; 439 440 /* 441 * scsi device associated with this 442 * pathinfo 443 */ 444 struct scsi_device *svp_psd; 445 446 /* 447 * number of outstanding commands on this 448 * path. Protected by svp_mutex 449 */ 450 int svp_cmds; 451 452 /* 453 * following is used to prevent packets completing with the 454 * same error reason from flooding the screen 455 */ 456 uchar_t svp_last_pkt_reason; 457 458 /* external failover scsi_watch token */ 459 opaque_t svp_sw_token; 460 461 /* any cleanup operations for a newly found path. */ 462 int svp_new_path; 463 } scsi_vhci_priv_t; 464 465 /* 466 * argument to scsi_watch callback. Used for processing 467 * externally initiated failovers 468 */ 469 typedef struct scsi_vhci_swarg { 470 scsi_vhci_priv_t *svs_svp; 471 hrtime_t svs_tos; /* time of submission */ 472 mdi_pathinfo_t *svs_pi; /* pathinfo being "watched" */ 473 int svs_release_lun; 474 int svs_done; 475 } scsi_vhci_swarg_t; 476 477 /* 478 * scsi_vhci softstate 479 * 480 * vhci_mutex protects 481 * vhci_state 482 * and vhci_reset_notify list 483 */ 484 struct scsi_vhci { 485 kmutex_t vhci_mutex; 486 dev_info_t *vhci_dip; 487 struct scsi_hba_tran *vhci_tran; 488 uint32_t vhci_state; 489 uint32_t vhci_instance; 490 kstat_t vhci_kstat; 491 /* 492 * This taskq is for general vhci operations like reservations, 493 * auto-failback, etc. 494 */ 495 taskq_t *vhci_taskq; 496 /* Dedicate taskq to handle external failovers */ 497 taskq_t *vhci_update_pathstates_taskq; 498 struct scsi_reset_notify_entry *vhci_reset_notify_listf; 499 uint16_t vhci_conf_flags; 500 mpapi_priv_t *mp_priv; 501 }; 502 503 /* 504 * vHCI flags for configuration settings, defined in scsi_vhci.conf 505 */ 506 #define VHCI_CONF_FLAGS_AUTO_FAILBACK 0x0001 /* Enables auto failback */ 507 508 typedef enum { 509 SCSI_PATH_INACTIVE, 510 SCSI_PATH_ACTIVE, 511 SCSI_PATH_ACTIVE_NONOPT 512 } scsi_path_state_t; 513 514 #define SCSI_MAXPCLASSLEN 25 515 516 #define OPINFO_REV 1 517 518 /* 519 * structure describing operational characteristics of 520 * path 521 */ 522 struct scsi_path_opinfo { 523 int opinfo_rev; 524 525 /* 526 * name of pathclass. Eg. "primary", "secondary" 527 */ 528 char opinfo_path_attr[SCSI_MAXPCLASSLEN]; 529 530 /* 531 * path state: ACTIVE/PASSIVE 532 */ 533 scsi_path_state_t opinfo_path_state; 534 535 /* 536 * the best and worst case time estimates for 537 * failover operation to complete 538 */ 539 uint_t opinfo_pswtch_best; 540 uint_t opinfo_pswtch_worst; 541 542 /* XLF implementation */ 543 int opinfo_xlf_capable; 544 uint16_t opinfo_preferred; 545 uint16_t opinfo_mode; 546 547 }; 548 549 550 #define SFO_REV 1 551 552 /* 553 * vectors for device specific failover related operations 554 */ 555 struct scsi_failover_ops { 556 int sfo_rev; 557 558 /* 559 * failover module name, begins with "f_" 560 */ 561 char *sfo_name; 562 563 /* 564 * devices supported by failover module 565 * 566 * NOTE: this is an aproximation, sfo_device_probe has the final say. 567 */ 568 char **sfo_devices; 569 570 /* 571 * initialize the failover module 572 */ 573 void (*sfo_init)(); 574 575 /* 576 * identify device 577 */ 578 int (*sfo_device_probe)( 579 struct scsi_device *sd, 580 struct scsi_inquiry *stdinq, 581 void **ctpriv); 582 583 /* 584 * housekeeping (free memory etc alloc'ed during probe 585 */ 586 void (*sfo_device_unprobe)( 587 struct scsi_device *sd, 588 void *ctpriv); 589 590 /* 591 * bring a path ONLINE (ie make it ACTIVE) 592 */ 593 int (*sfo_path_activate)( 594 struct scsi_device *sd, 595 char *pathclass, 596 void *ctpriv); 597 598 /* 599 * inverse of above 600 */ 601 int (*sfo_path_deactivate)( 602 struct scsi_device *sd, 603 char *pathclass, 604 void *ctpriv); 605 606 /* 607 * returns operational characteristics of path 608 */ 609 int (*sfo_path_get_opinfo)( 610 struct scsi_device *sd, 611 struct scsi_path_opinfo *opinfo, 612 void *ctpriv); 613 614 /* 615 * verify path is operational 616 */ 617 int (*sfo_path_ping)( 618 struct scsi_device *sd, 619 void *ctpriv); 620 621 /* 622 * analyze SENSE data to detect externally initiated 623 * failovers 624 */ 625 int (*sfo_analyze_sense)( 626 struct scsi_device *sd, 627 uint8_t *sense, 628 void *ctpriv); 629 630 /* 631 * return the next pathclass in order of preference 632 * eg. "secondary" comes after "primary" 633 */ 634 int (*sfo_pathclass_next)( 635 char *cur, 636 char **nxt, 637 void *ctpriv); 638 }; 639 640 /* 641 * Names of (too) 'well-known' failover ops. 642 * NOTE: consumers of these names should look for a better way... 643 */ 644 #define SFO_NAME_SYM "f_sym" 645 #define SFO_NAME_TPGS "f_tpgs" 646 #define SCSI_FAILOVER_IS_ASYM(svl) \ 647 ((svl) ? ((svl)->svl_fo_support != SCSI_NO_FAILOVER) : 0) 648 #define SCSI_FAILOVER_IS_TPGS(sfo) \ 649 ((sfo) ? (strcmp((sfo)->sfo_name, SFO_NAME_TPGS) == 0) : 0) 650 651 /* 652 * Macro to provide plumbing for basic failover module 653 */ 654 #define _SCSI_FAILOVER_OP(sfo_name, local_name, ops_name) \ 655 static struct modlmisc modlmisc = { \ 656 &mod_miscops, sfo_name \ 657 }; \ 658 static struct modlinkage modlinkage = { \ 659 MODREV_1, (void *)&modlmisc, NULL \ 660 }; \ 661 int _init() \ 662 { \ 663 return (mod_install(&modlinkage)); \ 664 } \ 665 int _fini() \ 666 { \ 667 return (mod_remove(&modlinkage)); \ 668 } \ 669 int _info(struct modinfo *modinfop) \ 670 { \ 671 return (mod_info(&modlinkage, modinfop)); \ 672 } \ 673 static int local_name##_device_probe( \ 674 struct scsi_device *, \ 675 struct scsi_inquiry *, void **); \ 676 static void local_name##_device_unprobe( \ 677 struct scsi_device *, void *); \ 678 static int local_name##_path_activate( \ 679 struct scsi_device *, char *, void *); \ 680 static int local_name##_path_deactivate( \ 681 struct scsi_device *, char *, void *); \ 682 static int local_name##_path_get_opinfo( \ 683 struct scsi_device *, \ 684 struct scsi_path_opinfo *, void *); \ 685 static int local_name##_path_ping( \ 686 struct scsi_device *, void *); \ 687 static int local_name##_analyze_sense( \ 688 struct scsi_device *, \ 689 uint8_t *, void *); \ 690 static int local_name##_pathclass_next( \ 691 char *, char **, void *); \ 692 struct scsi_failover_ops ops_name##_failover_ops = { \ 693 SFO_REV, \ 694 sfo_name, \ 695 local_name##_dev_table, \ 696 NULL, \ 697 local_name##_device_probe, \ 698 local_name##_device_unprobe, \ 699 local_name##_path_activate, \ 700 local_name##_path_deactivate, \ 701 local_name##_path_get_opinfo, \ 702 local_name##_path_ping, \ 703 local_name##_analyze_sense, \ 704 local_name##_pathclass_next \ 705 } 706 707 #ifdef lint 708 #define SCSI_FAILOVER_OP(sfo_name, local_name) \ 709 _SCSI_FAILOVER_OP(sfo_name, local_name, local_name) 710 #else /* lint */ 711 #define SCSI_FAILOVER_OP(sfo_name, local_name) \ 712 _SCSI_FAILOVER_OP(sfo_name, local_name, scsi_vhci) 713 #endif /* lint */ 714 715 /* 716 * Return values for sfo_device_probe 717 */ 718 #define SFO_DEVICE_PROBE_VHCI 1 /* supported under scsi_vhci */ 719 #define SFO_DEVICE_PROBE_PHCI 0 /* not supported under scsi_vhci */ 720 721 /* return values for sfo_analyze_sense() */ 722 #define SCSI_SENSE_NOFAILOVER 0 723 #define SCSI_SENSE_FAILOVER_INPROG 1 724 #define SCSI_SENSE_ACT2INACT 2 725 #define SCSI_SENSE_INACT2ACT 3 726 #define SCSI_SENSE_INACTIVE 4 727 #define SCSI_SENSE_UNKNOWN 5 728 #define SCSI_SENSE_STATE_CHANGED 6 729 #define SCSI_SENSE_NOT_READY 7 730 731 /* vhci_intr action codes */ 732 #define JUST_RETURN 0 733 #define BUSY_RETURN 1 734 #define PKT_RETURN 2 735 736 #if defined(_SYSCALL32) 737 /* 738 * 32 bit variants of sv_path_info_prop_t and sv_path_info_t; 739 * To be used only in the driver and NOT applications 740 */ 741 typedef struct sv_path_info_prop32 { 742 uint32_t buf_size; /* user buffer size */ 743 caddr32_t ret_buf_size; /* actual buffer needed */ 744 caddr32_t buf; /* user space buffer */ 745 } sv_path_info_prop32_t; 746 747 typedef struct sv_path_info32 { 748 union { 749 char ret_ct[MAXPATHLEN]; /* client device */ 750 char ret_phci[MAXPATHLEN]; /* pHCI device */ 751 } device; 752 753 char ret_addr[MAXNAMELEN]; /* device address */ 754 mdi_pathinfo_state_t ret_state; /* state information */ 755 uint32_t ret_ext_state; /* Extended State */ 756 sv_path_info_prop32_t ret_prop; /* path attributes */ 757 } sv_path_info32_t; 758 759 typedef struct sv_iocdata32 { 760 caddr32_t client; /* client dev devfs path name */ 761 caddr32_t phci; /* pHCI dev devfs path name */ 762 caddr32_t addr; /* device address */ 763 uint32_t buf_elem; /* number of path_info elems */ 764 caddr32_t ret_buf; /* addr of array of sv_path_info */ 765 caddr32_t ret_elem; /* count of above sv_path_info */ 766 } sv_iocdata32_t; 767 768 typedef struct sv_switch_to_cntlr_iocdata32 { 769 caddr32_t client; /* client device devfs path name */ 770 caddr32_t class; /* desired path class to be made active */ 771 } sv_switch_to_cntlr_iocdata32_t; 772 773 #endif /* _SYSCALL32 */ 774 775 #endif /* _KERNEL */ 776 777 /* 778 * Userland (Non Kernel) definitions start here. 779 * Multiplexed I/O SCSI vHCI IOCTL Definitions 780 */ 781 782 /* 783 * IOCTL structure for path properties 784 */ 785 typedef struct sv_path_info_prop { 786 uint_t buf_size; /* user buffer size */ 787 uint_t *ret_buf_size; /* actual buffer needed */ 788 caddr_t buf; /* user space buffer */ 789 } sv_path_info_prop_t; 790 791 /* 792 * Max buffer size of getting path properties 793 */ 794 #define SV_PROP_MAX_BUF_SIZE 4096 795 796 /* 797 * String values for "path-class" property 798 */ 799 #define PCLASS_PRIMARY "primary" 800 #define PCLASS_SECONDARY "secondary" 801 802 #define PCLASS_PREFERRED 1 803 #define PCLASS_NONPREFERRED 0 804 805 /* 806 * IOCTL structure for path information 807 */ 808 typedef struct sv_path_info { 809 union { 810 char ret_ct[MAXPATHLEN]; /* client device */ 811 char ret_phci[MAXPATHLEN]; /* pHCI device */ 812 } device; 813 814 char ret_addr[MAXNAMELEN]; /* device address */ 815 mdi_pathinfo_state_t ret_state; /* state information */ 816 uint32_t ret_ext_state; /* Extended State */ 817 sv_path_info_prop_t ret_prop; /* path attributes */ 818 } sv_path_info_t; 819 820 /* 821 * IOCTL argument structure 822 */ 823 typedef struct sv_iocdata { 824 caddr_t client; /* client dev devfs path name */ 825 caddr_t phci; /* pHCI dev devfs path name */ 826 caddr_t addr; /* device address */ 827 uint_t buf_elem; /* number of path_info elems */ 828 sv_path_info_t *ret_buf; /* array of sv_path_info */ 829 uint_t *ret_elem; /* count of sv_path_info */ 830 } sv_iocdata_t; 831 832 /* 833 * IOCTL argument structure for switching controllers 834 */ 835 typedef struct sv_switch_to_cntlr_iocdata { 836 caddr_t client; /* client device devfs path name */ 837 caddr_t class; /* desired path class to be made active */ 838 } sv_switch_to_cntlr_iocdata_t; 839 840 841 /* 842 * IOCTL definitions 843 */ 844 #define SCSI_VHCI_CTL ('X' << 8) 845 #define SCSI_VHCI_CTL_CMD (SCSI_VHCI_CTL | ('S' << 8) | 'P') 846 #define SCSI_VHCI_CTL_SUB_CMD ('x' << 8) 847 848 #define SCSI_VHCI_GET_CLIENT_MULTIPATH_INFO (SCSI_VHCI_CTL_SUB_CMD + 0x01) 849 #define SCSI_VHCI_GET_PHCI_MULTIPATH_INFO (SCSI_VHCI_CTL_SUB_CMD + 0x02) 850 #define SCSI_VHCI_GET_CLIENT_NAME (SCSI_VHCI_CTL_SUB_CMD + 0x03) 851 #define SCSI_VHCI_PATH_ONLINE (SCSI_VHCI_CTL_SUB_CMD + 0x04) 852 #define SCSI_VHCI_PATH_OFFLINE (SCSI_VHCI_CTL_SUB_CMD + 0x05) 853 #define SCSI_VHCI_PATH_STANDBY (SCSI_VHCI_CTL_SUB_CMD + 0x06) 854 #define SCSI_VHCI_PATH_TEST (SCSI_VHCI_CTL_SUB_CMD + 0x07) 855 #define SCSI_VHCI_SWITCH_TO_CNTLR (SCSI_VHCI_CTL_SUB_CMD + 0x08) 856 857 #ifdef DEBUG 858 #define SCSI_VHCI_GET_PHCI_LIST (SCSI_VHCI_CTL_SUB_CMD + 0x09) 859 #define SCSI_VHCI_CONFIGURE_PHCI (SCSI_VHCI_CTL_SUB_CMD + 0x0A) 860 #define SCSI_VHCI_UNCONFIGURE_PHCI (SCSI_VHCI_CTL_SUB_CMD + 0x0B) 861 #endif 862 863 #define SCSI_VHCI_PATH_DISABLE (SCSI_VHCI_CTL_SUB_CMD + 0x0C) 864 #define SCSI_VHCI_PATH_ENABLE (SCSI_VHCI_CTL_SUB_CMD + 0x0D) 865 #define SCSI_VHCI_MPAPI (SCSI_VHCI_CTL_SUB_CMD + 0x0E) 866 867 #define SCSI_VHCI_GET_TARGET_LONGNAME (SCSI_VHCI_CTL_SUB_CMD + 0x0F) 868 869 #ifdef __cplusplus 870 } 871 #endif 872 873 #endif /* _SYS_SCSI_ADAPTERS_SCSI_VHCI_H */ 874