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