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 */