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