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