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