xref: /titanic_53/usr/src/uts/common/sys/epm.h (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #ifndef	_SYS_EPM_H
28*7c478bd9Sstevel@tonic-gate #define	_SYS_EPM_H
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
31*7c478bd9Sstevel@tonic-gate 
32*7c478bd9Sstevel@tonic-gate #include <sys/pm.h>
33*7c478bd9Sstevel@tonic-gate #include <sys/dditypes.h>
34*7c478bd9Sstevel@tonic-gate #include <sys/devops.h>
35*7c478bd9Sstevel@tonic-gate #include <sys/ddi_impldefs.h>
36*7c478bd9Sstevel@tonic-gate #include <sys/taskq.h>
37*7c478bd9Sstevel@tonic-gate 
38*7c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
39*7c478bd9Sstevel@tonic-gate extern "C" {
40*7c478bd9Sstevel@tonic-gate #endif
41*7c478bd9Sstevel@tonic-gate 
42*7c478bd9Sstevel@tonic-gate #ifdef	_KERNEL
43*7c478bd9Sstevel@tonic-gate 
44*7c478bd9Sstevel@tonic-gate /*
45*7c478bd9Sstevel@tonic-gate  * epm.h:	Function prototypes and data structs for kernel pm functions.
46*7c478bd9Sstevel@tonic-gate  */
47*7c478bd9Sstevel@tonic-gate 
48*7c478bd9Sstevel@tonic-gate void e_pm_props(dev_info_t *);
49*7c478bd9Sstevel@tonic-gate int e_new_pm_props(dev_info_t *);
50*7c478bd9Sstevel@tonic-gate 
51*7c478bd9Sstevel@tonic-gate #define	PM_LEVEL_UPONLY (-2)	/* only raise power level */
52*7c478bd9Sstevel@tonic-gate #define	PM_LEVEL_DOWNONLY (-3)	/* only lower power level */
53*7c478bd9Sstevel@tonic-gate #define	PM_LEVEL_EXACT (-4)	/* wants exact power level */
54*7c478bd9Sstevel@tonic-gate 
55*7c478bd9Sstevel@tonic-gate /*
56*7c478bd9Sstevel@tonic-gate  * Values used by e_pm_props and friends, found in devi_pm_flags
57*7c478bd9Sstevel@tonic-gate  */
58*7c478bd9Sstevel@tonic-gate #define	PMC_NEEDS_SR		0x00001	/* do suspend/resume despite no "reg" */
59*7c478bd9Sstevel@tonic-gate #define	PMC_NO_SR		0x00002	/* don't suspend/resume despite "reg" */
60*7c478bd9Sstevel@tonic-gate #define	PMC_PARENTAL_SR		0x00004	/* call up tree to suspend/resume */
61*7c478bd9Sstevel@tonic-gate #define	PMC_WANTS_NOTIFY	0x00008	/* notify if child pwr level changes */
62*7c478bd9Sstevel@tonic-gate #define	PMC_BC			0x00010	/* no pm-components, backwards compat */
63*7c478bd9Sstevel@tonic-gate #define	PMC_COMPONENTS_DONE	0x00020 /* parsed pm-components */
64*7c478bd9Sstevel@tonic-gate #define	PMC_COMPONENTS_FAILED	0x00040 /* failed parsing pm-components */
65*7c478bd9Sstevel@tonic-gate #define	PMC_SUSPENDED		0x00080 /* device has been suspended */
66*7c478bd9Sstevel@tonic-gate #define	PMC_DEF_THRESH		0x00100 /* thresholds are default */
67*7c478bd9Sstevel@tonic-gate #define	PMC_DEV_THRESH		0x00200 /* SET_THRESHOLD ioctl seen */
68*7c478bd9Sstevel@tonic-gate #define	PMC_COMP_THRESH		0x00400 /* relative threshold set */
69*7c478bd9Sstevel@tonic-gate #define	PMC_NEXDEF_THRESH	0x00800 /* relative threshold set for nexus */
70*7c478bd9Sstevel@tonic-gate #define	PMC_NOPMKID		0x01000 /* non-pm'd child of pm'd parent */
71*7c478bd9Sstevel@tonic-gate #define	PMC_NO_INVOL		0x02000 /* no pm without driver's consent */
72*7c478bd9Sstevel@tonic-gate #define	PMC_VOLPMD		0x04000 /* went down voluntarily */
73*7c478bd9Sstevel@tonic-gate #define	PMC_SKIP_BRINGUP	0x08000 /* Skipped a dependency bringup */
74*7c478bd9Sstevel@tonic-gate 
75*7c478bd9Sstevel@tonic-gate /*
76*7c478bd9Sstevel@tonic-gate  * A node which is the console frame buffer, and should not be powered down
77*7c478bd9Sstevel@tonic-gate  * automatically because the OBP driver doesn't know how to power it back up
78*7c478bd9Sstevel@tonic-gate  * before using it  (can remove this when prom calls back into kernel to do
79*7c478bd9Sstevel@tonic-gate  * io to console).
80*7c478bd9Sstevel@tonic-gate  */
81*7c478bd9Sstevel@tonic-gate #define	PMC_CONSOLE_FB		0x10000	/* console framebuffer */
82*7c478bd9Sstevel@tonic-gate #define	PMC_NOINVOL_DONE	0x20000 /* processed by pm_noinvol_specd() */
83*7c478bd9Sstevel@tonic-gate #define	PMC_DRIVER_REMOVED	0x40000 /* driver is removed	*/
84*7c478bd9Sstevel@tonic-gate 
85*7c478bd9Sstevel@tonic-gate #define	PMC_THRESH_ALL	(PMC_DEF_THRESH | PMC_DEV_THRESH | \
86*7c478bd9Sstevel@tonic-gate     PMC_COMP_THRESH | PMC_NEXDEF_THRESH)
87*7c478bd9Sstevel@tonic-gate #define	PMC_THRESH_NONE	~(PMC_THRESH_ALL)
88*7c478bd9Sstevel@tonic-gate 
89*7c478bd9Sstevel@tonic-gate /* Flags for the component */
90*7c478bd9Sstevel@tonic-gate #define	PM_POWER_OP		0x00001	/* set power in process */
91*7c478bd9Sstevel@tonic-gate #define	PM_PHC_WHILE_SET_POWER	0x00002	/* phc and set power deadlock */
92*7c478bd9Sstevel@tonic-gate 
93*7c478bd9Sstevel@tonic-gate /*
94*7c478bd9Sstevel@tonic-gate  * One of these is attached to each devinfo that is autopm'd.
95*7c478bd9Sstevel@tonic-gate  */
96*7c478bd9Sstevel@tonic-gate typedef struct pm_scan {
97*7c478bd9Sstevel@tonic-gate 	int		ps_idle_down;	/* PMID_XXX flags */
98*7c478bd9Sstevel@tonic-gate 	int		ps_scan_flags;	/* scan flags, defined below */
99*7c478bd9Sstevel@tonic-gate 	timeout_id_t	ps_scan_id;	/* per dip scan timeout id */
100*7c478bd9Sstevel@tonic-gate } pm_scan_t;
101*7c478bd9Sstevel@tonic-gate 
102*7c478bd9Sstevel@tonic-gate /*
103*7c478bd9Sstevel@tonic-gate  * ps_scan_flags may take the following values, plus possibly
104*7c478bd9Sstevel@tonic-gate  * more defined.
105*7c478bd9Sstevel@tonic-gate  */
106*7c478bd9Sstevel@tonic-gate #define	PM_SCANNING		0x100	/* scanning: pm_scan_dev is active */
107*7c478bd9Sstevel@tonic-gate #define	PM_SCAN_AGAIN		0x200
108*7c478bd9Sstevel@tonic-gate #define	PM_SCAN_STOP		0x400
109*7c478bd9Sstevel@tonic-gate #define	PM_SCAN_DISPATCHED	0x800
110*7c478bd9Sstevel@tonic-gate 
111*7c478bd9Sstevel@tonic-gate #define	PM_MIN_SCAN	((clock_t)15)	/* Minimum scan interval in seconds */
112*7c478bd9Sstevel@tonic-gate 
113*7c478bd9Sstevel@tonic-gate /*
114*7c478bd9Sstevel@tonic-gate  * Power management component definitions, used for tracking idleness of
115*7c478bd9Sstevel@tonic-gate  * devices.  An array of these hangs off the devi_pm_components member of the
116*7c478bd9Sstevel@tonic-gate  * dev_info struct (if initialized by driver and/or auto-pm)
117*7c478bd9Sstevel@tonic-gate  * The array of these structs is followed in the same kmem_zalloc'd chunk by
118*7c478bd9Sstevel@tonic-gate  * the names pointed to by the structs.
119*7c478bd9Sstevel@tonic-gate  */
120*7c478bd9Sstevel@tonic-gate 
121*7c478bd9Sstevel@tonic-gate /*
122*7c478bd9Sstevel@tonic-gate  * This (sub-)struct contains all the info extracted from the pm-components
123*7c478bd9Sstevel@tonic-gate  * property for each component (name of component, names and values of power
124*7c478bd9Sstevel@tonic-gate  * levels supported).  It is in a separate structure to allow it to be handled
125*7c478bd9Sstevel@tonic-gate  * as a struct assignment.
126*7c478bd9Sstevel@tonic-gate  */
127*7c478bd9Sstevel@tonic-gate typedef struct pm_comp {
128*7c478bd9Sstevel@tonic-gate 	char 	*pmc_name;		/* name of component */
129*7c478bd9Sstevel@tonic-gate 	int	pmc_numlevels;		/* number of power levels supported */
130*7c478bd9Sstevel@tonic-gate 	int	*pmc_lvals;		/* numerical values of levels */
131*7c478bd9Sstevel@tonic-gate 	int	*pmc_thresh;		/* thresholds in secs, last INT_MAX */
132*7c478bd9Sstevel@tonic-gate 	char	**pmc_lnames;		/* human readable names of levels */
133*7c478bd9Sstevel@tonic-gate 	/*
134*7c478bd9Sstevel@tonic-gate 	 * This part is just bookkeeping for the storage space involved above
135*7c478bd9Sstevel@tonic-gate 	 * used for copying and freeing the struct members.  This because C
136*7c478bd9Sstevel@tonic-gate 	 * is really an assembler at heart.
137*7c478bd9Sstevel@tonic-gate 	 */
138*7c478bd9Sstevel@tonic-gate 	size_t	pmc_name_sz;		/* size of name string		*/
139*7c478bd9Sstevel@tonic-gate 	char	*pmc_lname_buf;		/* buffer holding *pmc_lnames	*/
140*7c478bd9Sstevel@tonic-gate 	size_t	pmc_lnames_sz;		/* total size of pmc_lname_buf	*/
141*7c478bd9Sstevel@tonic-gate } pm_comp_t;
142*7c478bd9Sstevel@tonic-gate 
143*7c478bd9Sstevel@tonic-gate /*
144*7c478bd9Sstevel@tonic-gate  * Here we have the rest of what we need to know about a component.
145*7c478bd9Sstevel@tonic-gate  */
146*7c478bd9Sstevel@tonic-gate typedef struct pm_component {
147*7c478bd9Sstevel@tonic-gate 	uint_t pmc_flags;		/* flags this component */
148*7c478bd9Sstevel@tonic-gate 	uint_t pmc_busycount;		/* for nesting busy calls */
149*7c478bd9Sstevel@tonic-gate 	time_t pmc_timestamp;		/* timestamp */
150*7c478bd9Sstevel@tonic-gate 	uint_t pmc_norm_pwr;		/* normal power index (or value) */
151*7c478bd9Sstevel@tonic-gate 	int pmc_cur_pwr;		/* current power index (or value)  */
152*7c478bd9Sstevel@tonic-gate 	int pmc_phc_pwr;		/* prev. value of curpwr (deadlock) */
153*7c478bd9Sstevel@tonic-gate 	pm_comp_t pmc_comp;		/* component description */
154*7c478bd9Sstevel@tonic-gate } pm_component_t;
155*7c478bd9Sstevel@tonic-gate 
156*7c478bd9Sstevel@tonic-gate /*
157*7c478bd9Sstevel@tonic-gate  * All members of this struct are protected by PM_LOCK_DIP(dip).
158*7c478bd9Sstevel@tonic-gate  *
159*7c478bd9Sstevel@tonic-gate  * kidsupcnt counts (the number of components of new-style children at non-zero
160*7c478bd9Sstevel@tonic-gate  * level (unknown counts as non-zero)) + (the number of old-style children with
161*7c478bd9Sstevel@tonic-gate  * component 0 at non-zero level) for parents that have not asked for
162*7c478bd9Sstevel@tonic-gate  * notifcation.  When kidsupcnt is 0 for a nexus node, then pm scans it,
163*7c478bd9Sstevel@tonic-gate  * otherwise it leaves it alone.
164*7c478bd9Sstevel@tonic-gate  * Parents that ask for notification always get get scanned,
165*7c478bd9Sstevel@tonic-gate  * so we keep their kidsupcnt at zero.
166*7c478bd9Sstevel@tonic-gate  */
167*7c478bd9Sstevel@tonic-gate typedef struct pm_info {
168*7c478bd9Sstevel@tonic-gate 	uint_t		pmi_dev_pm_state; /* PM state of a device */
169*7c478bd9Sstevel@tonic-gate 	int		pmi_clone;	/* owner for direct pm'd devs */
170*7c478bd9Sstevel@tonic-gate 	int		pmi_levels[2];	/* storage space for 2 levels */
171*7c478bd9Sstevel@tonic-gate 	int		*pmi_lp;	/* storage space for >2 levels */
172*7c478bd9Sstevel@tonic-gate 	kcondvar_t	pmi_cv;		/* condvar for direct PM access */
173*7c478bd9Sstevel@tonic-gate } pm_info_t;
174*7c478bd9Sstevel@tonic-gate 
175*7c478bd9Sstevel@tonic-gate /*
176*7c478bd9Sstevel@tonic-gate  * Work request structure for the dependency processing thread.
177*7c478bd9Sstevel@tonic-gate  */
178*7c478bd9Sstevel@tonic-gate typedef struct pm_dep_wk {
179*7c478bd9Sstevel@tonic-gate 	int		pdw_type;		/* Type of request */
180*7c478bd9Sstevel@tonic-gate 	int		pdw_wait;		/* caller waits for result */
181*7c478bd9Sstevel@tonic-gate 	int		pdw_done;		/* set when req is done */
182*7c478bd9Sstevel@tonic-gate 	int		pdw_ret;		/* return value to caller */
183*7c478bd9Sstevel@tonic-gate 	int		pdw_pwr;		/* pwr level of keeper */
184*7c478bd9Sstevel@tonic-gate 	kcondvar_t	pdw_cv;			/* cv to wake up caller */
185*7c478bd9Sstevel@tonic-gate 	struct		pm_dep_wk *pdw_next;	/* next element */
186*7c478bd9Sstevel@tonic-gate 	char		*pdw_keeper;
187*7c478bd9Sstevel@tonic-gate 	char		*pdw_kept;
188*7c478bd9Sstevel@tonic-gate } pm_dep_wk_t;
189*7c478bd9Sstevel@tonic-gate 
190*7c478bd9Sstevel@tonic-gate /*
191*7c478bd9Sstevel@tonic-gate  * Types of work, depends on when it gets called:
192*7c478bd9Sstevel@tonic-gate  */
193*7c478bd9Sstevel@tonic-gate #define	PM_DEP_WK_POWER_ON		1	/* power on */
194*7c478bd9Sstevel@tonic-gate #define	PM_DEP_WK_POWER_OFF		2	/* power off */
195*7c478bd9Sstevel@tonic-gate #define	PM_DEP_WK_DETACH		3	/* detach */
196*7c478bd9Sstevel@tonic-gate #define	PM_DEP_WK_REMOVE_DEP		4	/* dependency removed */
197*7c478bd9Sstevel@tonic-gate #define	PM_DEP_WK_BRINGUP_SELF		5	/* released from direct PM */
198*7c478bd9Sstevel@tonic-gate #define	PM_DEP_WK_RECORD_KEEPER		6	/* PM_ADD_DEPENDENT */
199*7c478bd9Sstevel@tonic-gate #define	PM_DEP_WK_RECORD_KEEPER_PROP	7	/* PM_ADD_DEPENDENT_PROP */
200*7c478bd9Sstevel@tonic-gate #define	PM_DEP_WK_KEPT			8	/* dep. work as a kept */
201*7c478bd9Sstevel@tonic-gate #define	PM_DEP_WK_KEEPER		9	/* dep. work as a keeper */
202*7c478bd9Sstevel@tonic-gate #define	PM_DEP_WK_ATTACH		10	/* when dip is attached */
203*7c478bd9Sstevel@tonic-gate #define	PM_DEP_WK_CHECK_KEPT		11	/* check if this is a kept */
204*7c478bd9Sstevel@tonic-gate #define	PM_DEP_WK_CPR_SUSPEND		12	/* Suspend dep. during CPR */
205*7c478bd9Sstevel@tonic-gate #define	PM_DEP_WK_CPR_RESUME		13	/* Resume dep. after CPR */
206*7c478bd9Sstevel@tonic-gate 
207*7c478bd9Sstevel@tonic-gate /*
208*7c478bd9Sstevel@tonic-gate  * Wait for dependency work to finish or not.
209*7c478bd9Sstevel@tonic-gate  */
210*7c478bd9Sstevel@tonic-gate #define	PM_DEP_WAIT	1
211*7c478bd9Sstevel@tonic-gate #define	PM_DEP_NOWAIT	0
212*7c478bd9Sstevel@tonic-gate 
213*7c478bd9Sstevel@tonic-gate typedef enum pm_canblock
214*7c478bd9Sstevel@tonic-gate {
215*7c478bd9Sstevel@tonic-gate 	PM_CANBLOCK_BLOCK,	/* wait for controlling process action */
216*7c478bd9Sstevel@tonic-gate 	PM_CANBLOCK_FAIL,	/* don't wait, fail request */
217*7c478bd9Sstevel@tonic-gate 	PM_CANBLOCK_BYPASS	/* don't wait, ignore controlling process */
218*7c478bd9Sstevel@tonic-gate } pm_canblock_t;
219*7c478bd9Sstevel@tonic-gate 
220*7c478bd9Sstevel@tonic-gate /*
221*7c478bd9Sstevel@tonic-gate  * The power request struct uses for the DDI_CTLOPS_POWER busctl.
222*7c478bd9Sstevel@tonic-gate  *
223*7c478bd9Sstevel@tonic-gate  * Note: When changing this enum it is necessary to maintain binary
224*7c478bd9Sstevel@tonic-gate  * compatibility with older versions.  To insure that, add new values only
225*7c478bd9Sstevel@tonic-gate  * at the end and refrain from deleting any existing values.
226*7c478bd9Sstevel@tonic-gate  */
227*7c478bd9Sstevel@tonic-gate typedef enum {
228*7c478bd9Sstevel@tonic-gate 	PMR_SET_POWER = 1,		/* called ddi_power (obsolete)	*/
229*7c478bd9Sstevel@tonic-gate 	PMR_SUSPEND,			/* parental suspend		*/
230*7c478bd9Sstevel@tonic-gate 	PMR_RESUME,			/* parental resume		*/
231*7c478bd9Sstevel@tonic-gate 	PMR_PRE_SET_POWER,		/* parent's "pre" notification	*/
232*7c478bd9Sstevel@tonic-gate 	PMR_POST_SET_POWER,		/* parent's "post" notification	*/
233*7c478bd9Sstevel@tonic-gate 	PMR_PPM_SET_POWER,		/* platform pm set power	*/
234*7c478bd9Sstevel@tonic-gate 	PMR_PPM_ATTACH,			/* ppm attach notify - unused	*/
235*7c478bd9Sstevel@tonic-gate 	PMR_PPM_DETACH,			/* ppm detach notify - unused   */
236*7c478bd9Sstevel@tonic-gate 	PMR_PPM_POWER_CHANGE_NOTIFY,	/* ppm level change notify	*/
237*7c478bd9Sstevel@tonic-gate 	PMR_REPORT_PMCAP,		/* report pm capability		*/
238*7c478bd9Sstevel@tonic-gate 	PMR_CHANGED_POWER,		/* parent's power_has_changed notif. */
239*7c478bd9Sstevel@tonic-gate 	PMR_PPM_PRE_PROBE,		/* ppm pre probe notify		*/
240*7c478bd9Sstevel@tonic-gate 	PMR_PPM_POST_PROBE,		/* ppm post probe notify	*/
241*7c478bd9Sstevel@tonic-gate 	PMR_PPM_PRE_ATTACH,		/* ppm pre attach notify	*/
242*7c478bd9Sstevel@tonic-gate 	PMR_PPM_POST_ATTACH,		/* ppm post pm attach notify	*/
243*7c478bd9Sstevel@tonic-gate 	PMR_PPM_PRE_DETACH,		/* ppm pre pm detach notify	*/
244*7c478bd9Sstevel@tonic-gate 	PMR_PPM_POST_DETACH,		/* ppm post pm detach notify	*/
245*7c478bd9Sstevel@tonic-gate 	PMR_PPM_UNMANAGE,		/* device being unmanaged	*/
246*7c478bd9Sstevel@tonic-gate 	PMR_PPM_PRE_RESUME,		/* ppm resume notify		*/
247*7c478bd9Sstevel@tonic-gate 	PMR_PPM_ALL_LOWEST,		/* ppm all lowest power notify	*/
248*7c478bd9Sstevel@tonic-gate 	PMR_PPM_LOCK_POWER,		/* ppm lock power		*/
249*7c478bd9Sstevel@tonic-gate 	PMR_PPM_UNLOCK_POWER,		/* ppm unlock power		*/
250*7c478bd9Sstevel@tonic-gate 	PMR_PPM_TRY_LOCK_POWER,		/* ppm try lock power		*/
251*7c478bd9Sstevel@tonic-gate 	PMR_PPM_INIT_CHILD,		/* ppm init child notify	*/
252*7c478bd9Sstevel@tonic-gate 	PMR_PPM_UNINIT_CHILD,		/* ppm uninit child notify	*/
253*7c478bd9Sstevel@tonic-gate 	PMR_PPM_POWER_LOCK_OWNER	/* ppm power lock owner's address */
254*7c478bd9Sstevel@tonic-gate } pm_request_type;
255*7c478bd9Sstevel@tonic-gate 
256*7c478bd9Sstevel@tonic-gate /*
257*7c478bd9Sstevel@tonic-gate  * When changing the elements of the union below it is necessary to
258*7c478bd9Sstevel@tonic-gate  * maintain binary compatibility with older versions.  Refrain from
259*7c478bd9Sstevel@tonic-gate  * deleting existing elements of the union or modifying their contents.
260*7c478bd9Sstevel@tonic-gate  * Avoid increasing the total size of this structure if new elements
261*7c478bd9Sstevel@tonic-gate  * must be added.
262*7c478bd9Sstevel@tonic-gate  */
263*7c478bd9Sstevel@tonic-gate typedef struct power_req {
264*7c478bd9Sstevel@tonic-gate 	pm_request_type request_type;
265*7c478bd9Sstevel@tonic-gate 	union req {
266*7c478bd9Sstevel@tonic-gate 		/*
267*7c478bd9Sstevel@tonic-gate 		 * PMR_SET_POWER (obsolete)
268*7c478bd9Sstevel@tonic-gate 		 */
269*7c478bd9Sstevel@tonic-gate 		struct set_power_req {
270*7c478bd9Sstevel@tonic-gate 			dev_info_t	*who;
271*7c478bd9Sstevel@tonic-gate 			int		cmpt;
272*7c478bd9Sstevel@tonic-gate 			int		level;
273*7c478bd9Sstevel@tonic-gate 		} set_power_req;
274*7c478bd9Sstevel@tonic-gate 		/*
275*7c478bd9Sstevel@tonic-gate 		 * PMR_SUSPEND
276*7c478bd9Sstevel@tonic-gate 		 */
277*7c478bd9Sstevel@tonic-gate 		struct suspend_req {
278*7c478bd9Sstevel@tonic-gate 			dev_info_t	*who;
279*7c478bd9Sstevel@tonic-gate 			ddi_detach_cmd_t cmd;
280*7c478bd9Sstevel@tonic-gate 		} suspend_req;
281*7c478bd9Sstevel@tonic-gate 		/*
282*7c478bd9Sstevel@tonic-gate 		 * PMR_PPM_PRE_RESUME or PMR_RESUME
283*7c478bd9Sstevel@tonic-gate 		 */
284*7c478bd9Sstevel@tonic-gate 		struct resume_req {
285*7c478bd9Sstevel@tonic-gate 			dev_info_t	*who;
286*7c478bd9Sstevel@tonic-gate 			ddi_attach_cmd_t cmd;
287*7c478bd9Sstevel@tonic-gate 		} resume_req;
288*7c478bd9Sstevel@tonic-gate 		/*
289*7c478bd9Sstevel@tonic-gate 		 * PMR_PRE_SET_POWER
290*7c478bd9Sstevel@tonic-gate 		 */
291*7c478bd9Sstevel@tonic-gate 		struct pre_set_power_req {
292*7c478bd9Sstevel@tonic-gate 			dev_info_t	*who;
293*7c478bd9Sstevel@tonic-gate 			int		cmpt;
294*7c478bd9Sstevel@tonic-gate 			int		old_level;
295*7c478bd9Sstevel@tonic-gate 			int		new_level;
296*7c478bd9Sstevel@tonic-gate 		} pre_set_power_req;
297*7c478bd9Sstevel@tonic-gate 		/*
298*7c478bd9Sstevel@tonic-gate 		 * PMR_POST_SET_POWER
299*7c478bd9Sstevel@tonic-gate 		 */
300*7c478bd9Sstevel@tonic-gate 		struct post_set_power_req {
301*7c478bd9Sstevel@tonic-gate 			dev_info_t	*who;
302*7c478bd9Sstevel@tonic-gate 			int		cmpt;
303*7c478bd9Sstevel@tonic-gate 			int		old_level;
304*7c478bd9Sstevel@tonic-gate 			int		new_level;
305*7c478bd9Sstevel@tonic-gate 			int		result;		/* driver's return */
306*7c478bd9Sstevel@tonic-gate 		} post_set_power_req;
307*7c478bd9Sstevel@tonic-gate 		/*
308*7c478bd9Sstevel@tonic-gate 		 * PMR_PPM_SET_POWER
309*7c478bd9Sstevel@tonic-gate 		 */
310*7c478bd9Sstevel@tonic-gate 		struct ppm_set_power_req {
311*7c478bd9Sstevel@tonic-gate 			dev_info_t	*who;
312*7c478bd9Sstevel@tonic-gate 			int		cmpt;
313*7c478bd9Sstevel@tonic-gate 			int		old_level;
314*7c478bd9Sstevel@tonic-gate 			int		new_level;
315*7c478bd9Sstevel@tonic-gate 			pm_canblock_t	canblock;
316*7c478bd9Sstevel@tonic-gate 			void		*cookie;
317*7c478bd9Sstevel@tonic-gate 		} ppm_set_power_req;
318*7c478bd9Sstevel@tonic-gate 		/*
319*7c478bd9Sstevel@tonic-gate 		 * PMR_PPM_POWER_CHANGE_NOTIFY
320*7c478bd9Sstevel@tonic-gate 		 */
321*7c478bd9Sstevel@tonic-gate 		struct ppm_notify_level_req {
322*7c478bd9Sstevel@tonic-gate 			dev_info_t	*who;
323*7c478bd9Sstevel@tonic-gate 			int		cmpt;
324*7c478bd9Sstevel@tonic-gate 			int		old_level;
325*7c478bd9Sstevel@tonic-gate 			int		new_level;
326*7c478bd9Sstevel@tonic-gate 		} ppm_notify_level_req;
327*7c478bd9Sstevel@tonic-gate 		/*
328*7c478bd9Sstevel@tonic-gate 		 * PMR_REPORT_PMCAP
329*7c478bd9Sstevel@tonic-gate 		 */
330*7c478bd9Sstevel@tonic-gate 		struct report_pmcap_req {
331*7c478bd9Sstevel@tonic-gate 			dev_info_t	*who;
332*7c478bd9Sstevel@tonic-gate 			int		cap;
333*7c478bd9Sstevel@tonic-gate 			void 		*arg;
334*7c478bd9Sstevel@tonic-gate 		} report_pmcap_req;
335*7c478bd9Sstevel@tonic-gate 		/*
336*7c478bd9Sstevel@tonic-gate 		 * PMR_CHANGED_POWER
337*7c478bd9Sstevel@tonic-gate 		 */
338*7c478bd9Sstevel@tonic-gate 		struct changed_power_req {
339*7c478bd9Sstevel@tonic-gate 			dev_info_t	*who;
340*7c478bd9Sstevel@tonic-gate 			int		cmpt;
341*7c478bd9Sstevel@tonic-gate 			int		old_level;
342*7c478bd9Sstevel@tonic-gate 			int		new_level;
343*7c478bd9Sstevel@tonic-gate 			int		result;
344*7c478bd9Sstevel@tonic-gate 		} changed_power_req;
345*7c478bd9Sstevel@tonic-gate 		/*
346*7c478bd9Sstevel@tonic-gate 		 * PMR_PPM_PRE_PROBE, PMR_PPM_POST_PROBE, PMR_PPM_PRE_ATTACH,
347*7c478bd9Sstevel@tonic-gate 		 * PMR_PPM_POST_ATTACH, PMR_PPM_PRE_DETACH, PMR_PPM_POST_DETACH
348*7c478bd9Sstevel@tonic-gate 		 * PMR_PPM_INIT_CHILD, PMR_PPM_UNINIT_CHILD, or PMR_PPM_UNMANAGE
349*7c478bd9Sstevel@tonic-gate 		 */
350*7c478bd9Sstevel@tonic-gate 		struct ppm_config_req {
351*7c478bd9Sstevel@tonic-gate 			dev_info_t	*who;
352*7c478bd9Sstevel@tonic-gate 			int		result;		/* post only */
353*7c478bd9Sstevel@tonic-gate 		} ppm_config_req;
354*7c478bd9Sstevel@tonic-gate 		/*
355*7c478bd9Sstevel@tonic-gate 		 * PMR_PPM_ALL_LOWEST
356*7c478bd9Sstevel@tonic-gate 		 */
357*7c478bd9Sstevel@tonic-gate 		struct ppm_all_lowest_req {
358*7c478bd9Sstevel@tonic-gate 			int		mode;
359*7c478bd9Sstevel@tonic-gate 		} ppm_all_lowest_req;
360*7c478bd9Sstevel@tonic-gate 		/*
361*7c478bd9Sstevel@tonic-gate 		 * PMR_PPM_LOCK_POWER, PMR_PPM_TRY_LOCK_POWER
362*7c478bd9Sstevel@tonic-gate 		 */
363*7c478bd9Sstevel@tonic-gate 		struct ppm_lock_power_req {
364*7c478bd9Sstevel@tonic-gate 			dev_info_t	*who;
365*7c478bd9Sstevel@tonic-gate 			int		*circp;
366*7c478bd9Sstevel@tonic-gate 		} ppm_lock_power_req;
367*7c478bd9Sstevel@tonic-gate 		/*
368*7c478bd9Sstevel@tonic-gate 		 * PMR_PPM_UNLOCK_POWER
369*7c478bd9Sstevel@tonic-gate 		 */
370*7c478bd9Sstevel@tonic-gate 		struct ppm_unlock_power_req {
371*7c478bd9Sstevel@tonic-gate 			dev_info_t	*who;
372*7c478bd9Sstevel@tonic-gate 			int		circ;
373*7c478bd9Sstevel@tonic-gate 		} ppm_unlock_power_req;
374*7c478bd9Sstevel@tonic-gate 		/*
375*7c478bd9Sstevel@tonic-gate 		 * PMR_PPM_POWER_LOCK_OWNER
376*7c478bd9Sstevel@tonic-gate 		 */
377*7c478bd9Sstevel@tonic-gate 		struct ppm_power_lock_owner_req {
378*7c478bd9Sstevel@tonic-gate 			dev_info_t	*who;
379*7c478bd9Sstevel@tonic-gate 			kthread_t	*owner;
380*7c478bd9Sstevel@tonic-gate 		} ppm_power_lock_owner_req;
381*7c478bd9Sstevel@tonic-gate 	} req;
382*7c478bd9Sstevel@tonic-gate } power_req_t;
383*7c478bd9Sstevel@tonic-gate 
384*7c478bd9Sstevel@tonic-gate /*
385*7c478bd9Sstevel@tonic-gate  * Structure used by the following bus_power operations:
386*7c478bd9Sstevel@tonic-gate  *
387*7c478bd9Sstevel@tonic-gate  *	BUS_POWER_PRE_NOTIFICATION
388*7c478bd9Sstevel@tonic-gate  *	BUS_POWER_POST_NOTIFICATION
389*7c478bd9Sstevel@tonic-gate  *	BUS_POWER_CHILD_PWRCHG
390*7c478bd9Sstevel@tonic-gate  */
391*7c478bd9Sstevel@tonic-gate typedef struct pm_bp_child_pwrchg {
392*7c478bd9Sstevel@tonic-gate 	dev_info_t	*bpc_dip;	/* dip of the target device */
393*7c478bd9Sstevel@tonic-gate 	char		*bpc_path;	/* path to the target device */
394*7c478bd9Sstevel@tonic-gate 	int		bpc_comp;	/* component changing power */
395*7c478bd9Sstevel@tonic-gate 	int		bpc_olevel;	/* old power level */
396*7c478bd9Sstevel@tonic-gate 	int		bpc_nlevel;	/* new power level */
397*7c478bd9Sstevel@tonic-gate 	void		*bpc_private;	/* PM framework private */
398*7c478bd9Sstevel@tonic-gate } pm_bp_child_pwrchg_t;
399*7c478bd9Sstevel@tonic-gate 
400*7c478bd9Sstevel@tonic-gate /*
401*7c478bd9Sstevel@tonic-gate  * Structure used by the BUS_POWER_NEXUS_PWRUP operation
402*7c478bd9Sstevel@tonic-gate  */
403*7c478bd9Sstevel@tonic-gate typedef struct pm_bp_nexus_pwrup {
404*7c478bd9Sstevel@tonic-gate 	dev_info_t	*bpn_dip;	/* dip of the nexus device */
405*7c478bd9Sstevel@tonic-gate 	int		bpn_comp;	/* component powering up */
406*7c478bd9Sstevel@tonic-gate 	int		bpn_level;	/* new power level */
407*7c478bd9Sstevel@tonic-gate 	void		*bpn_private;	/* PM framework private */
408*7c478bd9Sstevel@tonic-gate } pm_bp_nexus_pwrup_t;
409*7c478bd9Sstevel@tonic-gate 
410*7c478bd9Sstevel@tonic-gate /*
411*7c478bd9Sstevel@tonic-gate  * Structure used by the BUS_POWER_HAS_CHANGED operation
412*7c478bd9Sstevel@tonic-gate  */
413*7c478bd9Sstevel@tonic-gate typedef struct pm_bp_has_changed {
414*7c478bd9Sstevel@tonic-gate 	dev_info_t	*bphc_dip;	/* dip of the target device */
415*7c478bd9Sstevel@tonic-gate 	char		*bphc_path;	/* path to the target device */
416*7c478bd9Sstevel@tonic-gate 	int		bphc_comp;	/* component changing power */
417*7c478bd9Sstevel@tonic-gate 	int		bphc_olevel;	/* old power level */
418*7c478bd9Sstevel@tonic-gate 	int		bphc_nlevel;	/* new power level */
419*7c478bd9Sstevel@tonic-gate 	void		*bphc_private;	/* PM framework private */
420*7c478bd9Sstevel@tonic-gate } pm_bp_has_changed_t;
421*7c478bd9Sstevel@tonic-gate 
422*7c478bd9Sstevel@tonic-gate /*
423*7c478bd9Sstevel@tonic-gate  * Commands indicating which activity is requiring an
424*7c478bd9Sstevel@tonic-gate  * update to the noinvol counters.
425*7c478bd9Sstevel@tonic-gate  */
426*7c478bd9Sstevel@tonic-gate #define	PM_BP_NOINVOL_ATTACH	1
427*7c478bd9Sstevel@tonic-gate #define	PM_BP_NOINVOL_DETACH	2
428*7c478bd9Sstevel@tonic-gate #define	PM_BP_NOINVOL_REMDRV	3
429*7c478bd9Sstevel@tonic-gate #define	PM_BP_NOINVOL_CFB	4
430*7c478bd9Sstevel@tonic-gate #define	PM_BP_NOINVOL_POWER	5
431*7c478bd9Sstevel@tonic-gate 
432*7c478bd9Sstevel@tonic-gate /*
433*7c478bd9Sstevel@tonic-gate  * Structure used by the BUS_POWER_NOINVOL operation.
434*7c478bd9Sstevel@tonic-gate  */
435*7c478bd9Sstevel@tonic-gate typedef struct pm_bp_noinvol {
436*7c478bd9Sstevel@tonic-gate 	dev_info_t	*bpni_dip;	/* dip of the target device */
437*7c478bd9Sstevel@tonic-gate 	char		*bpni_path;	/* path to the target device */
438*7c478bd9Sstevel@tonic-gate 	int		bpni_cmd;	/* how to update the counters */
439*7c478bd9Sstevel@tonic-gate 	int		bpni_volpmd;	/* volpmd of target device */
440*7c478bd9Sstevel@tonic-gate 	int		bpni_wasvolpmd;	/* whether to update volpmd */
441*7c478bd9Sstevel@tonic-gate 	void		*bpni_private;	/* PM framework private */
442*7c478bd9Sstevel@tonic-gate } pm_bp_noinvol_t;
443*7c478bd9Sstevel@tonic-gate 
444*7c478bd9Sstevel@tonic-gate /*
445*7c478bd9Sstevel@tonic-gate  * This struct is used by the code that makes a PMR_PPM_SET_POWER request
446*7c478bd9Sstevel@tonic-gate  * to ppm. Devices that changed power other than the primary device (which
447*7c478bd9Sstevel@tonic-gate  * was requested) are passed back to the pm framework through this
448*7c478bd9Sstevel@tonic-gate  * structure.
449*7c478bd9Sstevel@tonic-gate  */
450*7c478bd9Sstevel@tonic-gate typedef struct pm_ppm_devlist {
451*7c478bd9Sstevel@tonic-gate 	dev_info_t	*ppd_who;
452*7c478bd9Sstevel@tonic-gate 	int		ppd_cmpt;
453*7c478bd9Sstevel@tonic-gate 	int		ppd_old_level;
454*7c478bd9Sstevel@tonic-gate 	int		ppd_new_level;
455*7c478bd9Sstevel@tonic-gate 	struct pm_ppm_devlist	*ppd_next;
456*7c478bd9Sstevel@tonic-gate } pm_ppm_devlist_t;
457*7c478bd9Sstevel@tonic-gate 
458*7c478bd9Sstevel@tonic-gate /*
459*7c478bd9Sstevel@tonic-gate  * This struct is used by the code that brings up parents and notifies
460*7c478bd9Sstevel@tonic-gate  * ppm drivers across probe/attach/detach (pm_pre/post_probe/attach/detach())
461*7c478bd9Sstevel@tonic-gate  */
462*7c478bd9Sstevel@tonic-gate typedef struct pm_ppm_cookie {
463*7c478bd9Sstevel@tonic-gate 	dev_info_t		*ppc_dip;	/* dip of target node */
464*7c478bd9Sstevel@tonic-gate 	dev_info_t		*ppc_pdip;	/* parent's dip */
465*7c478bd9Sstevel@tonic-gate 	dev_info_t		*ppc_ppm;	/* interested ppm driver */
466*7c478bd9Sstevel@tonic-gate 	int			ppc_cmd;	/* attach/detach cmd */
467*7c478bd9Sstevel@tonic-gate } pm_ppm_cookie_t;
468*7c478bd9Sstevel@tonic-gate 
469*7c478bd9Sstevel@tonic-gate /*
470*7c478bd9Sstevel@tonic-gate  * This struct records one dependency (a device keeps another or others up)
471*7c478bd9Sstevel@tonic-gate  * pdr_size includes size of strings.
472*7c478bd9Sstevel@tonic-gate  */
473*7c478bd9Sstevel@tonic-gate typedef struct pm_dep_rec {
474*7c478bd9Sstevel@tonic-gate 	char *pdr_keeper;		/* physpath of device keeping up */
475*7c478bd9Sstevel@tonic-gate 	char *pdr_kept;			/* physpath or property name */
476*7c478bd9Sstevel@tonic-gate 	char **pdr_kept_paths;		/* array of kept devices' paths */
477*7c478bd9Sstevel@tonic-gate 	struct pm_dep_rec *pdr_next;	/* next dependency device */
478*7c478bd9Sstevel@tonic-gate 	size_t pdr_size;		/* size to kmem_free */
479*7c478bd9Sstevel@tonic-gate 	major_t pdr_major;		/* major of kept driver (not props) */
480*7c478bd9Sstevel@tonic-gate 	int pdr_isprop;			/* true if kept is property name */
481*7c478bd9Sstevel@tonic-gate 	int pdr_kept_count;		/* how many kept altogether */
482*7c478bd9Sstevel@tonic-gate 	int pdr_satisfied;		/* true if in force (not properties) */
483*7c478bd9Sstevel@tonic-gate } pm_pdr_t;
484*7c478bd9Sstevel@tonic-gate 
485*7c478bd9Sstevel@tonic-gate 
486*7c478bd9Sstevel@tonic-gate /*
487*7c478bd9Sstevel@tonic-gate  * This struct records threshold information about a single component
488*7c478bd9Sstevel@tonic-gate  */
489*7c478bd9Sstevel@tonic-gate typedef struct pm_thresh_entry {
490*7c478bd9Sstevel@tonic-gate 	int pte_numthresh;
491*7c478bd9Sstevel@tonic-gate 	int *pte_thresh;
492*7c478bd9Sstevel@tonic-gate } pm_pte_t;
493*7c478bd9Sstevel@tonic-gate 
494*7c478bd9Sstevel@tonic-gate /*
495*7c478bd9Sstevel@tonic-gate  * Note that this header and its array of entry structs with their arrays
496*7c478bd9Sstevel@tonic-gate  * of thresholds and string storage for physpath are all kmem_alloced in one
497*7c478bd9Sstevel@tonic-gate  * chunk for easy freeing ptr_size is the size of that chunk
498*7c478bd9Sstevel@tonic-gate  */
499*7c478bd9Sstevel@tonic-gate typedef struct pm_thresh_rec {
500*7c478bd9Sstevel@tonic-gate 	char			*ptr_physpath;	/* identifies node */
501*7c478bd9Sstevel@tonic-gate 	struct pm_thresh_rec	*ptr_next;
502*7c478bd9Sstevel@tonic-gate 	int			ptr_numcomps;	/* number of components */
503*7c478bd9Sstevel@tonic-gate 	size_t			ptr_size;	/* total size for kmem_free */
504*7c478bd9Sstevel@tonic-gate 	pm_pte_t 		*ptr_entries;
505*7c478bd9Sstevel@tonic-gate } pm_thresh_rec_t;
506*7c478bd9Sstevel@tonic-gate 
507*7c478bd9Sstevel@tonic-gate /*
508*7c478bd9Sstevel@tonic-gate  * pmi_dev_pm_state state bits:
509*7c478bd9Sstevel@tonic-gate  */
510*7c478bd9Sstevel@tonic-gate 
511*7c478bd9Sstevel@tonic-gate /*
512*7c478bd9Sstevel@tonic-gate  * a direct-pm device, not scanned, but controlled by a process
513*7c478bd9Sstevel@tonic-gate  */
514*7c478bd9Sstevel@tonic-gate #define	PM_DIRECT	0x1
515*7c478bd9Sstevel@tonic-gate /*
516*7c478bd9Sstevel@tonic-gate  * autopm is suspended while waiting to see if detach succeeds
517*7c478bd9Sstevel@tonic-gate  */
518*7c478bd9Sstevel@tonic-gate #define	PM_DETACHING	0x2
519*7c478bd9Sstevel@tonic-gate 
520*7c478bd9Sstevel@tonic-gate /*
521*7c478bd9Sstevel@tonic-gate  * An all_to_normal operation for an autopm device that is detaching, is
522*7c478bd9Sstevel@tonic-gate  * deferred in case the detach fails.
523*7c478bd9Sstevel@tonic-gate  */
524*7c478bd9Sstevel@tonic-gate #define	PM_ALLNORM_DEFERRED	0x4
525*7c478bd9Sstevel@tonic-gate 
526*7c478bd9Sstevel@tonic-gate #define	PM_GET_PM_INFO(dip) (DEVI(dip)->devi_pm_info)
527*7c478bd9Sstevel@tonic-gate #define	PM_GET_PM_SCAN(dip) (DEVI(dip)->devi_pm_scan)
528*7c478bd9Sstevel@tonic-gate 
529*7c478bd9Sstevel@tonic-gate #define	PM_NUMCMPTS(dip) (DEVI(dip)->devi_pm_num_components)
530*7c478bd9Sstevel@tonic-gate #define	PM_CP(dip, comp) (&DEVI(dip)->devi_pm_components[comp])
531*7c478bd9Sstevel@tonic-gate 
532*7c478bd9Sstevel@tonic-gate /*
533*7c478bd9Sstevel@tonic-gate  * Returns true if the device specified by dip is directly power managed
534*7c478bd9Sstevel@tonic-gate  */
535*7c478bd9Sstevel@tonic-gate #define	PM_ISDIRECT(dip) \
536*7c478bd9Sstevel@tonic-gate 	(((pm_info_t *)PM_GET_PM_INFO(dip))->pmi_dev_pm_state & PM_DIRECT)
537*7c478bd9Sstevel@tonic-gate 
538*7c478bd9Sstevel@tonic-gate /*
539*7c478bd9Sstevel@tonic-gate  * Returns true if the device specified by dip is an old node for which we
540*7c478bd9Sstevel@tonic-gate  * provide backwards compatible behavior (e.g. no pm-components property).
541*7c478bd9Sstevel@tonic-gate  */
542*7c478bd9Sstevel@tonic-gate #define	PM_ISBC(dip) (DEVI(dip)->devi_pm_flags & PMC_BC)
543*7c478bd9Sstevel@tonic-gate 
544*7c478bd9Sstevel@tonic-gate /*
545*7c478bd9Sstevel@tonic-gate  * Returns true if we have skipped a dependency bringup on this dip.
546*7c478bd9Sstevel@tonic-gate  */
547*7c478bd9Sstevel@tonic-gate #define	PM_SKBU(dip) (DEVI(dip)->devi_pm_flags & PMC_SKIP_BRINGUP)
548*7c478bd9Sstevel@tonic-gate 
549*7c478bd9Sstevel@tonic-gate #define	PM_NOT_ALL_LOWEST	0x0	/* not all components are at lowest */
550*7c478bd9Sstevel@tonic-gate #define	PM_ALL_LOWEST		0x1	/* all components are at lowest lvl */
551*7c478bd9Sstevel@tonic-gate 
552*7c478bd9Sstevel@tonic-gate #define	PM_ADDR(dip)	(ddi_get_name_addr(dip) ? ddi_get_name_addr(dip) : "")
553*7c478bd9Sstevel@tonic-gate #define	PM_NAME(dip)	(ddi_binding_name(dip))
554*7c478bd9Sstevel@tonic-gate #define	PM_NODE(dip)	(ddi_node_name(dip))
555*7c478bd9Sstevel@tonic-gate #define	PM_INST(dip)	(ddi_get_instance(dip))
556*7c478bd9Sstevel@tonic-gate #define	PM_DEVICE(dip)	PM_NAME(dip), PM_ADDR(dip), PM_NODE(dip), PM_INST(dip)
557*7c478bd9Sstevel@tonic-gate 
558*7c478bd9Sstevel@tonic-gate #ifdef	DEBUG
559*7c478bd9Sstevel@tonic-gate /*
560*7c478bd9Sstevel@tonic-gate  * Flags passed to PMD to enable debug printfs.  If the same flag is set in
561*7c478bd9Sstevel@tonic-gate  * pm_debug below then the message is printed.  The most generally useful
562*7c478bd9Sstevel@tonic-gate  * ones are the first 3 or 4.
563*7c478bd9Sstevel@tonic-gate  */
564*7c478bd9Sstevel@tonic-gate #define	PMD_ERROR	0x0000001
565*7c478bd9Sstevel@tonic-gate #define	PMD_FAIL	0x0000002
566*7c478bd9Sstevel@tonic-gate #define	PMD_IOCTL	0x0000004
567*7c478bd9Sstevel@tonic-gate #define	PMD_SCAN	0x0000008
568*7c478bd9Sstevel@tonic-gate #define	PMD_RESCAN	0x0000010
569*7c478bd9Sstevel@tonic-gate #define	PMD_REMINFO	0x0000020
570*7c478bd9Sstevel@tonic-gate #define	PMD_NAMETODIP	0x0000040
571*7c478bd9Sstevel@tonic-gate #define	PMD_CLOSE	0x0000080
572*7c478bd9Sstevel@tonic-gate #define	PMD_DIN		0x0000100	/* Dev Is Needed */
573*7c478bd9Sstevel@tonic-gate #define	PMD_PMC		0x0000200	/* for testing with sun4m pmc driver */
574*7c478bd9Sstevel@tonic-gate #define	PMD_PPM		0x0000400
575*7c478bd9Sstevel@tonic-gate #define	PMD_DEP		0x0000800	/* dependency processing */
576*7c478bd9Sstevel@tonic-gate #define	PMD_IDLEDOWN	0x0001000
577*7c478bd9Sstevel@tonic-gate #define	PMD_SET		0x0002000
578*7c478bd9Sstevel@tonic-gate #define	PMD_BRING	0x0004000
579*7c478bd9Sstevel@tonic-gate #define	PMD_ALLNORM	0x0008000
580*7c478bd9Sstevel@tonic-gate #define	PMD_REMDEV	0x0010000
581*7c478bd9Sstevel@tonic-gate #define	PMD_LEVEL	0x0020000
582*7c478bd9Sstevel@tonic-gate #define	PMD_THRESH	0x0040000
583*7c478bd9Sstevel@tonic-gate #define	PMD_DPM		0x0080000	/* Direct Power Management */
584*7c478bd9Sstevel@tonic-gate #define	PMD_NORM	0x0100000
585*7c478bd9Sstevel@tonic-gate #define	PMD_STATS	0x0200000
586*7c478bd9Sstevel@tonic-gate #define	PMD_DEREG	0x0400000
587*7c478bd9Sstevel@tonic-gate #define	PMD_KEEPS	0x0800000
588*7c478bd9Sstevel@tonic-gate #define	PMD_KIDSUP	0x1000000
589*7c478bd9Sstevel@tonic-gate #define	PMD_TCHECK	0x2000000
590*7c478bd9Sstevel@tonic-gate #define	PMD_NOINVOL	0x4000000
591*7c478bd9Sstevel@tonic-gate #define	PMD_CFB		0x8000000	/* console fb pm */
592*7c478bd9Sstevel@tonic-gate #define	PMD_DHR		0x10000000	/* driver hold/rele changes */
593*7c478bd9Sstevel@tonic-gate #define	PMD_PIL		0x20000000	/* print out PIL when calling power */
594*7c478bd9Sstevel@tonic-gate #define	PMD_PHC		0x40000000	/* pm_power_has_changed messages */
595*7c478bd9Sstevel@tonic-gate #define	PMD_LOCK	0x80000000
596*7c478bd9Sstevel@tonic-gate 
597*7c478bd9Sstevel@tonic-gate extern uint_t	pm_debug;
598*7c478bd9Sstevel@tonic-gate extern uint_t	pm_divertdebug;
599*7c478bd9Sstevel@tonic-gate /*PRINTFLIKE1*/
600*7c478bd9Sstevel@tonic-gate extern void	pm_log(const char *fmt, ...) __KPRINTFLIKE(1);
601*7c478bd9Sstevel@tonic-gate 
602*7c478bd9Sstevel@tonic-gate #define	PMD(level, arglist) { 			\
603*7c478bd9Sstevel@tonic-gate 	if (pm_debug & (level)) {		\
604*7c478bd9Sstevel@tonic-gate 		pm_log arglist;			\
605*7c478bd9Sstevel@tonic-gate 	}					\
606*7c478bd9Sstevel@tonic-gate }
607*7c478bd9Sstevel@tonic-gate 
608*7c478bd9Sstevel@tonic-gate #else
609*7c478bd9Sstevel@tonic-gate #define	PMD(level, arglist)
610*7c478bd9Sstevel@tonic-gate #endif
611*7c478bd9Sstevel@tonic-gate 
612*7c478bd9Sstevel@tonic-gate extern void	pm_detaching(dev_info_t *);
613*7c478bd9Sstevel@tonic-gate extern void	pm_detach_failed(dev_info_t *);
614*7c478bd9Sstevel@tonic-gate extern int	pm_power(dev_info_t *, int, int);
615*7c478bd9Sstevel@tonic-gate extern int	pm_unmanage(dev_info_t *);
616*7c478bd9Sstevel@tonic-gate extern void	pm_rem_info(dev_info_t *);
617*7c478bd9Sstevel@tonic-gate extern int	pm_get_norm_pwrs(dev_info_t *, int **, size_t *);
618*7c478bd9Sstevel@tonic-gate extern dev_info_t *pm_name_to_dip(char *, int);
619*7c478bd9Sstevel@tonic-gate extern int	pm_power_up(dev_info_t *, int, int, int, pm_info_t *);
620*7c478bd9Sstevel@tonic-gate extern int	pm_default_idle_threshold;
621*7c478bd9Sstevel@tonic-gate extern void	pm_set_device_threshold(dev_info_t *, int, int);
622*7c478bd9Sstevel@tonic-gate extern int	pm_valid_power(dev_info_t *, int, int);
623*7c478bd9Sstevel@tonic-gate extern void	pm_lock_power(dev_info_t *, int *);
624*7c478bd9Sstevel@tonic-gate extern void	pm_unlock_power(dev_info_t *, int);
625*7c478bd9Sstevel@tonic-gate extern int	pm_try_locking_power(dev_info_t *, int *);
626*7c478bd9Sstevel@tonic-gate extern void	pm_lock_power_single(dev_info_t *, int *);
627*7c478bd9Sstevel@tonic-gate extern void	pm_unlock_power_single(dev_info_t *, int);
628*7c478bd9Sstevel@tonic-gate extern int	pm_try_locking_power_single(dev_info_t *, int *);
629*7c478bd9Sstevel@tonic-gate extern int	pm_isbc(dev_info_t *dip);
630*7c478bd9Sstevel@tonic-gate extern int	pm_isdirect(dev_info_t *dip);
631*7c478bd9Sstevel@tonic-gate extern int	pm_ctlops(dev_info_t *d, dev_info_t *r, ddi_ctl_enum_t o,
632*7c478bd9Sstevel@tonic-gate 			void *a, void *v);
633*7c478bd9Sstevel@tonic-gate extern int	pm_noinvol_detached(char *);
634*7c478bd9Sstevel@tonic-gate extern int	pm_init_child(dev_info_t *);
635*7c478bd9Sstevel@tonic-gate extern int	pm_uninit_child(dev_info_t *);
636*7c478bd9Sstevel@tonic-gate 
637*7c478bd9Sstevel@tonic-gate extern int	pm_all_to_normal(dev_info_t *, pm_canblock_t);
638*7c478bd9Sstevel@tonic-gate extern int	pm_set_power(dev_info_t *, int, int, int, pm_canblock_t, int,
639*7c478bd9Sstevel@tonic-gate 			int *);
640*7c478bd9Sstevel@tonic-gate extern void	pm_scan_init(dev_info_t *dip);
641*7c478bd9Sstevel@tonic-gate extern void	pm_scan_fini(dev_info_t *dip);
642*7c478bd9Sstevel@tonic-gate extern void	pm_scan_stop(dev_info_t *dip);
643*7c478bd9Sstevel@tonic-gate extern int	pm_scan_stop_walk(dev_info_t *dip, void *);
644*7c478bd9Sstevel@tonic-gate extern void	pm_scan(void *);
645*7c478bd9Sstevel@tonic-gate extern time_t	pm_scan_dev(dev_info_t *dip);
646*7c478bd9Sstevel@tonic-gate extern void	pm_rescan(void *);
647*7c478bd9Sstevel@tonic-gate extern int	pm_rescan_walk(dev_info_t *, void *);
648*7c478bd9Sstevel@tonic-gate extern void	pm_forget_power_level(dev_info_t *);
649*7c478bd9Sstevel@tonic-gate extern int	pm_pre_config(dev_info_t *, char *);
650*7c478bd9Sstevel@tonic-gate extern int	pm_pre_unconfig(dev_info_t *, int, int *, char *);
651*7c478bd9Sstevel@tonic-gate extern void	pm_post_config(dev_info_t *, char *);
652*7c478bd9Sstevel@tonic-gate extern void	pm_post_unconfig(dev_info_t *, int, char *);
653*7c478bd9Sstevel@tonic-gate extern void	pm_pre_probe(dev_info_t *, pm_ppm_cookie_t *);
654*7c478bd9Sstevel@tonic-gate extern void	pm_post_probe(pm_ppm_cookie_t *, int, int);
655*7c478bd9Sstevel@tonic-gate extern void	pm_post_attach(pm_ppm_cookie_t *, int);
656*7c478bd9Sstevel@tonic-gate extern void	pm_pre_attach(dev_info_t *, pm_ppm_cookie_t *,
657*7c478bd9Sstevel@tonic-gate 			ddi_attach_cmd_t);
658*7c478bd9Sstevel@tonic-gate extern void	pm_pre_detach(dev_info_t *, ddi_detach_cmd_t,
659*7c478bd9Sstevel@tonic-gate 			pm_ppm_cookie_t *);
660*7c478bd9Sstevel@tonic-gate extern void	pm_post_detach(pm_ppm_cookie_t *, int);
661*7c478bd9Sstevel@tonic-gate extern int	pm_powerup(dev_info_t *);
662*7c478bd9Sstevel@tonic-gate extern int	pm_all_at_normal(dev_info_t *);
663*7c478bd9Sstevel@tonic-gate extern int	pm_busop_bus_power(dev_info_t *, void *,
664*7c478bd9Sstevel@tonic-gate 		    pm_bus_power_op_t, void *, void *);
665*7c478bd9Sstevel@tonic-gate extern void	pm_hold_power(dev_info_t *);
666*7c478bd9Sstevel@tonic-gate extern void	pm_rele_power(dev_info_t *);
667*7c478bd9Sstevel@tonic-gate extern void	pm_driver_removed(major_t);
668*7c478bd9Sstevel@tonic-gate extern void	pm_borrow_lock(kthread_t *);
669*7c478bd9Sstevel@tonic-gate extern void	pm_return_lock(void);
670*7c478bd9Sstevel@tonic-gate extern int	pm_reattach_noinvol(void);
671*7c478bd9Sstevel@tonic-gate extern void	pm_reattach_noinvol_fini();
672*7c478bd9Sstevel@tonic-gate extern void	pm_restore_direct_levels(void);
673*7c478bd9Sstevel@tonic-gate extern void	pm_save_direct_levels(void);
674*7c478bd9Sstevel@tonic-gate extern void	pm_cfb_setup(const char *);
675*7c478bd9Sstevel@tonic-gate extern void	pm_proceed(dev_info_t *, int, int, int);
676*7c478bd9Sstevel@tonic-gate extern void	pm_get_timestamps(dev_info_t *, time_t *);
677*7c478bd9Sstevel@tonic-gate extern void	pm_deregister_watcher(int, dev_info_t *);
678*7c478bd9Sstevel@tonic-gate extern void	pm_dispatch_to_dep_thread(int, char *, char *, int, int *, int);
679*7c478bd9Sstevel@tonic-gate extern int	e_pm_valid_comp(dev_info_t *, int, pm_component_t **);
680*7c478bd9Sstevel@tonic-gate extern int	e_pm_valid_info(dev_info_t *, pm_info_t **);
681*7c478bd9Sstevel@tonic-gate extern int	e_pm_valid_power(dev_info_t *, int, int);
682*7c478bd9Sstevel@tonic-gate extern void	pm_init_locks(void);
683*7c478bd9Sstevel@tonic-gate extern int	pm_register_ppm(int (*)(dev_info_t *), dev_info_t *);
684*7c478bd9Sstevel@tonic-gate extern int	pm_is_cfb(dev_info_t *);
685*7c478bd9Sstevel@tonic-gate #ifdef	DEBUG
686*7c478bd9Sstevel@tonic-gate extern int	pm_cfb_is_up(void);
687*7c478bd9Sstevel@tonic-gate #endif
688*7c478bd9Sstevel@tonic-gate 
689*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
690*7c478bd9Sstevel@tonic-gate #define	PM_LOCK_DIP(dip)	{ PMD(PMD_LOCK, ("dip lock %s@%s(%s#%d) " \
691*7c478bd9Sstevel@tonic-gate 				    "%s %d\n", PM_DEVICE(dip),		  \
692*7c478bd9Sstevel@tonic-gate 				    __FILE__, __LINE__)) 		  \
693*7c478bd9Sstevel@tonic-gate 				    mutex_enter(&DEVI(dip)->devi_pm_lock); }
694*7c478bd9Sstevel@tonic-gate #define	PM_UNLOCK_DIP(dip)	{ PMD(PMD_LOCK, ("dip unlock %s@%s(%s#%d) " \
695*7c478bd9Sstevel@tonic-gate 				    "%s %d\n", PM_DEVICE(dip),		    \
696*7c478bd9Sstevel@tonic-gate 				    __FILE__, __LINE__))		    \
697*7c478bd9Sstevel@tonic-gate 				    mutex_exit(&DEVI(dip)->devi_pm_lock); }
698*7c478bd9Sstevel@tonic-gate #else
699*7c478bd9Sstevel@tonic-gate #define	PM_LOCK_DIP(dip)	mutex_enter(&DEVI(dip)->devi_pm_lock)
700*7c478bd9Sstevel@tonic-gate #define	PM_UNLOCK_DIP(dip)	mutex_exit(&DEVI(dip)->devi_pm_lock)
701*7c478bd9Sstevel@tonic-gate #endif
702*7c478bd9Sstevel@tonic-gate 
703*7c478bd9Sstevel@tonic-gate /*
704*7c478bd9Sstevel@tonic-gate  * These are the same DEBUG or not
705*7c478bd9Sstevel@tonic-gate  */
706*7c478bd9Sstevel@tonic-gate #define	PM_LOCK_BUSY(dip)	mutex_enter(&DEVI(dip)->devi_pm_busy_lock)
707*7c478bd9Sstevel@tonic-gate #define	PM_UNLOCK_BUSY(dip)	mutex_exit(&DEVI(dip)->devi_pm_busy_lock)
708*7c478bd9Sstevel@tonic-gate #define	PM_LOCK_POWER(dip, circp)	pm_lock_power(dip, circp)
709*7c478bd9Sstevel@tonic-gate #define	PM_UNLOCK_POWER(dip, circ)	pm_unlock_power(dip, circ)
710*7c478bd9Sstevel@tonic-gate #define	PM_TRY_LOCK_POWER(dip, circp)	pm_try_locking_power(dip, circp)
711*7c478bd9Sstevel@tonic-gate #define	PM_IAM_LOCKING_DIP(dip)	(mutex_owned(&DEVI(dip)->devi_pm_lock))
712*7c478bd9Sstevel@tonic-gate 
713*7c478bd9Sstevel@tonic-gate #define	PM_DEFAULT_SYS_IDLENESS	1800	/* 30 minutes */
714*7c478bd9Sstevel@tonic-gate 
715*7c478bd9Sstevel@tonic-gate /*
716*7c478bd9Sstevel@tonic-gate  * Codes put into the pr_retval field of pm_rsvp_t that tell pm_block()
717*7c478bd9Sstevel@tonic-gate  * how to proceed
718*7c478bd9Sstevel@tonic-gate  */
719*7c478bd9Sstevel@tonic-gate #define	PMP_SUCCEED	0x1	/* return success, the process did it */
720*7c478bd9Sstevel@tonic-gate #define	PMP_FAIL	0x2	/* return fail, process did something else */
721*7c478bd9Sstevel@tonic-gate #define	PMP_RELEASE	0x3	/* let it go, the process has lost interest */
722*7c478bd9Sstevel@tonic-gate 				/* also arg to pm_proceed to signal this */
723*7c478bd9Sstevel@tonic-gate /*
724*7c478bd9Sstevel@tonic-gate  * Values of "style" for e_pm_manage and pm_premanage
725*7c478bd9Sstevel@tonic-gate  */
726*7c478bd9Sstevel@tonic-gate #define	PM_STYLE_NEW		0
727*7c478bd9Sstevel@tonic-gate #define	PM_STYLE_UNKNOWN	1
728*7c478bd9Sstevel@tonic-gate 
729*7c478bd9Sstevel@tonic-gate /*
730*7c478bd9Sstevel@tonic-gate  * Arg passed to pm_proceed that results in PMP_SUCCEED or PMP_FAIL being set
731*7c478bd9Sstevel@tonic-gate  * in pr_retval depending on what is pending
732*7c478bd9Sstevel@tonic-gate  */
733*7c478bd9Sstevel@tonic-gate #define	PMP_SETPOWER	0x4
734*7c478bd9Sstevel@tonic-gate 
735*7c478bd9Sstevel@tonic-gate #define	PM_MAX_CLONE	256
736*7c478bd9Sstevel@tonic-gate 
737*7c478bd9Sstevel@tonic-gate typedef struct pm_rsvp {
738*7c478bd9Sstevel@tonic-gate 	dev_info_t	*pr_dip;
739*7c478bd9Sstevel@tonic-gate 	int		pr_comp;
740*7c478bd9Sstevel@tonic-gate 	int		pr_newlevel;
741*7c478bd9Sstevel@tonic-gate 	int		pr_oldlevel;
742*7c478bd9Sstevel@tonic-gate 	kcondvar_t	pr_cv;		/* a place to sleep */
743*7c478bd9Sstevel@tonic-gate 	int		pr_retval;	/* what to do when you wake up */
744*7c478bd9Sstevel@tonic-gate 	struct pm_rsvp	*pr_next;
745*7c478bd9Sstevel@tonic-gate 	struct pm_rsvp	*pr_prev;
746*7c478bd9Sstevel@tonic-gate } pm_rsvp_t;
747*7c478bd9Sstevel@tonic-gate 
748*7c478bd9Sstevel@tonic-gate typedef struct psce {	/* pm_state_change_entries */
749*7c478bd9Sstevel@tonic-gate 	struct pm_state_change		*psce_first;
750*7c478bd9Sstevel@tonic-gate 	struct pm_state_change		*psce_in;
751*7c478bd9Sstevel@tonic-gate 	struct pm_state_change		*psce_out;
752*7c478bd9Sstevel@tonic-gate 	struct pm_state_change		*psce_last;
753*7c478bd9Sstevel@tonic-gate 	int				psce_overruns;
754*7c478bd9Sstevel@tonic-gate 	int				psce_references;
755*7c478bd9Sstevel@tonic-gate 	kmutex_t			psce_lock;
756*7c478bd9Sstevel@tonic-gate } psce_t;
757*7c478bd9Sstevel@tonic-gate 
758*7c478bd9Sstevel@tonic-gate typedef struct pscc {			/* pm_state_change_control */
759*7c478bd9Sstevel@tonic-gate 	int		pscc_clone;
760*7c478bd9Sstevel@tonic-gate 	dev_info_t	*pscc_dip;
761*7c478bd9Sstevel@tonic-gate 	psce_t		*pscc_entries;
762*7c478bd9Sstevel@tonic-gate 	struct pscc	*pscc_next;
763*7c478bd9Sstevel@tonic-gate 	struct pscc	*pscc_prev;
764*7c478bd9Sstevel@tonic-gate } pscc_t;
765*7c478bd9Sstevel@tonic-gate 
766*7c478bd9Sstevel@tonic-gate #define	PSCCOUNT 128	/* number of state change entries kept per process */
767*7c478bd9Sstevel@tonic-gate 
768*7c478bd9Sstevel@tonic-gate /*
769*7c478bd9Sstevel@tonic-gate  * Struct used to track the existance of devices exporting the
770*7c478bd9Sstevel@tonic-gate  * no-involuntary-power-cycles property, and remember things from their
771*7c478bd9Sstevel@tonic-gate  * devinfo node for later attach.
772*7c478bd9Sstevel@tonic-gate  */
773*7c478bd9Sstevel@tonic-gate typedef struct pm_noinvol {
774*7c478bd9Sstevel@tonic-gate 	struct pm_noinvol	*ni_next;
775*7c478bd9Sstevel@tonic-gate 	char			*ni_path;
776*7c478bd9Sstevel@tonic-gate 	major_t			ni_major;	/* for attaching at cpr time */
777*7c478bd9Sstevel@tonic-gate 	uint_t			ni_flags;	/* selected PMC_* values */
778*7c478bd9Sstevel@tonic-gate 	uint_t			ni_noinvolpm;	/* saved noinvolpm count */
779*7c478bd9Sstevel@tonic-gate 	uint_t			ni_volpmd;	/* saved volpmd count */
780*7c478bd9Sstevel@tonic-gate 	uint_t			ni_wasvolpmd;	/* was vol pm'd at detach */
781*7c478bd9Sstevel@tonic-gate 	size_t			ni_size;
782*7c478bd9Sstevel@tonic-gate 	int			ni_persistent;	/* still around */
783*7c478bd9Sstevel@tonic-gate } pm_noinvol_t;
784*7c478bd9Sstevel@tonic-gate 
785*7c478bd9Sstevel@tonic-gate #define	PMID_IOCTIMER		0x1		/* pm_ioctl sets during timer */
786*7c478bd9Sstevel@tonic-gate #define	PMID_CFBTIMER		0x2		/* cfb sets during timer */
787*7c478bd9Sstevel@tonic-gate #define	PMID_IOCSCAN		0x4		/* pm_ioctl sets during scan */
788*7c478bd9Sstevel@tonic-gate #define	PMID_CFBSCAN		0x8		/* cfb sets during scan */
789*7c478bd9Sstevel@tonic-gate 
790*7c478bd9Sstevel@tonic-gate #define	PMID_IOC		(PMID_IOCTIMER | PMID_IOCSCAN)
791*7c478bd9Sstevel@tonic-gate #define	PMID_CFB		(PMID_CFBTIMER | PMID_CFBSCAN)
792*7c478bd9Sstevel@tonic-gate #define	PMID_TIMERS		(PMID_IOCTIMER | PMID_CFBTIMER)
793*7c478bd9Sstevel@tonic-gate #define	PMID_SCANS		(PMID_IOCSCAN | PMID_CFBSCAN)
794*7c478bd9Sstevel@tonic-gate #define	PMID_SCANS_SHIFT	2
795*7c478bd9Sstevel@tonic-gate #define	PMID_SET_SCANS(pmid)	(pmid) |= (((pmid) & PMID_TIMERS) <<	\
796*7c478bd9Sstevel@tonic-gate 				    PMID_SCANS_SHIFT);
797*7c478bd9Sstevel@tonic-gate #define	PMID_IS_IOC(pmid)	((pmid) & PMID_IOC)
798*7c478bd9Sstevel@tonic-gate #define	PMID_IS_CFB(pmid, dip)	(((pmid) & PMID_CFB) &&			\
799*7c478bd9Sstevel@tonic-gate 				    (DEVI(dip)->devi_pm_flags &		\
800*7c478bd9Sstevel@tonic-gate 				    (PMC_DEF_THRESH | PMC_NEXDEF_THRESH)))
801*7c478bd9Sstevel@tonic-gate #define	PM_IS_PID(dip)	(PMID_IS_IOC(PM_GET_PM_SCAN(dip)->ps_idle_down) || \
802*7c478bd9Sstevel@tonic-gate 	PMID_IS_CFB(PM_GET_PM_SCAN(dip)->ps_idle_down, dip))
803*7c478bd9Sstevel@tonic-gate #define	PM_IS_CFB(dip)		(DEVI(dip)->devi_pm_flags & PMC_CONSOLE_FB)
804*7c478bd9Sstevel@tonic-gate #define	PM_KUC(dip)		(DEVI(dip)->devi_pm_kidsupcnt)
805*7c478bd9Sstevel@tonic-gate #define	PM_CURPOWER(dip, comp)	cur_power(PM_CP(dip, comp))
806*7c478bd9Sstevel@tonic-gate 
807*7c478bd9Sstevel@tonic-gate #define	PM_WANTS_NOTIFICATION(dip)					\
808*7c478bd9Sstevel@tonic-gate 	(DEVI(dip)->devi_pm_flags & PMC_WANTS_NOTIFY)
809*7c478bd9Sstevel@tonic-gate 
810*7c478bd9Sstevel@tonic-gate #define	PM_HAS_BUS_POWER(dip)						\
811*7c478bd9Sstevel@tonic-gate 	((DEVI(dip)->devi_ops->devo_bus_ops != NULL) &&			\
812*7c478bd9Sstevel@tonic-gate 	(DEVI(dip)->devi_ops->devo_bus_ops->busops_rev >= BUSO_REV_7) &&\
813*7c478bd9Sstevel@tonic-gate 	(DEVI(dip)->devi_ops->devo_bus_ops->bus_power != NULL))
814*7c478bd9Sstevel@tonic-gate 
815*7c478bd9Sstevel@tonic-gate #define	PM_BUS_POWER_FUNC(dip)						\
816*7c478bd9Sstevel@tonic-gate 	DEVI(dip)->devi_ops->devo_bus_ops->bus_power
817*7c478bd9Sstevel@tonic-gate 
818*7c478bd9Sstevel@tonic-gate /*
819*7c478bd9Sstevel@tonic-gate  * Structure used to pass down sunpm's private data variables
820*7c478bd9Sstevel@tonic-gate  * through the bus_power bus_op calls
821*7c478bd9Sstevel@tonic-gate  */
822*7c478bd9Sstevel@tonic-gate typedef struct pm_sp_misc {
823*7c478bd9Sstevel@tonic-gate 	pm_canblock_t   pspm_canblock;
824*7c478bd9Sstevel@tonic-gate 	int pspm_scan;
825*7c478bd9Sstevel@tonic-gate 	int *pspm_errnop;
826*7c478bd9Sstevel@tonic-gate 	int pspm_direction;
827*7c478bd9Sstevel@tonic-gate } pm_sp_misc_t;
828*7c478bd9Sstevel@tonic-gate 
829*7c478bd9Sstevel@tonic-gate /*
830*7c478bd9Sstevel@tonic-gate  * This structure is used in validating that the power level
831*7c478bd9Sstevel@tonic-gate  * of the descendents are off, while a device is powered off.
832*7c478bd9Sstevel@tonic-gate  */
833*7c478bd9Sstevel@tonic-gate typedef struct pm_desc_pwrchk {
834*7c478bd9Sstevel@tonic-gate 	dev_info_t *pdpc_dip;
835*7c478bd9Sstevel@tonic-gate 	int pdpc_par_involved;
836*7c478bd9Sstevel@tonic-gate } pm_desc_pwrchk_t;
837*7c478bd9Sstevel@tonic-gate 
838*7c478bd9Sstevel@tonic-gate 
839*7c478bd9Sstevel@tonic-gate /*
840*7c478bd9Sstevel@tonic-gate  * These defines are used by pm_trans_check() to calculate time.
841*7c478bd9Sstevel@tonic-gate  * Mostly copied from "tzfile.h".
842*7c478bd9Sstevel@tonic-gate  */
843*7c478bd9Sstevel@tonic-gate #define	EPOCH_YEAR		1970
844*7c478bd9Sstevel@tonic-gate #define	SECSPERMIN		60
845*7c478bd9Sstevel@tonic-gate #define	MINSPERHOUR		60
846*7c478bd9Sstevel@tonic-gate #define	HOURSPERDAY		24
847*7c478bd9Sstevel@tonic-gate #define	DAYSPERWEEK		7
848*7c478bd9Sstevel@tonic-gate #define	DAYSPERNYEAR		365
849*7c478bd9Sstevel@tonic-gate #define	SECSPERHOUR		(SECSPERMIN * MINSPERHOUR)
850*7c478bd9Sstevel@tonic-gate #define	SECSPERDAY		(SECSPERHOUR * HOURSPERDAY)
851*7c478bd9Sstevel@tonic-gate #define	DC_SPY			(SECSPERDAY * DAYSPERNYEAR)
852*7c478bd9Sstevel@tonic-gate #define	DC_SPW			(SECSPERDAY * DAYSPERWEEK)
853*7c478bd9Sstevel@tonic-gate #define	DC_SPD			SECSPERDAY
854*7c478bd9Sstevel@tonic-gate 
855*7c478bd9Sstevel@tonic-gate #define	DC_SCSI_YEAR_LEN	4		/* YYYY */
856*7c478bd9Sstevel@tonic-gate #define	DC_SCSI_WEEK_LEN	2		/* WW */
857*7c478bd9Sstevel@tonic-gate #define	DC_SCSI_NPY		5		/* # power-cycle years */
858*7c478bd9Sstevel@tonic-gate 
859*7c478bd9Sstevel@tonic-gate #endif	/* _KERNEL */
860*7c478bd9Sstevel@tonic-gate 
861*7c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
862*7c478bd9Sstevel@tonic-gate }
863*7c478bd9Sstevel@tonic-gate #endif
864*7c478bd9Sstevel@tonic-gate 
865*7c478bd9Sstevel@tonic-gate #endif /* _SYS_EPM_H */
866