17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*144dfaa9Scth  * Common Development and Distribution License (the "License").
6*144dfaa9Scth  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*144dfaa9Scth  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #ifndef _SYS_DDI_IMPLDEFS_H
277c478bd9Sstevel@tonic-gate #define	_SYS_DDI_IMPLDEFS_H
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate #include <sys/types.h>
327c478bd9Sstevel@tonic-gate #include <sys/param.h>
337c478bd9Sstevel@tonic-gate #include <sys/t_lock.h>
347c478bd9Sstevel@tonic-gate #include <sys/ddipropdefs.h>
357c478bd9Sstevel@tonic-gate #include <sys/devops.h>
367c478bd9Sstevel@tonic-gate #include <sys/autoconf.h>
377c478bd9Sstevel@tonic-gate #include <sys/mutex.h>
387c478bd9Sstevel@tonic-gate #include <vm/page.h>
397c478bd9Sstevel@tonic-gate #include <sys/dacf_impl.h>
407c478bd9Sstevel@tonic-gate #include <sys/ndifm.h>
417c478bd9Sstevel@tonic-gate #include <sys/epm.h>
427c478bd9Sstevel@tonic-gate #include <sys/ddidmareq.h>
437c478bd9Sstevel@tonic-gate #include <sys/ddi_intr.h>
447c478bd9Sstevel@tonic-gate #include <sys/ddi_isa.h>
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
477c478bd9Sstevel@tonic-gate extern "C" {
487c478bd9Sstevel@tonic-gate #endif
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate /*
517c478bd9Sstevel@tonic-gate  * The device id implementation has been switched to be based on properties.
527c478bd9Sstevel@tonic-gate  * For compatibility with di_devid libdevinfo interface the following
537c478bd9Sstevel@tonic-gate  * must be defined:
547c478bd9Sstevel@tonic-gate  */
557c478bd9Sstevel@tonic-gate #define	DEVID_COMPATIBILITY	((ddi_devid_t)-1)
567c478bd9Sstevel@tonic-gate 
577c478bd9Sstevel@tonic-gate /*
587c478bd9Sstevel@tonic-gate  * Definitions for node class.
597c478bd9Sstevel@tonic-gate  * DDI_NC_PROM: a node with a nodeid that may be used in a promif call.
607c478bd9Sstevel@tonic-gate  * DDI_NC_PSEUDO: a software created node with a software assigned nodeid.
617c478bd9Sstevel@tonic-gate  */
627c478bd9Sstevel@tonic-gate typedef enum {
637c478bd9Sstevel@tonic-gate 	DDI_NC_PROM = 0,
647c478bd9Sstevel@tonic-gate 	DDI_NC_PSEUDO
657c478bd9Sstevel@tonic-gate } ddi_node_class_t;
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate /*
687c478bd9Sstevel@tonic-gate  * dev_info:	The main device information structure this is intended to be
697c478bd9Sstevel@tonic-gate  *		opaque to drivers and drivers should use ddi functions to
707c478bd9Sstevel@tonic-gate  *		access *all* driver accessible fields.
717c478bd9Sstevel@tonic-gate  *
727c478bd9Sstevel@tonic-gate  * devi_parent_data includes property lists (interrupts, registers, etc.)
737c478bd9Sstevel@tonic-gate  * devi_driver_data includes whatever the driver wants to place there.
747c478bd9Sstevel@tonic-gate  */
757c478bd9Sstevel@tonic-gate struct devinfo_audit;
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate struct dev_info  {
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate 	struct dev_info *devi_parent;	/* my parent node in tree	*/
807c478bd9Sstevel@tonic-gate 	struct dev_info *devi_child;	/* my child list head		*/
817c478bd9Sstevel@tonic-gate 	struct dev_info *devi_sibling;	/* next element on my level	*/
827c478bd9Sstevel@tonic-gate 
837c478bd9Sstevel@tonic-gate 	char	*devi_binding_name;	/* name used to bind driver	*/
847c478bd9Sstevel@tonic-gate 
857c478bd9Sstevel@tonic-gate 	char	*devi_addr;		/* address part of name		*/
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate 	int	devi_nodeid;		/* device nodeid		*/
887c478bd9Sstevel@tonic-gate 	int	devi_instance;		/* device instance number	*/
897c478bd9Sstevel@tonic-gate 
907c478bd9Sstevel@tonic-gate 	struct dev_ops *devi_ops;	/* driver operations		*/
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate 	void	*devi_parent_data;	/* parent private data		*/
937c478bd9Sstevel@tonic-gate 	void	*devi_driver_data;	/* driver private data		*/
947c478bd9Sstevel@tonic-gate 
957c478bd9Sstevel@tonic-gate 	ddi_prop_t *devi_drv_prop_ptr;	/* head of driver prop list */
967c478bd9Sstevel@tonic-gate 	ddi_prop_t *devi_sys_prop_ptr;	/* head of system prop list */
977c478bd9Sstevel@tonic-gate 
987c478bd9Sstevel@tonic-gate 	struct ddi_minor_data *devi_minor;	/* head of minor list */
997c478bd9Sstevel@tonic-gate 	struct dev_info *devi_next;	/* Next instance of this device */
1007c478bd9Sstevel@tonic-gate 	kmutex_t devi_lock;		/* Protects per-devinfo data */
1017c478bd9Sstevel@tonic-gate 
1027c478bd9Sstevel@tonic-gate 	/* logical parents for busop primitives	 */
1037c478bd9Sstevel@tonic-gate 
1047c478bd9Sstevel@tonic-gate 	struct dev_info *devi_bus_map_fault;	/* bus_map_fault parent	 */
1057c478bd9Sstevel@tonic-gate 	struct dev_info *devi_bus_dma_map;	/* bus_dma_map parent	 */
1067c478bd9Sstevel@tonic-gate 	struct dev_info *devi_bus_dma_allochdl; /* bus_dma_newhdl parent */
1077c478bd9Sstevel@tonic-gate 	struct dev_info *devi_bus_dma_freehdl;  /* bus_dma_freehdl parent */
1087c478bd9Sstevel@tonic-gate 	struct dev_info *devi_bus_dma_bindhdl;  /* bus_dma_bindhdl parent */
1097c478bd9Sstevel@tonic-gate 	struct dev_info *devi_bus_dma_unbindhdl; /* bus_dma_unbindhdl parent */
1107c478bd9Sstevel@tonic-gate 	struct dev_info *devi_bus_dma_flush;    /* bus_dma_flush parent	 */
1117c478bd9Sstevel@tonic-gate 	struct dev_info *devi_bus_dma_win;	/* bus_dma_win parent	 */
1127c478bd9Sstevel@tonic-gate 	struct dev_info *devi_bus_dma_ctl;	/* bus_dma_ctl parent	 */
1137c478bd9Sstevel@tonic-gate 	struct dev_info	*devi_bus_ctl;		/* bus_ctl parent	 */
1147c478bd9Sstevel@tonic-gate 
1157c478bd9Sstevel@tonic-gate 	ddi_prop_t *devi_hw_prop_ptr;		/* head of hw prop list */
1167c478bd9Sstevel@tonic-gate 
1177c478bd9Sstevel@tonic-gate 	char	*devi_node_name;		/* The 'name' of the node */
1187c478bd9Sstevel@tonic-gate 	char	*devi_compat_names;		/* A list of driver names */
1197c478bd9Sstevel@tonic-gate 	size_t	devi_compat_length;		/* Size of compat_names */
1207c478bd9Sstevel@tonic-gate 
1217c478bd9Sstevel@tonic-gate 	int (*devi_bus_dma_bindfunc)(dev_info_t *, dev_info_t *,
1227c478bd9Sstevel@tonic-gate 	    ddi_dma_handle_t, struct ddi_dma_req *, ddi_dma_cookie_t *,
1237c478bd9Sstevel@tonic-gate 	    uint_t *);
1247c478bd9Sstevel@tonic-gate 	int (*devi_bus_dma_unbindfunc)(dev_info_t *, dev_info_t *,
1257c478bd9Sstevel@tonic-gate 	    ddi_dma_handle_t);
1267c478bd9Sstevel@tonic-gate 
1277c478bd9Sstevel@tonic-gate #ifdef	DEVID_COMPATIBILITY
1287c478bd9Sstevel@tonic-gate 	ddi_devid_t	devi_devid;		/* registered device id */
1297c478bd9Sstevel@tonic-gate #endif	/* DEVID_COMPATIBILITY */
1307c478bd9Sstevel@tonic-gate 	/*
1317c478bd9Sstevel@tonic-gate 	 * power management entries
1327c478bd9Sstevel@tonic-gate 	 * components exist even if the device is not currently power managed
1337c478bd9Sstevel@tonic-gate 	 */
1347c478bd9Sstevel@tonic-gate 	struct pm_info *devi_pm_info;		/* 0 => dev not power managed */
1357c478bd9Sstevel@tonic-gate 	uint_t		devi_pm_flags;		/* pm flags */
1367c478bd9Sstevel@tonic-gate 	int		devi_pm_num_components;	/* number of components */
1377c478bd9Sstevel@tonic-gate 	size_t		devi_pm_comp_size;	/* size of devi_components */
1387c478bd9Sstevel@tonic-gate 	struct pm_component *devi_pm_components; /* array of pm components */
1397c478bd9Sstevel@tonic-gate 	struct dev_info *devi_pm_ppm;		/* ppm attached to this one */
1407c478bd9Sstevel@tonic-gate 	void		*devi_pm_ppm_private;	/* for use by ppm driver */
1417c478bd9Sstevel@tonic-gate 	int		devi_pm_dev_thresh;	/* "device" threshold */
142*144dfaa9Scth 	int		devi_pm_kidsupcnt;	/* # of kids powered up */
1437c478bd9Sstevel@tonic-gate 	struct pm_scan	*devi_pm_scan;		/* pm scan info */
1447c478bd9Sstevel@tonic-gate 	uint_t		devi_pm_noinvolpm;	/* # of descendents no-invol */
1457c478bd9Sstevel@tonic-gate 	uint_t		devi_pm_volpmd;		/* # of voluntarily pm'ed */
1467c478bd9Sstevel@tonic-gate 	kmutex_t	devi_pm_lock;		/* pm lock for state */
1477c478bd9Sstevel@tonic-gate 	kmutex_t	devi_pm_busy_lock;	/* for component busy count */
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate 	uint_t		devi_state;		/* device/bus state flags */
1507c478bd9Sstevel@tonic-gate 						/* see below for definitions */
1517c478bd9Sstevel@tonic-gate 	kcondvar_t	devi_cv;		/* cv */
1527c478bd9Sstevel@tonic-gate 	int		devi_ref;		/* reference count */
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate 	dacf_rsrvlist_t *devi_dacf_tasks;	/* dacf reservation queue */
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate 	ddi_node_class_t devi_node_class;	/* Node class */
1577c478bd9Sstevel@tonic-gate 	int		devi_node_attributes;	/* Node attributes: See below */
1587c478bd9Sstevel@tonic-gate 
1597c478bd9Sstevel@tonic-gate 	char		*devi_device_class;
1607c478bd9Sstevel@tonic-gate 
1617c478bd9Sstevel@tonic-gate 	/*
1627c478bd9Sstevel@tonic-gate 	 * New mpxio kernel hooks entries
1637c478bd9Sstevel@tonic-gate 	 */
1647c478bd9Sstevel@tonic-gate 	int		devi_mdi_component;	/* mpxio component type */
1657c478bd9Sstevel@tonic-gate 	void		*devi_mdi_client;	/* mpxio client information */
1667c478bd9Sstevel@tonic-gate 	void		*devi_mdi_xhci;		/* vhci/phci info */
1677c478bd9Sstevel@tonic-gate 
1687c478bd9Sstevel@tonic-gate 	ddi_prop_list_t	*devi_global_prop_list;	/* driver global properties */
1697c478bd9Sstevel@tonic-gate 	major_t		devi_major;		/* driver major number */
1707c478bd9Sstevel@tonic-gate 	ddi_node_state_t devi_node_state;	/* state of node */
1717c478bd9Sstevel@tonic-gate 	uint_t		devi_flags;		/* configuration flags */
1727c478bd9Sstevel@tonic-gate 	int		devi_circular;		/* for recursive operations */
1737c478bd9Sstevel@tonic-gate 	void		*devi_busy_thread;	/* thread operating on node */
1747c478bd9Sstevel@tonic-gate 	void		*devi_taskq;		/* hotplug taskq */
1757c478bd9Sstevel@tonic-gate 
1767c478bd9Sstevel@tonic-gate 	/* device driver statistical and audit info */
1777c478bd9Sstevel@tonic-gate 	struct devinfo_audit *devi_audit;		/* last state change */
1787c478bd9Sstevel@tonic-gate 
1797c478bd9Sstevel@tonic-gate 	/*
1807c478bd9Sstevel@tonic-gate 	 * FMA support for resource caches and error handlers
1817c478bd9Sstevel@tonic-gate 	 */
1827c478bd9Sstevel@tonic-gate 	struct i_ddi_fmhdl	*devi_fmhdl;
1837c478bd9Sstevel@tonic-gate 
1847c478bd9Sstevel@tonic-gate 	uint_t		devi_cpr_flags;
1857c478bd9Sstevel@tonic-gate 
1867c478bd9Sstevel@tonic-gate 	/* For interrupt support */
1877c478bd9Sstevel@tonic-gate 	devinfo_intr_t		*devi_intr_p;
1887c478bd9Sstevel@tonic-gate 
1897c478bd9Sstevel@tonic-gate 	void		*devi_nex_pm;		/* nexus PM private */
190fe9fe9fbScth 
191fe9fe9fbScth 	char		*devi_addr_buf;		/* buffer for devi_addr */
1927c478bd9Sstevel@tonic-gate };
1937c478bd9Sstevel@tonic-gate 
1947c478bd9Sstevel@tonic-gate #define	DEVI(dev_info_type)	((struct dev_info *)(dev_info_type))
1957c478bd9Sstevel@tonic-gate 
1967c478bd9Sstevel@tonic-gate /*
1977c478bd9Sstevel@tonic-gate  * NB: The 'name' field, for compatibility with old code (both existing
1987c478bd9Sstevel@tonic-gate  * device drivers and userland code), is now defined as the name used
1997c478bd9Sstevel@tonic-gate  * to bind the node to a device driver, and not the device node name.
2007c478bd9Sstevel@tonic-gate  * If the device node name does not define a binding to a device driver,
2017c478bd9Sstevel@tonic-gate  * and the framework uses a different algorithm to create the binding to
2027c478bd9Sstevel@tonic-gate  * the driver, the node name and binding name will be different.
2037c478bd9Sstevel@tonic-gate  *
2047c478bd9Sstevel@tonic-gate  * Note that this implies that the node name plus instance number does
2057c478bd9Sstevel@tonic-gate  * NOT create a unique driver id; only the binding name plus instance
2067c478bd9Sstevel@tonic-gate  * number creates a unique driver id.
2077c478bd9Sstevel@tonic-gate  *
2087c478bd9Sstevel@tonic-gate  * New code should not use 'devi_name'; use 'devi_binding_name' or
2097c478bd9Sstevel@tonic-gate  * 'devi_node_name' and/or the routines that access those fields.
2107c478bd9Sstevel@tonic-gate  */
2117c478bd9Sstevel@tonic-gate 
2127c478bd9Sstevel@tonic-gate #define	devi_name devi_binding_name
2137c478bd9Sstevel@tonic-gate 
2147c478bd9Sstevel@tonic-gate /*
2157c478bd9Sstevel@tonic-gate  * DDI_CF1, DDI_CF2 and DDI_DRV_UNLOADED are obsolete. They are kept
2167c478bd9Sstevel@tonic-gate  * around to allow legacy drivers to to compile.
2177c478bd9Sstevel@tonic-gate  */
2187c478bd9Sstevel@tonic-gate #define	DDI_CF1(devi)		(DEVI(devi)->devi_addr != NULL)
2197c478bd9Sstevel@tonic-gate #define	DDI_CF2(devi)		(DEVI(devi)->devi_ops != NULL)
2207c478bd9Sstevel@tonic-gate #define	DDI_DRV_UNLOADED(devi)	(DEVI(devi)->devi_ops == &mod_nodev_ops)
2217c478bd9Sstevel@tonic-gate 
2227c478bd9Sstevel@tonic-gate /*
22316747f41Scth  * The device state flags (devi_state) contains information regarding
2247c478bd9Sstevel@tonic-gate  * the state of the device (Online/Offline/Down).  For bus nexus
2257c478bd9Sstevel@tonic-gate  * devices, the device state also contains state information regarding
2267c478bd9Sstevel@tonic-gate  * the state of the bus represented by this nexus node.
2277c478bd9Sstevel@tonic-gate  *
2287c478bd9Sstevel@tonic-gate  * Device state information is stored in bits [0-7], bus state in bits
2297c478bd9Sstevel@tonic-gate  * [8-15].
2307c478bd9Sstevel@tonic-gate  *
23116747f41Scth  * NOTE: all devi_state updates shoule be protected by devi_lock.
2327c478bd9Sstevel@tonic-gate  */
2337c478bd9Sstevel@tonic-gate #define	DEVI_DEVICE_OFFLINE	0x00000001
2347c478bd9Sstevel@tonic-gate #define	DEVI_DEVICE_DOWN	0x00000002
2357c478bd9Sstevel@tonic-gate #define	DEVI_DEVICE_DEGRADED	0x00000004
2367c478bd9Sstevel@tonic-gate #define	DEVI_DEVICE_REMOVED	0x00000008 /* hardware removed */
23716747f41Scth 
2387c478bd9Sstevel@tonic-gate #define	DEVI_BUS_QUIESCED	0x00000100
2397c478bd9Sstevel@tonic-gate #define	DEVI_BUS_DOWN		0x00000200
2407c478bd9Sstevel@tonic-gate #define	DEVI_NDI_CONFIG		0x00000400 /* perform config when attaching */
2417c478bd9Sstevel@tonic-gate 
2427c478bd9Sstevel@tonic-gate #define	DEVI_S_ATTACHING	0x00010000
2437c478bd9Sstevel@tonic-gate #define	DEVI_S_DETACHING	0x00020000
2447c478bd9Sstevel@tonic-gate #define	DEVI_S_ONLINING		0x00040000
2457c478bd9Sstevel@tonic-gate #define	DEVI_S_OFFLINING	0x00080000
2467c478bd9Sstevel@tonic-gate 
2477c478bd9Sstevel@tonic-gate #define	DEVI_S_INVOKING_DACF	0x00100000 /* busy invoking a dacf task */
2487c478bd9Sstevel@tonic-gate 
2497c478bd9Sstevel@tonic-gate #define	DEVI_S_UNBOUND		0x00200000
2507c478bd9Sstevel@tonic-gate #define	DEVI_S_MD_UPDATE	0x00400000
2517c478bd9Sstevel@tonic-gate #define	DEVI_S_REPORT		0x08000000 /* report status change */
2527c478bd9Sstevel@tonic-gate 
2537c478bd9Sstevel@tonic-gate #define	DEVI_S_EVADD		0x10000000 /* state of devfs event */
2547c478bd9Sstevel@tonic-gate #define	DEVI_S_EVREMOVE		0x20000000 /* state of devfs event */
2557c478bd9Sstevel@tonic-gate #define	DEVI_S_NEED_RESET	0x40000000 /* devo_reset should be called */
2567c478bd9Sstevel@tonic-gate 
25716747f41Scth /*
25816747f41Scth  * Device state macros.
25916747f41Scth  * o All SET/CLR/DONE users must protect context with devi_lock.
26016747f41Scth  * o DEVI_SET_DEVICE_ONLINE users must do his own DEVI_SET_REPORT.
26116747f41Scth  * o DEVI_SET_DEVICE_{DOWN|DEGRADED|UP} should only be used when !OFFLINE.
26216747f41Scth  * o DEVI_SET_DEVICE_UP clears DOWN and DEGRADED.
26316747f41Scth  */
2647c478bd9Sstevel@tonic-gate #define	DEVI_IS_DEVICE_OFFLINE(dip)					\
26516747f41Scth 	((DEVI(dip)->devi_state & DEVI_DEVICE_OFFLINE) == DEVI_DEVICE_OFFLINE)
2667c478bd9Sstevel@tonic-gate 
26716747f41Scth #define	DEVI_SET_DEVICE_ONLINE(dip)	{				\
26816747f41Scth 	ASSERT(mutex_owned(&DEVI(dip)->devi_lock));			\
26916747f41Scth 	/* setting ONLINE clears DOWN, DEGRADED, OFFLINE */		\
27016747f41Scth 	DEVI(dip)->devi_state &= ~(DEVI_DEVICE_DOWN |			\
27116747f41Scth 	    DEVI_DEVICE_DEGRADED | DEVI_DEVICE_OFFLINE);		\
27216747f41Scth 	}
2737c478bd9Sstevel@tonic-gate 
27416747f41Scth #define	DEVI_SET_DEVICE_OFFLINE(dip)	{				\
27516747f41Scth 	ASSERT(mutex_owned(&DEVI(dip)->devi_lock));			\
27616747f41Scth 	DEVI(dip)->devi_state |= (DEVI_DEVICE_OFFLINE | DEVI_S_REPORT);	\
27716747f41Scth 	}
2787c478bd9Sstevel@tonic-gate 
2797c478bd9Sstevel@tonic-gate #define	DEVI_IS_DEVICE_DOWN(dip)					\
28016747f41Scth 	((DEVI(dip)->devi_state & DEVI_DEVICE_DOWN) == DEVI_DEVICE_DOWN)
2817c478bd9Sstevel@tonic-gate 
28216747f41Scth #define	DEVI_SET_DEVICE_DOWN(dip)	{				\
28316747f41Scth 	ASSERT(mutex_owned(&DEVI(dip)->devi_lock));			\
28416747f41Scth 	ASSERT(!DEVI_IS_DEVICE_OFFLINE(dip));				\
28516747f41Scth 	DEVI(dip)->devi_state |= (DEVI_DEVICE_DOWN | DEVI_S_REPORT);	\
28616747f41Scth 	}
2877c478bd9Sstevel@tonic-gate 
2887c478bd9Sstevel@tonic-gate #define	DEVI_IS_DEVICE_DEGRADED(dip)					\
28916747f41Scth 	((DEVI(dip)->devi_state &					\
29016747f41Scth 	    (DEVI_DEVICE_DEGRADED|DEVI_DEVICE_DOWN)) == DEVI_DEVICE_DEGRADED)
2917c478bd9Sstevel@tonic-gate 
29216747f41Scth #define	DEVI_SET_DEVICE_DEGRADED(dip)	{				\
29316747f41Scth 	ASSERT(mutex_owned(&DEVI(dip)->devi_lock));			\
29416747f41Scth 	ASSERT(!DEVI_IS_DEVICE_OFFLINE(dip));				\
29516747f41Scth 	DEVI(dip)->devi_state |= (DEVI_DEVICE_DEGRADED | DEVI_S_REPORT); \
29616747f41Scth 	}
2977c478bd9Sstevel@tonic-gate 
29816747f41Scth #define	DEVI_SET_DEVICE_UP(dip)		{				\
29916747f41Scth 	ASSERT(mutex_owned(&DEVI(dip)->devi_lock));			\
30016747f41Scth 	ASSERT(!DEVI_IS_DEVICE_OFFLINE(dip));				\
30116747f41Scth 	DEVI(dip)->devi_state &= ~(DEVI_DEVICE_DEGRADED | DEVI_DEVICE_DOWN); \
30216747f41Scth 	DEVI(dip)->devi_state |= DEVI_S_REPORT;				\
30316747f41Scth 	}
3047c478bd9Sstevel@tonic-gate 
30516747f41Scth /* Device removal and insertion */
3067c478bd9Sstevel@tonic-gate #define	DEVI_IS_DEVICE_REMOVED(dip)					\
30716747f41Scth 	((DEVI(dip)->devi_state & DEVI_DEVICE_REMOVED) == DEVI_DEVICE_REMOVED)
3087c478bd9Sstevel@tonic-gate 
30916747f41Scth #define	DEVI_SET_DEVICE_REMOVED(dip)	{				\
31016747f41Scth 	ASSERT(mutex_owned(&DEVI(dip)->devi_lock));			\
31116747f41Scth 	DEVI(dip)->devi_state |= DEVI_DEVICE_REMOVED;			\
31216747f41Scth 	}
3137c478bd9Sstevel@tonic-gate 
31416747f41Scth #define	DEVI_SET_DEVICE_REINSERTED(dip)	{				\
31516747f41Scth 	ASSERT(mutex_owned(&DEVI(dip)->devi_lock));			\
31616747f41Scth 	DEVI(dip)->devi_state &= ~DEVI_DEVICE_REMOVED;			\
31716747f41Scth 	}
3187c478bd9Sstevel@tonic-gate 
31916747f41Scth /* Bus state change macros */
3207c478bd9Sstevel@tonic-gate #define	DEVI_IS_BUS_QUIESCED(dip)					\
32116747f41Scth 	((DEVI(dip)->devi_state & DEVI_BUS_QUIESCED) == DEVI_BUS_QUIESCED)
3227c478bd9Sstevel@tonic-gate 
32316747f41Scth #define	DEVI_SET_BUS_ACTIVE(dip)	{				\
32416747f41Scth 	ASSERT(mutex_owned(&DEVI(dip)->devi_lock));			\
32516747f41Scth 	DEVI(dip)->devi_state &= ~DEVI_BUS_QUIESCED;			\
32616747f41Scth 	DEVI(dip)->devi_state |= DEVI_S_REPORT;				\
32716747f41Scth 	}
3287c478bd9Sstevel@tonic-gate 
32916747f41Scth #define	DEVI_SET_BUS_QUIESCE(dip)	{				\
33016747f41Scth 	ASSERT(mutex_owned(&DEVI(dip)->devi_lock));			\
33116747f41Scth 	DEVI(dip)->devi_state |= (DEVI_BUS_QUIESCED | DEVI_S_REPORT);	\
33216747f41Scth 	}
3337c478bd9Sstevel@tonic-gate 
3347c478bd9Sstevel@tonic-gate #define	DEVI_IS_BUS_DOWN(dip)						\
33516747f41Scth 	((DEVI(dip)->devi_state & DEVI_BUS_DOWN) == DEVI_BUS_DOWN)
3367c478bd9Sstevel@tonic-gate 
33716747f41Scth #define	DEVI_SET_BUS_UP(dip)		{				\
33816747f41Scth 	ASSERT(mutex_owned(&DEVI(dip)->devi_lock));			\
33916747f41Scth 	DEVI(dip)->devi_state &= ~DEVI_BUS_DOWN;			\
34016747f41Scth 	DEVI(dip)->devi_state |= DEVI_S_REPORT;				\
34116747f41Scth 	}
3427c478bd9Sstevel@tonic-gate 
34316747f41Scth #define	DEVI_SET_BUS_DOWN(dip)		{				\
34416747f41Scth 	ASSERT(mutex_owned(&DEVI(dip)->devi_lock));			\
34516747f41Scth 	DEVI(dip)->devi_state |= (DEVI_BUS_DOWN | DEVI_S_REPORT);	\
34616747f41Scth 	}
3477c478bd9Sstevel@tonic-gate 
34816747f41Scth /* Status change report needed */
3497c478bd9Sstevel@tonic-gate #define	DEVI_NEED_REPORT(dip)						\
35016747f41Scth 	((DEVI(dip)->devi_state & DEVI_S_REPORT) == DEVI_S_REPORT)
3517c478bd9Sstevel@tonic-gate 
35216747f41Scth #define	DEVI_SET_REPORT(dip)		{				\
35316747f41Scth 	ASSERT(mutex_owned(&DEVI(dip)->devi_lock));			\
35416747f41Scth 	DEVI(dip)->devi_state |= DEVI_S_REPORT;				\
35516747f41Scth 	}
3567c478bd9Sstevel@tonic-gate 
35716747f41Scth #define	DEVI_REPORT_DONE(dip)		{				\
35816747f41Scth 	ASSERT(mutex_owned(&DEVI(dip)->devi_lock));			\
35916747f41Scth 	DEVI(dip)->devi_state &= ~DEVI_S_REPORT;			\
36016747f41Scth 	}
36116747f41Scth 
36216747f41Scth /* Do an NDI_CONFIG for its children */
3637c478bd9Sstevel@tonic-gate #define	DEVI_NEED_NDI_CONFIG(dip)					\
36416747f41Scth 	((DEVI(dip)->devi_state & DEVI_NDI_CONFIG) == DEVI_NDI_CONFIG)
3657c478bd9Sstevel@tonic-gate 
36616747f41Scth #define	DEVI_SET_NDI_CONFIG(dip)	{				\
36716747f41Scth 	ASSERT(mutex_owned(&DEVI(dip)->devi_lock));			\
36816747f41Scth 	DEVI(dip)->devi_state |= DEVI_NDI_CONFIG;			\
36916747f41Scth 	}
3707c478bd9Sstevel@tonic-gate 
37116747f41Scth #define	DEVI_CLR_NDI_CONFIG(dip)	{				\
37216747f41Scth 	ASSERT(mutex_owned(&DEVI(dip)->devi_lock));			\
37316747f41Scth 	DEVI(dip)->devi_state &= ~DEVI_NDI_CONFIG;			\
37416747f41Scth 	}
3757c478bd9Sstevel@tonic-gate 
37616747f41Scth /* Attaching or detaching state */
3777c478bd9Sstevel@tonic-gate #define	DEVI_IS_ATTACHING(dip)						\
37816747f41Scth 	((DEVI(dip)->devi_state & DEVI_S_ATTACHING) == DEVI_S_ATTACHING)
3797c478bd9Sstevel@tonic-gate 
38016747f41Scth #define	DEVI_SET_ATTACHING(dip)		{				\
38116747f41Scth 	ASSERT(mutex_owned(&DEVI(dip)->devi_lock));			\
38216747f41Scth 	DEVI(dip)->devi_state |= DEVI_S_ATTACHING;			\
38316747f41Scth 	}
3847c478bd9Sstevel@tonic-gate 
38516747f41Scth #define	DEVI_CLR_ATTACHING(dip)		{				\
38616747f41Scth 	ASSERT(mutex_owned(&DEVI(dip)->devi_lock));			\
38716747f41Scth 	DEVI(dip)->devi_state &= ~DEVI_S_ATTACHING;			\
38816747f41Scth 	}
3897c478bd9Sstevel@tonic-gate 
3907c478bd9Sstevel@tonic-gate #define	DEVI_IS_DETACHING(dip)						\
39116747f41Scth 	((DEVI(dip)->devi_state & DEVI_S_DETACHING) == DEVI_S_DETACHING)
3927c478bd9Sstevel@tonic-gate 
39316747f41Scth #define	DEVI_SET_DETACHING(dip)		{				\
39416747f41Scth 	ASSERT(mutex_owned(&DEVI(dip)->devi_lock));			\
39516747f41Scth 	DEVI(dip)->devi_state |= DEVI_S_DETACHING;			\
39616747f41Scth 	}
3977c478bd9Sstevel@tonic-gate 
39816747f41Scth #define	DEVI_CLR_DETACHING(dip)		{				\
39916747f41Scth 	ASSERT(mutex_owned(&DEVI(dip)->devi_lock));			\
40016747f41Scth 	DEVI(dip)->devi_state &= ~DEVI_S_DETACHING;			\
40116747f41Scth 	}
4027c478bd9Sstevel@tonic-gate 
40316747f41Scth /* Onlining or offlining state */
4047c478bd9Sstevel@tonic-gate #define	DEVI_IS_ONLINING(dip)						\
40516747f41Scth 	((DEVI(dip)->devi_state & DEVI_S_ONLINING) == DEVI_S_ONLINING)
4067c478bd9Sstevel@tonic-gate 
40716747f41Scth #define	DEVI_SET_ONLINING(dip)		{				\
40816747f41Scth 	ASSERT(mutex_owned(&DEVI(dip)->devi_lock));			\
40916747f41Scth 	DEVI(dip)->devi_state |= DEVI_S_ONLINING;			\
41016747f41Scth 	}
4117c478bd9Sstevel@tonic-gate 
41216747f41Scth #define	DEVI_CLR_ONLINING(dip)		{				\
41316747f41Scth 	ASSERT(mutex_owned(&DEVI(dip)->devi_lock));			\
41416747f41Scth 	DEVI(dip)->devi_state &= ~DEVI_S_ONLINING;			\
41516747f41Scth 	}
4167c478bd9Sstevel@tonic-gate 
4177c478bd9Sstevel@tonic-gate #define	DEVI_IS_OFFLINING(dip)						\
41816747f41Scth 	((DEVI(dip)->devi_state & DEVI_S_OFFLINING) == DEVI_S_OFFLINING)
41916747f41Scth 
42016747f41Scth #define	DEVI_SET_OFFLINING(dip)		{				\
42116747f41Scth 	ASSERT(mutex_owned(&DEVI(dip)->devi_lock));			\
42216747f41Scth 	DEVI(dip)->devi_state |= DEVI_S_OFFLINING;			\
42316747f41Scth 	}
42416747f41Scth 
42516747f41Scth #define	DEVI_CLR_OFFLINING(dip)		{				\
42616747f41Scth 	ASSERT(mutex_owned(&DEVI(dip)->devi_lock));			\
42716747f41Scth 	DEVI(dip)->devi_state &= ~DEVI_S_OFFLINING;			\
42816747f41Scth 	}
4297c478bd9Sstevel@tonic-gate 
4307c478bd9Sstevel@tonic-gate #define	DEVI_IS_IN_RECONFIG(dip)					\
43116747f41Scth 	(DEVI(dip)->devi_state & (DEVI_S_OFFLINING | DEVI_S_ONLINING))
4327c478bd9Sstevel@tonic-gate 
43316747f41Scth /* Busy invoking a dacf task against this node */
4347c478bd9Sstevel@tonic-gate #define	DEVI_IS_INVOKING_DACF(dip)					\
43516747f41Scth 	((DEVI(dip)->devi_state & DEVI_S_INVOKING_DACF) == DEVI_S_INVOKING_DACF)
4367c478bd9Sstevel@tonic-gate 
43716747f41Scth #define	DEVI_SET_INVOKING_DACF(dip)	{				\
43816747f41Scth 	ASSERT(mutex_owned(&DEVI(dip)->devi_lock));			\
43916747f41Scth 	DEVI(dip)->devi_state |= DEVI_S_INVOKING_DACF;			\
44016747f41Scth 	}
4417c478bd9Sstevel@tonic-gate 
44216747f41Scth #define	DEVI_CLR_INVOKING_DACF(dip)	{				\
44316747f41Scth 	ASSERT(mutex_owned(&DEVI(dip)->devi_lock));			\
44416747f41Scth 	DEVI(dip)->devi_state &= ~DEVI_S_INVOKING_DACF;			\
44516747f41Scth 	}
4467c478bd9Sstevel@tonic-gate 
44716747f41Scth /* Events for add/remove */
4487c478bd9Sstevel@tonic-gate #define	DEVI_EVADD(dip)							\
44916747f41Scth 	((DEVI(dip)->devi_state & DEVI_S_EVADD) == DEVI_S_EVADD)
45016747f41Scth 
45116747f41Scth #define	DEVI_SET_EVADD(dip)		{				\
45216747f41Scth 	ASSERT(mutex_owned(&DEVI(dip)->devi_lock));			\
45316747f41Scth 	DEVI(dip)->devi_state &= ~DEVI_S_EVREMOVE;			\
45416747f41Scth 	DEVI(dip)->devi_state |= DEVI_S_EVADD;				\
45516747f41Scth 	}
4567c478bd9Sstevel@tonic-gate 
4577c478bd9Sstevel@tonic-gate #define	DEVI_EVREMOVE(dip)						\
45816747f41Scth 	((DEVI(dip)->devi_state & DEVI_S_EVREMOVE) == DEVI_S_EVREMOVE)
4597c478bd9Sstevel@tonic-gate 
46016747f41Scth #define	DEVI_SET_EVREMOVE(dip)		{				\
46116747f41Scth 	ASSERT(mutex_owned(&DEVI(dip)->devi_lock));			\
46216747f41Scth 	DEVI(dip)->devi_state &= ~DEVI_S_EVADD;				\
46316747f41Scth 	DEVI(dip)->devi_state |= DEVI_S_EVREMOVE;			\
46416747f41Scth 	}
46516747f41Scth 
46616747f41Scth #define	DEVI_SET_EVUNINIT(dip)		{				\
46716747f41Scth 	ASSERT(mutex_owned(&DEVI(dip)->devi_lock));			\
46816747f41Scth 	DEVI(dip)->devi_state &= ~(DEVI_S_EVADD | DEVI_S_EVREMOVE);	\
46916747f41Scth 	}
47016747f41Scth 
47116747f41Scth /* Need to call the devo_reset entry point for this device at shutdown */
4727c478bd9Sstevel@tonic-gate #define	DEVI_NEED_RESET(dip)						\
47316747f41Scth 	((DEVI(dip)->devi_state & DEVI_S_NEED_RESET) == DEVI_S_NEED_RESET)
4747c478bd9Sstevel@tonic-gate 
47516747f41Scth #define	DEVI_SET_NEED_RESET(dip)	{				\
47616747f41Scth 	ASSERT(mutex_owned(&DEVI(dip)->devi_lock));			\
47716747f41Scth 	DEVI(dip)->devi_state |= DEVI_S_NEED_RESET;			\
47816747f41Scth 	}
4797c478bd9Sstevel@tonic-gate 
48016747f41Scth #define	DEVI_CLR_NEED_RESET(dip)	{				\
48116747f41Scth 	ASSERT(mutex_owned(&DEVI(dip)->devi_lock));			\
48216747f41Scth 	DEVI(dip)->devi_state &= ~DEVI_S_NEED_RESET;			\
48316747f41Scth 	}
4847c478bd9Sstevel@tonic-gate 
4857c478bd9Sstevel@tonic-gate void	i_devi_enter(dev_info_t *, uint_t s_mask, uint_t w_mask, int has_lock);
4867c478bd9Sstevel@tonic-gate void	i_devi_exit(dev_info_t *, uint_t c_mask, int has_lock);
4877c478bd9Sstevel@tonic-gate 
48816747f41Scth /*
48916747f41Scth  * devi_flags bits
49016747f41Scth  *
49116747f41Scth  * NOTE: all devi_state updates shoule be protected by devi_lock.
49216747f41Scth  */
49316747f41Scth #define	DEVI_BUSY		0x00000001 /* busy configuring children */
49416747f41Scth #define	DEVI_MADE_CHILDREN	0x00000002 /* children made from specs */
49516747f41Scth #define	DEVI_ATTACHED_CHILDREN	0x00000004 /* attached all existing children */
49616747f41Scth #define	DEVI_BRANCH_HELD	0x00000008 /* branch rooted at this dip held */
49716747f41Scth #define	DEVI_NO_BIND		0x00000010 /* prevent driver binding */
49816747f41Scth #define	DEVI_REGISTERED_DEVID	0x00000020 /* device registered a devid */
499*144dfaa9Scth #define	DEVI_PHCI_SIGNALS_VHCI	0x00000040 /* pHCI ndi_devi_exit signals vHCI */
50016747f41Scth 
50116747f41Scth #define	DEVI_BUSY_CHANGING(dip)	(DEVI(dip)->devi_flags & DEVI_BUSY)
50216747f41Scth #define	DEVI_BUSY_OWNED(dip)	(DEVI_BUSY_CHANGING(dip) &&	\
50316747f41Scth 	((DEVI(dip))->devi_busy_thread == curthread))
50416747f41Scth 
5057c478bd9Sstevel@tonic-gate char	*i_ddi_devi_class(dev_info_t *);
5067c478bd9Sstevel@tonic-gate int	i_ddi_set_devi_class(dev_info_t *, char *, int);
5077c478bd9Sstevel@tonic-gate 
5087c478bd9Sstevel@tonic-gate /*
5097c478bd9Sstevel@tonic-gate  * This structure represents one piece of bus space occupied by a given
5107c478bd9Sstevel@tonic-gate  * device. It is used in an array for devices with multiple address windows.
5117c478bd9Sstevel@tonic-gate  */
5127c478bd9Sstevel@tonic-gate struct regspec {
5137c478bd9Sstevel@tonic-gate 	uint_t regspec_bustype;		/* cookie for bus type it's on */
5147c478bd9Sstevel@tonic-gate 	uint_t regspec_addr;		/* address of reg relative to bus */
5157c478bd9Sstevel@tonic-gate 	uint_t regspec_size;		/* size of this register set */
5167c478bd9Sstevel@tonic-gate };
5177c478bd9Sstevel@tonic-gate 
5187c478bd9Sstevel@tonic-gate /*
5197c478bd9Sstevel@tonic-gate  * This structure represents one piece of nexus bus space.
5207c478bd9Sstevel@tonic-gate  * It is used in an array for nexi with multiple bus spaces
5217c478bd9Sstevel@tonic-gate  * to define the childs offsets in the parents bus space.
5227c478bd9Sstevel@tonic-gate  */
5237c478bd9Sstevel@tonic-gate struct rangespec {
5247c478bd9Sstevel@tonic-gate 	uint_t rng_cbustype;		/* Child's address, hi order */
5257c478bd9Sstevel@tonic-gate 	uint_t rng_coffset;		/* Child's address, lo order */
5267c478bd9Sstevel@tonic-gate 	uint_t rng_bustype;		/* Parent's address, hi order */
5277c478bd9Sstevel@tonic-gate 	uint_t rng_offset;		/* Parent's address, lo order */
5287c478bd9Sstevel@tonic-gate 	uint_t rng_size;		/* size of space for this entry */
5297c478bd9Sstevel@tonic-gate };
5307c478bd9Sstevel@tonic-gate 
5317c478bd9Sstevel@tonic-gate #ifdef _KERNEL
5327c478bd9Sstevel@tonic-gate 
5337c478bd9Sstevel@tonic-gate typedef enum {
5347c478bd9Sstevel@tonic-gate 	DDI_PRE = 0,
5357c478bd9Sstevel@tonic-gate 	DDI_POST = 1
5367c478bd9Sstevel@tonic-gate } ddi_pre_post_t;
5377c478bd9Sstevel@tonic-gate 
5387c478bd9Sstevel@tonic-gate /*
5397c478bd9Sstevel@tonic-gate  * This structure represents notification of a child attach event
5407c478bd9Sstevel@tonic-gate  * These could both be the same if attach/detach commands were in the
5417c478bd9Sstevel@tonic-gate  * same name space.
5427c478bd9Sstevel@tonic-gate  * Note that the target dip is passed as an arg already.
5437c478bd9Sstevel@tonic-gate  */
5447c478bd9Sstevel@tonic-gate struct attachspec {
5457c478bd9Sstevel@tonic-gate 	ddi_attach_cmd_t cmd;	/* type of event */
5467c478bd9Sstevel@tonic-gate 	ddi_pre_post_t	when;	/* one of DDI_PRE or DDI_POST */
5477c478bd9Sstevel@tonic-gate 	dev_info_t	*pdip;	/* parent of attaching node */
5487c478bd9Sstevel@tonic-gate 	int		result;	/* result of attach op (post command only) */
5497c478bd9Sstevel@tonic-gate };
5507c478bd9Sstevel@tonic-gate 
5517c478bd9Sstevel@tonic-gate /*
5527c478bd9Sstevel@tonic-gate  * This structure represents notification of a child detach event
5537c478bd9Sstevel@tonic-gate  * Note that the target dip is passed as an arg already.
5547c478bd9Sstevel@tonic-gate  */
5557c478bd9Sstevel@tonic-gate struct detachspec {
5567c478bd9Sstevel@tonic-gate 	ddi_detach_cmd_t cmd;	/* type of event */
5577c478bd9Sstevel@tonic-gate 	ddi_pre_post_t	when;	/* one of DDI_PRE or DDI_POST */
5587c478bd9Sstevel@tonic-gate 	dev_info_t	*pdip;	/* parent of detaching node */
5597c478bd9Sstevel@tonic-gate 	int		result;	/* result of detach op (post command only) */
5607c478bd9Sstevel@tonic-gate };
5617c478bd9Sstevel@tonic-gate 
5627c478bd9Sstevel@tonic-gate #endif /* _KERNEL */
5637c478bd9Sstevel@tonic-gate 
5647c478bd9Sstevel@tonic-gate typedef enum {
5657c478bd9Sstevel@tonic-gate 	DDM_MINOR = 0,
5667c478bd9Sstevel@tonic-gate 	DDM_ALIAS,
5677c478bd9Sstevel@tonic-gate 	DDM_DEFAULT,
5687c478bd9Sstevel@tonic-gate 	DDM_INTERNAL_PATH
5697c478bd9Sstevel@tonic-gate } ddi_minor_type;
5707c478bd9Sstevel@tonic-gate 
5717c478bd9Sstevel@tonic-gate /* implementation flags for driver specified device access control */
5727c478bd9Sstevel@tonic-gate #define	DM_NO_FSPERM	0x1
5737c478bd9Sstevel@tonic-gate 
5747c478bd9Sstevel@tonic-gate struct devplcy;
5757c478bd9Sstevel@tonic-gate 
5767c478bd9Sstevel@tonic-gate struct ddi_minor {
5777c478bd9Sstevel@tonic-gate 	char		*name;		/* name of node */
5787c478bd9Sstevel@tonic-gate 	dev_t		dev;		/* device number */
5797c478bd9Sstevel@tonic-gate 	int		spec_type;	/* block or char */
5807c478bd9Sstevel@tonic-gate 	int		flags;		/* access flags */
5817c478bd9Sstevel@tonic-gate 	char		*node_type;	/* block, byte, serial, network */
5827c478bd9Sstevel@tonic-gate 	struct devplcy	*node_priv;	/* privilege for this minor */
5837c478bd9Sstevel@tonic-gate 	mode_t		priv_mode;	/* default apparent privilege mode */
5847c478bd9Sstevel@tonic-gate };
5857c478bd9Sstevel@tonic-gate 
5867c478bd9Sstevel@tonic-gate /*
5877c478bd9Sstevel@tonic-gate  * devi_node_attributes contains node attributes private to the
5887c478bd9Sstevel@tonic-gate  * ddi implementation. As a consumer, do not use these bit definitions
5897c478bd9Sstevel@tonic-gate  * directly, use the ndi functions that check for the existence of the
5907c478bd9Sstevel@tonic-gate  * specific node attributes.
5917c478bd9Sstevel@tonic-gate  *
5927c478bd9Sstevel@tonic-gate  * DDI_PERSISTENT indicates a 'persistent' node; one that is not
5937c478bd9Sstevel@tonic-gate  * automatically freed by the framework if the driver is unloaded
5947c478bd9Sstevel@tonic-gate  * or the driver fails to attach to this node.
5957c478bd9Sstevel@tonic-gate  *
5967c478bd9Sstevel@tonic-gate  * DDI_AUTO_ASSIGNED_NODEID indicates that the nodeid was auto-assigned
5977c478bd9Sstevel@tonic-gate  * by the framework and should be auto-freed if the node is removed.
5987c478bd9Sstevel@tonic-gate  *
5997c478bd9Sstevel@tonic-gate  * DDI_VHCI_NODE indicates that the node type is VHCI. This flag
6007c478bd9Sstevel@tonic-gate  * must be set by ndi_devi_config_vhci() routine only.
6017c478bd9Sstevel@tonic-gate  */
6027c478bd9Sstevel@tonic-gate #define	DDI_PERSISTENT			0x01
6037c478bd9Sstevel@tonic-gate #define	DDI_AUTO_ASSIGNED_NODEID	0x02
6047c478bd9Sstevel@tonic-gate #define	DDI_VHCI_NODE			0x04
6057c478bd9Sstevel@tonic-gate 
60616747f41Scth #define	DEVI_VHCI_NODE(dip)						\
60716747f41Scth 	(DEVI(dip)->devi_node_attributes & DDI_VHCI_NODE)
60816747f41Scth 
6097c478bd9Sstevel@tonic-gate /*
6107c478bd9Sstevel@tonic-gate  * The ddi_minor_data structure gets filled in by ddi_create_minor_node.
6117c478bd9Sstevel@tonic-gate  * It then gets attached to the devinfo node as a property.
6127c478bd9Sstevel@tonic-gate  */
6137c478bd9Sstevel@tonic-gate struct ddi_minor_data {
6147c478bd9Sstevel@tonic-gate 	struct ddi_minor_data *next;	/* next one in the chain */
6157c478bd9Sstevel@tonic-gate 	dev_info_t	*dip;		/* pointer to devinfo node */
6167c478bd9Sstevel@tonic-gate 	ddi_minor_type	type;		/* Following data type */
6177c478bd9Sstevel@tonic-gate 	struct ddi_minor d_minor;	/* Actual minor node data */
6187c478bd9Sstevel@tonic-gate };
6197c478bd9Sstevel@tonic-gate 
6207c478bd9Sstevel@tonic-gate #define	ddm_name	d_minor.name
6217c478bd9Sstevel@tonic-gate #define	ddm_dev		d_minor.dev
6227c478bd9Sstevel@tonic-gate #define	ddm_flags	d_minor.flags
6237c478bd9Sstevel@tonic-gate #define	ddm_spec_type	d_minor.spec_type
6247c478bd9Sstevel@tonic-gate #define	ddm_node_type	d_minor.node_type
6257c478bd9Sstevel@tonic-gate #define	ddm_node_priv	d_minor.node_priv
6267c478bd9Sstevel@tonic-gate #define	ddm_priv_mode	d_minor.priv_mode
6277c478bd9Sstevel@tonic-gate 
6287c478bd9Sstevel@tonic-gate /*
6297c478bd9Sstevel@tonic-gate  * parent private data structure contains register, interrupt, property
6307c478bd9Sstevel@tonic-gate  * and range information.
6317c478bd9Sstevel@tonic-gate  */
6327c478bd9Sstevel@tonic-gate struct ddi_parent_private_data {
6337c478bd9Sstevel@tonic-gate 	int par_nreg;			/* number of regs */
6347c478bd9Sstevel@tonic-gate 	struct regspec *par_reg;	/* array of regs */
6357c478bd9Sstevel@tonic-gate 	int par_nintr;			/* number of interrupts */
6367c478bd9Sstevel@tonic-gate 	struct intrspec *par_intr;	/* array of possible interrupts */
6377c478bd9Sstevel@tonic-gate 	int par_nrng;			/* number of ranges */
6387c478bd9Sstevel@tonic-gate 	struct rangespec *par_rng;	/* array of ranges */
6397c478bd9Sstevel@tonic-gate };
6407c478bd9Sstevel@tonic-gate #define	DEVI_PD(d)	\
6417c478bd9Sstevel@tonic-gate 	((struct ddi_parent_private_data *)DEVI((d))->devi_parent_data)
6427c478bd9Sstevel@tonic-gate 
6437c478bd9Sstevel@tonic-gate #define	sparc_pd_getnreg(dev)		(DEVI_PD(dev)->par_nreg)
6447c478bd9Sstevel@tonic-gate #define	sparc_pd_getnintr(dev)		(DEVI_PD(dev)->par_nintr)
6457c478bd9Sstevel@tonic-gate #define	sparc_pd_getnrng(dev)		(DEVI_PD(dev)->par_nrng)
6467c478bd9Sstevel@tonic-gate #define	sparc_pd_getreg(dev, n)		(&DEVI_PD(dev)->par_reg[(n)])
6477c478bd9Sstevel@tonic-gate #define	sparc_pd_getintr(dev, n)	(&DEVI_PD(dev)->par_intr[(n)])
6487c478bd9Sstevel@tonic-gate #define	sparc_pd_getrng(dev, n)		(&DEVI_PD(dev)->par_rng[(n)])
6497c478bd9Sstevel@tonic-gate 
6507c478bd9Sstevel@tonic-gate /*
6517c478bd9Sstevel@tonic-gate  * This data structure is entirely private to the soft state allocator.
6527c478bd9Sstevel@tonic-gate  */
6537c478bd9Sstevel@tonic-gate struct i_ddi_soft_state {
6547c478bd9Sstevel@tonic-gate 	void		**array;	/* the array of pointers */
6557c478bd9Sstevel@tonic-gate 	kmutex_t	lock;	/* serialize access to this struct */
6567c478bd9Sstevel@tonic-gate 	size_t		size;	/* how many bytes per state struct */
6577c478bd9Sstevel@tonic-gate 	size_t		n_items;	/* how many structs herein */
6587c478bd9Sstevel@tonic-gate 	struct i_ddi_soft_state *next;	/* 'dirty' elements */
6597c478bd9Sstevel@tonic-gate };
6607c478bd9Sstevel@tonic-gate 
6617c478bd9Sstevel@tonic-gate /*
6627c478bd9Sstevel@tonic-gate  * Solaris DDI DMA implementation structure and function definitions.
6637c478bd9Sstevel@tonic-gate  *
6647c478bd9Sstevel@tonic-gate  * Note: no callers of DDI functions must depend upon data structures
6657c478bd9Sstevel@tonic-gate  * declared below. They are not guaranteed to remain constant.
6667c478bd9Sstevel@tonic-gate  */
6677c478bd9Sstevel@tonic-gate 
6687c478bd9Sstevel@tonic-gate /*
6697c478bd9Sstevel@tonic-gate  * Implementation DMA mapping structure.
6707c478bd9Sstevel@tonic-gate  *
6717c478bd9Sstevel@tonic-gate  * The publicly visible ddi_dma_req structure is filled
6727c478bd9Sstevel@tonic-gate  * in by a caller that wishes to map a memory object
6737c478bd9Sstevel@tonic-gate  * for DMA. Internal to this implementation of the public
6747c478bd9Sstevel@tonic-gate  * DDI DMA functions this request structure is put together
6757c478bd9Sstevel@tonic-gate  * with bus nexus specific functions that have additional
6767c478bd9Sstevel@tonic-gate  * information and constraints as to how to go about doing
6777c478bd9Sstevel@tonic-gate  * the requested mapping function
6787c478bd9Sstevel@tonic-gate  *
6797c478bd9Sstevel@tonic-gate  * In this implementation, some of the information from the
6807c478bd9Sstevel@tonic-gate  * original requester is retained throughout the lifetime
6817c478bd9Sstevel@tonic-gate  * of the I/O mapping being active.
6827c478bd9Sstevel@tonic-gate  */
6837c478bd9Sstevel@tonic-gate 
6847c478bd9Sstevel@tonic-gate /*
6857c478bd9Sstevel@tonic-gate  * This is the implementation specific description
6867c478bd9Sstevel@tonic-gate  * of how we've mapped an object for DMA.
6877c478bd9Sstevel@tonic-gate  */
6887c478bd9Sstevel@tonic-gate #if defined(__sparc)
6897c478bd9Sstevel@tonic-gate typedef struct ddi_dma_impl {
6907c478bd9Sstevel@tonic-gate 	/*
6917c478bd9Sstevel@tonic-gate 	 * DMA mapping information
6927c478bd9Sstevel@tonic-gate 	 */
6937c478bd9Sstevel@tonic-gate 	ulong_t	dmai_mapping;	/* mapping cookie */
6947c478bd9Sstevel@tonic-gate 
6957c478bd9Sstevel@tonic-gate 	/*
6967c478bd9Sstevel@tonic-gate 	 * Size of the current mapping, in bytes.
6977c478bd9Sstevel@tonic-gate 	 *
6987c478bd9Sstevel@tonic-gate 	 * Note that this is distinct from the size of the object being mapped
6997c478bd9Sstevel@tonic-gate 	 * for DVMA. We might have only a portion of the object mapped at any
7007c478bd9Sstevel@tonic-gate 	 * given point in time.
7017c478bd9Sstevel@tonic-gate 	 */
7027c478bd9Sstevel@tonic-gate 	uint_t	dmai_size;
7037c478bd9Sstevel@tonic-gate 
7047c478bd9Sstevel@tonic-gate 	/*
7057c478bd9Sstevel@tonic-gate 	 * Offset, in bytes, into object that is currently mapped.
7067c478bd9Sstevel@tonic-gate 	 */
7077c478bd9Sstevel@tonic-gate 	off_t	dmai_offset;
7087c478bd9Sstevel@tonic-gate 
7097c478bd9Sstevel@tonic-gate 	/*
7107c478bd9Sstevel@tonic-gate 	 * Information gathered from the original DMA mapping
7117c478bd9Sstevel@tonic-gate 	 * request and saved for the lifetime of the mapping.
7127c478bd9Sstevel@tonic-gate 	 */
7137c478bd9Sstevel@tonic-gate 	uint_t		dmai_minxfer;
7147c478bd9Sstevel@tonic-gate 	uint_t		dmai_burstsizes;
7157c478bd9Sstevel@tonic-gate 	uint_t		dmai_ndvmapages;
7167c478bd9Sstevel@tonic-gate 	uint_t		dmai_pool;	/* cached DVMA space */
7177c478bd9Sstevel@tonic-gate 	uint_t		dmai_rflags;	/* requester's flags + ours */
7187c478bd9Sstevel@tonic-gate 	uint_t		dmai_inuse;	/* active handle? */
7197c478bd9Sstevel@tonic-gate 	uint_t		dmai_nwin;
7207c478bd9Sstevel@tonic-gate 	uint_t		dmai_winsize;
7217c478bd9Sstevel@tonic-gate 	caddr_t		dmai_nexus_private;
7227c478bd9Sstevel@tonic-gate 	void		*dmai_iopte;
7237c478bd9Sstevel@tonic-gate 	uint_t		*dmai_sbi;
7247c478bd9Sstevel@tonic-gate 	void		*dmai_minfo;	/* random mapping information */
7257c478bd9Sstevel@tonic-gate 	dev_info_t	*dmai_rdip;	/* original requester's dev_info_t */
7267c478bd9Sstevel@tonic-gate 	ddi_dma_obj_t	dmai_object;	/* requester's object */
7277c478bd9Sstevel@tonic-gate 	ddi_dma_attr_t	dmai_attr;	/* DMA attributes */
7287c478bd9Sstevel@tonic-gate 	ddi_dma_cookie_t *dmai_cookie;	/* pointer to first DMA cookie */
7297c478bd9Sstevel@tonic-gate 
7307c478bd9Sstevel@tonic-gate 	int		(*dmai_fault_check)(struct ddi_dma_impl *handle);
7317c478bd9Sstevel@tonic-gate 	void		(*dmai_fault_notify)(struct ddi_dma_impl *handle);
7327c478bd9Sstevel@tonic-gate 	int		dmai_fault;
7337c478bd9Sstevel@tonic-gate 	ndi_err_t	dmai_error;
7347c478bd9Sstevel@tonic-gate 
7357c478bd9Sstevel@tonic-gate } ddi_dma_impl_t;
7367c478bd9Sstevel@tonic-gate 
7377c478bd9Sstevel@tonic-gate #elif defined(__x86)
7387c478bd9Sstevel@tonic-gate 
73912f080e7Smrj /*
74012f080e7Smrj  * ddi_dma_impl portion that genunix (sunddi.c) depends on. x86 rootnex
74112f080e7Smrj  * implementation specific state is in dmai_private.
74212f080e7Smrj  */
7437c478bd9Sstevel@tonic-gate typedef struct ddi_dma_impl {
74412f080e7Smrj 	ddi_dma_cookie_t *dmai_cookie; /* array of DMA cookies */
74512f080e7Smrj 	void		*dmai_private;
7467c478bd9Sstevel@tonic-gate 
7477c478bd9Sstevel@tonic-gate 	/*
7487c478bd9Sstevel@tonic-gate 	 * Information gathered from the original dma mapping
7497c478bd9Sstevel@tonic-gate 	 * request and saved for the lifetime of the mapping.
7507c478bd9Sstevel@tonic-gate 	 */
7517c478bd9Sstevel@tonic-gate 	uint_t		dmai_minxfer;
7527c478bd9Sstevel@tonic-gate 	uint_t		dmai_burstsizes;
7537c478bd9Sstevel@tonic-gate 	uint_t		dmai_rflags;	/* requester's flags + ours */
7547c478bd9Sstevel@tonic-gate 	int		dmai_nwin;
7557c478bd9Sstevel@tonic-gate 	dev_info_t	*dmai_rdip;	/* original requester's dev_info_t */
7567c478bd9Sstevel@tonic-gate 
7577c478bd9Sstevel@tonic-gate 	ddi_dma_attr_t	dmai_attr;	/* DMA attributes */
7587c478bd9Sstevel@tonic-gate 
7597c478bd9Sstevel@tonic-gate 	int		(*dmai_fault_check)(struct ddi_dma_impl *handle);
7607c478bd9Sstevel@tonic-gate 	void		(*dmai_fault_notify)(struct ddi_dma_impl *handle);
7617c478bd9Sstevel@tonic-gate 	int		dmai_fault;
7627c478bd9Sstevel@tonic-gate 	ndi_err_t	dmai_error;
7637c478bd9Sstevel@tonic-gate } ddi_dma_impl_t;
7647c478bd9Sstevel@tonic-gate 
7657c478bd9Sstevel@tonic-gate #else
7667c478bd9Sstevel@tonic-gate #error "struct ddi_dma_impl not defined for this architecture"
7677c478bd9Sstevel@tonic-gate #endif  /* defined(__sparc) */
7687c478bd9Sstevel@tonic-gate 
7697c478bd9Sstevel@tonic-gate /*
7707c478bd9Sstevel@tonic-gate  * For now DMA segments share state with the DMA handle
7717c478bd9Sstevel@tonic-gate  */
7727c478bd9Sstevel@tonic-gate typedef ddi_dma_impl_t ddi_dma_seg_impl_t;
7737c478bd9Sstevel@tonic-gate 
7747c478bd9Sstevel@tonic-gate /*
7757c478bd9Sstevel@tonic-gate  * These flags use reserved bits from the dma request flags.
7767c478bd9Sstevel@tonic-gate  *
7777c478bd9Sstevel@tonic-gate  * A note about the DMP_NOSYNC flags: the root nexus will
7787c478bd9Sstevel@tonic-gate  * set these as it sees best. If an intermediate nexus
7797c478bd9Sstevel@tonic-gate  * actually needs these operations, then during the unwind
7807c478bd9Sstevel@tonic-gate  * from the call to ddi_dma_bind, the nexus driver *must*
7817c478bd9Sstevel@tonic-gate  * clear the appropriate flag(s). This is because, as an
7827c478bd9Sstevel@tonic-gate  * optimization, ddi_dma_sync(9F) looks at these flags before
7837c478bd9Sstevel@tonic-gate  * deciding to spend the time going back up the tree.
7847c478bd9Sstevel@tonic-gate  */
7857c478bd9Sstevel@tonic-gate 
7867c478bd9Sstevel@tonic-gate #define	_DMCM1	DDI_DMA_RDWR|DDI_DMA_REDZONE|DDI_DMA_PARTIAL
7877c478bd9Sstevel@tonic-gate #define	_DMCM2	DDI_DMA_CONSISTENT|DMP_VMEREQ
7887c478bd9Sstevel@tonic-gate #define	DMP_DDIFLAGS	(_DMCM1|_DMCM2)
7897c478bd9Sstevel@tonic-gate #define	DMP_SHADOW	0x20
7907c478bd9Sstevel@tonic-gate #define	DMP_LKIOPB	0x40
7917c478bd9Sstevel@tonic-gate #define	DMP_LKSYSV	0x80
7927c478bd9Sstevel@tonic-gate #define	DMP_IOCACHE	0x100
7937c478bd9Sstevel@tonic-gate #define	DMP_USEHAT	0x200
7947c478bd9Sstevel@tonic-gate #define	DMP_PHYSADDR	0x400
7957c478bd9Sstevel@tonic-gate #define	DMP_INVALID	0x800
7967c478bd9Sstevel@tonic-gate #define	DMP_NOLIMIT	0x1000
7977c478bd9Sstevel@tonic-gate #define	DMP_VMEREQ	0x10000000
7987c478bd9Sstevel@tonic-gate #define	DMP_BYPASSNEXUS	0x20000000
7997c478bd9Sstevel@tonic-gate #define	DMP_NODEVSYNC	0x40000000
8007c478bd9Sstevel@tonic-gate #define	DMP_NOCPUSYNC	0x80000000
8017c478bd9Sstevel@tonic-gate #define	DMP_NOSYNC	(DMP_NODEVSYNC|DMP_NOCPUSYNC)
8027c478bd9Sstevel@tonic-gate 
8037c478bd9Sstevel@tonic-gate /*
8047c478bd9Sstevel@tonic-gate  * In order to complete a device to device mapping that
8057c478bd9Sstevel@tonic-gate  * has percolated as high as an IU nexus (gone that high
8067c478bd9Sstevel@tonic-gate  * because the DMA request is a VADDR type), we define
8077c478bd9Sstevel@tonic-gate  * structure to use with the DDI_CTLOPS_DMAPMAPC request
8087c478bd9Sstevel@tonic-gate  * that re-traverses the request tree to finish the
8097c478bd9Sstevel@tonic-gate  * DMA 'mapping' for a device.
8107c478bd9Sstevel@tonic-gate  */
8117c478bd9Sstevel@tonic-gate struct dma_phys_mapc {
8127c478bd9Sstevel@tonic-gate 	struct ddi_dma_req *dma_req;	/* original request */
8137c478bd9Sstevel@tonic-gate 	ddi_dma_impl_t *mp;		/* current handle, or none */
8147c478bd9Sstevel@tonic-gate 	int nptes;			/* number of ptes */
8157c478bd9Sstevel@tonic-gate 	void *ptes;			/* ptes already read */
8167c478bd9Sstevel@tonic-gate };
8177c478bd9Sstevel@tonic-gate 
8187c478bd9Sstevel@tonic-gate #define	MAXCALLBACK		20
8197c478bd9Sstevel@tonic-gate 
8207c478bd9Sstevel@tonic-gate /*
8217c478bd9Sstevel@tonic-gate  * Callback definitions
8227c478bd9Sstevel@tonic-gate  */
8237c478bd9Sstevel@tonic-gate struct ddi_callback {
8247c478bd9Sstevel@tonic-gate 	struct ddi_callback	*c_nfree;
8257c478bd9Sstevel@tonic-gate 	struct ddi_callback	*c_nlist;
8267c478bd9Sstevel@tonic-gate 	int			(*c_call)();
8277c478bd9Sstevel@tonic-gate 	int			c_count;
8287c478bd9Sstevel@tonic-gate 	caddr_t			c_arg;
8297c478bd9Sstevel@tonic-gate 	size_t			c_size;
8307c478bd9Sstevel@tonic-gate };
8317c478bd9Sstevel@tonic-gate 
8327c478bd9Sstevel@tonic-gate 
8337c478bd9Sstevel@tonic-gate /*
8347c478bd9Sstevel@tonic-gate  * Device id - Internal definition.
8357c478bd9Sstevel@tonic-gate  */
8367c478bd9Sstevel@tonic-gate #define	DEVID_MAGIC_MSB		0x69
8377c478bd9Sstevel@tonic-gate #define	DEVID_MAGIC_LSB		0x64
8387c478bd9Sstevel@tonic-gate #define	DEVID_REV_MSB		0x00
8397c478bd9Sstevel@tonic-gate #define	DEVID_REV_LSB		0x01
8407c478bd9Sstevel@tonic-gate #define	DEVID_HINT_SIZE		4
8417c478bd9Sstevel@tonic-gate 
8427c478bd9Sstevel@tonic-gate typedef struct impl_devid {
8437c478bd9Sstevel@tonic-gate 	uchar_t	did_magic_hi;			/* device id magic # (msb) */
8447c478bd9Sstevel@tonic-gate 	uchar_t	did_magic_lo;			/* device id magic # (lsb) */
8457c478bd9Sstevel@tonic-gate 	uchar_t	did_rev_hi;			/* device id revision # (msb) */
8467c478bd9Sstevel@tonic-gate 	uchar_t	did_rev_lo;			/* device id revision # (lsb) */
8477c478bd9Sstevel@tonic-gate 	uchar_t	did_type_hi;			/* device id type (msb) */
8487c478bd9Sstevel@tonic-gate 	uchar_t	did_type_lo;			/* device id type (lsb) */
8497c478bd9Sstevel@tonic-gate 	uchar_t	did_len_hi;			/* length of devid data (msb) */
8507c478bd9Sstevel@tonic-gate 	uchar_t	did_len_lo;			/* length of devid data (lsb) */
8517c478bd9Sstevel@tonic-gate 	char	did_driver[DEVID_HINT_SIZE];	/* driver name - HINT */
8527c478bd9Sstevel@tonic-gate 	char	did_id[1];			/* start of device id data */
8537c478bd9Sstevel@tonic-gate } impl_devid_t;
8547c478bd9Sstevel@tonic-gate 
8557c478bd9Sstevel@tonic-gate #define	DEVID_GETTYPE(devid)		((ushort_t) \
8567c478bd9Sstevel@tonic-gate 					    (((devid)->did_type_hi << NBBY) + \
8577c478bd9Sstevel@tonic-gate 					    (devid)->did_type_lo))
8587c478bd9Sstevel@tonic-gate 
8597c478bd9Sstevel@tonic-gate #define	DEVID_FORMTYPE(devid, type)	(devid)->did_type_hi = hibyte((type)); \
8607c478bd9Sstevel@tonic-gate 					(devid)->did_type_lo = lobyte((type));
8617c478bd9Sstevel@tonic-gate 
8627c478bd9Sstevel@tonic-gate #define	DEVID_GETLEN(devid)		((ushort_t) \
8637c478bd9Sstevel@tonic-gate 					    (((devid)->did_len_hi << NBBY) + \
8647c478bd9Sstevel@tonic-gate 					    (devid)->did_len_lo))
8657c478bd9Sstevel@tonic-gate 
8667c478bd9Sstevel@tonic-gate #define	DEVID_FORMLEN(devid, len)	(devid)->did_len_hi = hibyte((len)); \
8677c478bd9Sstevel@tonic-gate 					(devid)->did_len_lo = lobyte((len));
8687c478bd9Sstevel@tonic-gate 
8697c478bd9Sstevel@tonic-gate /*
8707c478bd9Sstevel@tonic-gate  * Per PSARC/1995/352, a binary devid contains fields for <magic number>,
8717c478bd9Sstevel@tonic-gate  * <revision>, <driver_hint>, <type>, <id_length>, and the <id> itself.
8727c478bd9Sstevel@tonic-gate  * This proposal would encode the binary devid into a string consisting
8737c478bd9Sstevel@tonic-gate  * of "<magic><revision>,<driver_hint>@<type><id>" as indicated below
8747c478bd9Sstevel@tonic-gate  * (<id_length> is rederived from the length of the string
8757c478bd9Sstevel@tonic-gate  * representation of the <id>):
8767c478bd9Sstevel@tonic-gate  *
8777c478bd9Sstevel@tonic-gate  *	<magic>		->"id"
8787c478bd9Sstevel@tonic-gate  *
8797c478bd9Sstevel@tonic-gate  *	<rev>		->"%d"	// "0" -> type of DEVID_NONE  "id0"
8807c478bd9Sstevel@tonic-gate  *				// NOTE: PSARC/1995/352 <revision> is "1".
8817c478bd9Sstevel@tonic-gate  *				// NOTE: support limited to 10 revisions
8827c478bd9Sstevel@tonic-gate  *				//	in current implementation
8837c478bd9Sstevel@tonic-gate  *
8847c478bd9Sstevel@tonic-gate  *	<driver_hint>	->"%s"	// "sd"/"ssd"
8857c478bd9Sstevel@tonic-gate  *				// NOTE: driver names limited to 4
8867c478bd9Sstevel@tonic-gate  *				//	characters for <revision> "1"
8877c478bd9Sstevel@tonic-gate  *
8887c478bd9Sstevel@tonic-gate  *	<type>		->'w' |	// DEVID_SCSI3_WWN	<hex_id>
8897c478bd9Sstevel@tonic-gate  *			'W' |	// DEVID_SCSI3_WWN	<ascii_id>
8907c478bd9Sstevel@tonic-gate  *			't' |	// DEVID_SCSI3_VPD_T10	<hex_id>
8917c478bd9Sstevel@tonic-gate  *			'T' |	// DEVID_SCSI3_VPD_T10	<ascii_id>
8927c478bd9Sstevel@tonic-gate  *			'x' |	// DEVID_SCSI3_VPD_EUI	<hex_id>
8937c478bd9Sstevel@tonic-gate  *			'X' |	// DEVID_SCSI3_VPD_EUI	<ascii_id>
8947c478bd9Sstevel@tonic-gate  *			'n' |	// DEVID_SCSI3_VPD_NAA	<hex_id>
8957c478bd9Sstevel@tonic-gate  *			'N' |	// DEVID_SCSI3_VPD_NAA	<ascii_id>
8967c478bd9Sstevel@tonic-gate  *			's' |	// DEVID_SCSI_SERIAL	<hex_id>
8977c478bd9Sstevel@tonic-gate  *			'S' |	// DEVID_SCSI_SERIAL	<ascii_id>
8987c478bd9Sstevel@tonic-gate  *			'f' |	// DEVID_FAB		<hex_id>
8997c478bd9Sstevel@tonic-gate  *			'F' |	// DEVID_FAB		<ascii_id>
9007c478bd9Sstevel@tonic-gate  *			'e' |	// DEVID_ENCAP		<hex_id>
9017c478bd9Sstevel@tonic-gate  *			'E' |	// DEVID_ENCAP		<ascii_id>
9027c478bd9Sstevel@tonic-gate  *			'a' |	// DEVID_ATA_SERIAL	<hex_id>
9037c478bd9Sstevel@tonic-gate  *			'A' |	// DEVID_ATA_SERIAL	<ascii_id>
9047c478bd9Sstevel@tonic-gate  *			'u' |	// unknown		<hex_id>
9057c478bd9Sstevel@tonic-gate  *			'U'	// unknown		<ascii_id>
9067c478bd9Sstevel@tonic-gate  *              		// NOTE: lower case -> <hex_id>
9077c478bd9Sstevel@tonic-gate  *				//       upper case -> <ascii_id>
9087c478bd9Sstevel@tonic-gate  *				// NOTE: this covers all types currently
9097c478bd9Sstevel@tonic-gate  *				//	defined for <revision> 1.
9107c478bd9Sstevel@tonic-gate  *				// NOTE: a <type> can be added
9117c478bd9Sstevel@tonic-gate  *				//	without changing the <revision>.
9127c478bd9Sstevel@tonic-gate  *
9137c478bd9Sstevel@tonic-gate  *	<id>		-> <ascii_id> |	// <type> is upper case
9147c478bd9Sstevel@tonic-gate  *			<hex_id>	// <type> is lower case
9157c478bd9Sstevel@tonic-gate  *
9167c478bd9Sstevel@tonic-gate  *	<ascii_id>	// only if all bytes of binary <id> field
9177c478bd9Sstevel@tonic-gate  *			// are in the set:
9187c478bd9Sstevel@tonic-gate  *			//	[A-Z][a-z][0-9]+-.= and space and 0x00
9197c478bd9Sstevel@tonic-gate  *			// the encoded form is:
9207c478bd9Sstevel@tonic-gate  *			//	[A-Z][a-z][0-9]+-.= and _     and ~
9217c478bd9Sstevel@tonic-gate  *			//          NOTE: ' ' <=> '_', 0x00 <=> '~'
9227c478bd9Sstevel@tonic-gate  *			// these sets are chosen to avoid shell
9237c478bd9Sstevel@tonic-gate  *			// and conflicts with DDI node names.
9247c478bd9Sstevel@tonic-gate  *
9257c478bd9Sstevel@tonic-gate  *	<hex_id>	// if not <ascii_id>; each byte of binary
9267c478bd9Sstevel@tonic-gate  *			// <id> maps a to 2 digit ascii hex
9277c478bd9Sstevel@tonic-gate  *			// representation in the string.
9287c478bd9Sstevel@tonic-gate  *
9297c478bd9Sstevel@tonic-gate  * This encoding provides a meaningful correlation between the /devices
9307c478bd9Sstevel@tonic-gate  * path and the devid string where possible.
9317c478bd9Sstevel@tonic-gate  *
9327c478bd9Sstevel@tonic-gate  *   Fibre:
9337c478bd9Sstevel@tonic-gate  *	sbus@6,0/SUNW,socal@d,10000/sf@1,0/ssd@w21000020370bb488,0:c,raw
9347c478bd9Sstevel@tonic-gate  *      id1,ssd@w20000020370bb488:c,raw
9357c478bd9Sstevel@tonic-gate  *
9367c478bd9Sstevel@tonic-gate  *   Copper:
9377c478bd9Sstevel@tonic-gate  *	sbus@7,0/SUNW,fas@3,8800000/sd@a,0:c
9387c478bd9Sstevel@tonic-gate  *      id1,sd@SIBM_____1XY210__________:c
9397c478bd9Sstevel@tonic-gate  */
9407c478bd9Sstevel@tonic-gate /* determine if a byte of an id meets ASCII representation requirements */
9417c478bd9Sstevel@tonic-gate #define	DEVID_IDBYTE_ISASCII(b)		(				\
9427c478bd9Sstevel@tonic-gate 	(((b) >= 'a') && ((b) <= 'z')) ||				\
9437c478bd9Sstevel@tonic-gate 	(((b) >= 'A') && ((b) <= 'Z')) ||				\
9447c478bd9Sstevel@tonic-gate 	(((b) >= '0') && ((b) <= '9')) ||				\
9457c478bd9Sstevel@tonic-gate 	(b == '+') || (b == '-') || (b == '.') || (b == '=') ||		\
9467c478bd9Sstevel@tonic-gate 	(b == ' ') || (b == 0x00))
9477c478bd9Sstevel@tonic-gate 
9487c478bd9Sstevel@tonic-gate /* set type to lower case to indicate that the did_id field is ascii */
9497c478bd9Sstevel@tonic-gate #define	DEVID_TYPE_SETASCII(c)	(c - 0x20)	/* 'a' -> 'A' */
9507c478bd9Sstevel@tonic-gate 
9517c478bd9Sstevel@tonic-gate /* determine from type if did_id field is binary or ascii */
9527c478bd9Sstevel@tonic-gate #define	DEVID_TYPE_ISASCII(c)	(((c) >= 'A') && ((c) <= 'Z'))
9537c478bd9Sstevel@tonic-gate 
9547c478bd9Sstevel@tonic-gate /* convert type field from binary to ascii */
9557c478bd9Sstevel@tonic-gate #define	DEVID_TYPE_BINTOASCII(b)	(				\
9567c478bd9Sstevel@tonic-gate 	((b) == DEVID_SCSI3_WWN)	? 'w' :				\
9577c478bd9Sstevel@tonic-gate 	((b) == DEVID_SCSI3_VPD_T10)	? 't' :				\
9587c478bd9Sstevel@tonic-gate 	((b) == DEVID_SCSI3_VPD_EUI)	? 'x' :				\
9597c478bd9Sstevel@tonic-gate 	((b) == DEVID_SCSI3_VPD_NAA)	? 'n' :				\
9607c478bd9Sstevel@tonic-gate 	((b) == DEVID_SCSI_SERIAL)	? 's' :				\
9617c478bd9Sstevel@tonic-gate 	((b) == DEVID_FAB)		? 'f' :				\
9627c478bd9Sstevel@tonic-gate 	((b) == DEVID_ENCAP)		? 'e' :				\
9637c478bd9Sstevel@tonic-gate 	((b) == DEVID_ATA_SERIAL)	? 'a' :				\
9647c478bd9Sstevel@tonic-gate 	'u')						/* unknown */
9657c478bd9Sstevel@tonic-gate 
9667c478bd9Sstevel@tonic-gate /* convert type field from ascii to binary */
9677c478bd9Sstevel@tonic-gate #define	DEVID_TYPE_ASCIITOBIN(c)	(				\
9687c478bd9Sstevel@tonic-gate 	(((c) == 'w') || ((c) == 'W'))	? DEVID_SCSI3_WWN :		\
9697c478bd9Sstevel@tonic-gate 	(((c) == 't') || ((c) == 'T'))	? DEVID_SCSI3_VPD_T10 :		\
9707c478bd9Sstevel@tonic-gate 	(((c) == 'x') || ((c) == 'X'))	? DEVID_SCSI3_VPD_EUI :		\
9717c478bd9Sstevel@tonic-gate 	(((c) == 'n') || ((c) == 'N'))	? DEVID_SCSI3_VPD_NAA :		\
9727c478bd9Sstevel@tonic-gate 	(((c) == 's') || ((c) == 'S'))	? DEVID_SCSI_SERIAL :		\
9737c478bd9Sstevel@tonic-gate 	(((c) == 'f') || ((c) == 'F'))	? DEVID_FAB :			\
9747c478bd9Sstevel@tonic-gate 	(((c) == 'e') || ((c) == 'E'))	? DEVID_ENCAP :			\
9757c478bd9Sstevel@tonic-gate 	(((c) == 'a') || ((c) == 'A'))	? DEVID_ATA_SERIAL :		\
9767c478bd9Sstevel@tonic-gate 	DEVID_MAXTYPE +1)				/* unknown */
9777c478bd9Sstevel@tonic-gate 
9787c478bd9Sstevel@tonic-gate /* determine if the type should be forced to hex encoding (non-ascii) */
9797c478bd9Sstevel@tonic-gate #define	DEVID_TYPE_BIN_FORCEHEX(b) (	\
9807c478bd9Sstevel@tonic-gate 	((b) == DEVID_SCSI3_WWN) ||	\
9817c478bd9Sstevel@tonic-gate 	((b) == DEVID_SCSI3_VPD_EUI) ||	\
9827c478bd9Sstevel@tonic-gate 	((b) == DEVID_SCSI3_VPD_NAA) ||	\
9837c478bd9Sstevel@tonic-gate 	((b) == DEVID_FAB))
9847c478bd9Sstevel@tonic-gate 
9857c478bd9Sstevel@tonic-gate /* determine if the type is from a scsi3 vpd */
9867c478bd9Sstevel@tonic-gate #define	IS_DEVID_SCSI3_VPD_TYPE(b) (	\
9877c478bd9Sstevel@tonic-gate 	((b) == DEVID_SCSI3_VPD_T10) ||	\
9887c478bd9Sstevel@tonic-gate 	((b) == DEVID_SCSI3_VPD_EUI) ||	\
9897c478bd9Sstevel@tonic-gate 	((b) == DEVID_SCSI3_VPD_NAA))
9907c478bd9Sstevel@tonic-gate 
9917c478bd9Sstevel@tonic-gate /* convert rev field from binary to ascii (only supports 10 revs) */
9927c478bd9Sstevel@tonic-gate #define	DEVID_REV_BINTOASCII(b) (b + '0')
9937c478bd9Sstevel@tonic-gate 
9947c478bd9Sstevel@tonic-gate /* convert rev field from ascii to binary (only supports 10 revs) */
9957c478bd9Sstevel@tonic-gate #define	DEVID_REV_ASCIITOBIN(c) (c - '0')
9967c478bd9Sstevel@tonic-gate 
9977c478bd9Sstevel@tonic-gate /* name of devid property */
9987c478bd9Sstevel@tonic-gate #define	DEVID_PROP_NAME	"devid"
9997c478bd9Sstevel@tonic-gate 
10007c478bd9Sstevel@tonic-gate /*
10017c478bd9Sstevel@tonic-gate  * prop_name used by pci_{save,restore}_config_regs()
10027c478bd9Sstevel@tonic-gate  */
10037c478bd9Sstevel@tonic-gate #define	SAVED_CONFIG_REGS "pci-config-regs"
10047c478bd9Sstevel@tonic-gate #define	SAVED_CONFIG_REGS_MASK "pcie-config-regs-mask"
10057c478bd9Sstevel@tonic-gate #define	SAVED_CONFIG_REGS_CAPINFO "pci-cap-info"
10067c478bd9Sstevel@tonic-gate 
10077c478bd9Sstevel@tonic-gate typedef struct pci_config_header_state {
10087c478bd9Sstevel@tonic-gate 	uint16_t	chs_command;
10097c478bd9Sstevel@tonic-gate 	uint8_t		chs_cache_line_size;
10107c478bd9Sstevel@tonic-gate 	uint8_t		chs_latency_timer;
10117c478bd9Sstevel@tonic-gate 	uint8_t		chs_header_type;
10127c478bd9Sstevel@tonic-gate 	uint8_t		chs_sec_latency_timer;
10137c478bd9Sstevel@tonic-gate 	uint8_t		chs_bridge_control;
10147c478bd9Sstevel@tonic-gate 	uint32_t	chs_base0;
10157c478bd9Sstevel@tonic-gate 	uint32_t	chs_base1;
10167c478bd9Sstevel@tonic-gate 	uint32_t	chs_base2;
10177c478bd9Sstevel@tonic-gate 	uint32_t	chs_base3;
10187c478bd9Sstevel@tonic-gate 	uint32_t	chs_base4;
10197c478bd9Sstevel@tonic-gate 	uint32_t	chs_base5;
10207c478bd9Sstevel@tonic-gate } pci_config_header_state_t;
10217c478bd9Sstevel@tonic-gate 
10227c478bd9Sstevel@tonic-gate #ifdef _KERNEL
10237c478bd9Sstevel@tonic-gate 
10247c478bd9Sstevel@tonic-gate typedef struct pci_cap_save_desc {
10257c478bd9Sstevel@tonic-gate 	uint16_t	cap_offset;
10267c478bd9Sstevel@tonic-gate 	uint16_t	cap_id;
10277c478bd9Sstevel@tonic-gate 	uint32_t	cap_nregs;
10287c478bd9Sstevel@tonic-gate } pci_cap_save_desc_t;
10297c478bd9Sstevel@tonic-gate 
10307c478bd9Sstevel@tonic-gate typedef struct pci_cap_entry {
10317c478bd9Sstevel@tonic-gate 	uint16_t		cap_id;
10327c478bd9Sstevel@tonic-gate 	uint32_t		cap_ndwords;
10337c478bd9Sstevel@tonic-gate 	uint32_t (*cap_save_func)(ddi_acc_handle_t confhdl, uint16_t cap_ptr,
10347c478bd9Sstevel@tonic-gate 	    uint32_t *regbuf, uint32_t ndwords);
10357c478bd9Sstevel@tonic-gate } pci_cap_entry_t;
10367c478bd9Sstevel@tonic-gate 
10377c478bd9Sstevel@tonic-gate #endif /* _KERNEL */
10387c478bd9Sstevel@tonic-gate 
10397c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
10407c478bd9Sstevel@tonic-gate }
10417c478bd9Sstevel@tonic-gate #endif
10427c478bd9Sstevel@tonic-gate 
10437c478bd9Sstevel@tonic-gate #endif	/* _SYS_DDI_IMPLDEFS_H */
1044