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