scsi_vhci.h revision 4851:5e98cf4c2164
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 2007 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
43extern "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
74int vhci_do_scsi_cmd(struct scsi_pkt *);
75/*PRINTFLIKE3*/
76void 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
88extern 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
213struct	scsi_vhci_swarg;
214
215typedef struct vhci_prin_readkeys {
216	uint32_t		generation;
217	uint32_t		length;
218	mhioc_resv_key_t	keylist[MHIOC_RESV_KEY_SIZE];
219} vhci_prin_readkeys_t;
220
221#define	VHCI_PROUT_SIZE	\
222	((sizeof (vhci_prout_t) - 2 * (MHIOC_RESV_KEY_SIZE) * sizeof (char)))
223
224typedef struct vhci_prout {
225	/* PGR register parameters start */
226	uchar_t		res_key[MHIOC_RESV_KEY_SIZE];
227	uchar_t		service_key[MHIOC_RESV_KEY_SIZE];
228	uint32_t	scope_address;
229
230#if defined(_BIT_FIELDS_LTOH)
231	uchar_t		aptpl:1,
232			reserved:7;
233#else
234	uchar_t		reserved:7,
235			aptpl:1;
236#endif /* _BIT_FIELDS_LTOH */
237
238	uchar_t		reserved_1;
239	uint16_t	ext_len;
240	/* PGR register parameters end */
241
242	/* Update VHCI_PROUT_SIZE if new fields are added here */
243
244	uchar_t		active_res_key[MHIOC_RESV_KEY_SIZE];
245	uchar_t		active_service_key[MHIOC_RESV_KEY_SIZE];
246} vhci_prout_t;
247
248#define	VHCI_PROUT_REGISTER	0x0
249#define	VHCI_PROUT_RESERVE	0x1
250#define	VHCI_PROUT_RELEASE	0x2
251#define	VHCI_PROUT_CLEAR	0x3
252#define	VHCI_PROUT_PREEMPT	0x4
253#define	VHCI_PROUT_P_AND_A	0x5
254#define	VHCI_PROUT_R_AND_IGNORE	0x6
255
256struct vhci_pkt {
257	struct scsi_pkt			*vpkt_tgt_pkt;
258	mdi_pathinfo_t			*vpkt_path;	/* path pkt bound to */
259
260	/*
261	 * pHCI packet that does the actual work.
262	 */
263	struct scsi_pkt			*vpkt_hba_pkt;
264
265	uint_t				vpkt_state;
266	uint_t				vpkt_flags;
267
268	/*
269	 * copy of vhci_scsi_init_pkt args.  Used when we invoke
270	 * scsi_init_pkt() of the pHCI corresponding to the path that we
271	 * bind to
272	 */
273	int				vpkt_tgt_init_cdblen;
274	int				vpkt_tgt_init_privlen;
275	int				vpkt_tgt_init_scblen;
276	int				vpkt_tgt_init_pkt_flags;
277	struct buf			*vpkt_tgt_init_bp;
278
279	/*
280	 * Pointer to original struct vhci_pkt for cmd send by ssd.
281	 * Saved when the command is being retried internally.
282	 */
283	struct vhci_pkt			*vpkt_org_vpkt;
284};
285
286typedef struct scsi_vhci_lun {
287	kmutex_t		svl_mutex;
288	kcondvar_t		svl_cv;
289
290	/*
291	 * following three fields are under svl_mutex protection
292	 */
293	int			svl_transient;
294
295	/*
296	 * to prevent unnecessary failover when a device is
297	 * is discovered across a passive path and active path
298	 * is still comng up
299	 */
300	int			svl_waiting_for_activepath;
301	time_t			svl_wfa_time;
302
303	/*
304	 * for RESERVE/RELEASE support
305	 */
306	client_lb_t		svl_lb_policy_save;
307
308	/*
309	 * Failover ops and ops name selected for the lun.
310	 */
311	struct scsi_failover_ops	*svl_fops;
312	char			*svl_fops_name;
313
314	void			*svl_fops_ctpriv;
315
316	struct scsi_vhci_lun	*svl_hash_next;
317	char			*svl_lun_wwn;
318
319	/*
320	 * currently active pathclass
321	 */
322	char			*svl_active_pclass;
323
324	dev_info_t		*svl_dip;
325	uint32_t		svl_flags;	/* protected by svl_mutex */
326
327	/*
328	 * When SCSI-II reservations are active we set the following pip
329	 * to point to the path holding the reservation.  As long as
330	 * the reservation is active this svl_resrv_pip is bound for the
331	 * transport directly.  We bypass calling mdi_select_path to return
332	 * a pip.
333	 * The following pip is only valid when VLUN_RESERVE_ACTIVE_FLG
334	 * is set.  This pip should not be accessed if this flag is reset.
335	 */
336	mdi_pathinfo_t	*svl_resrv_pip;
337
338	/*
339	 * following fields are for PGR support
340	 */
341	taskq_t			*svl_taskq;
342	ksema_t			svl_pgr_sema;	/* PGR serialization */
343	vhci_prin_readkeys_t	svl_prin;	/* PGR in data */
344	vhci_prout_t		svl_prout;	/* PGR out data */
345	uchar_t			svl_cdb[CDB_GROUP4];
346	int			svl_time;	/* pkt_time */
347	uint32_t		svl_bcount;	/* amount of data */
348	int			svl_pgr_active; /* registrations active */
349	mdi_pathinfo_t		*svl_first_path;
350
351	/* external failover */
352	int			svl_efo_update_path;
353	struct	scsi_vhci_swarg	*svl_swarg;
354
355	uint32_t		svl_support_lun_reset; /* Lun reset support */
356	int			svl_not_supported;
357	int			svl_xlf_capable; /* XLF implementation */
358	int			svl_sector_size;
359	int			svl_setcap_done;
360	uint16_t		svl_fo_support;	 /* failover mode */
361} scsi_vhci_lun_t;
362
363#define	VLUN_TASK_D_ALIVE_FLG		0x01
364
365/*
366 * This flag is used to monitor the state of SCSI-II RESERVATION on the
367 * lun.  A SCSI-II RESERVE cmd may be accepted by the target on the inactive
368 * path.  This would then cause a subsequent IO to cause the paths to be
369 * updated and be returned with a reservation conflict.  By monitoring this
370 * flag, and sending a reset to the target when needed to clear the reservation,
371 * one can avoid this conflict.
372 */
373#define	VLUN_RESERVE_ACTIVE_FLG		0x04
374
375/*
376 * This flag is set when a SCSI-II RESERVE cmd is received by scsi_vhci
377 * and cleared when the pkt completes in vhci_intr.  It ensures that the
378 * lun remains quiesced for the duration of this pkt.  This is different
379 * from VHCI_HOLD_LUN as this pertains to IOs only.
380 */
381#define	VLUN_QUIESCED_FLG		0x08
382
383/*
384 * This flag is set to tell vhci_update_pathstates to call back
385 * into vhci_mpapi_update_tpg_acc_state.
386 */
387#define	VLUN_UPDATE_TPG			0x10
388
389/*
390 * Various reset recovery depth.
391 */
392
393#define	VHCI_DEPTH_ALL		3
394#define	VHCI_DEPTH_TARGET	2
395#define	VHCI_DEPTH_LUN		1	/* For the sake completeness */
396#define	TRUE			(1)
397#define	FALSE			(0)
398
399/*
400 * this is stashed away in the client private area of
401 * pathinfo
402 */
403typedef struct scsi_vhci_priv {
404	kmutex_t		svp_mutex;
405	kcondvar_t		svp_cv;
406	struct scsi_vhci_lun	*svp_svl;
407
408	/*
409	 * scsi device associated with this
410	 * pathinfo
411	 */
412	struct scsi_device	*svp_psd;
413
414	/*
415	 * number of outstanding commands on this
416	 * path.  Protected by svp_mutex
417	 */
418	int			svp_cmds;
419
420	/*
421	 * following is used to prevent packets completing with the
422	 * same error reason from flooding the screen
423	 */
424	uchar_t			svp_last_pkt_reason;
425
426	/* external failover scsi_watch token */
427	opaque_t		svp_sw_token;
428
429	/* any cleanup operations for a newly found path. */
430	int			svp_new_path;
431} scsi_vhci_priv_t;
432
433/*
434 * argument to scsi_watch callback.  Used for processing
435 * externally initiated failovers
436 */
437typedef struct scsi_vhci_swarg {
438	scsi_vhci_priv_t	*svs_svp;
439	time_t			svs_tos;	/* time of submission */
440	mdi_pathinfo_t		*svs_pi;	/* pathinfo being "watched" */
441	int			svs_release_lun;
442	int			svs_done;
443} scsi_vhci_swarg_t;
444
445/*
446 * scsi_vhci softstate
447 *
448 * vhci_mutex protects
449 *	vhci_state
450 * and	vhci_reset_notify list
451 */
452struct scsi_vhci {
453	kmutex_t			vhci_mutex;
454	dev_info_t			*vhci_dip;
455	struct scsi_hba_tran		*vhci_tran;
456	uint32_t			vhci_state;
457	uint32_t			vhci_instance;
458	kstat_t				vhci_kstat;
459	/*
460	 * This taskq is for general vhci operations like reservations,
461	 * auto-failback, etc.
462	 */
463	taskq_t				*vhci_taskq;
464	/* Dedicate taskq to handle external failovers */
465	taskq_t				*vhci_update_pathstates_taskq;
466	struct scsi_reset_notify_entry	*vhci_reset_notify_listf;
467	uint16_t			vhci_conf_flags;
468	mpapi_priv_t			*mp_priv;
469};
470
471/*
472 * vHCI flags for configuration settings, defined in scsi_vhci.conf
473 */
474#define	VHCI_CONF_FLAGS_AUTO_FAILBACK	0x0001	/* Enables auto failback */
475
476typedef enum {
477	SCSI_PATH_INACTIVE,
478	SCSI_PATH_ACTIVE,
479	SCSI_PATH_ACTIVE_NONOPT
480} scsi_path_state_t;
481
482#define	SCSI_MAXPCLASSLEN	25
483
484#define	OPINFO_REV	1
485
486/*
487 * structure describing operational characteristics of
488 * path
489 */
490struct scsi_path_opinfo {
491	int			opinfo_rev;
492
493	/*
494	 * name of pathclass. Eg. "primary", "secondary"
495	 */
496	char			opinfo_path_attr[SCSI_MAXPCLASSLEN];
497
498	/*
499	 * path state: ACTIVE/PASSIVE
500	 */
501	scsi_path_state_t	opinfo_path_state;
502
503	/*
504	 * the best and worst case time estimates for
505	 * failover operation to complete
506	 */
507	uint_t			opinfo_pswtch_best;
508	uint_t			opinfo_pswtch_worst;
509
510	/* XLF implementation */
511	int			opinfo_xlf_capable;
512	uint16_t		opinfo_preferred;
513	uint16_t		opinfo_mode;
514
515};
516
517
518#define	SFO_REV		1
519
520/*
521 * vectors for device specific failover related operations
522 */
523struct scsi_failover_ops {
524	int	sfo_rev;
525
526	/*
527	 * failover module name, begins with "f_"
528	 */
529	char	*sfo_name;
530
531	/*
532	 * devices supported by failover module
533	 *
534	 * NOTE: this is an aproximation, sfo_device_probe has the final say.
535	 */
536	char	**sfo_devices;
537
538	/*
539	 * initialize the failover module
540	 */
541	void	(*sfo_init)();
542
543	/*
544	 * identify device
545	 */
546	int	(*sfo_device_probe)(
547			struct scsi_device	*sd,
548			struct scsi_inquiry	*stdinq,
549			void			**ctpriv);
550
551	/*
552	 * housekeeping (free memory etc alloc'ed during probe
553	 */
554	void	(*sfo_device_unprobe)(
555			struct scsi_device	*sd,
556			void			*ctpriv);
557
558	/*
559	 * bring a path ONLINE (ie make it ACTIVE)
560	 */
561	int	(*sfo_path_activate)(
562			struct scsi_device	*sd,
563			char			*pathclass,
564			void			*ctpriv);
565
566	/*
567	 * inverse of above
568	 */
569	int	(*sfo_path_deactivate)(
570			struct scsi_device	*sd,
571			char			*pathclass,
572			void			*ctpriv);
573
574	/*
575	 * returns operational characteristics of path
576	 */
577	int	(*sfo_path_get_opinfo)(
578			struct scsi_device	*sd,
579			struct scsi_path_opinfo *opinfo,
580			void			*ctpriv);
581
582	/*
583	 * verify path is operational
584	 */
585	int	(*sfo_path_ping)(
586			struct scsi_device	*sd,
587			void			*ctpriv);
588
589	/*
590	 * analyze SENSE data to detect externally initiated
591	 * failovers
592	 */
593	int	(*sfo_analyze_sense)(
594			struct scsi_device		*sd,
595			struct scsi_extended_sense	*sense,
596			void				*ctpriv);
597
598	/*
599	 * return the next pathclass in order of preference
600	 * eg. "secondary" comes after "primary"
601	 */
602	int	(*sfo_pathclass_next)(
603			char			*cur,
604			char			**nxt,
605			void			*ctpriv);
606};
607
608/*
609 * Names of (too) 'well-known' failover ops.
610 *   NOTE: consumers of these names should look for a better way...
611 */
612#define	SFO_NAME_SYM		"f_sym"
613#define	SFO_NAME_TPGS		"f_tpgs"
614#define	SCSI_FAILOVER_IS_SYM(sfo)	\
615	((sfo) ? (strcmp((sfo)->sfo_name, SFO_NAME_SYM) == 0) : 0)
616#define	SCSI_FAILOVER_IS_TPGS(sfo)	\
617	((sfo) ? (strcmp((sfo)->sfo_name, SFO_NAME_TPGS) == 0) : 0)
618
619/*
620 * Macro to provide plumbing for basic failover module
621 */
622#define	_SCSI_FAILOVER_OP(sfo_name, local_name, ops_name, vers)		\
623	static struct modlmisc modlmisc = {				\
624		&mod_miscops, sfo_name  " " vers			\
625	};								\
626	static struct modlinkage modlinkage = {				\
627		MODREV_1, (void *)&modlmisc, NULL			\
628	};								\
629	int	_init()							\
630	{								\
631		return (mod_install(&modlinkage));			\
632	}								\
633	int	_fini()							\
634	{								\
635		return (mod_remove(&modlinkage));			\
636	}								\
637	int	_info(struct modinfo *modinfop)				\
638	{								\
639		return (mod_info(&modlinkage, modinfop));		\
640	}								\
641	static int	local_name##_device_probe(			\
642				struct scsi_device *,			\
643				struct scsi_inquiry *, void **);	\
644	static void	local_name##_device_unprobe(			\
645				struct scsi_device *, void *);		\
646	static int	local_name##_path_activate(			\
647				struct scsi_device *, char *, void *);	\
648	static int	local_name##_path_deactivate(			\
649				struct scsi_device *, char *, void *);	\
650	static int	local_name##_path_get_opinfo(			\
651				struct scsi_device *,			\
652				struct scsi_path_opinfo *, void *);	\
653	static int	local_name##_path_ping(				\
654				struct scsi_device *, void *);		\
655	static int	local_name##_analyze_sense(			\
656				struct scsi_device *,			\
657				struct scsi_extended_sense *, void *);	\
658	static int	local_name##_pathclass_next(			\
659				char *, char **, void *);		\
660	struct scsi_failover_ops ops_name##_failover_ops = {		\
661		SFO_REV,						\
662		sfo_name,						\
663		local_name##_dev_table,					\
664		NULL,							\
665		local_name##_device_probe,				\
666		local_name##_device_unprobe,				\
667		local_name##_path_activate,				\
668		local_name##_path_deactivate,				\
669		local_name##_path_get_opinfo,				\
670		local_name##_path_ping,					\
671		local_name##_analyze_sense,				\
672		local_name##_pathclass_next				\
673	}
674
675#ifdef	lint
676#define	SCSI_FAILOVER_OP(sfo_name, local_name, vers)			\
677	_SCSI_FAILOVER_OP(sfo_name, local_name, local_name, vers)
678#else	/* lint */
679#define	SCSI_FAILOVER_OP(sfo_name, local_name, vers)			\
680	_SCSI_FAILOVER_OP(sfo_name, local_name, scsi_vhci, vers)
681#endif	/* lint */
682
683/*
684 * Return values for sfo_device_probe
685 */
686#define	SFO_DEVICE_PROBE_VHCI	1	/* supported under scsi_vhci */
687#define	SFO_DEVICE_PROBE_PHCI	0	/* not supported under scsi_vhci */
688
689/* return values for sfo_analyze_sense() */
690#define	SCSI_SENSE_NOFAILOVER		0
691#define	SCSI_SENSE_FAILOVER_INPROG	1
692#define	SCSI_SENSE_ACT2INACT		2
693#define	SCSI_SENSE_INACT2ACT		3
694#define	SCSI_SENSE_INACTIVE		4
695#define	SCSI_SENSE_UNKNOWN		5
696#define	SCSI_SENSE_STATE_CHANGED	6
697#define	SCSI_SENSE_NOT_READY		7
698
699/* vhci_intr action codes */
700#define	JUST_RETURN			0
701#define	BUSY_RETURN			1
702#define	PKT_RETURN			2
703
704#if	defined(_SYSCALL32)
705/*
706 * 32 bit variants of sv_path_info_prop_t and sv_path_info_t;
707 * To be used only in the driver and NOT applications
708 */
709typedef struct sv_path_info_prop32 {
710	uint32_t	buf_size;	/* user buffer size */
711	caddr32_t	ret_buf_size;	/* actual buffer needed */
712	caddr32_t	buf;		/* user space buffer */
713} sv_path_info_prop32_t;
714
715typedef struct sv_path_info32 {
716	union {
717		char	ret_ct[MAXPATHLEN];		/* client device */
718		char	ret_phci[MAXPATHLEN];		/* pHCI device */
719	} device;
720
721	char			ret_addr[MAXNAMELEN];	/* device address */
722	mdi_pathinfo_state_t	ret_state;		/* state information */
723	uint32_t		ret_ext_state;		/* Extended State */
724	sv_path_info_prop32_t	ret_prop;		/* path attributes */
725} sv_path_info32_t;
726
727typedef struct sv_iocdata32 {
728	caddr32_t	client;		/* client dev devfs path name */
729	caddr32_t	phci;		/* pHCI dev devfs path name */
730	caddr32_t	addr;		/* device address */
731	uint32_t	buf_elem;	/* number of path_info elems */
732	caddr32_t	ret_buf;	/* addr of array of sv_path_info */
733	caddr32_t	ret_elem;	/* count of above sv_path_info */
734} sv_iocdata32_t;
735
736typedef struct sv_switch_to_cntlr_iocdata32 {
737	caddr32_t	client;	/* client device devfs path name */
738	caddr32_t	class;	/* desired path class to be made active */
739} sv_switch_to_cntlr_iocdata32_t;
740
741#endif	/* _SYSCALL32 */
742
743#endif	/* _KERNEL */
744
745/*
746 * Userland (Non Kernel) definitions start here.
747 * Multiplexed I/O SCSI vHCI IOCTL Definitions
748 */
749
750/*
751 * IOCTL structure for path properties
752 */
753typedef struct sv_path_info_prop {
754	uint_t	buf_size;	/* user buffer size */
755	uint_t	*ret_buf_size;	/* actual buffer needed */
756	caddr_t	buf;		/* user space buffer */
757} sv_path_info_prop_t;
758
759/*
760 * Max buffer size of getting path properties
761 */
762#define	SV_PROP_MAX_BUF_SIZE	4096
763
764/*
765 * String values for "path-class" property
766 */
767#define	PCLASS_PRIMARY		"primary"
768#define	PCLASS_SECONDARY	"secondary"
769
770#define	PCLASS_PREFERRED	1
771#define	PCLASS_NONPREFERRED	0
772
773/*
774 * IOCTL structure for path information
775 */
776typedef struct sv_path_info {
777	union {
778		char	ret_ct[MAXPATHLEN];		/* client device */
779		char	ret_phci[MAXPATHLEN];		/* pHCI device */
780	} device;
781
782	char			ret_addr[MAXNAMELEN];	/* device address */
783	mdi_pathinfo_state_t	ret_state;		/* state information */
784	uint32_t		ret_ext_state;		/* Extended State */
785	sv_path_info_prop_t	ret_prop;		/* path attributes */
786} sv_path_info_t;
787
788/*
789 * IOCTL argument structure
790 */
791typedef struct sv_iocdata {
792	caddr_t		client;		/* client dev devfs path name */
793	caddr_t		phci;		/* pHCI dev devfs path name */
794	caddr_t		addr;		/* device address */
795	uint_t		buf_elem;	/* number of path_info elems */
796	sv_path_info_t	*ret_buf;	/* array of sv_path_info */
797	uint_t		*ret_elem;	/* count of sv_path_info */
798} sv_iocdata_t;
799
800/*
801 * IOCTL argument structure for switching controllers
802 */
803typedef struct sv_switch_to_cntlr_iocdata {
804	caddr_t		client;	/* client device devfs path name */
805	caddr_t		class;	/* desired path class to be made active */
806} sv_switch_to_cntlr_iocdata_t;
807
808
809/*
810 * IOCTL definitions
811 */
812#define	SCSI_VHCI_CTL		('X' << 8)
813#define	SCSI_VHCI_CTL_CMD	(SCSI_VHCI_CTL | ('S' << 8) | 'P')
814#define	SCSI_VHCI_CTL_SUB_CMD	('x' << 8)
815
816#define	SCSI_VHCI_GET_CLIENT_MULTIPATH_INFO	(SCSI_VHCI_CTL_SUB_CMD + 0x01)
817#define	SCSI_VHCI_GET_PHCI_MULTIPATH_INFO	(SCSI_VHCI_CTL_SUB_CMD + 0x02)
818#define	SCSI_VHCI_GET_CLIENT_NAME		(SCSI_VHCI_CTL_SUB_CMD + 0x03)
819#define	SCSI_VHCI_PATH_ONLINE			(SCSI_VHCI_CTL_SUB_CMD + 0x04)
820#define	SCSI_VHCI_PATH_OFFLINE			(SCSI_VHCI_CTL_SUB_CMD + 0x05)
821#define	SCSI_VHCI_PATH_STANDBY			(SCSI_VHCI_CTL_SUB_CMD + 0x06)
822#define	SCSI_VHCI_PATH_TEST			(SCSI_VHCI_CTL_SUB_CMD + 0x07)
823#define	SCSI_VHCI_SWITCH_TO_CNTLR		(SCSI_VHCI_CTL_SUB_CMD + 0x08)
824
825#ifdef	DEBUG
826#define	SCSI_VHCI_GET_PHCI_LIST			(SCSI_VHCI_CTL_SUB_CMD + 0x09)
827#define	SCSI_VHCI_CONFIGURE_PHCI		(SCSI_VHCI_CTL_SUB_CMD + 0x0A)
828#define	SCSI_VHCI_UNCONFIGURE_PHCI		(SCSI_VHCI_CTL_SUB_CMD + 0x0B)
829#endif
830
831#define	SCSI_VHCI_PATH_DISABLE			(SCSI_VHCI_CTL_SUB_CMD + 0x0C)
832#define	SCSI_VHCI_PATH_ENABLE			(SCSI_VHCI_CTL_SUB_CMD + 0x0D)
833#define	SCSI_VHCI_MPAPI				(SCSI_VHCI_CTL_SUB_CMD + 0x0E)
834
835#define	SCSI_VHCI_GET_TARGET_LONGNAME		(SCSI_VHCI_CTL_SUB_CMD + 0x0F)
836
837#ifdef	__cplusplus
838}
839#endif
840
841#endif	/* _SYS_SCSI_ADAPTERS_SCSI_VHCI_H */
842