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