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