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