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