xref: /titanic_41/usr/src/uts/common/os/sunpm.c (revision ba7b222e36bac28710a7f43739283302b617e7f5)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*
27  * sunpm.c builds sunpm.o	"power management framework"
28  *	kernel-resident power management code.  Implements power management
29  *	policy
30  *	Assumes: all backwards compat. device components wake up on &
31  *		 the pm_info pointer in dev_info is initially NULL
32  *
33  * PM - (device) Power Management
34  *
35  * Each device may have 0 or more components.  If a device has no components,
36  * then it can't be power managed.  Each component has 2 or more
37  * power states.
38  *
39  * "Backwards Compatible" (bc) devices:
40  * There are two different types of devices from the point of view of this
41  * code.  The original type, left over from the original PM implementation on
42  * the voyager platform are known in this code as "backwards compatible"
43  * devices (PM_ISBC(dip) returns true).
44  * They are recognized by the pm code by the lack of a pm-components property
45  * and a call made by the driver to pm_create_components(9F).
46  * For these devices, component 0 is special, and represents the power state
47  * of the device.  If component 0 is to be set to power level 0 (off), then
48  * the framework must first call into the driver's detach(9E) routine with
49  * DDI_PM_SUSPEND, to get the driver to save the hardware state of the device.
50  * After setting component 0 from 0 to a non-zero power level, a call must be
51  * made into the driver's attach(9E) routine with DDI_PM_RESUME.
52  *
53  * Currently, the only way to get a bc device power managed is via a set of
54  * ioctls (PM_DIRECT_PM, PM_SET_CURRENT_POWER) issued to /dev/pm.
55  *
56  * For non-bc devices, the driver describes the components by exporting a
57  * pm-components(9P) property that tells how many components there are,
58  * tells what each component's power state values are, and provides human
59  * readable strings (currently unused) for each component name and power state.
60  * Devices which export pm-components(9P) are automatically power managed
61  * whenever autopm is enabled (via PM_START_PM ioctl issued by pmconfig(1M)
62  * after parsing power.conf(4)). The exception to this rule is that power
63  * manageable CPU devices may be automatically managed independently of autopm
64  * by either enabling or disabling (via PM_START_CPUPM and PM_STOP_CPUPM
65  * ioctls) cpupm. If the CPU devices are not managed independently, then they
66  * are managed by autopm. In either case, for automatically power managed
67  * devices, all components are considered independent of each other, and it is
68  * up to the driver to decide when a transition requires saving or restoring
69  * hardware state.
70  *
71  * Each device component also has a threshold time associated with each power
72  * transition (see power.conf(4)), and a busy/idle state maintained by the
73  * driver calling pm_idle_component(9F) and pm_busy_component(9F).
74  * Components are created idle.
75  *
76  * The PM framework provides several functions:
77  * -implement PM policy as described in power.conf(4)
78  *  Policy is set by pmconfig(1M) issuing pm ioctls based on power.conf(4).
79  *  Policies consist of:
80  *    -set threshold values (defaults if none provided by pmconfig)
81  *    -set dependencies among devices
82  *    -enable/disable autopm
83  *    -enable/disable cpupm
84  *    -turn down idle components based on thresholds (if autopm or cpupm is
85  *     enabled) (aka scanning)
86  *    -maintain power states based on dependencies among devices
87  *    -upon request, or when the frame buffer powers off, attempt to turn off
88  *     all components that are idle or become idle over the next (10 sec)
89  *     period in an attempt to get down to an EnergyStar compliant state
90  *    -prevent powering off of a device which exported the
91  *     pm-no-involuntary-power-cycles property without active involvement of
92  *     the device's driver (so no removing power when the device driver is
93  *     not attached)
94  * -provide a mechanism for a device driver to request that a device's component
95  *  be brought back to the power level necessary for the use of the device
96  * -allow a process to directly control the power levels of device components
97  *  (via ioctls issued to /dev/pm--see usr/src/uts/common/io/pm.c)
98  * -ensure that the console frame buffer is powered up before being referenced
99  *  via prom_printf() or other prom calls that might generate console output
100  * -maintain implicit dependencies (e.g. parent must be powered up if child is)
101  * -provide "backwards compatible" behavior for devices without pm-components
102  *  property
103  *
104  * Scanning:
105  * Whenever autopm or cpupm  is enabled, the framework attempts to bring each
106  * component of each managed device to its lowest power based on the threshold
107  * of idleness associated with each transition and the busy/idle state of the
108  * component.
109  *
110  * The actual work of this is done by pm_scan_dev(), which cycles through each
111  * component of a device, checking its idleness against its current threshold,
112  * and calling pm_set_power() as appropriate to change the power level.
113  * This function also indicates when it would next be profitable to scan the
114  * device again, and a new scan is scheduled after that time.
115  *
116  * Dependencies:
117  * It is possible to establish a dependency between the power states of two
118  * otherwise unrelated devices.  This is currently done to ensure that the
119  * cdrom is always up whenever the console framebuffer is up, so that the user
120  * can insert a cdrom and see a popup as a result.
121  *
122  * The dependency terminology used in power.conf(4) is not easy to understand,
123  * so we've adopted a different terminology in the implementation.  We write
124  * of a "keeps up" and a "kept up" device.  A relationship can be established
125  * where one device keeps up another.  That means that if the keepsup device
126  * has any component that is at a non-zero power level, all components of the
127  * "kept up" device must be brought to full power.  This relationship is
128  * asynchronous.  When the keeping device is powered up, a request is queued
129  * to a worker thread to bring up the kept device.  The caller does not wait.
130  * Scan will not turn down a kept up device.
131  *
132  * Direct PM:
133  * A device may be directly power managed by a process.  If a device is
134  * directly pm'd, then it will not be scanned, and dependencies will not be
135  * enforced.  * If a directly pm'd device's driver requests a power change (via
136  * pm_raise_power(9F)), then the request is blocked and notification is sent
137  * to the controlling process, which must issue the requested power change for
138  * the driver to proceed.
139  *
140  */
141 
142 #include <sys/types.h>
143 #include <sys/errno.h>
144 #include <sys/callb.h>		/* callback registration during CPR */
145 #include <sys/conf.h>		/* driver flags and functions */
146 #include <sys/open.h>		/* OTYP_CHR definition */
147 #include <sys/stat.h>		/* S_IFCHR definition */
148 #include <sys/pathname.h>	/* name -> dev_info xlation */
149 #include <sys/ddi_impldefs.h>	/* dev_info node fields */
150 #include <sys/kmem.h>		/* memory alloc stuff */
151 #include <sys/debug.h>
152 #include <sys/archsystm.h>
153 #include <sys/pm.h>
154 #include <sys/ddi.h>
155 #include <sys/sunddi.h>
156 #include <sys/sunndi.h>
157 #include <sys/sunpm.h>
158 #include <sys/epm.h>
159 #include <sys/vfs.h>
160 #include <sys/mode.h>
161 #include <sys/mkdev.h>
162 #include <sys/promif.h>
163 #include <sys/consdev.h>
164 #include <sys/esunddi.h>
165 #include <sys/modctl.h>
166 #include <sys/fs/ufs_fs.h>
167 #include <sys/note.h>
168 #include <sys/taskq.h>
169 #include <sys/bootconf.h>
170 #include <sys/reboot.h>
171 #include <sys/spl.h>
172 #include <sys/disp.h>
173 #include <sys/sobject.h>
174 #include <sys/sunmdi.h>
175 #include <sys/systm.h>
176 #include <sys/cpuvar.h>
177 #include <sys/cyclic.h>
178 #include <sys/uadmin.h>
179 #include <sys/srn.h>
180 
181 
182 /*
183  * PM LOCKING
184  *	The list of locks:
185  * Global pm mutex locks.
186  *
187  * pm_scan_lock:
188  *		It protects the timeout id of the scan thread, and the value
189  *		of autopm_enabled and cpupm.  This lock is not held
190  *		concurrently with any other PM locks.
191  *
192  * pm_clone_lock:	Protects the clone list and count of poll events
193  *		pending for the pm driver.
194  *		Lock ordering:
195  *			pm_clone_lock -> pm_pscc_interest_rwlock,
196  *			pm_clone_lock -> pm_pscc_direct_rwlock.
197  *
198  * pm_rsvp_lock:
199  *		Used to synchronize the data structures used for processes
200  *		to rendezvous with state change information when doing
201  *		direct PM.
202  *		Lock ordering:
203  *			pm_rsvp_lock -> pm_pscc_interest_rwlock,
204  *			pm_rsvp_lock -> pm_pscc_direct_rwlock,
205  *			pm_rsvp_lock -> pm_clone_lock.
206  *
207  * ppm_lock:	protects the list of registered ppm drivers
208  *		Lock ordering:
209  *			ppm_lock -> ppm driver unit_lock
210  *
211  * pm_compcnt_lock:
212  *		Protects count of components that are not at their lowest
213  *		power level.
214  *		Lock ordering:
215  *			pm_compcnt_lock -> ppm_lock.
216  *
217  * pm_dep_thread_lock:
218  *		Protects work list for pm_dep_thread.  Not taken concurrently
219  *		with any other pm lock.
220  *
221  * pm_remdrv_lock:
222  *		Serializes the operation of removing noinvol data structure
223  *		entries for a branch of the tree when a driver has been
224  *		removed from the system (modctl_rem_major).
225  *		Lock ordering:
226  *			pm_remdrv_lock -> pm_noinvol_rwlock.
227  *
228  * pm_cfb_lock: (High level spin lock)
229  *		Protects the count of how many components of the console
230  *		frame buffer are off (so we know if we have to bring up the
231  *		console as a result of a prom_printf, etc.
232  *		No other locks are taken while holding this lock.
233  *
234  * pm_loan_lock:
235  *		Protects the lock_loan list.  List is used to record that one
236  *		thread has acquired a power lock but has launched another thread
237  *		to complete its processing.  An entry in the list indicates that
238  *		the worker thread can borrow the lock held by the other thread,
239  *		which must block on the completion of the worker.  Use is
240  *		specific to module loading.
241  *		No other locks are taken while holding this lock.
242  *
243  * Global PM rwlocks
244  *
245  * pm_thresh_rwlock:
246  *		Protects the list of thresholds recorded for future use (when
247  *		devices attach).
248  *		Lock ordering:
249  *			pm_thresh_rwlock -> devi_pm_lock
250  *
251  * pm_noinvol_rwlock:
252  *		Protects list of detached nodes that had noinvol registered.
253  *		No other PM locks are taken while holding pm_noinvol_rwlock.
254  *
255  * pm_pscc_direct_rwlock:
256  *		Protects the list that maps devices being directly power
257  *		managed to the processes that manage them.
258  *		Lock ordering:
259  *			pm_pscc_direct_rwlock -> psce_lock
260  *
261  * pm_pscc_interest_rwlock;
262  *		Protects the list that maps state change events to processes
263  *		that want to know about them.
264  *		Lock ordering:
265  *			pm_pscc_interest_rwlock -> psce_lock
266  *
267  * per-dip locks:
268  *
269  * Each node has these per-dip locks, which are only used if the device is
270  * a candidate for power management (e.g. has pm components)
271  *
272  * devi_pm_lock:
273  *		Protects all power management state of the node except for
274  *		power level, which is protected by ndi_devi_enter().
275  *		Encapsulated in macros PM_LOCK_DIP()/PM_UNLOCK_DIP().
276  *		Lock ordering:
277  *			devi_pm_lock -> pm_rsvp_lock,
278  *			devi_pm_lock -> pm_dep_thread_lock,
279  *			devi_pm_lock -> pm_noinvol_rwlock,
280  *			devi_pm_lock -> power lock
281  *
282  * power lock (ndi_devi_enter()):
283  *		Since changing power level is possibly a slow operation (30
284  *		seconds to spin up a disk drive), this is locked separately.
285  *		Since a call into the driver to change the power level of one
286  *		component may result in a call back into the framework to change
287  *		the power level of another, this lock allows re-entrancy by
288  *		the same thread (ndi_devi_enter is used for this because
289  *		the USB framework uses ndi_devi_enter in its power entry point,
290  *		and use of any other lock would produce a deadlock.
291  *
292  * devi_pm_busy_lock:
293  *		This lock protects the integrity of the busy count.  It is
294  *		only taken by pm_busy_component() and pm_idle_component and
295  *		some code that adjust the busy time after the timer gets set
296  *		up or after a CPR operation.  It is per-dip to keep from
297  *		single-threading all the disk drivers on a system.
298  *		It could be per component instead, but most devices have
299  *		only one component.
300  *		No other PM locks are taken while holding this lock.
301  *
302  */
303 
304 static int stdout_is_framebuffer;
305 static kmutex_t	e_pm_power_lock;
306 static kmutex_t pm_loan_lock;
307 kmutex_t	pm_scan_lock;
308 callb_id_t	pm_cpr_cb_id;
309 callb_id_t	pm_panic_cb_id;
310 callb_id_t	pm_halt_cb_id;
311 int		pm_comps_notlowest;	/* no. of comps not at lowest power */
312 int		pm_powering_down;	/* cpr is source of DDI_SUSPEND calls */
313 
314 clock_t pm_id_ticks = 5;	/* ticks to wait before scan during idle-down */
315 clock_t pm_default_min_scan = PM_DEFAULT_MIN_SCAN;
316 clock_t pm_cpu_min_scan = PM_CPU_MIN_SCAN;
317 
318 #define	PM_MIN_SCAN(dip)	(PM_ISCPU(dip) ? pm_cpu_min_scan : \
319 				    pm_default_min_scan)
320 
321 static int pm_busop_set_power(dev_info_t *,
322     void *, pm_bus_power_op_t, void *, void *);
323 static int pm_busop_match_request(dev_info_t *, void *);
324 static int pm_all_to_normal_nexus(dev_info_t *, pm_canblock_t);
325 static void e_pm_set_max_power(dev_info_t *, int, int);
326 static int e_pm_get_max_power(dev_info_t *, int);
327 
328 /*
329  * Dependency Processing is done thru a seperate thread.
330  */
331 kmutex_t	pm_dep_thread_lock;
332 kcondvar_t	pm_dep_thread_cv;
333 pm_dep_wk_t	*pm_dep_thread_workq = NULL;
334 pm_dep_wk_t	*pm_dep_thread_tail = NULL;
335 
336 /*
337  * Autopm  must be turned on by a PM_START_PM ioctl, so we don't end up
338  * power managing things in single user mode that have been suppressed via
339  * power.conf entries.  Protected by pm_scan_lock.
340  */
341 int		autopm_enabled;
342 
343 /*
344  * cpupm is turned on and off, by the PM_START_CPUPM and PM_STOP_CPUPM ioctls,
345  * to define the power management behavior of CPU devices separate from
346  * autopm. Protected by pm_scan_lock.
347  */
348 pm_cpupm_t	cpupm = PM_CPUPM_NOTSET;
349 
350 /*
351  * Defines the default mode of operation for CPU power management,
352  * either the polling implementation, or the event based dispatcher driven
353  * implementation.
354  */
355 pm_cpupm_t	cpupm_default_mode = PM_CPUPM_EVENT;
356 
357 /*
358  * AutoS3 depends on autopm being enabled, and must be enabled by
359  * PM_START_AUTOS3 command.
360  */
361 int		autoS3_enabled;
362 
363 #if !defined(__sparc)
364 /*
365  * on sparc these live in fillsysinfo.c
366  *
367  * If this variable is non-zero, cpr should return "not supported" when
368  * it is queried even though it would normally be supported on this platform.
369  */
370 int cpr_supported_override;
371 
372 /*
373  * Some platforms may need to support CPR even in the absence of
374  * having the correct platform id information.  If this
375  * variable is non-zero, cpr should proceed even in the absence
376  * of otherwise being qualified.
377  */
378 int cpr_platform_enable = 0;
379 
380 #endif
381 
382 /*
383  * pm_S3_enabled indicates that we believe the platform can support S3,
384  * which we get from pmconfig(1M)
385  */
386 int		pm_S3_enabled;
387 
388 /*
389  * This flag is true while processes are stopped for a checkpoint/resume.
390  * Controlling processes of direct pm'd devices are not available to
391  * participate in power level changes, so we bypass them when this is set.
392  */
393 static int	pm_processes_stopped;
394 
395 #ifdef	DEBUG
396 
397 /*
398  * see common/sys/epm.h for PMD_* values
399  */
400 
401 uint_t		pm_debug = 0;
402 
403 /*
404  * If pm_divertdebug is set, then no prom_printf calls will be made by
405  * PMD(), which will prevent debug output from bringing up the console
406  * frame buffer.  Clearing this variable before setting pm_debug will result
407  * in PMD output going to the console.
408  *
409  * pm_divertdebug is incremented in pm_set_power() if dip == cfb_dip to avoid
410  * deadlocks and decremented at the end of pm_set_power()
411  */
412 uint_t		pm_divertdebug = 1;
413 volatile uint_t pm_debug_to_console = 0;
414 kmutex_t	pm_debug_lock;		/* protects pm_divertdebug */
415 
416 void prdeps(char *);
417 #endif
418 
419 /* Globals */
420 
421 /*
422  * List of recorded thresholds and dependencies
423  */
424 pm_thresh_rec_t *pm_thresh_head;
425 krwlock_t pm_thresh_rwlock;
426 
427 pm_pdr_t *pm_dep_head;
428 static int pm_unresolved_deps = 0;
429 static int pm_prop_deps = 0;
430 
431 /*
432  * List of devices that exported no-involuntary-power-cycles property
433  */
434 pm_noinvol_t *pm_noinvol_head;
435 
436 /*
437  * Locks used in noinvol processing
438  */
439 krwlock_t pm_noinvol_rwlock;
440 kmutex_t pm_remdrv_lock;
441 
442 int pm_default_idle_threshold = PM_DEFAULT_SYS_IDLENESS;
443 int pm_system_idle_threshold;
444 int pm_cpu_idle_threshold;
445 
446 /*
447  * By default nexus has 0 threshold, and depends on its children to keep it up
448  */
449 int pm_default_nexus_threshold = 0;
450 
451 /*
452  * Data structures shared with common/io/pm.c
453  */
454 kmutex_t	pm_clone_lock;
455 kcondvar_t	pm_clones_cv[PM_MAX_CLONE];
456 uint_t		pm_poll_cnt[PM_MAX_CLONE];	/* count of events for poll */
457 unsigned char	pm_interest[PM_MAX_CLONE];
458 struct pollhead	pm_pollhead;
459 
460 /*
461  * Data structures shared with common/io/srn.c
462  */
463 kmutex_t	srn_clone_lock;		/* protects srn_signal, srn_inuse */
464 void (*srn_signal)(int type, int event);
465 int srn_inuse;				/* stop srn detach */
466 
467 extern int	hz;
468 extern char	*platform_module_list[];
469 
470 /*
471  * Wrappers for use in ddi_walk_devs
472  */
473 
474 static int		pm_set_dev_thr_walk(dev_info_t *, void *);
475 static int		pm_restore_direct_lvl_walk(dev_info_t *, void *);
476 static int		pm_save_direct_lvl_walk(dev_info_t *, void *);
477 static int		pm_discard_dep_walk(dev_info_t *, void *);
478 #ifdef DEBUG
479 static int		pm_desc_pwrchk_walk(dev_info_t *, void *);
480 #endif
481 
482 /*
483  * Routines for managing noinvol devices
484  */
485 int			pm_noinvol_update(int, int, int, char *, dev_info_t *);
486 void			pm_noinvol_update_node(dev_info_t *,
487 			    pm_bp_noinvol_t *req);
488 
489 kmutex_t pm_rsvp_lock;
490 kmutex_t pm_compcnt_lock;
491 krwlock_t pm_pscc_direct_rwlock;
492 krwlock_t pm_pscc_interest_rwlock;
493 
494 #define	PSC_INTEREST	0	/* belongs to interest psc list */
495 #define	PSC_DIRECT	1	/* belongs to direct psc list */
496 
497 pscc_t *pm_pscc_interest;
498 pscc_t *pm_pscc_direct;
499 
500 #define	PM_MAJOR(dip) ddi_driver_major(dip)
501 #define	PM_IS_NEXUS(dip) ((PM_MAJOR(dip) == DDI_MAJOR_T_NONE) ? 0 : \
502 	NEXUS_DRV(devopsp[PM_MAJOR(dip)]))
503 #define	POWERING_ON(old, new) ((old) == 0 && (new) != 0)
504 #define	POWERING_OFF(old, new) ((old) != 0 && (new) == 0)
505 
506 #define	PM_INCR_NOTLOWEST(dip) {					\
507 	mutex_enter(&pm_compcnt_lock);					\
508 	if (!PM_IS_NEXUS(dip) ||					\
509 	    (DEVI(dip)->devi_pm_flags & (PMC_DEV_THRESH|PMC_COMP_THRESH))) {\
510 		if (pm_comps_notlowest == 0)				\
511 			pm_ppm_notify_all_lowest(dip, PM_NOT_ALL_LOWEST);\
512 		pm_comps_notlowest++;					\
513 		PMD(PMD_LEVEL, ("%s: %s@%s(%s#%d) incr notlowest->%d\n",\
514 		    pmf, PM_DEVICE(dip), pm_comps_notlowest))		\
515 	}								\
516 	mutex_exit(&pm_compcnt_lock);					\
517 }
518 #define	PM_DECR_NOTLOWEST(dip) {					\
519 	mutex_enter(&pm_compcnt_lock);					\
520 	if (!PM_IS_NEXUS(dip) ||					\
521 	    (DEVI(dip)->devi_pm_flags & (PMC_DEV_THRESH|PMC_COMP_THRESH))) {\
522 		ASSERT(pm_comps_notlowest);				\
523 		pm_comps_notlowest--;					\
524 		PMD(PMD_LEVEL, ("%s: %s@%s(%s#%d) decr notlowest to "	\
525 			    "%d\n", pmf, PM_DEVICE(dip), pm_comps_notlowest))\
526 		if (pm_comps_notlowest == 0)				\
527 			pm_ppm_notify_all_lowest(dip, PM_ALL_LOWEST);	\
528 	}								\
529 	mutex_exit(&pm_compcnt_lock);					\
530 }
531 
532 /*
533  * console frame-buffer power-management is not enabled when
534  * debugging services are present.  to override, set pm_cfb_override
535  * to non-zero.
536  */
537 uint_t pm_cfb_comps_off = 0;	/* PM_LEVEL_UNKNOWN is considered on */
538 kmutex_t pm_cfb_lock;
539 int pm_cfb_enabled = 1;		/* non-zero allows pm of console frame buffer */
540 #ifdef DEBUG
541 int pm_cfb_override = 1;	/* non-zero allows pm of cfb with debuggers */
542 #else
543 int pm_cfb_override = 0;	/* non-zero allows pm of cfb with debuggers */
544 #endif
545 
546 static dev_info_t *cfb_dip = 0;
547 static dev_info_t *cfb_dip_detaching = 0;
548 uint_t cfb_inuse = 0;
549 static ddi_softintr_t pm_soft_id;
550 static clock_t pm_soft_pending;
551 int	pm_scans_disabled = 0;
552 
553 /*
554  * A structure to record the fact that one thread has borrowed a lock held
555  * by another thread.  The context requires that the lender block on the
556  * completion of the borrower.
557  */
558 typedef struct lock_loan {
559 	struct lock_loan	*pmlk_next;
560 	kthread_t		*pmlk_borrower;
561 	kthread_t		*pmlk_lender;
562 	dev_info_t		*pmlk_dip;
563 } lock_loan_t;
564 static lock_loan_t lock_loan_head;	/* list head is a dummy element */
565 
566 #ifdef	DEBUG
567 #ifdef	PMDDEBUG
568 #define	PMD_FUNC(func, name)	char *(func) = (name);
569 #else	/* !PMDDEBUG */
570 #define	PMD_FUNC(func, name)
571 #endif	/* PMDDEBUG */
572 #else	/* !DEBUG */
573 #define	PMD_FUNC(func, name)
574 #endif	/* DEBUG */
575 
576 
577 /*
578  * Must be called before first device (including pseudo) attach
579  */
580 void
581 pm_init_locks(void)
582 {
583 	mutex_init(&pm_scan_lock, NULL, MUTEX_DRIVER, NULL);
584 	mutex_init(&pm_rsvp_lock, NULL, MUTEX_DRIVER, NULL);
585 	mutex_init(&pm_compcnt_lock, NULL, MUTEX_DRIVER, NULL);
586 	mutex_init(&pm_dep_thread_lock, NULL, MUTEX_DRIVER, NULL);
587 	mutex_init(&pm_remdrv_lock, NULL, MUTEX_DRIVER, NULL);
588 	mutex_init(&pm_loan_lock, NULL, MUTEX_DRIVER, NULL);
589 	rw_init(&pm_thresh_rwlock, NULL, RW_DEFAULT, NULL);
590 	rw_init(&pm_noinvol_rwlock, NULL, RW_DEFAULT, NULL);
591 	cv_init(&pm_dep_thread_cv, NULL, CV_DEFAULT, NULL);
592 }
593 
594 static int pm_reset_timestamps(dev_info_t *, void *);
595 
596 static boolean_t
597 pm_cpr_callb(void *arg, int code)
598 {
599 	_NOTE(ARGUNUSED(arg))
600 	static int auto_save;
601 	static pm_cpupm_t cpupm_save;
602 
603 	switch (code) {
604 	case CB_CODE_CPR_CHKPT:
605 		/*
606 		 * Cancel scan or wait for scan in progress to finish
607 		 * Other threads may be trying to restart the scan, so we
608 		 * have to keep at it unil it sticks
609 		 */
610 		mutex_enter(&pm_scan_lock);
611 		ASSERT(!pm_scans_disabled);
612 		pm_scans_disabled = 1;
613 		auto_save = autopm_enabled;
614 		autopm_enabled = 0;
615 		cpupm_save = cpupm;
616 		cpupm = PM_CPUPM_NOTSET;
617 		mutex_exit(&pm_scan_lock);
618 		ddi_walk_devs(ddi_root_node(), pm_scan_stop_walk, NULL);
619 		break;
620 
621 	case CB_CODE_CPR_RESUME:
622 		ASSERT(!autopm_enabled);
623 		ASSERT(cpupm == PM_CPUPM_NOTSET);
624 		ASSERT(pm_scans_disabled);
625 		pm_scans_disabled = 0;
626 		/*
627 		 * Call pm_reset_timestamps to reset timestamps of each
628 		 * device to the time when the system is resumed so that their
629 		 * idleness can be re-calculated. That's to avoid devices from
630 		 * being powered down right after resume if the system was in
631 		 * suspended mode long enough.
632 		 */
633 		ddi_walk_devs(ddi_root_node(), pm_reset_timestamps, NULL);
634 
635 		autopm_enabled = auto_save;
636 		cpupm = cpupm_save;
637 		/*
638 		 * If there is any auto-pm device, get the scanning
639 		 * going. Otherwise don't bother.
640 		 */
641 		ddi_walk_devs(ddi_root_node(), pm_rescan_walk, NULL);
642 		break;
643 	}
644 	return (B_TRUE);
645 }
646 
647 /*
648  * This callback routine is called when there is a system panic.  This function
649  * exists for prototype matching.
650  */
651 static boolean_t
652 pm_panic_callb(void *arg, int code)
653 {
654 	_NOTE(ARGUNUSED(arg, code))
655 	void pm_cfb_check_and_powerup(void);
656 	PMD(PMD_CFB, ("pm_panic_callb\n"))
657 	pm_cfb_check_and_powerup();
658 	return (B_TRUE);
659 }
660 
661 static boolean_t
662 pm_halt_callb(void *arg, int code)
663 {
664 	_NOTE(ARGUNUSED(arg, code))
665 	return (B_TRUE);
666 }
667 
668 static void pm_dep_thread(void);
669 
670 /*
671  * This needs to be called after the root and platform drivers are loaded
672  * and be single-threaded with respect to driver attach/detach
673  */
674 void
675 pm_init(void)
676 {
677 	PMD_FUNC(pmf, "pm_init")
678 	char **mod;
679 	extern pri_t minclsyspri;
680 
681 	pm_comps_notlowest = 0;
682 	pm_system_idle_threshold = pm_default_idle_threshold;
683 	pm_cpu_idle_threshold = 0;
684 
685 	pm_cpr_cb_id = callb_add(pm_cpr_callb, (void *)NULL,
686 	    CB_CL_CPR_PM, "pm_cpr");
687 	pm_panic_cb_id = callb_add(pm_panic_callb, (void *)NULL,
688 	    CB_CL_PANIC, "pm_panic");
689 	pm_halt_cb_id = callb_add(pm_halt_callb, (void *)NULL,
690 	    CB_CL_HALT, "pm_halt");
691 
692 	/*
693 	 * Create a thread to do dependency processing.
694 	 */
695 	(void) thread_create(NULL, 0, (void (*)())pm_dep_thread, NULL, 0, &p0,
696 	    TS_RUN, minclsyspri);
697 
698 	/*
699 	 * loadrootmodules already loaded these ppm drivers, now get them
700 	 * attached so they can claim the root drivers as they attach
701 	 */
702 	for (mod = platform_module_list; *mod; mod++) {
703 		if (i_ddi_attach_hw_nodes(*mod) != DDI_SUCCESS) {
704 			cmn_err(CE_WARN, "!cannot load platform pm driver %s\n",
705 			    *mod);
706 		} else {
707 			PMD(PMD_DHR, ("%s: %s (%s)\n", pmf, *mod,
708 			    ddi_major_to_name(ddi_name_to_major(*mod))))
709 		}
710 	}
711 }
712 
713 /*
714  * pm_scan_init - create pm scan data structure.  Called (if autopm or cpupm
715  * enabled) when device becomes power managed or after a failed detach and
716  * when autopm is started via PM_START_PM or PM_START_CPUPM ioctls, and after
717  * a CPR resume to get all the devices scanning again.
718  */
719 void
720 pm_scan_init(dev_info_t *dip)
721 {
722 	PMD_FUNC(pmf, "scan_init")
723 	pm_scan_t	*scanp;
724 
725 	ASSERT(!PM_ISBC(dip));
726 
727 	PM_LOCK_DIP(dip);
728 	scanp = PM_GET_PM_SCAN(dip);
729 	if (!scanp) {
730 		PMD(PMD_SCAN, ("%s: %s@%s(%s#%d): create scan data\n",
731 		    pmf, PM_DEVICE(dip)))
732 		scanp =  kmem_zalloc(sizeof (pm_scan_t), KM_SLEEP);
733 		DEVI(dip)->devi_pm_scan = scanp;
734 	} else if (scanp->ps_scan_flags & PM_SCAN_STOP) {
735 		PMD(PMD_SCAN, ("%s: %s@%s(%s#%d): "
736 		    "clear PM_SCAN_STOP flag\n", pmf, PM_DEVICE(dip)))
737 		scanp->ps_scan_flags &= ~PM_SCAN_STOP;
738 	}
739 	PM_UNLOCK_DIP(dip);
740 }
741 
742 /*
743  * pm_scan_fini - remove pm scan data structure when stopping pm on the device
744  */
745 void
746 pm_scan_fini(dev_info_t *dip)
747 {
748 	PMD_FUNC(pmf, "scan_fini")
749 	pm_scan_t	*scanp;
750 
751 	PMD(PMD_SCAN, ("%s: %s@%s(%s#%d)\n", pmf, PM_DEVICE(dip)))
752 	ASSERT(!PM_ISBC(dip));
753 	PM_LOCK_DIP(dip);
754 	scanp = PM_GET_PM_SCAN(dip);
755 	if (!scanp) {
756 		PM_UNLOCK_DIP(dip);
757 		return;
758 	}
759 
760 	ASSERT(!scanp->ps_scan_id && !(scanp->ps_scan_flags &
761 	    (PM_SCANNING | PM_SCAN_DISPATCHED | PM_SCAN_AGAIN)));
762 
763 	kmem_free(scanp, sizeof (pm_scan_t));
764 	DEVI(dip)->devi_pm_scan = NULL;
765 	PM_UNLOCK_DIP(dip);
766 }
767 
768 /*
769  * Given a pointer to a component struct, return the current power level
770  * (struct contains index unless it is a continuous level).
771  * Located here in hopes of getting both this and dev_is_needed into the
772  * cache together
773  */
774 static int
775 cur_power(pm_component_t *cp)
776 {
777 	if (cp->pmc_cur_pwr == PM_LEVEL_UNKNOWN)
778 		return (cp->pmc_cur_pwr);
779 
780 	return (cp->pmc_comp.pmc_lvals[cp->pmc_cur_pwr]);
781 }
782 
783 static char *
784 pm_decode_direction(int direction)
785 {
786 	switch (direction) {
787 	case PM_LEVEL_UPONLY:
788 		return ("up");
789 
790 	case PM_LEVEL_EXACT:
791 		return ("exact");
792 
793 	case PM_LEVEL_DOWNONLY:
794 		return ("down");
795 
796 	default:
797 		return ("INVALID DIRECTION");
798 	}
799 }
800 
801 char *
802 pm_decode_op(pm_bus_power_op_t op)
803 {
804 	switch (op) {
805 	case BUS_POWER_CHILD_PWRCHG:
806 		return ("CHILD_PWRCHG");
807 	case BUS_POWER_NEXUS_PWRUP:
808 		return ("NEXUS_PWRUP");
809 	case BUS_POWER_PRE_NOTIFICATION:
810 		return ("PRE_NOTIFICATION");
811 	case BUS_POWER_POST_NOTIFICATION:
812 		return ("POST_NOTIFICATION");
813 	case BUS_POWER_HAS_CHANGED:
814 		return ("HAS_CHANGED");
815 	case BUS_POWER_NOINVOL:
816 		return ("NOINVOL");
817 	default:
818 		return ("UNKNOWN OP");
819 	}
820 }
821 
822 /*
823  * Returns true if level is a possible (valid) power level for component
824  */
825 int
826 e_pm_valid_power(dev_info_t *dip, int cmpt, int level)
827 {
828 	PMD_FUNC(pmf, "e_pm_valid_power")
829 	pm_component_t *cp = PM_CP(dip, cmpt);
830 	int i;
831 	int *ip = cp->pmc_comp.pmc_lvals;
832 	int limit = cp->pmc_comp.pmc_numlevels;
833 
834 	if (level < 0)
835 		return (0);
836 	for (i = 0; i < limit; i++) {
837 		if (level == *ip++)
838 			return (1);
839 	}
840 #ifdef DEBUG
841 	if (pm_debug & PMD_FAIL) {
842 		ip = cp->pmc_comp.pmc_lvals;
843 
844 		for (i = 0; i < limit; i++)
845 			PMD(PMD_FAIL, ("%s: index=%d, level=%d\n",
846 			    pmf, i, *ip++))
847 	}
848 #endif
849 	return (0);
850 }
851 
852 static int pm_start(dev_info_t *dip);
853 /*
854  * Returns true if device is pm'd (after calling pm_start if need be)
855  */
856 int
857 e_pm_valid_info(dev_info_t *dip, pm_info_t **infop)
858 {
859 	pm_info_t *info;
860 
861 	/*
862 	 * Check if the device is power managed if not.
863 	 * To make the common case (device is power managed already)
864 	 * fast, we check without the lock.  If device is not already
865 	 * power managed, then we take the lock and the long route through
866 	 * go get it managed.  Devices never go unmanaged until they
867 	 * detach.
868 	 */
869 	info = PM_GET_PM_INFO(dip);
870 	if (!info) {
871 		if (!DEVI_IS_ATTACHING(dip)) {
872 			return (0);
873 		}
874 		if (pm_start(dip) != DDI_SUCCESS) {
875 			return (0);
876 		}
877 		info = PM_GET_PM_INFO(dip);
878 	}
879 	ASSERT(info);
880 	if (infop != NULL)
881 		*infop = info;
882 	return (1);
883 }
884 
885 int
886 e_pm_valid_comp(dev_info_t *dip, int cmpt, pm_component_t **cpp)
887 {
888 	if (cmpt >= 0 && cmpt < PM_NUMCMPTS(dip)) {
889 		if (cpp != NULL)
890 			*cpp = PM_CP(dip, cmpt);
891 		return (1);
892 	} else {
893 		return (0);
894 	}
895 }
896 
897 /*
898  * Internal guts of ddi_dev_is_needed and pm_raise/lower_power
899  */
900 static int
901 dev_is_needed(dev_info_t *dip, int cmpt, int level, int direction)
902 {
903 	PMD_FUNC(pmf, "din")
904 	pm_component_t *cp;
905 	char *pathbuf;
906 	int result;
907 
908 	ASSERT(direction == PM_LEVEL_UPONLY || direction == PM_LEVEL_DOWNONLY);
909 	if (!e_pm_valid_info(dip, NULL) || !e_pm_valid_comp(dip, cmpt, &cp) ||
910 	    !e_pm_valid_power(dip, cmpt, level))
911 		return (DDI_FAILURE);
912 
913 	PMD(PMD_DIN, ("%s: %s@%s(%s#%d) cmpt=%d, dir=%s, new=%d, cur=%d\n",
914 	    pmf, PM_DEVICE(dip), cmpt, pm_decode_direction(direction),
915 	    level, cur_power(cp)))
916 
917 	if (pm_set_power(dip, cmpt, level,  direction,
918 	    PM_CANBLOCK_BLOCK, 0, &result) != DDI_SUCCESS) {
919 		if (direction == PM_LEVEL_UPONLY) {
920 			pathbuf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
921 			(void) ddi_pathname(dip, pathbuf);
922 			cmn_err(CE_WARN, "Device %s failed to power up.",
923 			    pathbuf);
924 			kmem_free(pathbuf, MAXPATHLEN);
925 		}
926 		PMD(PMD_DIN | PMD_FAIL, ("%s: %s@%s(%s#%d) [%d] %s->%d failed, "
927 		    "errno %d\n", pmf, PM_DEVICE(dip), cmpt,
928 		    pm_decode_direction(direction), level, result))
929 		return (DDI_FAILURE);
930 	}
931 
932 	PMD(PMD_RESCAN | PMD_DIN, ("%s: pm_rescan %s@%s(%s#%d)\n", pmf,
933 	    PM_DEVICE(dip)))
934 	pm_rescan(dip);
935 	return (DDI_SUCCESS);
936 }
937 
938 /*
939  * We can get multiple pm_rescan() threads, if one of them discovers
940  * that no scan is running at the moment, it kicks it into action.
941  * Otherwise, it tells the current scanning thread to scan again when
942  * it is done by asserting the PM_SCAN_AGAIN flag. The PM_SCANNING and
943  * PM_SCAN_AGAIN flags are used to regulate scan, to make sure only one
944  * thread at a time runs the pm_scan_dev() code.
945  */
946 void
947 pm_rescan(void *arg)
948 {
949 	PMD_FUNC(pmf, "rescan")
950 	dev_info_t	*dip = (dev_info_t *)arg;
951 	pm_info_t	*info;
952 	pm_scan_t	*scanp;
953 	timeout_id_t	scanid;
954 
955 	PMD(PMD_SCAN, ("%s: %s@%s(%s#%d)\n", pmf, PM_DEVICE(dip)))
956 	PM_LOCK_DIP(dip);
957 	info = PM_GET_PM_INFO(dip);
958 	scanp = PM_GET_PM_SCAN(dip);
959 	if (pm_scans_disabled || !PM_SCANABLE(dip) || !info || !scanp ||
960 	    (scanp->ps_scan_flags & PM_SCAN_STOP)) {
961 		PM_UNLOCK_DIP(dip);
962 		return;
963 	}
964 	if (scanp->ps_scan_flags & PM_SCANNING) {
965 		scanp->ps_scan_flags |= PM_SCAN_AGAIN;
966 		PM_UNLOCK_DIP(dip);
967 		return;
968 	} else if (scanp->ps_scan_id) {
969 		scanid = scanp->ps_scan_id;
970 		scanp->ps_scan_id = 0;
971 		PMD(PMD_SCAN, ("%s: %s@%s(%s#%d): cancel timeout scanid %lx\n",
972 		    pmf, PM_DEVICE(dip), (ulong_t)scanid))
973 		PM_UNLOCK_DIP(dip);
974 		(void) untimeout(scanid);
975 		PM_LOCK_DIP(dip);
976 	}
977 
978 	/*
979 	 * Dispatching pm_scan during attach time is risky due to the fact that
980 	 * attach might soon fail and dip dissolved, and panic may happen while
981 	 * attempting to stop scan. So schedule a pm_rescan instead.
982 	 * (Note that if either of the first two terms are true, taskq_dispatch
983 	 * will not be invoked).
984 	 *
985 	 * Multiple pm_scan dispatching is unecessary and costly to keep track
986 	 * of. The PM_SCAN_DISPATCHED flag is used between pm_rescan and pm_scan
987 	 * to regulate the dispatching.
988 	 *
989 	 * Scan is stopped before the device is detached (in pm_detaching())
990 	 * but it may get re-started during the post_detach processing if the
991 	 * driver fails to detach.
992 	 */
993 	if (DEVI_IS_ATTACHING(dip) ||
994 	    (scanp->ps_scan_flags & PM_SCAN_DISPATCHED) ||
995 	    !taskq_dispatch(system_taskq, pm_scan, (void *)dip, TQ_NOSLEEP)) {
996 		PMD(PMD_SCAN, ("%s: %s@%s(%s#%d): attaching, pm_scan already "
997 		    "dispatched or dispatching failed\n", pmf, PM_DEVICE(dip)))
998 		if (scanp->ps_scan_id) {
999 			scanid = scanp->ps_scan_id;
1000 			scanp->ps_scan_id = 0;
1001 			PM_UNLOCK_DIP(dip);
1002 			(void) untimeout(scanid);
1003 			PM_LOCK_DIP(dip);
1004 			if (scanp->ps_scan_id) {
1005 				PMD(PMD_SCAN, ("%s: %s@%s(%s#%d): a competing "
1006 				    "thread scheduled pm_rescan, scanid %lx\n",
1007 				    pmf, PM_DEVICE(dip),
1008 				    (ulong_t)scanp->ps_scan_id))
1009 				PM_UNLOCK_DIP(dip);
1010 				return;
1011 			}
1012 		}
1013 		scanp->ps_scan_id = timeout(pm_rescan, (void *)dip,
1014 		    (scanp->ps_idle_down ? pm_id_ticks :
1015 		    (PM_MIN_SCAN(dip) * hz)));
1016 		PMD(PMD_SCAN, ("%s: %s@%s(%s#%d): scheduled next pm_rescan, "
1017 		    "scanid %lx\n", pmf, PM_DEVICE(dip),
1018 		    (ulong_t)scanp->ps_scan_id))
1019 	} else {
1020 		PMD(PMD_SCAN, ("%s: dispatched pm_scan for %s@%s(%s#%d)\n",
1021 		    pmf, PM_DEVICE(dip)))
1022 		scanp->ps_scan_flags |= PM_SCAN_DISPATCHED;
1023 	}
1024 	PM_UNLOCK_DIP(dip);
1025 }
1026 
1027 void
1028 pm_scan(void *arg)
1029 {
1030 	PMD_FUNC(pmf, "scan")
1031 	dev_info_t	*dip = (dev_info_t *)arg;
1032 	pm_scan_t	*scanp;
1033 	time_t		nextscan;
1034 
1035 	PMD(PMD_SCAN, ("%s: %s@%s(%s#%d)\n", pmf, PM_DEVICE(dip)))
1036 
1037 	PM_LOCK_DIP(dip);
1038 	scanp = PM_GET_PM_SCAN(dip);
1039 	ASSERT(scanp && PM_GET_PM_INFO(dip));
1040 
1041 	if (pm_scans_disabled || !PM_SCANABLE(dip) ||
1042 	    (scanp->ps_scan_flags & PM_SCAN_STOP)) {
1043 		scanp->ps_scan_flags &= ~(PM_SCAN_AGAIN | PM_SCAN_DISPATCHED);
1044 		PM_UNLOCK_DIP(dip);
1045 		return;
1046 	}
1047 
1048 	if (scanp->ps_idle_down) {
1049 		/*
1050 		 * make sure we remember idledown was in affect until
1051 		 * we've completed the scan
1052 		 */
1053 		PMID_SET_SCANS(scanp->ps_idle_down)
1054 		PMD(PMD_IDLEDOWN, ("%s: %s@%s(%s#%d): idledown starts "
1055 		    "(pmid %x)\n", pmf, PM_DEVICE(dip), scanp->ps_idle_down))
1056 	}
1057 
1058 	/* possible having two threads running pm_scan() */
1059 	if (scanp->ps_scan_flags & PM_SCANNING) {
1060 		scanp->ps_scan_flags |= PM_SCAN_AGAIN;
1061 		PMD(PMD_SCAN, ("%s: scanning, will scan %s@%s(%s#%d) again\n",
1062 		    pmf, PM_DEVICE(dip)))
1063 		scanp->ps_scan_flags &= ~PM_SCAN_DISPATCHED;
1064 		PM_UNLOCK_DIP(dip);
1065 		return;
1066 	}
1067 
1068 	scanp->ps_scan_flags |= PM_SCANNING;
1069 	scanp->ps_scan_flags &= ~PM_SCAN_DISPATCHED;
1070 	do {
1071 		scanp->ps_scan_flags &= ~PM_SCAN_AGAIN;
1072 		PM_UNLOCK_DIP(dip);
1073 		nextscan = pm_scan_dev(dip);
1074 		PM_LOCK_DIP(dip);
1075 	} while (scanp->ps_scan_flags & PM_SCAN_AGAIN);
1076 
1077 	ASSERT(scanp->ps_scan_flags & PM_SCANNING);
1078 	scanp->ps_scan_flags &= ~PM_SCANNING;
1079 
1080 	if (scanp->ps_idle_down) {
1081 		scanp->ps_idle_down &= ~PMID_SCANS;
1082 		PMD(PMD_IDLEDOWN, ("%s: %s@%s(%s#%d): idledown ends "
1083 		    "(pmid %x)\n", pmf, PM_DEVICE(dip), scanp->ps_idle_down))
1084 	}
1085 
1086 	/* schedule for next idle check */
1087 	if (nextscan != LONG_MAX) {
1088 		if (nextscan > (LONG_MAX / hz))
1089 			nextscan = (LONG_MAX - 1) / hz;
1090 		if (scanp->ps_scan_id) {
1091 			PMD(PMD_SCAN, ("%s: %s@%s(%s#%d): while scanning "
1092 			    "another rescan scheduled scanid(%lx)\n", pmf,
1093 			    PM_DEVICE(dip), (ulong_t)scanp->ps_scan_id))
1094 			PM_UNLOCK_DIP(dip);
1095 			return;
1096 		} else if (!(scanp->ps_scan_flags & PM_SCAN_STOP)) {
1097 			scanp->ps_scan_id = timeout(pm_rescan, (void *)dip,
1098 			    (clock_t)(nextscan * hz));
1099 			PMD(PMD_SCAN, ("%s: nextscan for %s@%s(%s#%d) in "
1100 			    "%lx sec, scanid(%lx) \n", pmf, PM_DEVICE(dip),
1101 			    (ulong_t)nextscan, (ulong_t)scanp->ps_scan_id))
1102 		}
1103 	}
1104 	PM_UNLOCK_DIP(dip);
1105 }
1106 
1107 void
1108 pm_get_timestamps(dev_info_t *dip, time_t *valuep)
1109 {
1110 	int components = PM_NUMCMPTS(dip);
1111 	int i;
1112 
1113 	ASSERT(components > 0);
1114 	PM_LOCK_BUSY(dip);	/* so we get a consistent view */
1115 	for (i = 0; i < components; i++) {
1116 		valuep[i] = PM_CP(dip, i)->pmc_timestamp;
1117 	}
1118 	PM_UNLOCK_BUSY(dip);
1119 }
1120 
1121 /*
1122  * Returns true if device needs to be kept up because it exported the
1123  * "no-involuntary-power-cycles" property or we're pretending it did (console
1124  * fb case) or it is an ancestor of such a device and has used up the "one
1125  * free cycle" allowed when all such leaf nodes have voluntarily powered down
1126  * upon detach
1127  */
1128 int
1129 pm_noinvol(dev_info_t *dip)
1130 {
1131 	PMD_FUNC(pmf, "noinvol")
1132 
1133 	/*
1134 	 * This doesn't change over the life of a driver, so no locking needed
1135 	 */
1136 	if (PM_IS_CFB(dip)) {
1137 		PMD(PMD_NOINVOL | PMD_CFB, ("%s: inhibits CFB %s@%s(%s#%d)\n",
1138 		    pmf, PM_DEVICE(dip)))
1139 		return (1);
1140 	}
1141 	/*
1142 	 * Not an issue if no such kids
1143 	 */
1144 	if (DEVI(dip)->devi_pm_noinvolpm == 0) {
1145 #ifdef DEBUG
1146 		if (DEVI(dip)->devi_pm_volpmd != 0) {
1147 			dev_info_t *pdip = dip;
1148 			do {
1149 				PMD(PMD_NOINVOL, ("%s: %s@%s(%s#%d) noinvol %d "
1150 				    "volpmd %d\n", pmf, PM_DEVICE(pdip),
1151 				    DEVI(pdip)->devi_pm_noinvolpm,
1152 				    DEVI(pdip)->devi_pm_volpmd))
1153 				pdip = ddi_get_parent(pdip);
1154 			} while (pdip);
1155 		}
1156 #endif
1157 		ASSERT(DEVI(dip)->devi_pm_volpmd == 0);
1158 		return (0);
1159 	}
1160 
1161 	/*
1162 	 * Since we now maintain the counts correct at every node, we no longer
1163 	 * need to look up the tree.  An ancestor cannot use up the free cycle
1164 	 * without the children getting their counts adjusted.
1165 	 */
1166 
1167 #ifdef	DEBUG
1168 	if (DEVI(dip)->devi_pm_noinvolpm != DEVI(dip)->devi_pm_volpmd)
1169 		PMD(PMD_NOINVOL, ("%s: (%d != %d) inhibits %s@%s(%s#%d)\n", pmf,
1170 		    DEVI(dip)->devi_pm_noinvolpm, DEVI(dip)->devi_pm_volpmd,
1171 		    PM_DEVICE(dip)))
1172 #endif
1173 	return (DEVI(dip)->devi_pm_noinvolpm != DEVI(dip)->devi_pm_volpmd);
1174 }
1175 
1176 static int	cur_threshold(dev_info_t *, int);
1177 static int	pm_next_lower_power(pm_component_t *, int);
1178 
1179 /*
1180  * This function performs the actual scanning of the device.
1181  * It attempts to power off the indicated device's components if they have
1182  * been idle and other restrictions are met.
1183  * pm_scan_dev calculates and returns when the next scan should happen for
1184  * this device.
1185  */
1186 time_t
1187 pm_scan_dev(dev_info_t *dip)
1188 {
1189 	PMD_FUNC(pmf, "scan_dev")
1190 	pm_scan_t	*scanp;
1191 	time_t		*timestamp, idletime, now, thresh;
1192 	time_t		timeleft = 0;
1193 #ifdef PMDDEBUG
1194 	int		curpwr;
1195 #endif
1196 	int		i, nxtpwr, pwrndx, unused;
1197 	size_t		size;
1198 	pm_component_t	 *cp;
1199 	dev_info_t	*pdip = ddi_get_parent(dip);
1200 	int		circ;
1201 	clock_t		min_scan = pm_default_min_scan;
1202 
1203 	/*
1204 	 * skip attaching device
1205 	 */
1206 	if (DEVI_IS_ATTACHING(dip)) {
1207 		PMD(PMD_SCAN, ("%s: %s@%s(%s#%d) is attaching, timeleft(%lx)\n",
1208 		    pmf, PM_DEVICE(dip), min_scan))
1209 		return (min_scan);
1210 	}
1211 
1212 	PM_LOCK_DIP(dip);
1213 	scanp = PM_GET_PM_SCAN(dip);
1214 	min_scan = PM_MIN_SCAN(dip);
1215 	ASSERT(scanp && PM_GET_PM_INFO(dip));
1216 
1217 	PMD(PMD_SCAN, ("%s: [BEGIN %s@%s(%s#%d)]\n", pmf, PM_DEVICE(dip)))
1218 	PMD(PMD_SCAN, ("%s: %s@%s(%s#%d): kuc is %d\n", pmf, PM_DEVICE(dip),
1219 	    PM_KUC(dip)))
1220 
1221 	/* no scan under the following conditions */
1222 	if (pm_scans_disabled || !PM_SCANABLE(dip) ||
1223 	    (scanp->ps_scan_flags & PM_SCAN_STOP) ||
1224 	    (PM_KUC(dip) != 0) ||
1225 	    PM_ISDIRECT(dip) || pm_noinvol(dip)) {
1226 		PM_UNLOCK_DIP(dip);
1227 		PMD(PMD_SCAN, ("%s: [END, %s@%s(%s#%d)] no scan, "
1228 		    "scan_disabled(%d), apm_enabled(%d), cpupm(%d), "
1229 		    "kuc(%d), %s directpm, %s pm_noinvol\n",
1230 		    pmf, PM_DEVICE(dip), pm_scans_disabled, autopm_enabled,
1231 		    cpupm, PM_KUC(dip),
1232 		    PM_ISDIRECT(dip) ? "is" : "is not",
1233 		    pm_noinvol(dip) ? "is" : "is not"))
1234 		return (LONG_MAX);
1235 	}
1236 	PM_UNLOCK_DIP(dip);
1237 
1238 	if (!ndi_devi_tryenter(pdip, &circ)) {
1239 		PMD(PMD_SCAN, ("%s: %s@%s(%s#%d) can't hold pdip",
1240 		    pmf, PM_DEVICE(pdip)))
1241 		return ((time_t)1);
1242 	}
1243 	now = gethrestime_sec();
1244 	size = PM_NUMCMPTS(dip) * sizeof (time_t);
1245 	timestamp = kmem_alloc(size, KM_SLEEP);
1246 	pm_get_timestamps(dip, timestamp);
1247 
1248 	/*
1249 	 * Since we removed support for backwards compatible devices,
1250 	 * (see big comment at top of file)
1251 	 * it is no longer required to deal with component 0 last.
1252 	 */
1253 	for (i = 0; i < PM_NUMCMPTS(dip); i++) {
1254 		/*
1255 		 * If already off (an optimization, perhaps)
1256 		 */
1257 		cp = PM_CP(dip, i);
1258 		pwrndx = cp->pmc_cur_pwr;
1259 #ifdef PMDDEBUG
1260 		curpwr = (pwrndx == PM_LEVEL_UNKNOWN) ?
1261 		    PM_LEVEL_UNKNOWN :
1262 		    cp->pmc_comp.pmc_lvals[pwrndx];
1263 #endif
1264 
1265 		if (pwrndx == 0) {
1266 			PMD(PMD_SCAN, ("%s: %s@%s(%s#%d) comp %d off or "
1267 			    "lowest\n", pmf, PM_DEVICE(dip), i))
1268 			/* skip device if off or at its lowest */
1269 			continue;
1270 		}
1271 
1272 		thresh = cur_threshold(dip, i);		/* comp i threshold */
1273 		if ((timestamp[i] == 0) || (cp->pmc_busycount > 0)) {
1274 			/* were busy or newly became busy by another thread */
1275 			if (timeleft == 0)
1276 				timeleft = max(thresh, min_scan);
1277 			else
1278 				timeleft = min(
1279 				    timeleft, max(thresh, min_scan));
1280 			continue;
1281 		}
1282 
1283 		idletime = now - timestamp[i];		/* idle time */
1284 		PMD(PMD_SCAN, ("%s: %s@%s(%s#%d) comp %d idle time %lx\n",
1285 		    pmf, PM_DEVICE(dip), i, idletime))
1286 		if (idletime >= thresh || PM_IS_PID(dip)) {
1287 			nxtpwr = pm_next_lower_power(cp, pwrndx);
1288 			PMD(PMD_SCAN, ("%s: %s@%s(%s#%d) comp %d, %d->%d\n",
1289 			    pmf, PM_DEVICE(dip), i, curpwr, nxtpwr))
1290 			if (pm_set_power(dip, i, nxtpwr, PM_LEVEL_DOWNONLY,
1291 			    PM_CANBLOCK_FAIL, 1, &unused) != DDI_SUCCESS &&
1292 			    PM_CURPOWER(dip, i) != nxtpwr) {
1293 				PMD(PMD_SCAN, ("%s: %s@%s(%s#%d) comp %d, "
1294 				    "%d->%d Failed\n", pmf, PM_DEVICE(dip),
1295 				    i, curpwr, nxtpwr))
1296 				timeleft = min_scan;
1297 				continue;
1298 			} else {
1299 				PMD(PMD_SCAN, ("%s: %s@%s(%s#%d) comp %d, "
1300 				    "%d->%d, GOOD curpwr %d\n", pmf,
1301 				    PM_DEVICE(dip), i, curpwr, nxtpwr,
1302 				    cur_power(cp)))
1303 
1304 				if (nxtpwr == 0)	/* component went off */
1305 					continue;
1306 
1307 				/*
1308 				 * scan to next lower level
1309 				 */
1310 				if (timeleft == 0)
1311 					timeleft = max(
1312 					    1, cur_threshold(dip, i));
1313 				else
1314 					timeleft = min(timeleft,
1315 					    max(1, cur_threshold(dip, i)));
1316 				PMD(PMD_SCAN, ("%s: %s@%s(%s#%d) comp %d, "
1317 				    "timeleft(%lx)\n", pmf, PM_DEVICE(dip),
1318 				    i, timeleft))
1319 			}
1320 		} else {	/* comp not idle long enough */
1321 			if (timeleft == 0)
1322 				timeleft = thresh - idletime;
1323 			else
1324 				timeleft = min(timeleft, (thresh - idletime));
1325 			PMD(PMD_SCAN, ("%s: %s@%s(%s#%d) comp %d, timeleft="
1326 			    "%lx\n", pmf, PM_DEVICE(dip), i, timeleft))
1327 		}
1328 	}
1329 	ndi_devi_exit(pdip, circ);
1330 	kmem_free(timestamp, size);
1331 	PMD(PMD_SCAN, ("%s: [END %s@%s(%s#%d)] timeleft(%lx)\n", pmf,
1332 	    PM_DEVICE(dip), timeleft))
1333 
1334 	/*
1335 	 * if components are already at lowest level, timeleft is left 0
1336 	 */
1337 	return ((timeleft == 0) ? LONG_MAX : timeleft);
1338 }
1339 
1340 /*
1341  * pm_scan_stop - cancel scheduled pm_rescan,
1342  *                wait for termination of dispatched pm_scan thread
1343  *                     and active pm_scan_dev thread.
1344  */
1345 void
1346 pm_scan_stop(dev_info_t *dip)
1347 {
1348 	PMD_FUNC(pmf, "scan_stop")
1349 	pm_scan_t	*scanp;
1350 	timeout_id_t	scanid;
1351 
1352 	PMD(PMD_SCAN, ("%s: [BEGIN %s@%s(%s#%d)]\n", pmf, PM_DEVICE(dip)))
1353 	PM_LOCK_DIP(dip);
1354 	scanp = PM_GET_PM_SCAN(dip);
1355 	if (!scanp) {
1356 		PMD(PMD_SCAN, ("%s: [END %s@%s(%s#%d)] scan not initialized\n",
1357 		    pmf, PM_DEVICE(dip)))
1358 		PM_UNLOCK_DIP(dip);
1359 		return;
1360 	}
1361 	scanp->ps_scan_flags |= PM_SCAN_STOP;
1362 
1363 	/* cancel scheduled scan taskq */
1364 	while (scanp->ps_scan_id) {
1365 		scanid = scanp->ps_scan_id;
1366 		scanp->ps_scan_id = 0;
1367 		PM_UNLOCK_DIP(dip);
1368 		(void) untimeout(scanid);
1369 		PM_LOCK_DIP(dip);
1370 	}
1371 
1372 	while (scanp->ps_scan_flags & (PM_SCANNING | PM_SCAN_DISPATCHED)) {
1373 		PM_UNLOCK_DIP(dip);
1374 		delay(1);
1375 		PM_LOCK_DIP(dip);
1376 	}
1377 	PM_UNLOCK_DIP(dip);
1378 	PMD(PMD_SCAN, ("%s: [END %s@%s(%s#%d)]\n", pmf, PM_DEVICE(dip)))
1379 }
1380 
1381 int
1382 pm_scan_stop_walk(dev_info_t *dip, void *arg)
1383 {
1384 	_NOTE(ARGUNUSED(arg))
1385 
1386 	if (!PM_GET_PM_SCAN(dip))
1387 		return (DDI_WALK_CONTINUE);
1388 	ASSERT(!PM_ISBC(dip));
1389 	pm_scan_stop(dip);
1390 	return (DDI_WALK_CONTINUE);
1391 }
1392 
1393 /*
1394  * Converts a power level value to its index
1395  */
1396 static int
1397 power_val_to_index(pm_component_t *cp, int val)
1398 {
1399 	int limit, i, *ip;
1400 
1401 	ASSERT(val != PM_LEVEL_UPONLY && val != PM_LEVEL_DOWNONLY &&
1402 	    val != PM_LEVEL_EXACT);
1403 	/*  convert power value into index (i) */
1404 	limit = cp->pmc_comp.pmc_numlevels;
1405 	ip = cp->pmc_comp.pmc_lvals;
1406 	for (i = 0; i < limit; i++)
1407 		if (val == *ip++)
1408 			return (i);
1409 	return (-1);
1410 }
1411 
1412 /*
1413  * Converts a numeric power level to a printable string
1414  */
1415 static char *
1416 power_val_to_string(pm_component_t *cp, int val)
1417 {
1418 	int index;
1419 
1420 	if (val == PM_LEVEL_UPONLY)
1421 		return ("<UPONLY>");
1422 
1423 	if (val == PM_LEVEL_UNKNOWN ||
1424 	    (index = power_val_to_index(cp, val)) == -1)
1425 		return ("<LEVEL_UNKNOWN>");
1426 
1427 	return (cp->pmc_comp.pmc_lnames[index]);
1428 }
1429 
1430 /*
1431  * Return true if this node has been claimed by a ppm.
1432  */
1433 static int
1434 pm_ppm_claimed(dev_info_t *dip)
1435 {
1436 	return (PPM(dip) != NULL);
1437 }
1438 
1439 /*
1440  * A node which was voluntarily power managed has just used up its "free cycle"
1441  * and need is volpmd field cleared, and the same done to all its descendents
1442  */
1443 static void
1444 pm_clear_volpm_dip(dev_info_t *dip)
1445 {
1446 	PMD_FUNC(pmf, "clear_volpm_dip")
1447 
1448 	if (dip == NULL)
1449 		return;
1450 	PMD(PMD_NOINVOL, ("%s: clear volpm from %s@%s(%s#%d)\n", pmf,
1451 	    PM_DEVICE(dip)))
1452 	DEVI(dip)->devi_pm_volpmd = 0;
1453 	for (dip = ddi_get_child(dip); dip; dip = ddi_get_next_sibling(dip)) {
1454 		pm_clear_volpm_dip(dip);
1455 	}
1456 }
1457 
1458 /*
1459  * A node which was voluntarily power managed has used up the "free cycles"
1460  * for the subtree that it is the root of.  Scan through the list of detached
1461  * nodes and adjust the counts of any that are descendents of the node.
1462  */
1463 static void
1464 pm_clear_volpm_list(dev_info_t *dip)
1465 {
1466 	PMD_FUNC(pmf, "clear_volpm_list")
1467 	char	*pathbuf;
1468 	size_t	len;
1469 	pm_noinvol_t *ip;
1470 
1471 	pathbuf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
1472 	(void) ddi_pathname(dip, pathbuf);
1473 	len = strlen(pathbuf);
1474 	PMD(PMD_NOINVOL, ("%s: clear volpm list %s\n", pmf, pathbuf))
1475 	rw_enter(&pm_noinvol_rwlock, RW_WRITER);
1476 	for (ip = pm_noinvol_head; ip; ip = ip->ni_next) {
1477 		PMD(PMD_NOINVOL, ("%s: clear volpm: ni_path %s\n", pmf,
1478 		    ip->ni_path))
1479 		if (strncmp(pathbuf, ip->ni_path, len) == 0 &&
1480 		    ip->ni_path[len] == '/') {
1481 			PMD(PMD_NOINVOL, ("%s: clear volpm: %s\n", pmf,
1482 			    ip->ni_path))
1483 			ip->ni_volpmd = 0;
1484 			ip->ni_wasvolpmd = 0;
1485 		}
1486 	}
1487 	kmem_free(pathbuf, MAXPATHLEN);
1488 	rw_exit(&pm_noinvol_rwlock);
1489 }
1490 
1491 /*
1492  * Powers a device, suspending or resuming the driver if it is a backward
1493  * compatible device, calling into ppm to change power level.
1494  * Called with the component's power lock held.
1495  */
1496 static int
1497 power_dev(dev_info_t *dip, int comp, int level, int old_level,
1498     pm_canblock_t canblock, pm_ppm_devlist_t **devlist)
1499 {
1500 	PMD_FUNC(pmf, "power_dev")
1501 	power_req_t power_req;
1502 	int		power_op_ret;	/* DDI_SUCCESS or DDI_FAILURE */
1503 	int		resume_needed = 0;
1504 	int		suspended = 0;
1505 	int		result;
1506 #ifdef PMDDEBUG
1507 	struct pm_component *cp = PM_CP(dip, comp);
1508 #endif
1509 	int		bc = PM_ISBC(dip);
1510 	int pm_all_components_off(dev_info_t *);
1511 	int		clearvolpmd = 0;
1512 	char		pathbuf[MAXNAMELEN];
1513 #ifdef PMDDEBUG
1514 	char *ppmname, *ppmaddr;
1515 #endif
1516 	/*
1517 	 * If this is comp 0 of a backwards compat device and we are
1518 	 * going to take the power away, we need to detach it with
1519 	 * DDI_PM_SUSPEND command.
1520 	 */
1521 	if (bc && comp == 0 && POWERING_OFF(old_level, level)) {
1522 		if (devi_detach(dip, DDI_PM_SUSPEND) != DDI_SUCCESS) {
1523 			/* We could not suspend before turning cmpt zero off */
1524 			PMD(PMD_ERROR, ("%s: could not suspend %s@%s(%s#%d)\n",
1525 			    pmf, PM_DEVICE(dip)))
1526 			return (DDI_FAILURE);
1527 		} else {
1528 			DEVI(dip)->devi_pm_flags |= PMC_SUSPENDED;
1529 			suspended++;
1530 		}
1531 	}
1532 	power_req.request_type = PMR_PPM_SET_POWER;
1533 	power_req.req.ppm_set_power_req.who = dip;
1534 	power_req.req.ppm_set_power_req.cmpt = comp;
1535 	power_req.req.ppm_set_power_req.old_level = old_level;
1536 	power_req.req.ppm_set_power_req.new_level = level;
1537 	power_req.req.ppm_set_power_req.canblock = canblock;
1538 	power_req.req.ppm_set_power_req.cookie = NULL;
1539 #ifdef PMDDEBUG
1540 	if (pm_ppm_claimed(dip)) {
1541 		ppmname = PM_NAME(PPM(dip));
1542 		ppmaddr = PM_ADDR(PPM(dip));
1543 
1544 	} else {
1545 		ppmname = "noppm";
1546 		ppmaddr = "0";
1547 	}
1548 	PMD(PMD_PPM, ("%s: %s@%s(%s#%d):%s[%d] %s (%d) -> %s (%d) via %s@%s\n",
1549 	    pmf, PM_DEVICE(dip), cp->pmc_comp.pmc_name, comp,
1550 	    power_val_to_string(cp, old_level), old_level,
1551 	    power_val_to_string(cp, level), level, ppmname, ppmaddr))
1552 #endif
1553 	/*
1554 	 * If non-bc noinvolpm device is turning first comp on, or noinvolpm
1555 	 * bc device comp 0 is powering on, then we count it as a power cycle
1556 	 * against its voluntary count.
1557 	 */
1558 	if (DEVI(dip)->devi_pm_volpmd &&
1559 	    (!bc && pm_all_components_off(dip) && level != 0) ||
1560 	    (bc && comp == 0 && POWERING_ON(old_level, level)))
1561 		clearvolpmd = 1;
1562 	if ((power_op_ret = pm_ctlops(PPM(dip), dip, DDI_CTLOPS_POWER,
1563 	    &power_req, &result)) == DDI_SUCCESS) {
1564 		/*
1565 		 * Now do involuntary pm accounting;  If we've just cycled power
1566 		 * on a voluntarily pm'd node, and by inference on its entire
1567 		 * subtree, we need to set the subtree (including those nodes
1568 		 * already detached) volpmd counts to 0, and subtract out the
1569 		 * value of the current node's volpmd count from the ancestors
1570 		 */
1571 		if (clearvolpmd) {
1572 			int volpmd = DEVI(dip)->devi_pm_volpmd;
1573 			pm_clear_volpm_dip(dip);
1574 			pm_clear_volpm_list(dip);
1575 			if (volpmd) {
1576 				(void) ddi_pathname(dip, pathbuf);
1577 				(void) pm_noinvol_update(PM_BP_NOINVOL_POWER,
1578 				    volpmd, 0, pathbuf, dip);
1579 			}
1580 		}
1581 	} else {
1582 		PMD(PMD_FAIL, ("%s: can't set comp %d (%s) of %s@%s(%s#%d) "
1583 		    "to level %d (%s)\n", pmf, comp, cp->pmc_comp.pmc_name,
1584 		    PM_DEVICE(dip), level, power_val_to_string(cp, level)))
1585 	}
1586 	/*
1587 	 * If some other devices were also powered up (e.g. other cpus in
1588 	 * the same domain) return a pointer to that list
1589 	 */
1590 	if (devlist) {
1591 		*devlist = (pm_ppm_devlist_t *)
1592 		    power_req.req.ppm_set_power_req.cookie;
1593 	}
1594 	/*
1595 	 * We will have to resume the device if the device is backwards compat
1596 	 * device and either of the following is true:
1597 	 * -This is comp 0 and we have successfully powered it up
1598 	 * -This is comp 0 and we have failed to power it down. Resume is
1599 	 *  needed because we have suspended it above
1600 	 */
1601 
1602 	if (bc && comp == 0) {
1603 		ASSERT(PM_ISDIRECT(dip) || DEVI_IS_DETACHING(dip));
1604 		if (power_op_ret == DDI_SUCCESS) {
1605 			if (POWERING_ON(old_level, level)) {
1606 				/*
1607 				 * It must be either suspended or resumed
1608 				 * via pm_power_has_changed path
1609 				 */
1610 				ASSERT((DEVI(dip)->devi_pm_flags &
1611 				    PMC_SUSPENDED) ||
1612 				    (PM_CP(dip, comp)->pmc_flags &
1613 				    PM_PHC_WHILE_SET_POWER));
1614 
1615 					resume_needed = suspended;
1616 			}
1617 		} else {
1618 			if (POWERING_OFF(old_level, level)) {
1619 				/*
1620 				 * It must be either suspended or resumed
1621 				 * via pm_power_has_changed path
1622 				 */
1623 				ASSERT((DEVI(dip)->devi_pm_flags &
1624 				    PMC_SUSPENDED) ||
1625 				    (PM_CP(dip, comp)->pmc_flags &
1626 				    PM_PHC_WHILE_SET_POWER));
1627 
1628 					resume_needed = suspended;
1629 			}
1630 		}
1631 	}
1632 	if (resume_needed) {
1633 		ASSERT(DEVI(dip)->devi_pm_flags & PMC_SUSPENDED);
1634 		/* ppm is not interested in DDI_PM_RESUME */
1635 		if ((power_op_ret = devi_attach(dip, DDI_PM_RESUME)) ==
1636 		    DDI_SUCCESS) {
1637 			DEVI(dip)->devi_pm_flags &= ~PMC_SUSPENDED;
1638 		} else
1639 			cmn_err(CE_WARN, "!pm: Can't resume %s@%s(%s#%d)",
1640 			    PM_DEVICE(dip));
1641 	}
1642 	return (power_op_ret);
1643 }
1644 
1645 /*
1646  * Return true if we are the owner or a borrower of the devi lock.  See
1647  * pm_lock_power_single() about borrowing the lock.
1648  */
1649 static int
1650 pm_devi_lock_held(dev_info_t *dip)
1651 {
1652 	lock_loan_t *cur;
1653 
1654 	if (DEVI_BUSY_OWNED(dip))
1655 		return (1);
1656 
1657 	/* return false if no locks borrowed */
1658 	if (lock_loan_head.pmlk_next == NULL)
1659 		return (0);
1660 
1661 	mutex_enter(&pm_loan_lock);
1662 	/* see if our thread is registered as a lock borrower. */
1663 	for (cur = lock_loan_head.pmlk_next; cur; cur = cur->pmlk_next)
1664 		if (cur->pmlk_borrower == curthread)
1665 			break;
1666 	mutex_exit(&pm_loan_lock);
1667 
1668 	return (cur != NULL && cur->pmlk_lender == DEVI(dip)->devi_busy_thread);
1669 }
1670 
1671 /*
1672  * pm_set_power: adjusts power level of device.	 Assumes device is power
1673  * manageable & component exists.
1674  *
1675  * Cases which require us to bring up devices we keep up ("wekeepups") for
1676  * backwards compatible devices:
1677  *	component 0 is off and we're bringing it up from 0
1678  *		bring up wekeepup first
1679  *	and recursively when component 0 is off and we bring some other
1680  *	component up from 0
1681  * For devices which are not backward compatible, our dependency notion is much
1682  * simpler.  Unless all components are off, then wekeeps must be on.
1683  * We don't treat component 0 differently.
1684  * Canblock tells how to deal with a direct pm'd device.
1685  * Scan arg tells us if we were called from scan, in which case we don't need
1686  * to go back to the root node and walk down to change power.
1687  */
1688 int
1689 pm_set_power(dev_info_t *dip, int comp, int level, int direction,
1690     pm_canblock_t canblock, int scan, int *retp)
1691 {
1692 	PMD_FUNC(pmf, "set_power")
1693 	char		*pathbuf;
1694 	pm_bp_child_pwrchg_t bpc;
1695 	pm_sp_misc_t	pspm;
1696 	int		ret = DDI_SUCCESS;
1697 	int		unused = DDI_SUCCESS;
1698 	dev_info_t	*pdip = ddi_get_parent(dip);
1699 
1700 #ifdef DEBUG
1701 	int		diverted = 0;
1702 
1703 	/*
1704 	 * This prevents operations on the console from calling prom_printf and
1705 	 * either deadlocking or bringing up the console because of debug
1706 	 * output
1707 	 */
1708 	if (dip == cfb_dip) {
1709 		diverted++;
1710 		mutex_enter(&pm_debug_lock);
1711 		pm_divertdebug++;
1712 		mutex_exit(&pm_debug_lock);
1713 	}
1714 #endif
1715 	ASSERT(direction == PM_LEVEL_UPONLY || direction == PM_LEVEL_DOWNONLY ||
1716 	    direction == PM_LEVEL_EXACT);
1717 	PMD(PMD_SET, ("%s: %s@%s(%s#%d), comp=%d, dir=%s, new=%d\n",
1718 	    pmf, PM_DEVICE(dip), comp, pm_decode_direction(direction), level))
1719 	pathbuf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
1720 	(void) ddi_pathname(dip, pathbuf);
1721 	bpc.bpc_dip = dip;
1722 	bpc.bpc_path = pathbuf;
1723 	bpc.bpc_comp = comp;
1724 	bpc.bpc_olevel = PM_CURPOWER(dip, comp);
1725 	bpc.bpc_nlevel = level;
1726 	pspm.pspm_direction = direction;
1727 	pspm.pspm_errnop = retp;
1728 	pspm.pspm_canblock = canblock;
1729 	pspm.pspm_scan = scan;
1730 	bpc.bpc_private = &pspm;
1731 
1732 	/*
1733 	 * If a config operation is being done (we've locked the parent) or
1734 	 * we already hold the power lock (we've locked the node)
1735 	 * then we can operate directly on the node because we have already
1736 	 * brought up all the ancestors, otherwise, we have to go back to the
1737 	 * top of the tree.
1738 	 */
1739 	if (pm_devi_lock_held(pdip) || pm_devi_lock_held(dip))
1740 		ret = pm_busop_set_power(dip, NULL, BUS_POWER_CHILD_PWRCHG,
1741 		    (void *)&bpc, (void *)&unused);
1742 	else
1743 		ret = pm_busop_bus_power(ddi_root_node(), NULL,
1744 		    BUS_POWER_CHILD_PWRCHG, (void *)&bpc, (void *)&unused);
1745 #ifdef DEBUG
1746 	if (ret != DDI_SUCCESS || *retp != DDI_SUCCESS) {
1747 		PMD(PMD_ERROR, ("%s: %s@%s(%s#%d) can't change power, ret=%d, "
1748 		    "errno=%d\n", pmf, PM_DEVICE(dip), ret, *retp))
1749 	}
1750 	if (diverted) {
1751 		mutex_enter(&pm_debug_lock);
1752 		pm_divertdebug--;
1753 		mutex_exit(&pm_debug_lock);
1754 	}
1755 #endif
1756 	kmem_free(pathbuf, MAXPATHLEN);
1757 	return (ret);
1758 }
1759 
1760 /*
1761  * If holddip is set, then if a dip is found we return with the node held.
1762  *
1763  * This code uses the same locking scheme as e_ddi_hold_devi_by_path
1764  * (resolve_pathname), but it does not drive attach.
1765  */
1766 dev_info_t *
1767 pm_name_to_dip(char *pathname, int holddip)
1768 {
1769 	struct pathname pn;
1770 	char		*component;
1771 	dev_info_t	*parent, *child;
1772 	int		circ;
1773 
1774 	if ((pathname == NULL) || (*pathname != '/'))
1775 		return (NULL);
1776 
1777 	/* setup pathname and allocate component */
1778 	if (pn_get(pathname, UIO_SYSSPACE, &pn))
1779 		return (NULL);
1780 	component = kmem_alloc(MAXNAMELEN, KM_SLEEP);
1781 
1782 	/* start at top, process '/' component */
1783 	parent = child = ddi_root_node();
1784 	ndi_hold_devi(parent);
1785 	pn_skipslash(&pn);
1786 	ASSERT(i_ddi_devi_attached(parent));
1787 
1788 	/* process components of pathname */
1789 	while (pn_pathleft(&pn)) {
1790 		(void) pn_getcomponent(&pn, component);
1791 
1792 		/* enter parent and search for component child */
1793 		ndi_devi_enter(parent, &circ);
1794 		child = ndi_devi_findchild(parent, component);
1795 		if ((child == NULL) || !i_ddi_devi_attached(child)) {
1796 			child = NULL;
1797 			ndi_devi_exit(parent, circ);
1798 			ndi_rele_devi(parent);
1799 			goto out;
1800 		}
1801 
1802 		/* attached child found, hold child and release parent */
1803 		ndi_hold_devi(child);
1804 		ndi_devi_exit(parent, circ);
1805 		ndi_rele_devi(parent);
1806 
1807 		/* child becomes parent, and process next component */
1808 		parent = child;
1809 		pn_skipslash(&pn);
1810 
1811 		/* loop with active ndi_devi_hold of child->parent */
1812 	}
1813 
1814 out:
1815 	pn_free(&pn);
1816 	kmem_free(component, MAXNAMELEN);
1817 
1818 	/* if we are not asked to return with hold, drop current hold */
1819 	if (child && !holddip)
1820 		ndi_rele_devi(child);
1821 	return (child);
1822 }
1823 
1824 /*
1825  * Search for a dependency and mark it unsatisfied
1826  */
1827 static void
1828 pm_unsatisfy(char *keeper, char *kept)
1829 {
1830 	PMD_FUNC(pmf, "unsatisfy")
1831 	pm_pdr_t *dp;
1832 
1833 	PMD(PMD_KEEPS, ("%s: keeper=%s, kept=%s\n", pmf, keeper, kept))
1834 	for (dp = pm_dep_head; dp; dp = dp->pdr_next) {
1835 		if (!dp->pdr_isprop) {
1836 			if (strcmp(dp->pdr_keeper, keeper) == 0 &&
1837 			    (dp->pdr_kept_count > 0) &&
1838 			    strcmp(dp->pdr_kept_paths[0], kept) == 0) {
1839 				if (dp->pdr_satisfied) {
1840 					dp->pdr_satisfied = 0;
1841 					pm_unresolved_deps++;
1842 					PMD(PMD_KEEPS, ("%s: clear satisfied, "
1843 					    "pm_unresolved_deps now %d\n", pmf,
1844 					    pm_unresolved_deps))
1845 				}
1846 			}
1847 		}
1848 	}
1849 }
1850 
1851 /*
1852  * Device dip is being un power managed, it keeps up count other devices.
1853  * We need to release any hold we have on the kept devices, and also
1854  * mark the dependency no longer satisfied.
1855  */
1856 static void
1857 pm_unkeeps(int count, char *keeper, char **keptpaths, int pwr)
1858 {
1859 	PMD_FUNC(pmf, "unkeeps")
1860 	int i, j;
1861 	dev_info_t *kept;
1862 	dev_info_t *dip;
1863 	struct pm_component *cp;
1864 	int keeper_on = 0, circ;
1865 
1866 	PMD(PMD_KEEPS, ("%s: count=%d, keeper=%s, keptpaths=%p\n", pmf, count,
1867 	    keeper, (void *)keptpaths))
1868 	/*
1869 	 * Try to grab keeper. Keeper may have gone away by now,
1870 	 * in this case, used the passed in value pwr
1871 	 */
1872 	dip = pm_name_to_dip(keeper, 1);
1873 	for (i = 0; i < count; i++) {
1874 		/* Release power hold */
1875 		kept = pm_name_to_dip(keptpaths[i], 1);
1876 		if (kept) {
1877 			PMD(PMD_KEEPS, ("%s: %s@%s(%s#%d)[%d]\n", pmf,
1878 			    PM_DEVICE(kept), i))
1879 			/*
1880 			 * We need to check if we skipped a bringup here
1881 			 * because we could have failed the bringup
1882 			 * (ie DIRECT PM device) and have
1883 			 * not increment the count.
1884 			 */
1885 			if ((dip != NULL) && (PM_GET_PM_INFO(dip) != NULL)) {
1886 				keeper_on = 0;
1887 				PM_LOCK_POWER(dip, &circ);
1888 				for (j = 0; j < PM_NUMCMPTS(dip); j++) {
1889 					cp = &DEVI(dip)->devi_pm_components[j];
1890 					if (cur_power(cp)) {
1891 						keeper_on++;
1892 						break;
1893 					}
1894 				}
1895 				if (keeper_on && (PM_SKBU(kept) == 0)) {
1896 					pm_rele_power(kept);
1897 					DEVI(kept)->devi_pm_flags
1898 					    &= ~PMC_SKIP_BRINGUP;
1899 				}
1900 				PM_UNLOCK_POWER(dip, circ);
1901 			} else if (pwr) {
1902 				if (PM_SKBU(kept) == 0) {
1903 					pm_rele_power(kept);
1904 					DEVI(kept)->devi_pm_flags
1905 					    &= ~PMC_SKIP_BRINGUP;
1906 				}
1907 			}
1908 			ddi_release_devi(kept);
1909 		}
1910 		/*
1911 		 * mark this dependency not satisfied
1912 		 */
1913 		pm_unsatisfy(keeper, keptpaths[i]);
1914 	}
1915 	if (dip)
1916 		ddi_release_devi(dip);
1917 }
1918 
1919 /*
1920  * Device kept is being un power managed, it is kept up by keeper.
1921  * We need to mark the dependency no longer satisfied.
1922  */
1923 static void
1924 pm_unkepts(char *kept, char *keeper)
1925 {
1926 	PMD_FUNC(pmf, "unkepts")
1927 	PMD(PMD_KEEPS, ("%s: kept=%s, keeper=%s\n", pmf, kept, keeper))
1928 	ASSERT(keeper != NULL);
1929 	/*
1930 	 * mark this dependency not satisfied
1931 	 */
1932 	pm_unsatisfy(keeper, kept);
1933 }
1934 
1935 /*
1936  * Removes dependency information and hold on the kepts, if the path is a
1937  * path of a keeper.
1938  */
1939 static void
1940 pm_free_keeper(char *path, int pwr)
1941 {
1942 	pm_pdr_t *dp;
1943 	int i;
1944 	size_t length;
1945 
1946 	for (dp = pm_dep_head; dp; dp = dp->pdr_next) {
1947 		if (strcmp(dp->pdr_keeper, path) != 0)
1948 			continue;
1949 		/*
1950 		 * Remove all our kept holds and the dependency records,
1951 		 * then free up the kept lists.
1952 		 */
1953 		pm_unkeeps(dp->pdr_kept_count, path, dp->pdr_kept_paths, pwr);
1954 		if (dp->pdr_kept_count)  {
1955 			for (i = 0; i < dp->pdr_kept_count; i++) {
1956 				length = strlen(dp->pdr_kept_paths[i]);
1957 				kmem_free(dp->pdr_kept_paths[i], length + 1);
1958 			}
1959 			kmem_free(dp->pdr_kept_paths,
1960 			    dp->pdr_kept_count * sizeof (char **));
1961 			dp->pdr_kept_paths = NULL;
1962 			dp->pdr_kept_count = 0;
1963 		}
1964 	}
1965 }
1966 
1967 /*
1968  * Removes the device represented by path from the list of kepts, if the
1969  * path is a path of a kept
1970  */
1971 static void
1972 pm_free_kept(char *path)
1973 {
1974 	pm_pdr_t *dp;
1975 	int i;
1976 	int j, count;
1977 	size_t length;
1978 	char **paths;
1979 
1980 	for (dp = pm_dep_head; dp; dp = dp->pdr_next) {
1981 		if (dp->pdr_kept_count == 0)
1982 			continue;
1983 		count = dp->pdr_kept_count;
1984 		/* Remove this device from the kept path lists */
1985 		for (i = 0; i < count; i++) {
1986 			if (strcmp(dp->pdr_kept_paths[i], path) == 0) {
1987 				pm_unkepts(path, dp->pdr_keeper);
1988 				length = strlen(dp->pdr_kept_paths[i]) + 1;
1989 				kmem_free(dp->pdr_kept_paths[i], length);
1990 				dp->pdr_kept_paths[i] = NULL;
1991 				dp->pdr_kept_count--;
1992 			}
1993 		}
1994 		/* Compact the kept paths array */
1995 		if (dp->pdr_kept_count) {
1996 			length = dp->pdr_kept_count * sizeof (char **);
1997 			paths = kmem_zalloc(length, KM_SLEEP);
1998 			j = 0;
1999 			for (i = 0; i < count; i++) {
2000 				if (dp->pdr_kept_paths[i] != NULL) {
2001 					paths[j] = dp->pdr_kept_paths[i];
2002 					j++;
2003 				}
2004 			}
2005 			ASSERT(j == dp->pdr_kept_count);
2006 		}
2007 		/* Now free the old array and point to the new one */
2008 		kmem_free(dp->pdr_kept_paths, count * sizeof (char **));
2009 		if (dp->pdr_kept_count)
2010 			dp->pdr_kept_paths = paths;
2011 		else
2012 			dp->pdr_kept_paths = NULL;
2013 	}
2014 }
2015 
2016 /*
2017  * Free the dependency information for a device.
2018  */
2019 void
2020 pm_free_keeps(char *path, int pwr)
2021 {
2022 	PMD_FUNC(pmf, "free_keeps")
2023 
2024 #ifdef DEBUG
2025 	int doprdeps = 0;
2026 	void prdeps(char *);
2027 
2028 	PMD(PMD_KEEPS, ("%s: %s\n", pmf, path))
2029 	if (pm_debug & PMD_KEEPS) {
2030 		doprdeps = 1;
2031 		prdeps("pm_free_keeps before");
2032 	}
2033 #endif
2034 	/*
2035 	 * First assume we are a keeper and remove all our kepts.
2036 	 */
2037 	pm_free_keeper(path, pwr);
2038 	/*
2039 	 * Now assume we a kept device, and remove all our records.
2040 	 */
2041 	pm_free_kept(path);
2042 #ifdef	DEBUG
2043 	if (doprdeps) {
2044 		prdeps("pm_free_keeps after");
2045 	}
2046 #endif
2047 }
2048 
2049 static int
2050 pm_is_kept(char *path)
2051 {
2052 	pm_pdr_t *dp;
2053 	int i;
2054 
2055 	for (dp = pm_dep_head; dp; dp = dp->pdr_next) {
2056 		if (dp->pdr_kept_count == 0)
2057 			continue;
2058 		for (i = 0; i < dp->pdr_kept_count; i++) {
2059 			if (strcmp(dp->pdr_kept_paths[i], path) == 0)
2060 				return (1);
2061 		}
2062 	}
2063 	return (0);
2064 }
2065 
2066 static void
2067 e_pm_hold_rele_power(dev_info_t *dip, int cnt)
2068 {
2069 	PMD_FUNC(pmf, "hold_rele_power")
2070 	int circ;
2071 
2072 	if ((dip == NULL) ||
2073 	    (PM_GET_PM_INFO(dip) == NULL) || PM_ISBC(dip))
2074 		return;
2075 
2076 	PM_LOCK_POWER(dip, &circ);
2077 	ASSERT(cnt >= 0 && PM_KUC(dip) >= 0 || cnt < 0 && PM_KUC(dip) > 0);
2078 	PMD(PMD_KIDSUP, ("%s: kidsupcnt for %s@%s(%s#%d) %d->%d\n", pmf,
2079 	    PM_DEVICE(dip), PM_KUC(dip), (PM_KUC(dip) + cnt)))
2080 
2081 	PM_KUC(dip) += cnt;
2082 
2083 	ASSERT(PM_KUC(dip) >= 0);
2084 	PM_UNLOCK_POWER(dip, circ);
2085 
2086 	if (cnt < 0 && PM_KUC(dip) == 0)
2087 		pm_rescan(dip);
2088 }
2089 
2090 #define	MAX_PPM_HANDLERS	4
2091 
2092 kmutex_t ppm_lock;	/* in case we ever do multi-threaded startup */
2093 
2094 struct	ppm_callbacks {
2095 	int (*ppmc_func)(dev_info_t *);
2096 	dev_info_t	*ppmc_dip;
2097 } ppm_callbacks[MAX_PPM_HANDLERS + 1];
2098 
2099 
2100 /*
2101  * This routine calls into all the registered ppms to notify them
2102  * that either all components of power-managed devices are at their
2103  * lowest levels or no longer all are at their lowest levels.
2104  */
2105 static void
2106 pm_ppm_notify_all_lowest(dev_info_t *dip, int mode)
2107 {
2108 	struct ppm_callbacks *ppmcp;
2109 	power_req_t power_req;
2110 	int result = 0;
2111 
2112 	power_req.request_type = PMR_PPM_ALL_LOWEST;
2113 	power_req.req.ppm_all_lowest_req.mode = mode;
2114 	mutex_enter(&ppm_lock);
2115 	for (ppmcp = ppm_callbacks; ppmcp->ppmc_func; ppmcp++)
2116 		(void) pm_ctlops((dev_info_t *)ppmcp->ppmc_dip, dip,
2117 		    DDI_CTLOPS_POWER, &power_req, &result);
2118 	mutex_exit(&ppm_lock);
2119 	if (mode == PM_ALL_LOWEST) {
2120 		if (autoS3_enabled) {
2121 			PMD(PMD_SX, ("pm_ppm_notify_all_lowest triggering "
2122 			    "autos3\n"))
2123 			mutex_enter(&srn_clone_lock);
2124 			if (srn_signal) {
2125 				srn_inuse++;
2126 				PMD(PMD_SX, ("(*srn_signal)(AUTOSX, 3)\n"))
2127 				(*srn_signal)(SRN_TYPE_AUTOSX, 3);
2128 				srn_inuse--;
2129 			} else {
2130 				PMD(PMD_SX, ("srn_signal NULL\n"))
2131 			}
2132 			mutex_exit(&srn_clone_lock);
2133 		} else {
2134 			PMD(PMD_SX, ("pm_ppm_notify_all_lowest autos3 "
2135 			    "disabled\n"));
2136 		}
2137 	}
2138 }
2139 
2140 static void
2141 pm_set_pm_info(dev_info_t *dip, void *value)
2142 {
2143 	DEVI(dip)->devi_pm_info = value;
2144 }
2145 
2146 pm_rsvp_t *pm_blocked_list;
2147 
2148 /*
2149  * Look up an entry in the blocked list by dip and component
2150  */
2151 static pm_rsvp_t *
2152 pm_rsvp_lookup(dev_info_t *dip, int comp)
2153 {
2154 	pm_rsvp_t *p;
2155 	ASSERT(MUTEX_HELD(&pm_rsvp_lock));
2156 	for (p = pm_blocked_list; p; p = p->pr_next)
2157 		if (p->pr_dip == dip && p->pr_comp == comp) {
2158 			return (p);
2159 		}
2160 	return (NULL);
2161 }
2162 
2163 /*
2164  * Called when a device which is direct power managed (or the parent or
2165  * dependent of such a device) changes power, or when a pm clone is closed
2166  * that was direct power managing a device.  This call results in pm_blocked()
2167  * (below) returning.
2168  */
2169 void
2170 pm_proceed(dev_info_t *dip, int cmd, int comp, int newlevel)
2171 {
2172 	PMD_FUNC(pmf, "proceed")
2173 	pm_rsvp_t *found = NULL;
2174 	pm_rsvp_t *p;
2175 
2176 	mutex_enter(&pm_rsvp_lock);
2177 	switch (cmd) {
2178 	/*
2179 	 * we're giving up control, let any pending op continue
2180 	 */
2181 	case PMP_RELEASE:
2182 		for (p = pm_blocked_list; p; p = p->pr_next) {
2183 			if (dip == p->pr_dip) {
2184 				p->pr_retval = PMP_RELEASE;
2185 				PMD(PMD_DPM, ("%s: RELEASE %s@%s(%s#%d)\n",
2186 				    pmf, PM_DEVICE(dip)))
2187 				cv_signal(&p->pr_cv);
2188 			}
2189 		}
2190 		break;
2191 
2192 	/*
2193 	 * process has done PM_SET_CURRENT_POWER; let a matching request
2194 	 * succeed and a non-matching request for the same device fail
2195 	 */
2196 	case PMP_SETPOWER:
2197 		found = pm_rsvp_lookup(dip, comp);
2198 		if (!found)	/* if driver not waiting */
2199 			break;
2200 		/*
2201 		 * This cannot be pm_lower_power, since that can only happen
2202 		 * during detach or probe
2203 		 */
2204 		if (found->pr_newlevel <= newlevel) {
2205 			found->pr_retval = PMP_SUCCEED;
2206 			PMD(PMD_DPM, ("%s: SUCCEED %s@%s(%s#%d)\n", pmf,
2207 			    PM_DEVICE(dip)))
2208 		} else {
2209 			found->pr_retval = PMP_FAIL;
2210 			PMD(PMD_DPM, ("%s: FAIL %s@%s(%s#%d)\n", pmf,
2211 			    PM_DEVICE(dip)))
2212 		}
2213 		cv_signal(&found->pr_cv);
2214 		break;
2215 
2216 	default:
2217 		panic("pm_proceed unknown cmd %d", cmd);
2218 	}
2219 	mutex_exit(&pm_rsvp_lock);
2220 }
2221 
2222 /*
2223  * This routine dispatches new work to the dependency thread. Caller must
2224  * be prepared to block for memory if necessary.
2225  */
2226 void
2227 pm_dispatch_to_dep_thread(int cmd, char *keeper, char *kept, int wait,
2228     int *res, int cached_pwr)
2229 {
2230 	pm_dep_wk_t	*new_work;
2231 
2232 	new_work = kmem_zalloc(sizeof (pm_dep_wk_t), KM_SLEEP);
2233 	new_work->pdw_type = cmd;
2234 	new_work->pdw_wait = wait;
2235 	new_work->pdw_done = 0;
2236 	new_work->pdw_ret = 0;
2237 	new_work->pdw_pwr = cached_pwr;
2238 	cv_init(&new_work->pdw_cv, NULL, CV_DEFAULT, NULL);
2239 	if (keeper != NULL) {
2240 		new_work->pdw_keeper = kmem_zalloc(strlen(keeper) + 1,
2241 		    KM_SLEEP);
2242 		(void) strcpy(new_work->pdw_keeper, keeper);
2243 	}
2244 	if (kept != NULL) {
2245 		new_work->pdw_kept = kmem_zalloc(strlen(kept) + 1, KM_SLEEP);
2246 		(void) strcpy(new_work->pdw_kept, kept);
2247 	}
2248 	mutex_enter(&pm_dep_thread_lock);
2249 	if (pm_dep_thread_workq == NULL) {
2250 		pm_dep_thread_workq = new_work;
2251 		pm_dep_thread_tail = new_work;
2252 		new_work->pdw_next = NULL;
2253 	} else {
2254 		pm_dep_thread_tail->pdw_next = new_work;
2255 		pm_dep_thread_tail = new_work;
2256 		new_work->pdw_next = NULL;
2257 	}
2258 	cv_signal(&pm_dep_thread_cv);
2259 	/* If caller asked for it, wait till it is done. */
2260 	if (wait)  {
2261 		while (!new_work->pdw_done)
2262 			cv_wait(&new_work->pdw_cv, &pm_dep_thread_lock);
2263 		/*
2264 		 * Pass return status, if any, back.
2265 		 */
2266 		if (res != NULL)
2267 			*res = new_work->pdw_ret;
2268 		/*
2269 		 * If we asked to wait, it is our job to free the request
2270 		 * structure.
2271 		 */
2272 		if (new_work->pdw_keeper)
2273 			kmem_free(new_work->pdw_keeper,
2274 			    strlen(new_work->pdw_keeper) + 1);
2275 		if (new_work->pdw_kept)
2276 			kmem_free(new_work->pdw_kept,
2277 			    strlen(new_work->pdw_kept) + 1);
2278 		kmem_free(new_work, sizeof (pm_dep_wk_t));
2279 	}
2280 	mutex_exit(&pm_dep_thread_lock);
2281 }
2282 
2283 /*
2284  * Release the pm resource for this device.
2285  */
2286 void
2287 pm_rem_info(dev_info_t *dip)
2288 {
2289 	PMD_FUNC(pmf, "rem_info")
2290 	int		i, count = 0;
2291 	pm_info_t	*info = PM_GET_PM_INFO(dip);
2292 	dev_info_t	*pdip = ddi_get_parent(dip);
2293 	char		*pathbuf;
2294 	int		work_type = PM_DEP_WK_DETACH;
2295 
2296 	ASSERT(info);
2297 
2298 	ASSERT(!PM_IAM_LOCKING_DIP(dip));
2299 	if (PM_ISDIRECT(dip)) {
2300 		info->pmi_dev_pm_state &= ~PM_DIRECT;
2301 		ASSERT(info->pmi_clone);
2302 		info->pmi_clone = 0;
2303 		pm_proceed(dip, PMP_RELEASE, -1, -1);
2304 	}
2305 	ASSERT(!PM_GET_PM_SCAN(dip));
2306 
2307 	/*
2308 	 * Now adjust parent's kidsupcnt.  BC nodes we check only comp 0,
2309 	 * Others we check all components.  BC node that has already
2310 	 * called pm_destroy_components() has zero component count.
2311 	 * Parents that get notification are not adjusted because their
2312 	 * kidsupcnt is always 0 (or 1 during configuration).
2313 	 */
2314 	PMD(PMD_KEEPS, ("%s: %s@%s(%s#%d) has %d components\n", pmf,
2315 	    PM_DEVICE(dip), PM_NUMCMPTS(dip)))
2316 
2317 	/* node is detached, so we can examine power without locking */
2318 	if (PM_ISBC(dip)) {
2319 		count = (PM_CURPOWER(dip, 0) != 0);
2320 	} else {
2321 		for (i = 0; i < PM_NUMCMPTS(dip); i++)
2322 			count += (PM_CURPOWER(dip, i) != 0);
2323 	}
2324 
2325 	if (PM_NUMCMPTS(dip) && pdip && !PM_WANTS_NOTIFICATION(pdip))
2326 		e_pm_hold_rele_power(pdip, -count);
2327 
2328 	/* Schedule a request to clean up dependency records */
2329 	pathbuf = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
2330 	(void) ddi_pathname(dip, pathbuf);
2331 	pm_dispatch_to_dep_thread(work_type, pathbuf, pathbuf,
2332 	    PM_DEP_NOWAIT, NULL, (count > 0));
2333 	kmem_free(pathbuf, MAXPATHLEN);
2334 
2335 	/*
2336 	 * Adjust the pm_comps_notlowest count since this device is
2337 	 * not being power-managed anymore.
2338 	 */
2339 	for (i = 0; i < PM_NUMCMPTS(dip); i++) {
2340 		pm_component_t *cp = PM_CP(dip, i);
2341 		if (cp->pmc_cur_pwr != 0)
2342 			PM_DECR_NOTLOWEST(dip)
2343 	}
2344 	/*
2345 	 * Once we clear the info pointer, it looks like it is not power
2346 	 * managed to everybody else.
2347 	 */
2348 	pm_set_pm_info(dip, NULL);
2349 	kmem_free(info, sizeof (pm_info_t));
2350 }
2351 
2352 int
2353 pm_get_norm_pwrs(dev_info_t *dip, int **valuep, size_t *length)
2354 {
2355 	int components = PM_NUMCMPTS(dip);
2356 	int *bufp;
2357 	size_t size;
2358 	int i;
2359 
2360 	if (components <= 0) {
2361 		cmn_err(CE_NOTE, "!pm: %s@%s(%s#%d) has no components, "
2362 		    "can't get normal power values\n", PM_DEVICE(dip));
2363 		return (DDI_FAILURE);
2364 	} else {
2365 		size = components * sizeof (int);
2366 		bufp = kmem_alloc(size, KM_SLEEP);
2367 		for (i = 0; i < components; i++) {
2368 			bufp[i] = pm_get_normal_power(dip, i);
2369 		}
2370 	}
2371 	*length = size;
2372 	*valuep = bufp;
2373 	return (DDI_SUCCESS);
2374 }
2375 
2376 static int
2377 pm_reset_timestamps(dev_info_t *dip, void *arg)
2378 {
2379 	_NOTE(ARGUNUSED(arg))
2380 
2381 	int components;
2382 	int	i;
2383 
2384 	if (!PM_GET_PM_INFO(dip))
2385 		return (DDI_WALK_CONTINUE);
2386 	components = PM_NUMCMPTS(dip);
2387 	ASSERT(components > 0);
2388 	PM_LOCK_BUSY(dip);
2389 	for (i = 0; i < components; i++) {
2390 		struct pm_component *cp;
2391 		/*
2392 		 * If the component was not marked as busy,
2393 		 * reset its timestamp to now.
2394 		 */
2395 		cp = PM_CP(dip, i);
2396 		if (cp->pmc_timestamp)
2397 			cp->pmc_timestamp = gethrestime_sec();
2398 	}
2399 	PM_UNLOCK_BUSY(dip);
2400 	return (DDI_WALK_CONTINUE);
2401 }
2402 
2403 /*
2404  * Convert a power level to an index into the levels array (or
2405  * just PM_LEVEL_UNKNOWN in that special case).
2406  */
2407 static int
2408 pm_level_to_index(dev_info_t *dip, pm_component_t *cp, int level)
2409 {
2410 	PMD_FUNC(pmf, "level_to_index")
2411 	int i;
2412 	int limit = cp->pmc_comp.pmc_numlevels;
2413 	int *ip = cp->pmc_comp.pmc_lvals;
2414 
2415 	if (level == PM_LEVEL_UNKNOWN)
2416 		return (level);
2417 
2418 	for (i = 0; i < limit; i++) {
2419 		if (level == *ip++) {
2420 			PMD(PMD_LEVEL, ("%s: %s@%s(%s#%d)[%d] to %x\n",
2421 			    pmf, PM_DEVICE(dip),
2422 			    (int)(cp - DEVI(dip)->devi_pm_components), level))
2423 			return (i);
2424 		}
2425 	}
2426 	panic("pm_level_to_index: level %d not found for device "
2427 	    "%s@%s(%s#%d)", level, PM_DEVICE(dip));
2428 	/*NOTREACHED*/
2429 }
2430 
2431 /*
2432  * Internal function to set current power level
2433  */
2434 static void
2435 e_pm_set_cur_pwr(dev_info_t *dip, pm_component_t *cp, int level)
2436 {
2437 	PMD_FUNC(pmf, "set_cur_pwr")
2438 	int curpwr = (cp->pmc_flags & PM_PHC_WHILE_SET_POWER ?
2439 	    cp->pmc_phc_pwr : cp->pmc_cur_pwr);
2440 
2441 	/*
2442 	 * Nothing to adjust if current & new levels are the same.
2443 	 */
2444 	if (curpwr != PM_LEVEL_UNKNOWN &&
2445 	    level == cp->pmc_comp.pmc_lvals[curpwr])
2446 		return;
2447 
2448 	/*
2449 	 * Keep the count for comps doing transition to/from lowest
2450 	 * level.
2451 	 */
2452 	if (curpwr == 0) {
2453 		PM_INCR_NOTLOWEST(dip);
2454 	} else if (level == cp->pmc_comp.pmc_lvals[0]) {
2455 		PM_DECR_NOTLOWEST(dip);
2456 	}
2457 	cp->pmc_phc_pwr = PM_LEVEL_UNKNOWN;
2458 	cp->pmc_cur_pwr = pm_level_to_index(dip, cp, level);
2459 }
2460 
2461 static int pm_phc_impl(dev_info_t *, int, int, int);
2462 
2463 /*
2464  * This is the default method of setting the power of a device if no ppm
2465  * driver has claimed it.
2466  */
2467 int
2468 pm_power(dev_info_t *dip, int comp, int level)
2469 {
2470 	PMD_FUNC(pmf, "power")
2471 	struct dev_ops	*ops;
2472 	int		(*fn)(dev_info_t *, int, int);
2473 	struct pm_component *cp = PM_CP(dip, comp);
2474 	int retval;
2475 	pm_info_t *info = PM_GET_PM_INFO(dip);
2476 
2477 	PMD(PMD_KIDSUP, ("%s: %s@%s(%s#%d), comp=%d, level=%d\n", pmf,
2478 	    PM_DEVICE(dip), comp, level))
2479 	if (!(ops = ddi_get_driver(dip))) {
2480 		PMD(PMD_FAIL, ("%s: %s@%s(%s#%d) has no ops\n", pmf,
2481 		    PM_DEVICE(dip)))
2482 		return (DDI_FAILURE);
2483 	}
2484 	if ((ops->devo_rev < 2) || !(fn = ops->devo_power)) {
2485 		PMD(PMD_FAIL, ("%s: %s%s\n", pmf,
2486 		    (ops->devo_rev < 2 ? " wrong devo_rev" : ""),
2487 		    (!fn ? " devo_power NULL" : "")))
2488 		return (DDI_FAILURE);
2489 	}
2490 	cp->pmc_flags |= PM_POWER_OP;
2491 	retval = (*fn)(dip, comp, level);
2492 	cp->pmc_flags &= ~PM_POWER_OP;
2493 	if (retval == DDI_SUCCESS) {
2494 		e_pm_set_cur_pwr(dip, PM_CP(dip, comp), level);
2495 		return (DDI_SUCCESS);
2496 	}
2497 
2498 	/*
2499 	 * If pm_power_has_changed() detected a deadlock with pm_power() it
2500 	 * updated only the power level of the component.  If our attempt to
2501 	 * set the device new to a power level above has failed we sync the
2502 	 * total power state via phc code now.
2503 	 */
2504 	if (cp->pmc_flags & PM_PHC_WHILE_SET_POWER) {
2505 		int phc_lvl =
2506 		    cp->pmc_comp.pmc_lvals[cp->pmc_cur_pwr];
2507 
2508 		ASSERT(info);
2509 		(void) pm_phc_impl(dip, comp, phc_lvl, 0);
2510 		PMD(PMD_PHC, ("%s: phc %s@%s(%s#%d) comp=%d level=%d\n",
2511 		    pmf, PM_DEVICE(dip), comp, phc_lvl))
2512 	}
2513 
2514 	PMD(PMD_FAIL, ("%s: can't set comp=%d (%s) of %s@%s(%s#%d) to "
2515 	    "level=%d (%s)\n", pmf, comp, cp->pmc_comp.pmc_name, PM_DEVICE(dip),
2516 	    level, power_val_to_string(cp, level)));
2517 	return (DDI_FAILURE);
2518 }
2519 
2520 int
2521 pm_unmanage(dev_info_t *dip)
2522 {
2523 	PMD_FUNC(pmf, "unmanage")
2524 	power_req_t power_req;
2525 	int result, retval = 0;
2526 
2527 	ASSERT(!PM_IAM_LOCKING_DIP(dip));
2528 	PMD(PMD_REMDEV | PMD_KIDSUP, ("%s: %s@%s(%s#%d)\n", pmf,
2529 	    PM_DEVICE(dip)))
2530 	power_req.request_type = PMR_PPM_UNMANAGE;
2531 	power_req.req.ppm_config_req.who = dip;
2532 	if (pm_ppm_claimed(dip))
2533 		retval = pm_ctlops(PPM(dip), dip, DDI_CTLOPS_POWER,
2534 		    &power_req, &result);
2535 #ifdef DEBUG
2536 	else
2537 		retval = pm_ctlops(PPM(dip), dip, DDI_CTLOPS_POWER,
2538 		    &power_req, &result);
2539 #endif
2540 	ASSERT(retval == DDI_SUCCESS);
2541 	pm_rem_info(dip);
2542 	return (retval);
2543 }
2544 
2545 int
2546 pm_raise_power(dev_info_t *dip, int comp, int level)
2547 {
2548 	if (level < 0)
2549 		return (DDI_FAILURE);
2550 	if (!e_pm_valid_info(dip, NULL) || !e_pm_valid_comp(dip, comp, NULL) ||
2551 	    !e_pm_valid_power(dip, comp, level))
2552 		return (DDI_FAILURE);
2553 
2554 	return (dev_is_needed(dip, comp, level, PM_LEVEL_UPONLY));
2555 }
2556 
2557 int
2558 pm_lower_power(dev_info_t *dip, int comp, int level)
2559 {
2560 	PMD_FUNC(pmf, "pm_lower_power")
2561 
2562 	if (!e_pm_valid_info(dip, NULL) || !e_pm_valid_comp(dip, comp, NULL) ||
2563 	    !e_pm_valid_power(dip, comp, level)) {
2564 		PMD(PMD_FAIL, ("%s: validation checks failed for %s@%s(%s#%d) "
2565 		    "comp=%d level=%d\n", pmf, PM_DEVICE(dip), comp, level))
2566 		return (DDI_FAILURE);
2567 	}
2568 
2569 	if (!DEVI_IS_DETACHING(dip)) {
2570 		PMD(PMD_FAIL, ("%s: %s@%s(%s#%d) not detaching\n",
2571 		    pmf, PM_DEVICE(dip)))
2572 		return (DDI_FAILURE);
2573 	}
2574 
2575 	/*
2576 	 * If we don't care about saving power, or we're treating this node
2577 	 * specially, then this is a no-op
2578 	 */
2579 	if (!PM_SCANABLE(dip) || pm_noinvol(dip)) {
2580 		PMD(PMD_FAIL, ("%s: %s@%s(%s#%d) %s%s%s%s\n",
2581 		    pmf, PM_DEVICE(dip),
2582 		    !autopm_enabled ? "!autopm_enabled " : "",
2583 		    !PM_POLLING_CPUPM ? "!cpupm_polling " : "",
2584 		    PM_CPUPM_DISABLED ? "cpupm_disabled " : "",
2585 		    pm_noinvol(dip) ? "pm_noinvol()" : ""))
2586 		return (DDI_SUCCESS);
2587 	}
2588 
2589 	if (dev_is_needed(dip, comp, level, PM_LEVEL_DOWNONLY) != DDI_SUCCESS) {
2590 		PMD(PMD_FAIL, ("%s: %s@%s(%s#%d) dev_is_needed failed\n", pmf,
2591 		    PM_DEVICE(dip)))
2592 		return (DDI_FAILURE);
2593 	}
2594 	return (DDI_SUCCESS);
2595 }
2596 
2597 /*
2598  * Find the entries struct for a given dip in the blocked list, return it locked
2599  */
2600 static psce_t *
2601 pm_psc_dip_to_direct(dev_info_t *dip, pscc_t **psccp)
2602 {
2603 	pscc_t *p;
2604 	psce_t *psce;
2605 
2606 	rw_enter(&pm_pscc_direct_rwlock, RW_READER);
2607 	for (p = pm_pscc_direct; p; p = p->pscc_next) {
2608 		if (p->pscc_dip == dip) {
2609 			*psccp = p;
2610 			psce = p->pscc_entries;
2611 			mutex_enter(&psce->psce_lock);
2612 			ASSERT(psce);
2613 			rw_exit(&pm_pscc_direct_rwlock);
2614 			return (psce);
2615 		}
2616 	}
2617 	rw_exit(&pm_pscc_direct_rwlock);
2618 	panic("sunpm: no entry for dip %p in direct list", (void *)dip);
2619 	/*NOTREACHED*/
2620 }
2621 
2622 /*
2623  * Write an entry indicating a power level change (to be passed to a process
2624  * later) in the given psce.
2625  * If we were called in the path that brings up the console fb in the
2626  * case of entering the prom, we don't want to sleep.  If the alloc fails, then
2627  * we create a record that has a size of -1, a physaddr of NULL, and that
2628  * has the overflow flag set.
2629  */
2630 static int
2631 psc_entry(ushort_t event, psce_t *psce, dev_info_t *dip, int comp, int new,
2632     int old, int which, pm_canblock_t canblock)
2633 {
2634 	char	buf[MAXNAMELEN];
2635 	pm_state_change_t *p;
2636 	size_t	size;
2637 	caddr_t physpath = NULL;
2638 	int	overrun = 0;
2639 
2640 	ASSERT(MUTEX_HELD(&psce->psce_lock));
2641 	(void) ddi_pathname(dip, buf);
2642 	size = strlen(buf) + 1;
2643 	p = psce->psce_in;
2644 	if (canblock == PM_CANBLOCK_BYPASS) {
2645 		physpath = kmem_alloc(size, KM_NOSLEEP);
2646 		if (physpath == NULL) {
2647 			/*
2648 			 * mark current entry as overrun
2649 			 */
2650 			p->flags |= PSC_EVENT_LOST;
2651 			size = (size_t)-1;
2652 		}
2653 	} else
2654 		physpath = kmem_alloc(size, KM_SLEEP);
2655 	if (p->size) {	/* overflow; mark the next entry */
2656 		if (p->size != (size_t)-1)
2657 			kmem_free(p->physpath, p->size);
2658 		ASSERT(psce->psce_out == p);
2659 		if (p == psce->psce_last) {
2660 			psce->psce_first->flags |= PSC_EVENT_LOST;
2661 			psce->psce_out = psce->psce_first;
2662 		} else {
2663 			(p + 1)->flags |= PSC_EVENT_LOST;
2664 			psce->psce_out = (p + 1);
2665 		}
2666 		overrun++;
2667 	} else if (physpath == NULL) {	/* alloc failed, mark this entry */
2668 		p->flags |= PSC_EVENT_LOST;
2669 		p->size = 0;
2670 		p->physpath = NULL;
2671 	}
2672 	if (which == PSC_INTEREST) {
2673 		mutex_enter(&pm_compcnt_lock);
2674 		if (pm_comps_notlowest == 0)
2675 			p->flags |= PSC_ALL_LOWEST;
2676 		else
2677 			p->flags &= ~PSC_ALL_LOWEST;
2678 		mutex_exit(&pm_compcnt_lock);
2679 	}
2680 	p->event = event;
2681 	p->timestamp = gethrestime_sec();
2682 	p->component = comp;
2683 	p->old_level = old;
2684 	p->new_level = new;
2685 	p->physpath = physpath;
2686 	p->size = size;
2687 	if (physpath != NULL)
2688 		(void) strcpy(p->physpath, buf);
2689 	if (p == psce->psce_last)
2690 		psce->psce_in = psce->psce_first;
2691 	else
2692 		psce->psce_in = ++p;
2693 	mutex_exit(&psce->psce_lock);
2694 	return (overrun);
2695 }
2696 
2697 /*
2698  * Find the next entry on the interest list.  We keep a pointer to the item we
2699  * last returned in the user's cooke.  Returns a locked entries struct.
2700  */
2701 static psce_t *
2702 psc_interest(void **cookie, pscc_t **psccp)
2703 {
2704 	pscc_t *pscc;
2705 	pscc_t **cookiep = (pscc_t **)cookie;
2706 
2707 	if (*cookiep == NULL)
2708 		pscc = pm_pscc_interest;
2709 	else
2710 		pscc = (*cookiep)->pscc_next;
2711 	if (pscc) {
2712 		*cookiep = pscc;
2713 		*psccp = pscc;
2714 		mutex_enter(&pscc->pscc_entries->psce_lock);
2715 		return (pscc->pscc_entries);
2716 	} else {
2717 		return (NULL);
2718 	}
2719 }
2720 
2721 /*
2722  * Create an entry for a process to pick up indicating a power level change.
2723  */
2724 static void
2725 pm_enqueue_notify(ushort_t cmd, dev_info_t *dip, int comp,
2726     int newlevel, int oldlevel, pm_canblock_t canblock)
2727 {
2728 	PMD_FUNC(pmf, "enqueue_notify")
2729 	pscc_t	*pscc;
2730 	psce_t	*psce;
2731 	void		*cookie = NULL;
2732 	int	overrun;
2733 
2734 	ASSERT(MUTEX_HELD(&pm_rsvp_lock));
2735 	switch (cmd) {
2736 	case PSC_PENDING_CHANGE:	/* only for controlling process */
2737 		PMD(PMD_DPM, ("%s: PENDING %s@%s(%s#%d), comp %d, %d -> %d\n",
2738 		    pmf, PM_DEVICE(dip), comp, oldlevel, newlevel))
2739 		psce = pm_psc_dip_to_direct(dip, &pscc);
2740 		ASSERT(psce);
2741 		PMD(PMD_IOCTL, ("%s: PENDING: %s@%s(%s#%d) pm_poll_cnt[%d] "
2742 		    "%d\n", pmf, PM_DEVICE(dip), pscc->pscc_clone,
2743 		    pm_poll_cnt[pscc->pscc_clone]))
2744 		overrun = psc_entry(cmd, psce, dip, comp, newlevel, oldlevel,
2745 		    PSC_DIRECT, canblock);
2746 		PMD(PMD_DPM, ("%s: sig %d\n", pmf, pscc->pscc_clone))
2747 		mutex_enter(&pm_clone_lock);
2748 		if (!overrun)
2749 			pm_poll_cnt[pscc->pscc_clone]++;
2750 		cv_signal(&pm_clones_cv[pscc->pscc_clone]);
2751 		pollwakeup(&pm_pollhead, (POLLRDNORM | POLLIN));
2752 		mutex_exit(&pm_clone_lock);
2753 		break;
2754 	case PSC_HAS_CHANGED:
2755 		PMD(PMD_DPM, ("%s: HAS %s@%s(%s#%d), comp %d, %d -> %d\n",
2756 		    pmf, PM_DEVICE(dip), comp, oldlevel, newlevel))
2757 		if (PM_ISDIRECT(dip) && canblock != PM_CANBLOCK_BYPASS) {
2758 			psce = pm_psc_dip_to_direct(dip, &pscc);
2759 			PMD(PMD_IOCTL, ("%s: HAS: %s@%s(%s#%d) pm_poll_cnt[%d] "
2760 			    "%d\n", pmf, PM_DEVICE(dip), pscc->pscc_clone,
2761 			    pm_poll_cnt[pscc->pscc_clone]))
2762 			overrun = psc_entry(cmd, psce, dip, comp, newlevel,
2763 			    oldlevel, PSC_DIRECT, canblock);
2764 			PMD(PMD_DPM, ("%s: sig %d\n", pmf, pscc->pscc_clone))
2765 			mutex_enter(&pm_clone_lock);
2766 			if (!overrun)
2767 				pm_poll_cnt[pscc->pscc_clone]++;
2768 			cv_signal(&pm_clones_cv[pscc->pscc_clone]);
2769 			pollwakeup(&pm_pollhead, (POLLRDNORM | POLLIN));
2770 			mutex_exit(&pm_clone_lock);
2771 		}
2772 		mutex_enter(&pm_clone_lock);
2773 		rw_enter(&pm_pscc_interest_rwlock, RW_READER);
2774 		while ((psce = psc_interest(&cookie, &pscc)) != NULL) {
2775 			(void) psc_entry(cmd, psce, dip, comp, newlevel,
2776 			    oldlevel, PSC_INTEREST, canblock);
2777 			cv_signal(&pm_clones_cv[pscc->pscc_clone]);
2778 		}
2779 		rw_exit(&pm_pscc_interest_rwlock);
2780 		mutex_exit(&pm_clone_lock);
2781 		break;
2782 #ifdef DEBUG
2783 	default:
2784 		ASSERT(0);
2785 #endif
2786 	}
2787 }
2788 
2789 static void
2790 pm_enqueue_notify_others(pm_ppm_devlist_t **listp, pm_canblock_t canblock)
2791 {
2792 	if (listp) {
2793 		pm_ppm_devlist_t *p, *next = NULL;
2794 
2795 		for (p = *listp; p; p = next) {
2796 			next = p->ppd_next;
2797 			pm_enqueue_notify(PSC_HAS_CHANGED, p->ppd_who,
2798 			    p->ppd_cmpt, p->ppd_new_level, p->ppd_old_level,
2799 			    canblock);
2800 			kmem_free(p, sizeof (pm_ppm_devlist_t));
2801 		}
2802 		*listp = NULL;
2803 	}
2804 }
2805 
2806 /*
2807  * Try to get the power locks of the parent node and target (child)
2808  * node.  Return true if successful (with both locks held) or false
2809  * (with no locks held).
2810  */
2811 static int
2812 pm_try_parent_child_locks(dev_info_t *pdip,
2813     dev_info_t *dip, int *pcircp, int *circp)
2814 {
2815 	if (ndi_devi_tryenter(pdip, pcircp))
2816 		if (PM_TRY_LOCK_POWER(dip, circp)) {
2817 			return (1);
2818 		} else {
2819 			ndi_devi_exit(pdip, *pcircp);
2820 		}
2821 	return (0);
2822 }
2823 
2824 /*
2825  * Determine if the power lock owner is blocked by current thread.
2826  * returns :
2827  * 	1 - If the thread owning the effective power lock (the first lock on
2828  *          which a thread blocks when it does PM_LOCK_POWER) is blocked by
2829  *          a mutex held by the current thread.
2830  *
2831  *	0 - otherwise
2832  *
2833  * Note : This function is called by pm_power_has_changed to determine whether
2834  * it is executing in parallel with pm_set_power.
2835  */
2836 static int
2837 pm_blocked_by_us(dev_info_t *dip)
2838 {
2839 	power_req_t power_req;
2840 	kthread_t *owner;
2841 	int result;
2842 	kmutex_t *mp;
2843 	dev_info_t *ppm = (dev_info_t *)DEVI(dip)->devi_pm_ppm;
2844 
2845 	power_req.request_type = PMR_PPM_POWER_LOCK_OWNER;
2846 	power_req.req.ppm_power_lock_owner_req.who = dip;
2847 	if (pm_ctlops(ppm, dip, DDI_CTLOPS_POWER, &power_req, &result) !=
2848 	    DDI_SUCCESS) {
2849 		/*
2850 		 * It is assumed that if the device is claimed by ppm, ppm
2851 		 * will always implement this request type and it'll always
2852 		 * return success. We panic here, if it fails.
2853 		 */
2854 		panic("pm: Can't determine power lock owner of %s@%s(%s#%d)\n",
2855 		    PM_DEVICE(dip));
2856 		/*NOTREACHED*/
2857 	}
2858 
2859 	if ((owner = power_req.req.ppm_power_lock_owner_req.owner) != NULL &&
2860 	    owner->t_state == TS_SLEEP &&
2861 	    owner->t_sobj_ops &&
2862 	    SOBJ_TYPE(owner->t_sobj_ops) == SOBJ_MUTEX &&
2863 	    (mp = (kmutex_t *)owner->t_wchan) &&
2864 	    mutex_owner(mp) == curthread)
2865 		return (1);
2866 
2867 	return (0);
2868 }
2869 
2870 /*
2871  * Notify parent which wants to hear about a child's power changes.
2872  */
2873 static void
2874 pm_notify_parent(dev_info_t *dip,
2875     dev_info_t *pdip, int comp, int old_level, int level)
2876 {
2877 	pm_bp_has_changed_t bphc;
2878 	pm_sp_misc_t pspm;
2879 	char *pathbuf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
2880 	int result = DDI_SUCCESS;
2881 
2882 	bphc.bphc_dip = dip;
2883 	bphc.bphc_path = ddi_pathname(dip, pathbuf);
2884 	bphc.bphc_comp = comp;
2885 	bphc.bphc_olevel = old_level;
2886 	bphc.bphc_nlevel = level;
2887 	pspm.pspm_canblock = PM_CANBLOCK_BLOCK;
2888 	pspm.pspm_scan = 0;
2889 	bphc.bphc_private = &pspm;
2890 	(void) (*PM_BUS_POWER_FUNC(pdip))(pdip, NULL,
2891 	    BUS_POWER_HAS_CHANGED, (void *)&bphc, (void *)&result);
2892 	kmem_free(pathbuf, MAXPATHLEN);
2893 }
2894 
2895 /*
2896  * Check if we need to resume a BC device, and make the attach call as required.
2897  */
2898 static int
2899 pm_check_and_resume(dev_info_t *dip, int comp, int old_level, int level)
2900 {
2901 	int ret = DDI_SUCCESS;
2902 
2903 	if (PM_ISBC(dip) && comp == 0 && old_level == 0 && level != 0) {
2904 		ASSERT(DEVI(dip)->devi_pm_flags & PMC_SUSPENDED);
2905 		/* ppm is not interested in DDI_PM_RESUME */
2906 		if ((ret = devi_attach(dip, DDI_PM_RESUME)) != DDI_SUCCESS)
2907 			/* XXX Should we mark it resumed, */
2908 			/* even though it failed? */
2909 			cmn_err(CE_WARN, "!pm: Can't resume %s@%s",
2910 			    PM_NAME(dip), PM_ADDR(dip));
2911 		DEVI(dip)->devi_pm_flags &= ~PMC_SUSPENDED;
2912 	}
2913 
2914 	return (ret);
2915 }
2916 
2917 /*
2918  * Tests outside the lock to see if we should bother to enqueue an entry
2919  * for any watching process.  If yes, then caller will take the lock and
2920  * do the full protocol
2921  */
2922 static int
2923 pm_watchers()
2924 {
2925 	if (pm_processes_stopped)
2926 		return (0);
2927 	return (pm_pscc_direct || pm_pscc_interest);
2928 }
2929 
2930 static int pm_phc_impl(dev_info_t *, int, int, int);
2931 
2932 /*
2933  * A driver is reporting that the power of one of its device's components
2934  * has changed.  Update the power state accordingly.
2935  */
2936 int
2937 pm_power_has_changed(dev_info_t *dip, int comp, int level)
2938 {
2939 	PMD_FUNC(pmf, "pm_power_has_changed")
2940 	int ret;
2941 	dev_info_t *pdip = ddi_get_parent(dip);
2942 	struct pm_component *cp;
2943 	int blocked, circ, pcirc, old_level;
2944 
2945 	if (level < 0) {
2946 		PMD(PMD_FAIL, ("%s: %s@%s(%s#%d): bad level=%d\n", pmf,
2947 		    PM_DEVICE(dip), level))
2948 		return (DDI_FAILURE);
2949 	}
2950 
2951 	PMD(PMD_KIDSUP | PMD_DEP, ("%s: %s@%s(%s#%d), comp=%d, level=%d\n", pmf,
2952 	    PM_DEVICE(dip), comp, level))
2953 
2954 	if (!e_pm_valid_info(dip, NULL) || !e_pm_valid_comp(dip, comp, &cp) ||
2955 	    !e_pm_valid_power(dip, comp, level))
2956 		return (DDI_FAILURE);
2957 
2958 	/*
2959 	 * A driver thread calling pm_power_has_changed and another thread
2960 	 * calling pm_set_power can deadlock.  The problem is not resolvable
2961 	 * by changing lock order, so we use pm_blocked_by_us() to detect
2962 	 * this specific deadlock.  If we can't get the lock immediately
2963 	 * and we are deadlocked, just update the component's level, do
2964 	 * notifications, and return.  We intend to update the total power
2965 	 * state later (if the other thread fails to set power to the
2966 	 * desired level).  If we were called because of a power change on a
2967 	 * component that isn't involved in a set_power op, update all state
2968 	 * immediately.
2969 	 */
2970 	cp = PM_CP(dip, comp);
2971 	while (!pm_try_parent_child_locks(pdip, dip, &pcirc, &circ)) {
2972 		if (((blocked = pm_blocked_by_us(dip)) != 0) &&
2973 		    (cp->pmc_flags & PM_POWER_OP)) {
2974 			if (pm_watchers()) {
2975 				mutex_enter(&pm_rsvp_lock);
2976 				pm_enqueue_notify(PSC_HAS_CHANGED, dip, comp,
2977 				    level, cur_power(cp), PM_CANBLOCK_BLOCK);
2978 				mutex_exit(&pm_rsvp_lock);
2979 			}
2980 			if (pdip && PM_WANTS_NOTIFICATION(pdip))
2981 				pm_notify_parent(dip,
2982 				    pdip, comp, cur_power(cp), level);
2983 			(void) pm_check_and_resume(dip,
2984 			    comp, cur_power(cp), level);
2985 
2986 			/*
2987 			 * Stash the old power index, update curpwr, and flag
2988 			 * that the total power state needs to be synched.
2989 			 */
2990 			cp->pmc_flags |= PM_PHC_WHILE_SET_POWER;
2991 			/*
2992 			 * Several pm_power_has_changed calls could arrive
2993 			 * while the set power path remains blocked.  Keep the
2994 			 * oldest old power and the newest new power of any
2995 			 * sequence of phc calls which arrive during deadlock.
2996 			 */
2997 			if (cp->pmc_phc_pwr == PM_LEVEL_UNKNOWN)
2998 				cp->pmc_phc_pwr = cp->pmc_cur_pwr;
2999 			cp->pmc_cur_pwr =
3000 			    pm_level_to_index(dip, cp, level);
3001 			PMD(PMD_PHC, ("%s: deadlock for %s@%s(%s#%d), comp=%d, "
3002 			    "level=%d\n", pmf, PM_DEVICE(dip), comp, level))
3003 			return (DDI_SUCCESS);
3004 		} else
3005 			if (blocked) {	/* blocked, but different cmpt? */
3006 				if (!ndi_devi_tryenter(pdip, &pcirc)) {
3007 					cmn_err(CE_NOTE,
3008 					    "!pm: parent kuc not updated due "
3009 					    "to possible deadlock.\n");
3010 					return (pm_phc_impl(dip,
3011 					    comp, level, 1));
3012 				}
3013 				old_level = cur_power(cp);
3014 				if (pdip && !PM_WANTS_NOTIFICATION(pdip) &&
3015 				    (!PM_ISBC(dip) || comp == 0) &&
3016 				    POWERING_ON(old_level, level))
3017 					pm_hold_power(pdip);
3018 				ret = pm_phc_impl(dip, comp, level, 1);
3019 				if (pdip && !PM_WANTS_NOTIFICATION(pdip)) {
3020 					if ((!PM_ISBC(dip) ||
3021 					    comp == 0) && level == 0 &&
3022 					    old_level != PM_LEVEL_UNKNOWN)
3023 						pm_rele_power(pdip);
3024 				}
3025 				ndi_devi_exit(pdip, pcirc);
3026 				/* child lock not held: deadlock */
3027 				return (ret);
3028 			}
3029 		delay(1);
3030 		PMD(PMD_PHC, ("%s: try lock again\n", pmf))
3031 	}
3032 
3033 	/* non-deadlock case */
3034 	old_level = cur_power(cp);
3035 	if (pdip && !PM_WANTS_NOTIFICATION(pdip) &&
3036 	    (!PM_ISBC(dip) || comp == 0) && POWERING_ON(old_level, level))
3037 		pm_hold_power(pdip);
3038 	ret = pm_phc_impl(dip, comp, level, 1);
3039 	if (pdip && !PM_WANTS_NOTIFICATION(pdip)) {
3040 		if ((!PM_ISBC(dip) || comp == 0) && level == 0 &&
3041 		    old_level != PM_LEVEL_UNKNOWN)
3042 			pm_rele_power(pdip);
3043 	}
3044 	PM_UNLOCK_POWER(dip, circ);
3045 	ndi_devi_exit(pdip, pcirc);
3046 	return (ret);
3047 }
3048 
3049 /*
3050  * Account for power changes to a component of the the console frame buffer.
3051  * If lowering power from full (or "unkown", which is treatd as full)
3052  * we will increment the "components off" count of the fb device.
3053  * Subsequent lowering of the same component doesn't affect the count.  If
3054  * raising a component back to full power, we will decrement the count.
3055  *
3056  * Return: the increment value for pm_cfb_comps_off (-1, 0, or 1)
3057  */
3058 static int
3059 calc_cfb_comps_incr(dev_info_t *dip, int cmpt, int old, int new)
3060 {
3061 	struct pm_component *cp = PM_CP(dip, cmpt);
3062 	int on = (old == PM_LEVEL_UNKNOWN || old == cp->pmc_norm_pwr);
3063 	int want_normal = (new == cp->pmc_norm_pwr);
3064 	int incr = 0;
3065 
3066 	if (on && !want_normal)
3067 		incr = 1;
3068 	else if (!on && want_normal)
3069 		incr = -1;
3070 	return (incr);
3071 }
3072 
3073 /*
3074  * Adjust the count of console frame buffer components < full power.
3075  */
3076 static void
3077 update_comps_off(int incr, dev_info_t *dip)
3078 {
3079 		mutex_enter(&pm_cfb_lock);
3080 		pm_cfb_comps_off += incr;
3081 		ASSERT(pm_cfb_comps_off <= PM_NUMCMPTS(dip));
3082 		mutex_exit(&pm_cfb_lock);
3083 }
3084 
3085 /*
3086  * Update the power state in the framework (via the ppm).  The 'notify'
3087  * argument tells whether to notify watchers.  Power lock is already held.
3088  */
3089 static int
3090 pm_phc_impl(dev_info_t *dip, int comp, int level, int notify)
3091 {
3092 	PMD_FUNC(pmf, "phc_impl")
3093 	power_req_t power_req;
3094 	int i, dodeps = 0;
3095 	dev_info_t *pdip = ddi_get_parent(dip);
3096 	int result;
3097 	int old_level;
3098 	struct pm_component *cp;
3099 	int incr = 0;
3100 	dev_info_t *ppm = (dev_info_t *)DEVI(dip)->devi_pm_ppm;
3101 	int work_type = 0;
3102 	char *pathbuf;
3103 
3104 	/* Must use "official" power level for this test. */
3105 	cp = PM_CP(dip, comp);
3106 	old_level = (cp->pmc_flags & PM_PHC_WHILE_SET_POWER ?
3107 	    cp->pmc_phc_pwr : cp->pmc_cur_pwr);
3108 	if (old_level != PM_LEVEL_UNKNOWN)
3109 		old_level = cp->pmc_comp.pmc_lvals[old_level];
3110 
3111 	if (level == old_level) {
3112 		PMD(PMD_SET, ("%s: %s@%s(%s#%d), comp=%d is already at "
3113 		    "level=%d\n", pmf, PM_DEVICE(dip), comp, level))
3114 		return (DDI_SUCCESS);
3115 	}
3116 
3117 	/*
3118 	 * Tell ppm about this.
3119 	 */
3120 	power_req.request_type = PMR_PPM_POWER_CHANGE_NOTIFY;
3121 	power_req.req.ppm_notify_level_req.who = dip;
3122 	power_req.req.ppm_notify_level_req.cmpt = comp;
3123 	power_req.req.ppm_notify_level_req.new_level = level;
3124 	power_req.req.ppm_notify_level_req.old_level = old_level;
3125 	if (pm_ctlops(ppm, dip, DDI_CTLOPS_POWER, &power_req,
3126 	    &result) == DDI_FAILURE) {
3127 		PMD(PMD_FAIL, ("%s: pm_ctlops %s@%s(%s#%d) to %d failed\n",
3128 		    pmf, PM_DEVICE(dip), level))
3129 		return (DDI_FAILURE);
3130 	}
3131 
3132 	if (PM_IS_CFB(dip)) {
3133 		incr = calc_cfb_comps_incr(dip, comp, old_level, level);
3134 
3135 		if (incr) {
3136 			update_comps_off(incr, dip);
3137 			PMD(PMD_CFB, ("%s: %s@%s(%s#%d) comp=%d %d->%d "
3138 			    "cfb_comps_off->%d\n", pmf, PM_DEVICE(dip),
3139 			    comp, old_level, level, pm_cfb_comps_off))
3140 		}
3141 	}
3142 	e_pm_set_cur_pwr(dip, PM_CP(dip, comp), level);
3143 	result = DDI_SUCCESS;
3144 
3145 	if (notify) {
3146 		if (pdip && PM_WANTS_NOTIFICATION(pdip))
3147 			pm_notify_parent(dip, pdip, comp, old_level, level);
3148 		(void) pm_check_and_resume(dip, comp, old_level, level);
3149 	}
3150 
3151 	/*
3152 	 * Decrement the dependency kidsup count if we turn a device
3153 	 * off.
3154 	 */
3155 	if (POWERING_OFF(old_level, level)) {
3156 		dodeps = 1;
3157 		for (i = 0; i < PM_NUMCMPTS(dip); i++) {
3158 			cp = PM_CP(dip, i);
3159 			if (cur_power(cp)) {
3160 				dodeps = 0;
3161 				break;
3162 			}
3163 		}
3164 		if (dodeps)
3165 			work_type = PM_DEP_WK_POWER_OFF;
3166 	}
3167 
3168 	/*
3169 	 * Increment if we turn it on. Check to see
3170 	 * if other comps are already on, if so,
3171 	 * dont increment.
3172 	 */
3173 	if (POWERING_ON(old_level, level)) {
3174 		dodeps = 1;
3175 		for (i = 0; i < PM_NUMCMPTS(dip); i++) {
3176 			cp = PM_CP(dip, i);
3177 			if (comp == i)
3178 				continue;
3179 			/* -1 also treated as 0 in this case */
3180 			if (cur_power(cp) > 0) {
3181 				dodeps = 0;
3182 				break;
3183 			}
3184 		}
3185 		if (dodeps)
3186 			work_type = PM_DEP_WK_POWER_ON;
3187 	}
3188 
3189 	if (dodeps) {
3190 		pathbuf = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
3191 		(void) ddi_pathname(dip, pathbuf);
3192 		pm_dispatch_to_dep_thread(work_type, pathbuf, NULL,
3193 		    PM_DEP_NOWAIT, NULL, 0);
3194 		kmem_free(pathbuf, MAXPATHLEN);
3195 	}
3196 
3197 	if (notify && (level != old_level) && pm_watchers()) {
3198 		mutex_enter(&pm_rsvp_lock);
3199 		pm_enqueue_notify(PSC_HAS_CHANGED, dip, comp, level, old_level,
3200 		    PM_CANBLOCK_BLOCK);
3201 		mutex_exit(&pm_rsvp_lock);
3202 	}
3203 
3204 	PMD(PMD_RESCAN, ("%s: %s@%s(%s#%d): pm_rescan\n", pmf, PM_DEVICE(dip)))
3205 	pm_rescan(dip);
3206 	return (DDI_SUCCESS);
3207 }
3208 
3209 /*
3210  * This function is called at startup time to notify pm of the existence
3211  * of any platform power managers for this platform.  As a result of
3212  * this registration, each function provided will be called each time
3213  * a device node is attached, until one returns true, and it must claim the
3214  * device node (by returning non-zero) if it wants to be involved in the
3215  * node's power management.  If it does claim the node, then it will
3216  * subsequently be notified of attach and detach events.
3217  *
3218  */
3219 
3220 int
3221 pm_register_ppm(int (*func)(dev_info_t *), dev_info_t *dip)
3222 {
3223 	PMD_FUNC(pmf, "register_ppm")
3224 	struct ppm_callbacks *ppmcp;
3225 	pm_component_t *cp;
3226 	int i, pwr, result, circ;
3227 	power_req_t power_req;
3228 	struct ppm_notify_level_req *p = &power_req.req.ppm_notify_level_req;
3229 	void pm_ppm_claim(dev_info_t *);
3230 
3231 	mutex_enter(&ppm_lock);
3232 	ppmcp = ppm_callbacks;
3233 	for (i = 0; i < MAX_PPM_HANDLERS; i++, ppmcp++) {
3234 		if (ppmcp->ppmc_func == NULL) {
3235 			ppmcp->ppmc_func = func;
3236 			ppmcp->ppmc_dip = dip;
3237 			break;
3238 		}
3239 	}
3240 	mutex_exit(&ppm_lock);
3241 
3242 	if (i >= MAX_PPM_HANDLERS)
3243 		return (DDI_FAILURE);
3244 	while ((dip = ddi_get_parent(dip)) != NULL) {
3245 		if (dip != ddi_root_node() && PM_GET_PM_INFO(dip) == NULL)
3246 			continue;
3247 		pm_ppm_claim(dip);
3248 		/* don't bother with the not power-manageable nodes */
3249 		if (pm_ppm_claimed(dip) && PM_GET_PM_INFO(dip)) {
3250 			/*
3251 			 * Tell ppm about this.
3252 			 */
3253 			power_req.request_type = PMR_PPM_POWER_CHANGE_NOTIFY;
3254 			p->old_level = PM_LEVEL_UNKNOWN;
3255 			p->who = dip;
3256 			PM_LOCK_POWER(dip, &circ);
3257 			for (i = 0; i < PM_NUMCMPTS(dip); i++) {
3258 				cp = PM_CP(dip, i);
3259 				pwr = cp->pmc_cur_pwr;
3260 				if (pwr != PM_LEVEL_UNKNOWN) {
3261 					p->cmpt = i;
3262 					p->new_level = cur_power(cp);
3263 					p->old_level = PM_LEVEL_UNKNOWN;
3264 					if (pm_ctlops(PPM(dip), dip,
3265 					    DDI_CTLOPS_POWER, &power_req,
3266 					    &result) == DDI_FAILURE) {
3267 						PMD(PMD_FAIL, ("%s: pc "
3268 						    "%s@%s(%s#%d) to %d "
3269 						    "fails\n", pmf,
3270 						    PM_DEVICE(dip), pwr))
3271 					}
3272 				}
3273 			}
3274 			PM_UNLOCK_POWER(dip, circ);
3275 		}
3276 	}
3277 	return (DDI_SUCCESS);
3278 }
3279 
3280 /*
3281  * Call the ppm's that have registered and adjust the devinfo struct as
3282  * appropriate.  First one to claim it gets it.  The sets of devices claimed
3283  * by each ppm are assumed to be disjoint.
3284  */
3285 void
3286 pm_ppm_claim(dev_info_t *dip)
3287 {
3288 	struct ppm_callbacks *ppmcp;
3289 
3290 	if (PPM(dip)) {
3291 		return;
3292 	}
3293 	mutex_enter(&ppm_lock);
3294 	for (ppmcp = ppm_callbacks; ppmcp->ppmc_func; ppmcp++) {
3295 		if ((*ppmcp->ppmc_func)(dip)) {
3296 			DEVI(dip)->devi_pm_ppm =
3297 			    (struct dev_info *)ppmcp->ppmc_dip;
3298 			mutex_exit(&ppm_lock);
3299 			return;
3300 		}
3301 	}
3302 	mutex_exit(&ppm_lock);
3303 }
3304 
3305 /*
3306  * Node is being detached so stop autopm until we see if it succeeds, in which
3307  * case pm_stop will be called.  For backwards compatible devices we bring the
3308  * device up to full power on the assumption the detach will succeed.
3309  */
3310 void
3311 pm_detaching(dev_info_t *dip)
3312 {
3313 	PMD_FUNC(pmf, "detaching")
3314 	pm_info_t *info = PM_GET_PM_INFO(dip);
3315 	int iscons;
3316 
3317 	PMD(PMD_REMDEV, ("%s: %s@%s(%s#%d), %d comps\n", pmf, PM_DEVICE(dip),
3318 	    PM_NUMCMPTS(dip)))
3319 	if (info == NULL)
3320 		return;
3321 	ASSERT(DEVI_IS_DETACHING(dip));
3322 	PM_LOCK_DIP(dip);
3323 	info->pmi_dev_pm_state |= PM_DETACHING;
3324 	PM_UNLOCK_DIP(dip);
3325 	if (!PM_ISBC(dip))
3326 		pm_scan_stop(dip);
3327 
3328 	/*
3329 	 * console and old-style devices get brought up when detaching.
3330 	 */
3331 	iscons = PM_IS_CFB(dip);
3332 	if (iscons || PM_ISBC(dip)) {
3333 		(void) pm_all_to_normal(dip, PM_CANBLOCK_BYPASS);
3334 		if (iscons) {
3335 			mutex_enter(&pm_cfb_lock);
3336 			while (cfb_inuse) {
3337 				mutex_exit(&pm_cfb_lock);
3338 				PMD(PMD_CFB, ("%s: delay; cfb_inuse\n", pmf))
3339 				delay(1);
3340 				mutex_enter(&pm_cfb_lock);
3341 			}
3342 			ASSERT(cfb_dip_detaching == NULL);
3343 			ASSERT(cfb_dip);
3344 			cfb_dip_detaching = cfb_dip;	/* case detach fails */
3345 			cfb_dip = NULL;
3346 			mutex_exit(&pm_cfb_lock);
3347 		}
3348 	}
3349 }
3350 
3351 /*
3352  * Node failed to detach.  If it used to be autopm'd, make it so again.
3353  */
3354 void
3355 pm_detach_failed(dev_info_t *dip)
3356 {
3357 	PMD_FUNC(pmf, "detach_failed")
3358 	pm_info_t *info = PM_GET_PM_INFO(dip);
3359 	int pm_all_at_normal(dev_info_t *);
3360 
3361 	if (info == NULL)
3362 		return;
3363 	ASSERT(DEVI_IS_DETACHING(dip));
3364 	if (info->pmi_dev_pm_state & PM_DETACHING) {
3365 		info->pmi_dev_pm_state &= ~PM_DETACHING;
3366 		if (info->pmi_dev_pm_state & PM_ALLNORM_DEFERRED) {
3367 			/* Make sure the operation is still needed */
3368 			if (!pm_all_at_normal(dip)) {
3369 				if (pm_all_to_normal(dip,
3370 				    PM_CANBLOCK_FAIL) != DDI_SUCCESS) {
3371 					PMD(PMD_ERROR, ("%s: could not bring "
3372 					    "%s@%s(%s#%d) to normal\n", pmf,
3373 					    PM_DEVICE(dip)))
3374 				}
3375 			}
3376 			info->pmi_dev_pm_state &= ~PM_ALLNORM_DEFERRED;
3377 		}
3378 	}
3379 	if (!PM_ISBC(dip)) {
3380 		mutex_enter(&pm_scan_lock);
3381 		if (PM_SCANABLE(dip))
3382 			pm_scan_init(dip);
3383 		mutex_exit(&pm_scan_lock);
3384 		pm_rescan(dip);
3385 	}
3386 }
3387 
3388 /* generic Backwards Compatible component */
3389 static char *bc_names[] = {"off", "on"};
3390 
3391 static pm_comp_t bc_comp = {"unknown", 2, NULL, NULL, &bc_names[0]};
3392 
3393 static void
3394 e_pm_default_levels(dev_info_t *dip, pm_component_t *cp, int norm)
3395 {
3396 	pm_comp_t *pmc;
3397 	pmc = &cp->pmc_comp;
3398 	pmc->pmc_numlevels = 2;
3399 	pmc->pmc_lvals[0] = 0;
3400 	pmc->pmc_lvals[1] = norm;
3401 	e_pm_set_cur_pwr(dip, cp, norm);
3402 }
3403 
3404 static void
3405 e_pm_default_components(dev_info_t *dip, int cmpts)
3406 {
3407 	int i;
3408 	pm_component_t *p = DEVI(dip)->devi_pm_components;
3409 
3410 	p = DEVI(dip)->devi_pm_components;
3411 	for (i = 0; i < cmpts; i++, p++) {
3412 		p->pmc_comp = bc_comp;	/* struct assignment */
3413 		p->pmc_comp.pmc_lvals = kmem_zalloc(2 * sizeof (int),
3414 		    KM_SLEEP);
3415 		p->pmc_comp.pmc_thresh = kmem_alloc(2 * sizeof (int),
3416 		    KM_SLEEP);
3417 		p->pmc_comp.pmc_numlevels = 2;
3418 		p->pmc_comp.pmc_thresh[0] = INT_MAX;
3419 		p->pmc_comp.pmc_thresh[1] = INT_MAX;
3420 	}
3421 }
3422 
3423 /*
3424  * Called from functions that require components to exist already to allow
3425  * for their creation by parsing the pm-components property.
3426  * Device will not be power managed as a result of this call
3427  * No locking needed because we're single threaded by the ndi_devi_enter
3428  * done while attaching, and the device isn't visible until after it has
3429  * attached
3430  */
3431 int
3432 pm_premanage(dev_info_t *dip, int style)
3433 {
3434 	PMD_FUNC(pmf, "premanage")
3435 	pm_comp_t	*pcp, *compp;
3436 	int		cmpts, i, norm, error;
3437 	pm_component_t *p = DEVI(dip)->devi_pm_components;
3438 	pm_comp_t *pm_autoconfig(dev_info_t *, int *);
3439 
3440 	ASSERT(!PM_IAM_LOCKING_DIP(dip));
3441 	/*
3442 	 * If this dip has already been processed, don't mess with it
3443 	 */
3444 	if (DEVI(dip)->devi_pm_flags & PMC_COMPONENTS_DONE)
3445 		return (DDI_SUCCESS);
3446 	if (DEVI(dip)->devi_pm_flags & PMC_COMPONENTS_FAILED) {
3447 		return (DDI_FAILURE);
3448 	}
3449 	/*
3450 	 * Look up pm-components property and create components accordingly
3451 	 * If that fails, fall back to backwards compatibility
3452 	 */
3453 	if ((compp = pm_autoconfig(dip, &error)) == NULL) {
3454 		/*
3455 		 * If error is set, the property existed but was not well formed
3456 		 */
3457 		if (error || (style == PM_STYLE_NEW)) {
3458 			DEVI(dip)->devi_pm_flags |= PMC_COMPONENTS_FAILED;
3459 			return (DDI_FAILURE);
3460 		}
3461 		/*
3462 		 * If they don't have the pm-components property, then we
3463 		 * want the old "no pm until PM_SET_DEVICE_THRESHOLDS ioctl"
3464 		 * behavior driver must have called pm_create_components, and
3465 		 * we need to flesh out dummy components
3466 		 */
3467 		if ((cmpts = PM_NUMCMPTS(dip)) == 0) {
3468 			/*
3469 			 * Not really failure, but we don't want the
3470 			 * caller to treat it as success
3471 			 */
3472 			return (DDI_FAILURE);
3473 		}
3474 		DEVI(dip)->devi_pm_flags |= PMC_BC;
3475 		e_pm_default_components(dip, cmpts);
3476 		for (i = 0; i < cmpts; i++) {
3477 			/*
3478 			 * if normal power not set yet, we don't really know
3479 			 * what *ANY* of the power values are.  If normal
3480 			 * power is set, then we assume for this backwards
3481 			 * compatible case that the values are 0, normal power.
3482 			 */
3483 			norm = pm_get_normal_power(dip, i);
3484 			if (norm == (uint_t)-1) {
3485 				PMD(PMD_ERROR, ("%s: %s@%s(%s#%d)[%d]\n", pmf,
3486 				    PM_DEVICE(dip), i))
3487 				return (DDI_FAILURE);
3488 			}
3489 			/*
3490 			 * Components of BC devices start at their normal power,
3491 			 * so count them to be not at their lowest power.
3492 			 */
3493 			PM_INCR_NOTLOWEST(dip);
3494 			e_pm_default_levels(dip, PM_CP(dip, i), norm);
3495 		}
3496 	} else {
3497 		/*
3498 		 * e_pm_create_components was called from pm_autoconfig(), it
3499 		 * creates components with no descriptions (or known levels)
3500 		 */
3501 		cmpts = PM_NUMCMPTS(dip);
3502 		ASSERT(cmpts != 0);
3503 		pcp = compp;
3504 		p = DEVI(dip)->devi_pm_components;
3505 		for (i = 0; i < cmpts; i++, p++) {
3506 			p->pmc_comp = *pcp++;   /* struct assignment */
3507 			ASSERT(PM_CP(dip, i)->pmc_cur_pwr == 0);
3508 			e_pm_set_cur_pwr(dip, PM_CP(dip, i), PM_LEVEL_UNKNOWN);
3509 		}
3510 		if (DEVI(dip)->devi_pm_flags & PMC_CPU_THRESH)
3511 			pm_set_device_threshold(dip, pm_cpu_idle_threshold,
3512 			    PMC_CPU_THRESH);
3513 		else
3514 			pm_set_device_threshold(dip, pm_system_idle_threshold,
3515 			    PMC_DEF_THRESH);
3516 		kmem_free(compp, cmpts * sizeof (pm_comp_t));
3517 	}
3518 	return (DDI_SUCCESS);
3519 }
3520 
3521 /*
3522  * Called from during or after the device's attach to let us know it is ready
3523  * to play autopm.   Look up the pm model and manage the device accordingly.
3524  * Returns system call errno value.
3525  * If DDI_ATTACH and DDI_DETACH were in same namespace, this would be
3526  * a little cleaner
3527  *
3528  * Called with dip lock held, return with dip lock unheld.
3529  */
3530 
3531 int
3532 e_pm_manage(dev_info_t *dip, int style)
3533 {
3534 	PMD_FUNC(pmf, "e_manage")
3535 	pm_info_t	*info;
3536 	dev_info_t	*pdip = ddi_get_parent(dip);
3537 	int	pm_thresh_specd(dev_info_t *);
3538 	int	count;
3539 	char	*pathbuf;
3540 
3541 	if (pm_premanage(dip, style) != DDI_SUCCESS) {
3542 		return (DDI_FAILURE);
3543 	}
3544 	PMD(PMD_KIDSUP, ("%s: %s@%s(%s#%d)\n", pmf, PM_DEVICE(dip)))
3545 	ASSERT(PM_GET_PM_INFO(dip) == NULL);
3546 	info = kmem_zalloc(sizeof (pm_info_t), KM_SLEEP);
3547 
3548 	/*
3549 	 * Now set up parent's kidsupcnt.  BC nodes are assumed to start
3550 	 * out at their normal power, so they are "up", others start out
3551 	 * unknown, which is effectively "up".  Parent which want notification
3552 	 * get kidsupcnt of 0 always.
3553 	 */
3554 	count = (PM_ISBC(dip)) ? 1 : PM_NUMCMPTS(dip);
3555 	if (count && pdip && !PM_WANTS_NOTIFICATION(pdip))
3556 		e_pm_hold_rele_power(pdip, count);
3557 
3558 	pm_set_pm_info(dip, info);
3559 	/*
3560 	 * Apply any recorded thresholds
3561 	 */
3562 	(void) pm_thresh_specd(dip);
3563 
3564 	/*
3565 	 * Do dependency processing.
3566 	 */
3567 	pathbuf = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
3568 	(void) ddi_pathname(dip, pathbuf);
3569 	pm_dispatch_to_dep_thread(PM_DEP_WK_ATTACH, pathbuf, pathbuf,
3570 	    PM_DEP_NOWAIT, NULL, 0);
3571 	kmem_free(pathbuf, MAXPATHLEN);
3572 
3573 	if (!PM_ISBC(dip)) {
3574 		mutex_enter(&pm_scan_lock);
3575 		if (PM_SCANABLE(dip)) {
3576 			pm_scan_init(dip);
3577 			mutex_exit(&pm_scan_lock);
3578 			pm_rescan(dip);
3579 		} else {
3580 			mutex_exit(&pm_scan_lock);
3581 		}
3582 	}
3583 	return (0);
3584 }
3585 
3586 /*
3587  * This is the obsolete exported interface for a driver to find out its
3588  * "normal" (max) power.
3589  * We only get components destroyed while no power management is
3590  * going on (and the device is detached), so we don't need a mutex here
3591  */
3592 int
3593 pm_get_normal_power(dev_info_t *dip, int comp)
3594 {
3595 
3596 	if (comp >= 0 && comp < PM_NUMCMPTS(dip)) {
3597 		return (PM_CP(dip, comp)->pmc_norm_pwr);
3598 	}
3599 	return (DDI_FAILURE);
3600 }
3601 
3602 /*
3603  * Fetches the current power level.  Return DDI_SUCCESS or DDI_FAILURE.
3604  */
3605 int
3606 pm_get_current_power(dev_info_t *dip, int comp, int *levelp)
3607 {
3608 	if (comp >= 0 && comp < PM_NUMCMPTS(dip)) {
3609 		*levelp = PM_CURPOWER(dip, comp);
3610 		return (DDI_SUCCESS);
3611 	}
3612 	return (DDI_FAILURE);
3613 }
3614 
3615 /*
3616  * Returns current threshold of indicated component
3617  */
3618 static int
3619 cur_threshold(dev_info_t *dip, int comp)
3620 {
3621 	pm_component_t *cp = PM_CP(dip, comp);
3622 	int pwr;
3623 
3624 	if (PM_ISBC(dip)) {
3625 		/*
3626 		 * backwards compatible nodes only have one threshold
3627 		 */
3628 		return (cp->pmc_comp.pmc_thresh[1]);
3629 	}
3630 	pwr = cp->pmc_cur_pwr;
3631 	if (pwr == PM_LEVEL_UNKNOWN) {
3632 		int thresh;
3633 		if (DEVI(dip)->devi_pm_flags & PMC_NEXDEF_THRESH)
3634 			thresh = pm_default_nexus_threshold;
3635 		else if (DEVI(dip)->devi_pm_flags & PMC_CPU_THRESH)
3636 			thresh = pm_cpu_idle_threshold;
3637 		else
3638 			thresh = pm_system_idle_threshold;
3639 		return (thresh);
3640 	}
3641 	ASSERT(cp->pmc_comp.pmc_thresh);
3642 	return (cp->pmc_comp.pmc_thresh[pwr]);
3643 }
3644 
3645 /*
3646  * Compute next lower component power level given power index.
3647  */
3648 static int
3649 pm_next_lower_power(pm_component_t *cp, int pwrndx)
3650 {
3651 	int nxt_pwr;
3652 
3653 	if (pwrndx == PM_LEVEL_UNKNOWN) {
3654 		nxt_pwr = cp->pmc_comp.pmc_lvals[0];
3655 	} else {
3656 		pwrndx--;
3657 		ASSERT(pwrndx >= 0);
3658 		nxt_pwr = cp->pmc_comp.pmc_lvals[pwrndx];
3659 	}
3660 	return (nxt_pwr);
3661 }
3662 
3663 /*
3664  * Update the maxpower (normal) power of a component. Note that the
3665  * component's power level is only changed if it's current power level
3666  * is higher than the new max power.
3667  */
3668 int
3669 pm_update_maxpower(dev_info_t *dip, int comp, int level)
3670 {
3671 	PMD_FUNC(pmf, "update_maxpower")
3672 	int old;
3673 	int result;
3674 
3675 	if (!e_pm_valid_info(dip, NULL) || !e_pm_valid_comp(dip, comp, NULL) ||
3676 	    !e_pm_valid_power(dip, comp, level)) {
3677 		PMD(PMD_FAIL, ("%s: validation checks failed for %s@%s(%s#%d) "
3678 		    "comp=%d level=%d\n", pmf, PM_DEVICE(dip), comp, level))
3679 		return (DDI_FAILURE);
3680 	}
3681 	old = e_pm_get_max_power(dip, comp);
3682 	e_pm_set_max_power(dip, comp, level);
3683 
3684 	if (pm_set_power(dip, comp, level, PM_LEVEL_DOWNONLY,
3685 	    PM_CANBLOCK_BLOCK, 0, &result) != DDI_SUCCESS) {
3686 		e_pm_set_max_power(dip, comp, old);
3687 		PMD(PMD_FAIL, ("%s: %s@%s(%s#%d) pm_set_power failed\n", pmf,
3688 		    PM_DEVICE(dip)))
3689 		return (DDI_FAILURE);
3690 	}
3691 	return (DDI_SUCCESS);
3692 }
3693 
3694 /*
3695  * Bring all components of device to normal power
3696  */
3697 int
3698 pm_all_to_normal(dev_info_t *dip, pm_canblock_t canblock)
3699 {
3700 	PMD_FUNC(pmf, "all_to_normal")
3701 	int		*normal;
3702 	int		i, ncomps, result;
3703 	size_t		size;
3704 	int		changefailed = 0;
3705 
3706 	PMD(PMD_ALLNORM, ("%s: %s@%s(%s#%d)\n", pmf, PM_DEVICE(dip)))
3707 	ASSERT(PM_GET_PM_INFO(dip));
3708 	if (pm_get_norm_pwrs(dip, &normal, &size) != DDI_SUCCESS) {
3709 		PMD(PMD_ALLNORM, ("%s: can't get norm pwrs for "
3710 		    "%s@%s(%s#%d)\n", pmf, PM_DEVICE(dip)))
3711 		return (DDI_FAILURE);
3712 	}
3713 	ncomps = PM_NUMCMPTS(dip);
3714 	for (i = 0; i < ncomps; i++) {
3715 		if (pm_set_power(dip, i, normal[i],
3716 		    PM_LEVEL_UPONLY, canblock, 0, &result) != DDI_SUCCESS) {
3717 			changefailed++;
3718 			PMD(PMD_ALLNORM | PMD_FAIL, ("%s: failed to set "
3719 			    "%s@%s(%s#%d)[%d] to %d, errno %d\n", pmf,
3720 			    PM_DEVICE(dip), i, normal[i], result))
3721 		}
3722 	}
3723 	kmem_free(normal, size);
3724 	if (changefailed) {
3725 		PMD(PMD_FAIL, ("%s: failed to set %d comps %s@%s(%s#%d) "
3726 		    "to full power\n", pmf, changefailed, PM_DEVICE(dip)))
3727 		return (DDI_FAILURE);
3728 	}
3729 	return (DDI_SUCCESS);
3730 }
3731 
3732 /*
3733  * Returns true if all components of device are at normal power
3734  */
3735 int
3736 pm_all_at_normal(dev_info_t *dip)
3737 {
3738 	PMD_FUNC(pmf, "all_at_normal")
3739 	int		*normal;
3740 	int		i;
3741 	size_t		size;
3742 
3743 	PMD(PMD_ALLNORM, ("%s: %s@%s(%s#%d)\n", pmf, PM_DEVICE(dip)))
3744 	if (pm_get_norm_pwrs(dip, &normal, &size) != DDI_SUCCESS) {
3745 		PMD(PMD_ALLNORM, ("%s: can't get normal power\n", pmf))
3746 		return (DDI_FAILURE);
3747 	}
3748 	for (i = 0; i < PM_NUMCMPTS(dip); i++) {
3749 		int current = PM_CURPOWER(dip, i);
3750 		if (normal[i] > current) {
3751 			PMD(PMD_ALLNORM, ("%s: %s@%s(%s#%d) comp=%d, "
3752 			    "norm=%d, cur=%d\n", pmf, PM_DEVICE(dip), i,
3753 			    normal[i], current))
3754 			break;
3755 		}
3756 	}
3757 	kmem_free(normal, size);
3758 	if (i != PM_NUMCMPTS(dip)) {
3759 		return (0);
3760 	}
3761 	return (1);
3762 }
3763 
3764 static void bring_pmdep_up(dev_info_t *, int);
3765 
3766 static void
3767 bring_wekeeps_up(char *keeper)
3768 {
3769 	PMD_FUNC(pmf, "bring_wekeeps_up")
3770 	int i;
3771 	pm_pdr_t *dp;
3772 	pm_info_t *wku_info;
3773 	char *kept_path;
3774 	dev_info_t *kept;
3775 
3776 	if (panicstr) {
3777 		return;
3778 	}
3779 	/*
3780 	 * We process the request even if the keeper detaches because
3781 	 * detach processing expects this to increment kidsupcnt of kept.
3782 	 */
3783 	PMD(PMD_BRING, ("%s: keeper= %s\n", pmf, keeper))
3784 	for (dp = pm_dep_head; dp; dp = dp->pdr_next) {
3785 		if (strcmp(dp->pdr_keeper, keeper) != 0)
3786 			continue;
3787 		for (i = 0; i < dp->pdr_kept_count; i++) {
3788 			kept_path = dp->pdr_kept_paths[i];
3789 			if (kept_path == NULL)
3790 				continue;
3791 			ASSERT(kept_path[0] != '\0');
3792 			if ((kept = pm_name_to_dip(kept_path, 1)) == NULL)
3793 				continue;
3794 			wku_info = PM_GET_PM_INFO(kept);
3795 			if (wku_info == NULL) {
3796 				if (kept)
3797 					ddi_release_devi(kept);
3798 				continue;
3799 			}
3800 			/*
3801 			 * Don't mess with it if it is being detached, it isn't
3802 			 * safe to call its power entry point
3803 			 */
3804 			if (wku_info->pmi_dev_pm_state & PM_DETACHING) {
3805 				if (kept)
3806 					ddi_release_devi(kept);
3807 				continue;
3808 			}
3809 			bring_pmdep_up(kept, 1);
3810 			ddi_release_devi(kept);
3811 		}
3812 	}
3813 }
3814 
3815 /*
3816  * Bring up the 'kept' device passed as argument
3817  */
3818 static void
3819 bring_pmdep_up(dev_info_t *kept_dip, int hold)
3820 {
3821 	PMD_FUNC(pmf, "bring_pmdep_up")
3822 	int is_all_at_normal = 0;
3823 
3824 	/*
3825 	 * If the kept device has been unmanaged, do nothing.
3826 	 */
3827 	if (!PM_GET_PM_INFO(kept_dip))
3828 		return;
3829 
3830 	/* Just ignore DIRECT PM device till they are released. */
3831 	if (!pm_processes_stopped && PM_ISDIRECT(kept_dip) &&
3832 	    !(is_all_at_normal = pm_all_at_normal(kept_dip))) {
3833 		PMD(PMD_BRING, ("%s: can't bring up PM_DIRECT %s@%s(%s#%d) "
3834 		    "controlling process did something else\n", pmf,
3835 		    PM_DEVICE(kept_dip)))
3836 		DEVI(kept_dip)->devi_pm_flags |= PMC_SKIP_BRINGUP;
3837 		return;
3838 	}
3839 	/* if we got here the keeper had a transition from OFF->ON */
3840 	if (hold)
3841 		pm_hold_power(kept_dip);
3842 
3843 	if (!is_all_at_normal)
3844 		(void) pm_all_to_normal(kept_dip, PM_CANBLOCK_FAIL);
3845 }
3846 
3847 /*
3848  * A bunch of stuff that belongs only to the next routine (or two)
3849  */
3850 
3851 static const char namestr[] = "NAME=";
3852 static const int nameln = sizeof (namestr) - 1;
3853 static const char pmcompstr[] = "pm-components";
3854 
3855 struct pm_comp_pkg {
3856 	pm_comp_t		*comp;
3857 	struct pm_comp_pkg	*next;
3858 };
3859 
3860 #define	isdigit(ch)	((ch) >= '0' && (ch) <= '9')
3861 
3862 #define	isxdigit(ch)	(isdigit(ch) || ((ch) >= 'a' && (ch) <= 'f') || \
3863 			((ch) >= 'A' && (ch) <= 'F'))
3864 
3865 /*
3866  * Rather than duplicate this code ...
3867  * (this code excerpted from the function that follows it)
3868  */
3869 #define	FINISH_COMP { \
3870 	ASSERT(compp); \
3871 	compp->pmc_lnames_sz = size; \
3872 	tp = compp->pmc_lname_buf = kmem_alloc(size, KM_SLEEP); \
3873 	compp->pmc_numlevels = level; \
3874 	compp->pmc_lnames = kmem_alloc(level * sizeof (char *), KM_SLEEP); \
3875 	compp->pmc_lvals = kmem_alloc(level * sizeof (int), KM_SLEEP); \
3876 	compp->pmc_thresh = kmem_alloc(level * sizeof (int), KM_SLEEP); \
3877 	/* copy string out of prop array into buffer */ \
3878 	for (j = 0; j < level; j++) { \
3879 		compp->pmc_thresh[j] = INT_MAX;		/* only [0] sticks */ \
3880 		compp->pmc_lvals[j] = lvals[j]; \
3881 		(void) strcpy(tp, lnames[j]); \
3882 		compp->pmc_lnames[j] = tp; \
3883 		tp += lszs[j]; \
3884 	} \
3885 	ASSERT(tp > compp->pmc_lname_buf && tp <= \
3886 	    compp->pmc_lname_buf + compp->pmc_lnames_sz); \
3887 	}
3888 
3889 /*
3890  * Create (empty) component data structures.
3891  */
3892 static void
3893 e_pm_create_components(dev_info_t *dip, int num_components)
3894 {
3895 	struct pm_component *compp, *ocompp;
3896 	int i, size = 0;
3897 
3898 	ASSERT(!PM_IAM_LOCKING_DIP(dip));
3899 	ASSERT(!DEVI(dip)->devi_pm_components);
3900 	ASSERT(!(DEVI(dip)->devi_pm_flags & PMC_COMPONENTS_DONE));
3901 	size = sizeof (struct pm_component) * num_components;
3902 
3903 	compp = kmem_zalloc(size, KM_SLEEP);
3904 	ocompp = compp;
3905 	DEVI(dip)->devi_pm_comp_size = size;
3906 	DEVI(dip)->devi_pm_num_components = num_components;
3907 	PM_LOCK_BUSY(dip);
3908 	for (i = 0; i < num_components;  i++) {
3909 		compp->pmc_timestamp = gethrestime_sec();
3910 		compp->pmc_norm_pwr = (uint_t)-1;
3911 		compp++;
3912 	}
3913 	PM_UNLOCK_BUSY(dip);
3914 	DEVI(dip)->devi_pm_components = ocompp;
3915 	DEVI(dip)->devi_pm_flags |= PMC_COMPONENTS_DONE;
3916 }
3917 
3918 /*
3919  * Parse hex or decimal value from char string
3920  */
3921 static char *
3922 pm_parsenum(char *cp, int *valp)
3923 {
3924 	int ch, offset;
3925 	char numbuf[256];
3926 	char *np = numbuf;
3927 	int value = 0;
3928 
3929 	ch = *cp++;
3930 	if (isdigit(ch)) {
3931 		if (ch == '0') {
3932 			if ((ch = *cp++) == 'x' || ch == 'X') {
3933 				ch = *cp++;
3934 				while (isxdigit(ch)) {
3935 					*np++ = (char)ch;
3936 					ch = *cp++;
3937 				}
3938 				*np = 0;
3939 				cp--;
3940 				goto hexval;
3941 			} else {
3942 				goto digit;
3943 			}
3944 		} else {
3945 digit:
3946 			while (isdigit(ch)) {
3947 				*np++ = (char)ch;
3948 				ch = *cp++;
3949 			}
3950 			*np = 0;
3951 			cp--;
3952 			goto decval;
3953 		}
3954 	} else
3955 		return (NULL);
3956 
3957 hexval:
3958 	for (np = numbuf; *np; np++) {
3959 		if (*np >= 'a' && *np <= 'f')
3960 			offset = 'a' - 10;
3961 		else if (*np >= 'A' && *np <= 'F')
3962 			offset = 'A' - 10;
3963 		else if (*np >= '0' && *np <= '9')
3964 			offset = '0';
3965 		value *= 16;
3966 		value += *np - offset;
3967 	}
3968 	*valp = value;
3969 	return (cp);
3970 
3971 decval:
3972 	offset = '0';
3973 	for (np = numbuf; *np; np++) {
3974 		value *= 10;
3975 		value += *np - offset;
3976 	}
3977 	*valp = value;
3978 	return (cp);
3979 }
3980 
3981 /*
3982  * Set max (previously documented as "normal") power.
3983  */
3984 static void
3985 e_pm_set_max_power(dev_info_t *dip, int component_number, int level)
3986 {
3987 	PM_CP(dip, component_number)->pmc_norm_pwr = level;
3988 }
3989 
3990 /*
3991  * Get max (previously documented as "normal") power.
3992  */
3993 static int
3994 e_pm_get_max_power(dev_info_t *dip, int component_number)
3995 {
3996 	return (PM_CP(dip, component_number)->pmc_norm_pwr);
3997 }
3998 
3999 /*
4000  * Internal routine for destroying components
4001  * It is called even when there might not be any, so it must be forgiving.
4002  */
4003 static void
4004 e_pm_destroy_components(dev_info_t *dip)
4005 {
4006 	int i;
4007 	struct pm_component *cp;
4008 
4009 	ASSERT(!PM_IAM_LOCKING_DIP(dip));
4010 	if (PM_NUMCMPTS(dip) == 0)
4011 		return;
4012 	cp = DEVI(dip)->devi_pm_components;
4013 	ASSERT(cp);
4014 	for (i = 0; i < PM_NUMCMPTS(dip); i++, cp++) {
4015 		int nlevels = cp->pmc_comp.pmc_numlevels;
4016 		kmem_free(cp->pmc_comp.pmc_lvals, nlevels * sizeof (int));
4017 		kmem_free(cp->pmc_comp.pmc_thresh, nlevels * sizeof (int));
4018 		/*
4019 		 * For BC nodes, the rest is static in bc_comp, so skip it
4020 		 */
4021 		if (PM_ISBC(dip))
4022 			continue;
4023 		kmem_free(cp->pmc_comp.pmc_name, cp->pmc_comp.pmc_name_sz);
4024 		kmem_free(cp->pmc_comp.pmc_lnames, nlevels * sizeof (char *));
4025 		kmem_free(cp->pmc_comp.pmc_lname_buf,
4026 		    cp->pmc_comp.pmc_lnames_sz);
4027 	}
4028 	kmem_free(DEVI(dip)->devi_pm_components, DEVI(dip)->devi_pm_comp_size);
4029 	DEVI(dip)->devi_pm_components = NULL;
4030 	DEVI(dip)->devi_pm_num_components = 0;
4031 	DEVI(dip)->devi_pm_flags &=
4032 	    ~(PMC_COMPONENTS_DONE | PMC_COMPONENTS_FAILED);
4033 }
4034 
4035 /*
4036  * Read the pm-components property (if there is one) and use it to set up
4037  * components.  Returns a pointer to an array of component structures if
4038  * pm-components found and successfully parsed, else returns NULL.
4039  * Sets error return *errp to true to indicate a failure (as opposed to no
4040  * property being present).
4041  */
4042 pm_comp_t *
4043 pm_autoconfig(dev_info_t *dip, int *errp)
4044 {
4045 	PMD_FUNC(pmf, "autoconfig")
4046 	uint_t nelems;
4047 	char **pp;
4048 	pm_comp_t *compp = NULL;
4049 	int i, j, level, components = 0;
4050 	size_t size = 0;
4051 	struct pm_comp_pkg *p, *ptail;
4052 	struct pm_comp_pkg *phead = NULL;
4053 	int *lvals = NULL;
4054 	int *lszs = NULL;
4055 	int *np = NULL;
4056 	int npi = 0;
4057 	char **lnames = NULL;
4058 	char *cp, *tp;
4059 	pm_comp_t *ret = NULL;
4060 
4061 	ASSERT(!PM_IAM_LOCKING_DIP(dip));
4062 	*errp = 0;	/* assume success */
4063 	if (ddi_prop_lookup_string_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
4064 	    (char *)pmcompstr, &pp, &nelems) != DDI_PROP_SUCCESS) {
4065 		return (NULL);
4066 	}
4067 
4068 	if (nelems < 3) {	/* need at least one name and two levels */
4069 		goto errout;
4070 	}
4071 
4072 	/*
4073 	 * pm_create_components is no longer allowed
4074 	 */
4075 	if (PM_NUMCMPTS(dip) != 0) {
4076 		PMD(PMD_ERROR, ("%s: %s@%s(%s#%d) has %d comps\n",
4077 		    pmf, PM_DEVICE(dip), PM_NUMCMPTS(dip)))
4078 		goto errout;
4079 	}
4080 
4081 	lvals = kmem_alloc(nelems * sizeof (int), KM_SLEEP);
4082 	lszs = kmem_alloc(nelems * sizeof (int), KM_SLEEP);
4083 	lnames = kmem_alloc(nelems * sizeof (char *), KM_SLEEP);
4084 	np = kmem_alloc(nelems * sizeof (int), KM_SLEEP);
4085 
4086 	level = 0;
4087 	phead = NULL;
4088 	for (i = 0; i < nelems; i++) {
4089 		cp = pp[i];
4090 		if (!isdigit(*cp)) {	/*  must be name */
4091 			if (strncmp(cp, namestr, nameln) != 0) {
4092 				goto errout;
4093 			}
4094 			if (i != 0) {
4095 				if (level == 0) {	/* no level spec'd */
4096 					PMD(PMD_ERROR, ("%s: no level spec'd\n",
4097 					    pmf))
4098 					goto errout;
4099 				}
4100 				np[npi++] = lvals[level - 1];
4101 				/* finish up previous component levels */
4102 				FINISH_COMP;
4103 			}
4104 			cp += nameln;
4105 			if (!*cp) {
4106 				PMD(PMD_ERROR, ("%s: nsa\n", pmf))
4107 				goto errout;
4108 			}
4109 			p = kmem_zalloc(sizeof (*phead), KM_SLEEP);
4110 			if (phead == NULL) {
4111 				phead = ptail = p;
4112 			} else {
4113 				ptail->next = p;
4114 				ptail = p;
4115 			}
4116 			compp = p->comp = kmem_zalloc(sizeof (pm_comp_t),
4117 			    KM_SLEEP);
4118 			compp->pmc_name_sz = strlen(cp) + 1;
4119 			compp->pmc_name = kmem_zalloc(compp->pmc_name_sz,
4120 			    KM_SLEEP);
4121 			(void) strncpy(compp->pmc_name, cp, compp->pmc_name_sz);
4122 			components++;
4123 			level = 0;
4124 		} else {	/* better be power level <num>=<name> */
4125 #ifdef DEBUG
4126 			tp = cp;
4127 #endif
4128 			if (i == 0 ||
4129 			    (cp = pm_parsenum(cp, &lvals[level])) == NULL) {
4130 				PMD(PMD_ERROR, ("%s: parsenum(%s)\n", pmf, tp))
4131 				goto errout;
4132 			}
4133 #ifdef DEBUG
4134 			tp = cp;
4135 #endif
4136 			if (*cp++ != '=' || !*cp) {
4137 				PMD(PMD_ERROR, ("%s: ex =, got %s\n", pmf, tp))
4138 				goto errout;
4139 			}
4140 
4141 			lszs[level] = strlen(cp) + 1;
4142 			size += lszs[level];
4143 			lnames[level] = cp;	/* points into prop string */
4144 			level++;
4145 		}
4146 	}
4147 	np[npi++] = lvals[level - 1];
4148 	if (level == 0) {	/* ended with a name */
4149 		PMD(PMD_ERROR, ("%s: ewn\n", pmf))
4150 		goto errout;
4151 	}
4152 	FINISH_COMP;
4153 
4154 
4155 	/*
4156 	 * Now we have a list of components--we have to return instead an
4157 	 * array of them, but we can just copy the top level and leave
4158 	 * the rest as is
4159 	 */
4160 	(void) e_pm_create_components(dip, components);
4161 	for (i = 0; i < components; i++)
4162 		e_pm_set_max_power(dip, i, np[i]);
4163 
4164 	ret = kmem_zalloc(components * sizeof (pm_comp_t), KM_SLEEP);
4165 	for (i = 0, p = phead; i < components; i++) {
4166 		ASSERT(p);
4167 		/*
4168 		 * Now sanity-check values:  levels must be monotonically
4169 		 * increasing
4170 		 */
4171 		if (p->comp->pmc_numlevels < 2) {
4172 			PMD(PMD_ERROR, ("%s: comp %s of %s@%s(%s#%d) only %d "
4173 			    "levels\n", pmf,
4174 			    p->comp->pmc_name, PM_DEVICE(dip),
4175 			    p->comp->pmc_numlevels))
4176 			goto errout;
4177 		}
4178 		for (j = 0; j < p->comp->pmc_numlevels; j++) {
4179 			if ((p->comp->pmc_lvals[j] < 0) || ((j > 0) &&
4180 			    (p->comp->pmc_lvals[j] <=
4181 			    p->comp->pmc_lvals[j - 1]))) {
4182 				PMD(PMD_ERROR, ("%s: comp %s of %s@%s(%s#%d) "
4183 				    "not mono. incr, %d follows %d\n", pmf,
4184 				    p->comp->pmc_name, PM_DEVICE(dip),
4185 				    p->comp->pmc_lvals[j],
4186 				    p->comp->pmc_lvals[j - 1]))
4187 				goto errout;
4188 			}
4189 		}
4190 		ret[i] = *p->comp;	/* struct assignment */
4191 		for (j = 0; j < i; j++) {
4192 			/*
4193 			 * Test for unique component names
4194 			 */
4195 			if (strcmp(ret[j].pmc_name, ret[i].pmc_name) == 0) {
4196 				PMD(PMD_ERROR, ("%s: %s of %s@%s(%s#%d) not "
4197 				    "unique\n", pmf, ret[j].pmc_name,
4198 				    PM_DEVICE(dip)))
4199 				goto errout;
4200 			}
4201 		}
4202 		ptail = p;
4203 		p = p->next;
4204 		phead = p;	/* errout depends on phead making sense */
4205 		kmem_free(ptail->comp, sizeof (*ptail->comp));
4206 		kmem_free(ptail, sizeof (*ptail));
4207 	}
4208 out:
4209 	ddi_prop_free(pp);
4210 	if (lvals)
4211 		kmem_free(lvals, nelems * sizeof (int));
4212 	if (lszs)
4213 		kmem_free(lszs, nelems * sizeof (int));
4214 	if (lnames)
4215 		kmem_free(lnames, nelems * sizeof (char *));
4216 	if (np)
4217 		kmem_free(np, nelems * sizeof (int));
4218 	return (ret);
4219 
4220 errout:
4221 	e_pm_destroy_components(dip);
4222 	*errp = 1;	/* signal failure */
4223 	cmn_err(CE_CONT, "!pm: %s property ", pmcompstr);
4224 	for (i = 0; i < nelems - 1; i++)
4225 		cmn_err(CE_CONT, "!'%s', ", pp[i]);
4226 	if (nelems != 0)
4227 		cmn_err(CE_CONT, "!'%s'", pp[nelems - 1]);
4228 	cmn_err(CE_CONT, "! for %s@%s(%s#%d) is ill-formed.\n", PM_DEVICE(dip));
4229 	for (p = phead; p; ) {
4230 		pm_comp_t *pp;
4231 		int n;
4232 
4233 		ptail = p;
4234 		/*
4235 		 * Free component data structures
4236 		 */
4237 		pp = p->comp;
4238 		n = pp->pmc_numlevels;
4239 		if (pp->pmc_name_sz) {
4240 			kmem_free(pp->pmc_name, pp->pmc_name_sz);
4241 		}
4242 		if (pp->pmc_lnames_sz) {
4243 			kmem_free(pp->pmc_lname_buf, pp->pmc_lnames_sz);
4244 		}
4245 		if (pp->pmc_lnames) {
4246 			kmem_free(pp->pmc_lnames, n * (sizeof (char *)));
4247 		}
4248 		if (pp->pmc_thresh) {
4249 			kmem_free(pp->pmc_thresh, n * (sizeof (int)));
4250 		}
4251 		if (pp->pmc_lvals) {
4252 			kmem_free(pp->pmc_lvals, n * (sizeof (int)));
4253 		}
4254 		p = ptail->next;
4255 		kmem_free(ptail, sizeof (*ptail));
4256 	}
4257 	if (ret != NULL)
4258 		kmem_free(ret, components * sizeof (pm_comp_t));
4259 	ret = NULL;
4260 	goto out;
4261 }
4262 
4263 /*
4264  * Set threshold values for a devices components by dividing the target
4265  * threshold (base) by the number of transitions and assign each transition
4266  * that threshold.  This will get the entire device down in the target time if
4267  * all components are idle and even if there are dependencies among components.
4268  *
4269  * Devices may well get powered all the way down before the target time, but
4270  * at least the EPA will be happy.
4271  */
4272 void
4273 pm_set_device_threshold(dev_info_t *dip, int base, int flag)
4274 {
4275 	PMD_FUNC(pmf, "set_device_threshold")
4276 	int target_threshold = (base * 95) / 100;
4277 	int level, comp;		/* loop counters */
4278 	int transitions = 0;
4279 	int ncomp = PM_NUMCMPTS(dip);
4280 	int thresh;
4281 	int remainder;
4282 	pm_comp_t *pmc;
4283 	int i, circ;
4284 
4285 	ASSERT(!PM_IAM_LOCKING_DIP(dip));
4286 	PM_LOCK_DIP(dip);
4287 	/*
4288 	 * First we handle the easy one.  If we're setting the default
4289 	 * threshold for a node with children, then we set it to the
4290 	 * default nexus threshold (currently 0) and mark it as default
4291 	 * nexus threshold instead
4292 	 */
4293 	if (PM_IS_NEXUS(dip)) {
4294 		if (flag == PMC_DEF_THRESH) {
4295 			PMD(PMD_THRESH, ("%s: [%s@%s(%s#%d) NEXDEF]\n", pmf,
4296 			    PM_DEVICE(dip)))
4297 			thresh = pm_default_nexus_threshold;
4298 			for (comp = 0; comp < ncomp; comp++) {
4299 				pmc = &PM_CP(dip, comp)->pmc_comp;
4300 				for (level = 1; level < pmc->pmc_numlevels;
4301 				    level++) {
4302 					pmc->pmc_thresh[level] = thresh;
4303 				}
4304 			}
4305 			DEVI(dip)->devi_pm_dev_thresh =
4306 			    pm_default_nexus_threshold;
4307 			/*
4308 			 * If the nexus node is being reconfigured back to
4309 			 * the default threshold, adjust the notlowest count.
4310 			 */
4311 			if (DEVI(dip)->devi_pm_flags &
4312 			    (PMC_DEV_THRESH|PMC_COMP_THRESH)) {
4313 				PM_LOCK_POWER(dip, &circ);
4314 				for (i = 0; i < PM_NUMCMPTS(dip); i++) {
4315 					if (PM_CURPOWER(dip, i) == 0)
4316 						continue;
4317 					mutex_enter(&pm_compcnt_lock);
4318 					ASSERT(pm_comps_notlowest);
4319 					pm_comps_notlowest--;
4320 					PMD(PMD_LEVEL, ("%s: %s@%s(%s#%d) decr "
4321 					    "notlowest to %d\n", pmf,
4322 					    PM_DEVICE(dip), pm_comps_notlowest))
4323 					if (pm_comps_notlowest == 0)
4324 						pm_ppm_notify_all_lowest(dip,
4325 						    PM_ALL_LOWEST);
4326 					mutex_exit(&pm_compcnt_lock);
4327 				}
4328 				PM_UNLOCK_POWER(dip, circ);
4329 			}
4330 			DEVI(dip)->devi_pm_flags &= PMC_THRESH_NONE;
4331 			DEVI(dip)->devi_pm_flags |= PMC_NEXDEF_THRESH;
4332 			PM_UNLOCK_DIP(dip);
4333 			return;
4334 		} else if (DEVI(dip)->devi_pm_flags & PMC_NEXDEF_THRESH) {
4335 			/*
4336 			 * If the nexus node is being configured for a
4337 			 * non-default threshold, include that node in
4338 			 * the notlowest accounting.
4339 			 */
4340 			PM_LOCK_POWER(dip, &circ);
4341 			for (i = 0; i < PM_NUMCMPTS(dip); i++) {
4342 				if (PM_CURPOWER(dip, i) == 0)
4343 					continue;
4344 				mutex_enter(&pm_compcnt_lock);
4345 				if (pm_comps_notlowest == 0)
4346 					pm_ppm_notify_all_lowest(dip,
4347 					    PM_NOT_ALL_LOWEST);
4348 				pm_comps_notlowest++;
4349 				PMD(PMD_LEVEL, ("%s: %s@%s(%s#%d) incr "
4350 				    "notlowest to %d\n", pmf,
4351 				    PM_DEVICE(dip), pm_comps_notlowest))
4352 				mutex_exit(&pm_compcnt_lock);
4353 			}
4354 			PM_UNLOCK_POWER(dip, circ);
4355 		}
4356 	}
4357 	/*
4358 	 * Compute the total number of transitions for all components
4359 	 * of the device.  Distribute the threshold evenly over them
4360 	 */
4361 	for (comp = 0; comp < ncomp; comp++) {
4362 		pmc = &PM_CP(dip, comp)->pmc_comp;
4363 		ASSERT(pmc->pmc_numlevels > 1);
4364 		transitions += pmc->pmc_numlevels - 1;
4365 	}
4366 	ASSERT(transitions);
4367 	thresh = target_threshold / transitions;
4368 
4369 	for (comp = 0; comp < ncomp; comp++) {
4370 		pmc = &PM_CP(dip, comp)->pmc_comp;
4371 		for (level = 1; level < pmc->pmc_numlevels; level++) {
4372 			pmc->pmc_thresh[level] = thresh;
4373 		}
4374 	}
4375 
4376 #ifdef DEBUG
4377 	for (comp = 0; comp < ncomp; comp++) {
4378 		pmc = &PM_CP(dip, comp)->pmc_comp;
4379 		for (level = 1; level < pmc->pmc_numlevels; level++) {
4380 			PMD(PMD_THRESH, ("%s: thresh before %s@%s(%s#%d) "
4381 			    "comp=%d, level=%d, %d\n", pmf, PM_DEVICE(dip),
4382 			    comp, level, pmc->pmc_thresh[level]))
4383 		}
4384 	}
4385 #endif
4386 	/*
4387 	 * Distribute any remainder till they are all gone
4388 	 */
4389 	remainder = target_threshold - thresh * transitions;
4390 	level = 1;
4391 #ifdef DEBUG
4392 	PMD(PMD_THRESH, ("%s: remainder=%d target_threshold=%d thresh=%d "
4393 	    "trans=%d\n", pmf, remainder, target_threshold, thresh,
4394 	    transitions))
4395 #endif
4396 	while (remainder > 0) {
4397 		comp = 0;
4398 		while (remainder && (comp < ncomp)) {
4399 			pmc = &PM_CP(dip, comp)->pmc_comp;
4400 			if (level < pmc->pmc_numlevels) {
4401 				pmc->pmc_thresh[level] += 1;
4402 				remainder--;
4403 			}
4404 			comp++;
4405 		}
4406 		level++;
4407 	}
4408 #ifdef DEBUG
4409 	for (comp = 0; comp < ncomp; comp++) {
4410 		pmc = &PM_CP(dip, comp)->pmc_comp;
4411 		for (level = 1; level < pmc->pmc_numlevels; level++) {
4412 			PMD(PMD_THRESH, ("%s: thresh after %s@%s(%s#%d) "
4413 			    "comp=%d level=%d, %d\n", pmf, PM_DEVICE(dip),
4414 			    comp, level, pmc->pmc_thresh[level]))
4415 		}
4416 	}
4417 #endif
4418 	ASSERT(PM_IAM_LOCKING_DIP(dip));
4419 	DEVI(dip)->devi_pm_dev_thresh = base;
4420 	DEVI(dip)->devi_pm_flags &= PMC_THRESH_NONE;
4421 	DEVI(dip)->devi_pm_flags |= flag;
4422 	PM_UNLOCK_DIP(dip);
4423 }
4424 
4425 /*
4426  * Called when there is no old-style platform power management driver
4427  */
4428 static int
4429 ddi_no_platform_power(power_req_t *req)
4430 {
4431 	_NOTE(ARGUNUSED(req))
4432 	return (DDI_FAILURE);
4433 }
4434 
4435 /*
4436  * This function calls the entry point supplied by the platform-specific
4437  * pm driver to bring the device component 'pm_cmpt' to power level 'pm_level'.
4438  * The use of global for getting the  function name from platform-specific
4439  * pm driver is not ideal, but it is simple and efficient.
4440  * The previous property lookup was being done in the idle loop on swift
4441  * systems without pmc chips and hurt deskbench performance as well as
4442  * violating scheduler locking rules
4443  */
4444 int	(*pm_platform_power)(power_req_t *) = ddi_no_platform_power;
4445 
4446 /*
4447  * Old obsolete interface for a device to request a power change (but only
4448  * an increase in power)
4449  */
4450 int
4451 ddi_dev_is_needed(dev_info_t *dip, int cmpt, int level)
4452 {
4453 	return (pm_raise_power(dip, cmpt, level));
4454 }
4455 
4456 /*
4457  * The old obsolete interface to platform power management.  Only used by
4458  * Gypsy platform and APM on X86.
4459  */
4460 int
4461 ddi_power(dev_info_t *dip, int pm_cmpt, int pm_level)
4462 {
4463 	power_req_t	request;
4464 
4465 	request.request_type = PMR_SET_POWER;
4466 	request.req.set_power_req.who = dip;
4467 	request.req.set_power_req.cmpt = pm_cmpt;
4468 	request.req.set_power_req.level = pm_level;
4469 	return (ddi_ctlops(dip, dip, DDI_CTLOPS_POWER, &request, NULL));
4470 }
4471 
4472 /*
4473  * A driver can invoke this from its detach routine when DDI_SUSPEND is
4474  * passed.  Returns true if subsequent processing could result in power being
4475  * removed from the device.  The arg is not currently used because it is
4476  * implicit in the operation of cpr/DR.
4477  */
4478 int
4479 ddi_removing_power(dev_info_t *dip)
4480 {
4481 	_NOTE(ARGUNUSED(dip))
4482 	return (pm_powering_down);
4483 }
4484 
4485 /*
4486  * Returns true if a device indicates that its parent handles suspend/resume
4487  * processing for it.
4488  */
4489 int
4490 e_ddi_parental_suspend_resume(dev_info_t *dip)
4491 {
4492 	return (DEVI(dip)->devi_pm_flags & PMC_PARENTAL_SR);
4493 }
4494 
4495 /*
4496  * Called for devices which indicate that their parent does suspend/resume
4497  * handling for them
4498  */
4499 int
4500 e_ddi_suspend(dev_info_t *dip, ddi_detach_cmd_t cmd)
4501 {
4502 	power_req_t	request;
4503 	request.request_type = PMR_SUSPEND;
4504 	request.req.suspend_req.who = dip;
4505 	request.req.suspend_req.cmd = cmd;
4506 	return (ddi_ctlops(dip, dip, DDI_CTLOPS_POWER, &request, NULL));
4507 }
4508 
4509 /*
4510  * Called for devices which indicate that their parent does suspend/resume
4511  * handling for them
4512  */
4513 int
4514 e_ddi_resume(dev_info_t *dip, ddi_attach_cmd_t cmd)
4515 {
4516 	power_req_t	request;
4517 	request.request_type = PMR_RESUME;
4518 	request.req.resume_req.who = dip;
4519 	request.req.resume_req.cmd = cmd;
4520 	return (ddi_ctlops(dip, dip, DDI_CTLOPS_POWER, &request, NULL));
4521 }
4522 
4523 /*
4524  * Old obsolete exported interface for drivers to create components.
4525  * This is now handled by exporting the pm-components property.
4526  */
4527 int
4528 pm_create_components(dev_info_t *dip, int num_components)
4529 {
4530 	PMD_FUNC(pmf, "pm_create_components")
4531 
4532 	if (num_components < 1)
4533 		return (DDI_FAILURE);
4534 
4535 	if (!DEVI_IS_ATTACHING(dip)) {
4536 		return (DDI_FAILURE);
4537 	}
4538 
4539 	/* don't need to lock dip because attach is single threaded */
4540 	if (DEVI(dip)->devi_pm_components) {
4541 		PMD(PMD_ERROR, ("%s: %s@%s(%s#%d) already has %d\n", pmf,
4542 		    PM_DEVICE(dip), PM_NUMCMPTS(dip)))
4543 		return (DDI_FAILURE);
4544 	}
4545 	e_pm_create_components(dip, num_components);
4546 	DEVI(dip)->devi_pm_flags |= PMC_BC;
4547 	e_pm_default_components(dip, num_components);
4548 	return (DDI_SUCCESS);
4549 }
4550 
4551 /*
4552  * Obsolete interface previously called by drivers to destroy their components
4553  * at detach time.  This is now done automatically.  However, we need to keep
4554  * this for the old drivers.
4555  */
4556 void
4557 pm_destroy_components(dev_info_t *dip)
4558 {
4559 	PMD_FUNC(pmf, "pm_destroy_components")
4560 	dev_info_t *pdip = ddi_get_parent(dip);
4561 
4562 	PMD(PMD_REMDEV | PMD_KIDSUP, ("%s: %s@%s(%s#%d)\n", pmf,
4563 	    PM_DEVICE(dip)))
4564 	ASSERT(DEVI_IS_DETACHING(dip));
4565 #ifdef DEBUG
4566 	if (!PM_ISBC(dip))
4567 		cmn_err(CE_WARN, "!driver exporting pm-components property "
4568 		    "(%s@%s) calls pm_destroy_components", PM_NAME(dip),
4569 		    PM_ADDR(dip));
4570 #endif
4571 	/*
4572 	 * We ignore this unless this is an old-style driver, except for
4573 	 * printing the message above
4574 	 */
4575 	if (PM_NUMCMPTS(dip) == 0 || !PM_ISBC(dip)) {
4576 		PMD(PMD_REMDEV, ("%s: ignore %s@%s(%s#%d)\n", pmf,
4577 		    PM_DEVICE(dip)))
4578 		return;
4579 	}
4580 	ASSERT(PM_GET_PM_INFO(dip));
4581 
4582 	/*
4583 	 * pm_unmanage will clear info pointer later, after dealing with
4584 	 * dependencies
4585 	 */
4586 	ASSERT(!PM_GET_PM_SCAN(dip));	/* better be gone already */
4587 	/*
4588 	 * Now adjust parent's kidsupcnt.  We check only comp 0.
4589 	 * Parents that get notification are not adjusted because their
4590 	 * kidsupcnt is always 0 (or 1 during probe and attach).
4591 	 */
4592 	if ((PM_CURPOWER(dip, 0) != 0) && pdip && !PM_WANTS_NOTIFICATION(pdip))
4593 		pm_rele_power(pdip);
4594 #ifdef DEBUG
4595 	else {
4596 		PMD(PMD_KIDSUP, ("%s: kuc stays %s@%s(%s#%d) comps gone\n",
4597 		    pmf, PM_DEVICE(dip)))
4598 	}
4599 #endif
4600 	e_pm_destroy_components(dip);
4601 	/*
4602 	 * Forget we ever knew anything about the components of this  device
4603 	 */
4604 	DEVI(dip)->devi_pm_flags &=
4605 	    ~(PMC_BC | PMC_COMPONENTS_DONE | PMC_COMPONENTS_FAILED);
4606 }
4607 
4608 /*
4609  * Exported interface for a driver to set a component busy.
4610  */
4611 int
4612 pm_busy_component(dev_info_t *dip, int cmpt)
4613 {
4614 	struct pm_component *cp;
4615 
4616 	ASSERT(dip != NULL);
4617 	if (!e_pm_valid_info(dip, NULL) || !e_pm_valid_comp(dip, cmpt, &cp))
4618 		return (DDI_FAILURE);
4619 	PM_LOCK_BUSY(dip);
4620 	cp->pmc_busycount++;
4621 	cp->pmc_timestamp = 0;
4622 	PM_UNLOCK_BUSY(dip);
4623 	return (DDI_SUCCESS);
4624 }
4625 
4626 /*
4627  * Exported interface for a driver to set a component idle.
4628  */
4629 int
4630 pm_idle_component(dev_info_t *dip, int cmpt)
4631 {
4632 	PMD_FUNC(pmf, "pm_idle_component")
4633 	struct pm_component *cp;
4634 	pm_scan_t	*scanp = PM_GET_PM_SCAN(dip);
4635 
4636 	if (!e_pm_valid_info(dip, NULL) || !e_pm_valid_comp(dip, cmpt, &cp))
4637 		return (DDI_FAILURE);
4638 
4639 	PM_LOCK_BUSY(dip);
4640 	if (cp->pmc_busycount) {
4641 		if (--(cp->pmc_busycount) == 0)
4642 			cp->pmc_timestamp = gethrestime_sec();
4643 	} else {
4644 		cp->pmc_timestamp = gethrestime_sec();
4645 	}
4646 
4647 	PM_UNLOCK_BUSY(dip);
4648 
4649 	/*
4650 	 * if device becomes idle during idle down period, try scan it down
4651 	 */
4652 	if (scanp && PM_IS_PID(dip)) {
4653 		PMD(PMD_IDLEDOWN, ("%s: %s@%s(%s#%d) idle.\n", pmf,
4654 		    PM_DEVICE(dip)))
4655 		pm_rescan(dip);
4656 		return (DDI_SUCCESS);
4657 	}
4658 
4659 	/*
4660 	 * handle scan not running with nexus threshold == 0
4661 	 */
4662 
4663 	if (PM_IS_NEXUS(dip) && (cp->pmc_busycount == 0)) {
4664 		pm_rescan(dip);
4665 	}
4666 
4667 	return (DDI_SUCCESS);
4668 }
4669 
4670 /*
4671  * This is the old  obsolete interface called by drivers to set their normal
4672  * power.  Thus we can't fix its behavior or return a value.
4673  * This functionality is replaced by the pm-component property.
4674  * We'll only get components destroyed while no power management is
4675  * going on (and the device is detached), so we don't need a mutex here
4676  */
4677 void
4678 pm_set_normal_power(dev_info_t *dip, int comp, int level)
4679 {
4680 	PMD_FUNC(pmf, "set_normal_power")
4681 #ifdef DEBUG
4682 	if (!PM_ISBC(dip))
4683 		cmn_err(CE_WARN, "!call to pm_set_normal_power() by %s@%s "
4684 		    "(driver exporting pm-components property) ignored",
4685 		    PM_NAME(dip), PM_ADDR(dip));
4686 #endif
4687 	if (PM_ISBC(dip)) {
4688 		PMD(PMD_NORM, ("%s: %s@%s(%s#%d) set normal power comp=%d, "
4689 		    "level=%d\n", pmf, PM_DEVICE(dip), comp, level))
4690 		e_pm_set_max_power(dip, comp, level);
4691 		e_pm_default_levels(dip, PM_CP(dip, comp), level);
4692 	}
4693 }
4694 
4695 /*
4696  * Called on a successfully detached driver to free pm resources
4697  */
4698 static void
4699 pm_stop(dev_info_t *dip)
4700 {
4701 	PMD_FUNC(pmf, "stop")
4702 	dev_info_t *pdip = ddi_get_parent(dip);
4703 
4704 	ASSERT(!PM_IAM_LOCKING_DIP(dip));
4705 	/* stopping scan, destroy scan data structure */
4706 	if (!PM_ISBC(dip)) {
4707 		pm_scan_stop(dip);
4708 		pm_scan_fini(dip);
4709 	}
4710 
4711 	if (PM_GET_PM_INFO(dip) != NULL) {
4712 		if (pm_unmanage(dip) == DDI_SUCCESS) {
4713 			/*
4714 			 * Old style driver may have called
4715 			 * pm_destroy_components already, but just in case ...
4716 			 */
4717 			e_pm_destroy_components(dip);
4718 		} else {
4719 			PMD(PMD_FAIL, ("%s: can't pm_unmanage %s@%s(%s#%d)\n",
4720 			    pmf, PM_DEVICE(dip)))
4721 		}
4722 	} else {
4723 		if (PM_NUMCMPTS(dip))
4724 			e_pm_destroy_components(dip);
4725 		else {
4726 			if (DEVI(dip)->devi_pm_flags & PMC_NOPMKID) {
4727 				DEVI(dip)->devi_pm_flags &= ~PMC_NOPMKID;
4728 				if (pdip && !PM_WANTS_NOTIFICATION(pdip)) {
4729 					pm_rele_power(pdip);
4730 				} else if (pdip &&
4731 				    MDI_VHCI(pdip) && MDI_CLIENT(dip)) {
4732 					(void) mdi_power(pdip,
4733 					    MDI_PM_RELE_POWER,
4734 					    (void *)dip, NULL, 0);
4735 				}
4736 			}
4737 		}
4738 	}
4739 }
4740 
4741 /*
4742  * The node is the subject of a reparse pm props ioctl. Throw away the old
4743  * info and start over.
4744  */
4745 int
4746 e_new_pm_props(dev_info_t *dip)
4747 {
4748 	if (PM_GET_PM_INFO(dip) != NULL) {
4749 		pm_stop(dip);
4750 
4751 		if (e_pm_manage(dip, PM_STYLE_NEW) != DDI_SUCCESS) {
4752 			return (DDI_FAILURE);
4753 		}
4754 	}
4755 	e_pm_props(dip);
4756 	return (DDI_SUCCESS);
4757 }
4758 
4759 /*
4760  * Device has been attached, so process its pm properties
4761  */
4762 void
4763 e_pm_props(dev_info_t *dip)
4764 {
4765 	char *pp;
4766 	int len;
4767 	int flags = 0;
4768 	int propflag = DDI_PROP_DONTPASS|DDI_PROP_CANSLEEP;
4769 
4770 	/*
4771 	 * It doesn't matter if we do this more than once, we should always
4772 	 * get the same answers, and if not, then the last one in is the
4773 	 * best one.
4774 	 */
4775 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip, propflag, "pm-hardware-state",
4776 	    (caddr_t)&pp, &len) == DDI_PROP_SUCCESS) {
4777 		if (strcmp(pp, "needs-suspend-resume") == 0) {
4778 			flags = PMC_NEEDS_SR;
4779 		} else if (strcmp(pp, "no-suspend-resume") == 0) {
4780 			flags = PMC_NO_SR;
4781 		} else if (strcmp(pp, "parental-suspend-resume") == 0) {
4782 			flags = PMC_PARENTAL_SR;
4783 		} else {
4784 			cmn_err(CE_NOTE, "!device %s@%s has unrecognized "
4785 			    "%s property value '%s'", PM_NAME(dip),
4786 			    PM_ADDR(dip), "pm-hardware-state", pp);
4787 		}
4788 		kmem_free(pp, len);
4789 	}
4790 	/*
4791 	 * This next segment (PMC_WANTS_NOTIFY) is in
4792 	 * support of nexus drivers which will want to be involved in
4793 	 * (or at least notified of) their child node's power level transitions.
4794 	 * "pm-want-child-notification?" is defined by the parent.
4795 	 */
4796 	if (ddi_prop_exists(DDI_DEV_T_ANY, dip, propflag,
4797 	    "pm-want-child-notification?") && PM_HAS_BUS_POWER(dip))
4798 		flags |= PMC_WANTS_NOTIFY;
4799 	ASSERT(PM_HAS_BUS_POWER(dip) || !ddi_prop_exists(DDI_DEV_T_ANY,
4800 	    dip, propflag, "pm-want-child-notification?"));
4801 	if (ddi_prop_exists(DDI_DEV_T_ANY, dip, propflag,
4802 	    "no-involuntary-power-cycles"))
4803 		flags |= PMC_NO_INVOL;
4804 	/*
4805 	 * Is the device a CPU device?
4806 	 */
4807 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip, propflag, "pm-class",
4808 	    (caddr_t)&pp, &len) == DDI_PROP_SUCCESS) {
4809 		if (strcmp(pp, "CPU") == 0) {
4810 			flags |= PMC_CPU_DEVICE;
4811 		} else {
4812 			cmn_err(CE_NOTE, "!device %s@%s has unrecognized "
4813 			    "%s property value '%s'", PM_NAME(dip),
4814 			    PM_ADDR(dip), "pm-class", pp);
4815 		}
4816 		kmem_free(pp, len);
4817 	}
4818 	/* devfs single threads us */
4819 	DEVI(dip)->devi_pm_flags |= flags;
4820 }
4821 
4822 /*
4823  * This is the DDI_CTLOPS_POWER handler that is used when there is no ppm
4824  * driver which has claimed a node.
4825  * Sets old_power in arg struct.
4826  */
4827 static int
4828 pm_default_ctlops(dev_info_t *dip, dev_info_t *rdip,
4829     ddi_ctl_enum_t ctlop, void *arg, void *result)
4830 {
4831 	_NOTE(ARGUNUSED(dip))
4832 	PMD_FUNC(pmf, "ctlops")
4833 	power_req_t *reqp = (power_req_t *)arg;
4834 	int retval;
4835 	dev_info_t *target_dip;
4836 	int new_level, old_level, cmpt;
4837 #ifdef PMDDEBUG
4838 	char *format;
4839 #endif
4840 
4841 	/*
4842 	 * The interface for doing the actual power level changes is now
4843 	 * through the DDI_CTLOPS_POWER bus_ctl, so that we can plug in
4844 	 * different platform-specific power control drivers.
4845 	 *
4846 	 * This driver implements the "default" version of this interface.
4847 	 * If no ppm driver has been installed then this interface is called
4848 	 * instead.
4849 	 */
4850 	ASSERT(dip == NULL);
4851 	switch (ctlop) {
4852 	case DDI_CTLOPS_POWER:
4853 		switch (reqp->request_type) {
4854 		case PMR_PPM_SET_POWER:
4855 		{
4856 			target_dip = reqp->req.ppm_set_power_req.who;
4857 			ASSERT(target_dip == rdip);
4858 			new_level = reqp->req.ppm_set_power_req.new_level;
4859 			cmpt = reqp->req.ppm_set_power_req.cmpt;
4860 			/* pass back old power for the PM_LEVEL_UNKNOWN case */
4861 			old_level = PM_CURPOWER(target_dip, cmpt);
4862 			reqp->req.ppm_set_power_req.old_level = old_level;
4863 			retval = pm_power(target_dip, cmpt, new_level);
4864 			PMD(PMD_PPM, ("%s: PPM_SET_POWER %s@%s(%s#%d)[%d] %d->"
4865 			    "%d %s\n", pmf, PM_DEVICE(target_dip), cmpt,
4866 			    old_level, new_level, (retval == DDI_SUCCESS ?
4867 			    "chd" : "no chg")))
4868 			return (retval);
4869 		}
4870 
4871 		case PMR_PPM_PRE_DETACH:
4872 		case PMR_PPM_POST_DETACH:
4873 		case PMR_PPM_PRE_ATTACH:
4874 		case PMR_PPM_POST_ATTACH:
4875 		case PMR_PPM_PRE_PROBE:
4876 		case PMR_PPM_POST_PROBE:
4877 		case PMR_PPM_PRE_RESUME:
4878 		case PMR_PPM_INIT_CHILD:
4879 		case PMR_PPM_UNINIT_CHILD:
4880 #ifdef PMDDEBUG
4881 			switch (reqp->request_type) {
4882 				case PMR_PPM_PRE_DETACH:
4883 					format = "%s: PMR_PPM_PRE_DETACH "
4884 					    "%s@%s(%s#%d)\n";
4885 					break;
4886 				case PMR_PPM_POST_DETACH:
4887 					format = "%s: PMR_PPM_POST_DETACH "
4888 					    "%s@%s(%s#%d) rets %d\n";
4889 					break;
4890 				case PMR_PPM_PRE_ATTACH:
4891 					format = "%s: PMR_PPM_PRE_ATTACH "
4892 					    "%s@%s(%s#%d)\n";
4893 					break;
4894 				case PMR_PPM_POST_ATTACH:
4895 					format = "%s: PMR_PPM_POST_ATTACH "
4896 					    "%s@%s(%s#%d) rets %d\n";
4897 					break;
4898 				case PMR_PPM_PRE_PROBE:
4899 					format = "%s: PMR_PPM_PRE_PROBE "
4900 					    "%s@%s(%s#%d)\n";
4901 					break;
4902 				case PMR_PPM_POST_PROBE:
4903 					format = "%s: PMR_PPM_POST_PROBE "
4904 					    "%s@%s(%s#%d) rets %d\n";
4905 					break;
4906 				case PMR_PPM_PRE_RESUME:
4907 					format = "%s: PMR_PPM_PRE_RESUME "
4908 					    "%s@%s(%s#%d) rets %d\n";
4909 					break;
4910 				case PMR_PPM_INIT_CHILD:
4911 					format = "%s: PMR_PPM_INIT_CHILD "
4912 					    "%s@%s(%s#%d)\n";
4913 					break;
4914 				case PMR_PPM_UNINIT_CHILD:
4915 					format = "%s: PMR_PPM_UNINIT_CHILD "
4916 					    "%s@%s(%s#%d)\n";
4917 					break;
4918 				default:
4919 					break;
4920 			}
4921 			PMD(PMD_PPM, (format, pmf, PM_DEVICE(rdip),
4922 			    reqp->req.ppm_config_req.result))
4923 #endif
4924 			return (DDI_SUCCESS);
4925 
4926 		case PMR_PPM_POWER_CHANGE_NOTIFY:
4927 			/*
4928 			 * Nothing for us to do
4929 			 */
4930 			ASSERT(reqp->req.ppm_notify_level_req.who == rdip);
4931 			PMD(PMD_PPM, ("%s: PMR_PPM_POWER_CHANGE_NOTIFY "
4932 			    "%s@%s(%s#%d)[%d] %d->%d\n", pmf,
4933 			    PM_DEVICE(reqp->req.ppm_notify_level_req.who),
4934 			    reqp->req.ppm_notify_level_req.cmpt,
4935 			    PM_CURPOWER(reqp->req.ppm_notify_level_req.who,
4936 			    reqp->req.ppm_notify_level_req.cmpt),
4937 			    reqp->req.ppm_notify_level_req.new_level))
4938 			return (DDI_SUCCESS);
4939 
4940 		case PMR_PPM_UNMANAGE:
4941 			PMD(PMD_PPM, ("%s: PMR_PPM_UNMANAGE %s@%s(%s#%d)\n",
4942 			    pmf, PM_DEVICE(rdip)))
4943 			return (DDI_SUCCESS);
4944 
4945 		case PMR_PPM_LOCK_POWER:
4946 			pm_lock_power_single(reqp->req.ppm_lock_power_req.who,
4947 			    reqp->req.ppm_lock_power_req.circp);
4948 			return (DDI_SUCCESS);
4949 
4950 		case PMR_PPM_UNLOCK_POWER:
4951 			pm_unlock_power_single(
4952 			    reqp->req.ppm_unlock_power_req.who,
4953 			    reqp->req.ppm_unlock_power_req.circ);
4954 			return (DDI_SUCCESS);
4955 
4956 		case PMR_PPM_TRY_LOCK_POWER:
4957 			*(int *)result = pm_try_locking_power_single(
4958 			    reqp->req.ppm_lock_power_req.who,
4959 			    reqp->req.ppm_lock_power_req.circp);
4960 			return (DDI_SUCCESS);
4961 
4962 		case PMR_PPM_POWER_LOCK_OWNER:
4963 			target_dip = reqp->req.ppm_power_lock_owner_req.who;
4964 			ASSERT(target_dip == rdip);
4965 			reqp->req.ppm_power_lock_owner_req.owner =
4966 			    DEVI(rdip)->devi_busy_thread;
4967 			return (DDI_SUCCESS);
4968 		default:
4969 			PMD(PMD_ERROR, ("%s: default!\n", pmf))
4970 			return (DDI_FAILURE);
4971 		}
4972 
4973 	default:
4974 		PMD(PMD_ERROR, ("%s: unknown\n", pmf))
4975 		return (DDI_FAILURE);
4976 	}
4977 }
4978 
4979 /*
4980  * We overload the bus_ctl ops here--perhaps we ought to have a distinct
4981  * power_ops struct for this functionality instead?
4982  * However, we only ever do this on a ppm driver.
4983  */
4984 int
4985 pm_ctlops(dev_info_t *d, dev_info_t *r, ddi_ctl_enum_t op, void *a, void *v)
4986 {
4987 	int (*fp)();
4988 
4989 	/* if no ppm handler, call the default routine */
4990 	if (d == NULL) {
4991 		return (pm_default_ctlops(d, r, op, a, v));
4992 	}
4993 	if (!d || !r)
4994 		return (DDI_FAILURE);
4995 	ASSERT(DEVI(d)->devi_ops && DEVI(d)->devi_ops->devo_bus_ops &&
4996 	    DEVI(d)->devi_ops->devo_bus_ops->bus_ctl);
4997 
4998 	fp = DEVI(d)->devi_ops->devo_bus_ops->bus_ctl;
4999 	return ((*fp)(d, r, op, a, v));
5000 }
5001 
5002 /*
5003  * Called on a node when attach completes or the driver makes its first pm
5004  * call (whichever comes first).
5005  * In the attach case, device may not be power manageable at all.
5006  * Don't need to lock the dip because we're single threaded by the devfs code
5007  */
5008 static int
5009 pm_start(dev_info_t *dip)
5010 {
5011 	PMD_FUNC(pmf, "start")
5012 	int ret;
5013 	dev_info_t *pdip = ddi_get_parent(dip);
5014 	int e_pm_manage(dev_info_t *, int);
5015 	void pm_noinvol_specd(dev_info_t *dip);
5016 
5017 	e_pm_props(dip);
5018 	pm_noinvol_specd(dip);
5019 	/*
5020 	 * If this dip has already been processed, don't mess with it
5021 	 * (but decrement the speculative count we did above, as whatever
5022 	 * code put it under pm already will have dealt with it)
5023 	 */
5024 	if (PM_GET_PM_INFO(dip)) {
5025 		PMD(PMD_KIDSUP, ("%s: pm already done for %s@%s(%s#%d)\n",
5026 		    pmf, PM_DEVICE(dip)))
5027 		return (0);
5028 	}
5029 	ret = e_pm_manage(dip, PM_STYLE_UNKNOWN);
5030 
5031 	if (PM_GET_PM_INFO(dip) == NULL) {
5032 		/*
5033 		 * keep the kidsupcount increment as is
5034 		 */
5035 		DEVI(dip)->devi_pm_flags |= PMC_NOPMKID;
5036 		if (pdip && !PM_WANTS_NOTIFICATION(pdip)) {
5037 			pm_hold_power(pdip);
5038 		} else if (pdip && MDI_VHCI(pdip) && MDI_CLIENT(dip)) {
5039 			(void) mdi_power(pdip, MDI_PM_HOLD_POWER,
5040 			    (void *)dip, NULL, 0);
5041 		}
5042 
5043 		PMD(PMD_KIDSUP, ("%s: pm of %s@%s(%s#%d) failed, parent "
5044 		    "left up\n", pmf, PM_DEVICE(dip)))
5045 	}
5046 
5047 	return (ret);
5048 }
5049 
5050 /*
5051  * Keep a list of recorded thresholds.  For now we just keep a list and
5052  * search it linearly.  We don't expect too many entries.  Can always hash it
5053  * later if we need to.
5054  */
5055 void
5056 pm_record_thresh(pm_thresh_rec_t *rp)
5057 {
5058 	pm_thresh_rec_t *pptr, *ptr;
5059 
5060 	ASSERT(*rp->ptr_physpath);
5061 	rw_enter(&pm_thresh_rwlock, RW_WRITER);
5062 	for (pptr = NULL, ptr = pm_thresh_head;
5063 	    ptr; pptr = ptr,  ptr = ptr->ptr_next) {
5064 		if (strcmp(rp->ptr_physpath, ptr->ptr_physpath) == 0) {
5065 			/* replace this one */
5066 			rp->ptr_next = ptr->ptr_next;
5067 			if (pptr) {
5068 				pptr->ptr_next = rp;
5069 			} else {
5070 				pm_thresh_head = rp;
5071 			}
5072 			rw_exit(&pm_thresh_rwlock);
5073 			kmem_free(ptr, ptr->ptr_size);
5074 			return;
5075 		}
5076 		continue;
5077 	}
5078 	/*
5079 	 * There was not a match in the list, insert this one in front
5080 	 */
5081 	if (pm_thresh_head) {
5082 		rp->ptr_next = pm_thresh_head;
5083 		pm_thresh_head = rp;
5084 	} else {
5085 		rp->ptr_next = NULL;
5086 		pm_thresh_head = rp;
5087 	}
5088 	rw_exit(&pm_thresh_rwlock);
5089 }
5090 
5091 /*
5092  * Create a new dependency record and hang a new dependency entry off of it
5093  */
5094 pm_pdr_t *
5095 newpdr(char *kept, char *keeps, int isprop)
5096 {
5097 	size_t size = strlen(kept) + strlen(keeps) + 2 + sizeof (pm_pdr_t);
5098 	pm_pdr_t *p = kmem_zalloc(size, KM_SLEEP);
5099 	p->pdr_size = size;
5100 	p->pdr_isprop = isprop;
5101 	p->pdr_kept_paths = NULL;
5102 	p->pdr_kept_count = 0;
5103 	p->pdr_kept = (char *)((intptr_t)p + sizeof (pm_pdr_t));
5104 	(void) strcpy(p->pdr_kept, kept);
5105 	p->pdr_keeper = (char *)((intptr_t)p->pdr_kept + strlen(kept) + 1);
5106 	(void) strcpy(p->pdr_keeper, keeps);
5107 	ASSERT((intptr_t)p->pdr_keeper + strlen(p->pdr_keeper) + 1 <=
5108 	    (intptr_t)p + size);
5109 	ASSERT((intptr_t)p->pdr_kept + strlen(p->pdr_kept) + 1 <=
5110 	    (intptr_t)p + size);
5111 	return (p);
5112 }
5113 
5114 /*
5115  * Keep a list of recorded dependencies.  We only keep the
5116  * keeper -> kept list for simplification. At this point We do not
5117  * care about whether the devices are attached or not yet,
5118  * this would be done in pm_keeper() and pm_kept().
5119  * If a PM_RESET_PM happens, then we tear down and forget the dependencies,
5120  * and it is up to the user to issue the ioctl again if they want it
5121  * (e.g. pmconfig)
5122  * Returns true if dependency already exists in the list.
5123  */
5124 int
5125 pm_record_keeper(char *kept, char *keeper, int isprop)
5126 {
5127 	PMD_FUNC(pmf, "record_keeper")
5128 	pm_pdr_t *npdr, *ppdr, *pdr;
5129 
5130 	PMD(PMD_KEEPS, ("%s: %s, %s\n", pmf, kept, keeper))
5131 	ASSERT(kept && keeper);
5132 #ifdef DEBUG
5133 	if (pm_debug & PMD_KEEPS)
5134 		prdeps("pm_record_keeper entry");
5135 #endif
5136 	for (ppdr = NULL, pdr = pm_dep_head; pdr;
5137 	    ppdr = pdr, pdr = pdr->pdr_next) {
5138 		PMD(PMD_KEEPS, ("%s: check %s, %s\n", pmf, pdr->pdr_kept,
5139 		    pdr->pdr_keeper))
5140 		if (strcmp(kept, pdr->pdr_kept) == 0 &&
5141 		    strcmp(keeper, pdr->pdr_keeper) == 0) {
5142 			PMD(PMD_KEEPS, ("%s: match\n", pmf))
5143 			return (1);
5144 		}
5145 	}
5146 	/*
5147 	 * We did not find any match, so we have to make an entry
5148 	 */
5149 	npdr = newpdr(kept, keeper, isprop);
5150 	if (ppdr) {
5151 		ASSERT(ppdr->pdr_next == NULL);
5152 		ppdr->pdr_next = npdr;
5153 	} else {
5154 		ASSERT(pm_dep_head == NULL);
5155 		pm_dep_head = npdr;
5156 	}
5157 #ifdef DEBUG
5158 	if (pm_debug & PMD_KEEPS)
5159 		prdeps("pm_record_keeper after new record");
5160 #endif
5161 	if (!isprop)
5162 		pm_unresolved_deps++;
5163 	else
5164 		pm_prop_deps++;
5165 	return (0);
5166 }
5167 
5168 /*
5169  * Look up this device in the set of devices we've seen ioctls for
5170  * to see if we are holding a threshold spec for it.  If so, make it so.
5171  * At ioctl time, we were given the physical path of the device.
5172  */
5173 int
5174 pm_thresh_specd(dev_info_t *dip)
5175 {
5176 	void pm_apply_recorded_thresh(dev_info_t *, pm_thresh_rec_t *);
5177 	char *path = 0;
5178 	char pathbuf[MAXNAMELEN];
5179 	pm_thresh_rec_t *rp;
5180 
5181 	path = ddi_pathname(dip, pathbuf);
5182 
5183 	rw_enter(&pm_thresh_rwlock, RW_READER);
5184 	for (rp = pm_thresh_head; rp; rp = rp->ptr_next) {
5185 		if (strcmp(rp->ptr_physpath, path) != 0)
5186 			continue;
5187 		pm_apply_recorded_thresh(dip, rp);
5188 		rw_exit(&pm_thresh_rwlock);
5189 		return (1);
5190 	}
5191 	rw_exit(&pm_thresh_rwlock);
5192 	return (0);
5193 }
5194 
5195 static int
5196 pm_set_keeping(dev_info_t *keeper, dev_info_t *kept)
5197 {
5198 	PMD_FUNC(pmf, "set_keeping")
5199 	pm_info_t *kept_info;
5200 	int j, up = 0, circ;
5201 	void prdeps(char *);
5202 
5203 	PMD(PMD_KEEPS, ("%s: keeper=%s@%s(%s#%d), kept=%s@%s(%s#%d)\n", pmf,
5204 	    PM_DEVICE(keeper), PM_DEVICE(kept)))
5205 #ifdef DEBUG
5206 	if (pm_debug & PMD_KEEPS)
5207 		prdeps("Before PAD\n");
5208 #endif
5209 	ASSERT(keeper != kept);
5210 	if (PM_GET_PM_INFO(keeper) == NULL) {
5211 		cmn_err(CE_CONT, "!device %s@%s(%s#%d) keeps up device "
5212 		    "%s@%s(%s#%d), but the former is not power managed",
5213 		    PM_DEVICE(keeper), PM_DEVICE(kept));
5214 		PMD((PMD_FAIL | PMD_KEEPS), ("%s: keeper %s@%s(%s#%d) is not"
5215 		    "power managed\n", pmf, PM_DEVICE(keeper)))
5216 		return (0);
5217 	}
5218 	kept_info = PM_GET_PM_INFO(kept);
5219 	ASSERT(kept_info);
5220 	PM_LOCK_POWER(keeper, &circ);
5221 	for (j = 0; j < PM_NUMCMPTS(keeper); j++) {
5222 		if (PM_CURPOWER(keeper, j)) {
5223 			up++;
5224 			break;
5225 		}
5226 	}
5227 	if (up) {
5228 		/* Bringup and maintain a hold on the kept */
5229 		PMD(PMD_KEEPS, ("%s: place a hold on kept %s@%s(%s#%d)\n", pmf,
5230 		    PM_DEVICE(kept)))
5231 		bring_pmdep_up(kept, 1);
5232 	}
5233 	PM_UNLOCK_POWER(keeper, circ);
5234 #ifdef DEBUG
5235 	if (pm_debug & PMD_KEEPS)
5236 		prdeps("After PAD\n");
5237 #endif
5238 	return (1);
5239 }
5240 
5241 /*
5242  * Should this device keep up another device?
5243  * Look up this device in the set of devices we've seen ioctls for
5244  * to see if we are holding a dependency spec for it.  If so, make it so.
5245  * Because we require the kept device to be attached already in order to
5246  * make the list entry (and hold it), we only need to look for keepers.
5247  * At ioctl time, we were given the physical path of the device.
5248  */
5249 int
5250 pm_keeper(char *keeper)
5251 {
5252 	PMD_FUNC(pmf, "keeper")
5253 	int pm_apply_recorded_dep(dev_info_t *, pm_pdr_t *);
5254 	dev_info_t *dip;
5255 	pm_pdr_t *dp;
5256 	dev_info_t *kept = NULL;
5257 	int ret = 0;
5258 	int i;
5259 
5260 	if (!pm_unresolved_deps && !pm_prop_deps)
5261 		return (0);
5262 	ASSERT(keeper != NULL);
5263 	dip = pm_name_to_dip(keeper, 1);
5264 	if (dip == NULL)
5265 		return (0);
5266 	PMD(PMD_KEEPS, ("%s: keeper=%s\n", pmf, keeper))
5267 	for (dp = pm_dep_head; dp; dp = dp->pdr_next) {
5268 		if (!dp->pdr_isprop) {
5269 			if (!pm_unresolved_deps)
5270 				continue;
5271 			PMD(PMD_KEEPS, ("%s: keeper %s\n", pmf, dp->pdr_keeper))
5272 			if (dp->pdr_satisfied) {
5273 				PMD(PMD_KEEPS, ("%s: satisfied\n", pmf))
5274 				continue;
5275 			}
5276 			if (strcmp(dp->pdr_keeper, keeper) == 0) {
5277 				ret += pm_apply_recorded_dep(dip, dp);
5278 			}
5279 		} else {
5280 			if (strcmp(dp->pdr_keeper, keeper) != 0)
5281 				continue;
5282 			for (i = 0; i < dp->pdr_kept_count; i++) {
5283 				if (dp->pdr_kept_paths[i] == NULL)
5284 					continue;
5285 				kept = pm_name_to_dip(dp->pdr_kept_paths[i], 1);
5286 				if (kept == NULL)
5287 					continue;
5288 				ASSERT(ddi_prop_exists(DDI_DEV_T_ANY, kept,
5289 				    DDI_PROP_DONTPASS, dp->pdr_kept));
5290 				PMD(PMD_KEEPS, ("%s: keeper=%s@%s(%s#%d), "
5291 				    "kept=%s@%s(%s#%d) keptcnt=%d\n",
5292 				    pmf, PM_DEVICE(dip), PM_DEVICE(kept),
5293 				    dp->pdr_kept_count))
5294 				if (kept != dip) {
5295 					ret += pm_set_keeping(dip, kept);
5296 				}
5297 				ddi_release_devi(kept);
5298 			}
5299 
5300 		}
5301 	}
5302 	ddi_release_devi(dip);
5303 	return (ret);
5304 }
5305 
5306 /*
5307  * Should this device be kept up by another device?
5308  * Look up all dependency recorded from PM_ADD_DEPENDENT and
5309  * PM_ADD_DEPENDENT_PROPERTY ioctls. Record down on the keeper's
5310  * kept device lists.
5311  */
5312 static int
5313 pm_kept(char *keptp)
5314 {
5315 	PMD_FUNC(pmf, "kept")
5316 	pm_pdr_t *dp;
5317 	int found = 0;
5318 	int ret = 0;
5319 	dev_info_t *keeper;
5320 	dev_info_t *kept;
5321 	size_t length;
5322 	int i;
5323 	char **paths;
5324 	char *path;
5325 
5326 	ASSERT(keptp != NULL);
5327 	kept = pm_name_to_dip(keptp, 1);
5328 	if (kept == NULL)
5329 		return (0);
5330 	PMD(PMD_KEEPS, ("%s: %s@%s(%s#%d)\n", pmf, PM_DEVICE(kept)))
5331 	for (dp = pm_dep_head; dp; dp = dp->pdr_next) {
5332 		if (dp->pdr_isprop) {
5333 			PMD(PMD_KEEPS, ("%s: property %s\n", pmf, dp->pdr_kept))
5334 			if (ddi_prop_exists(DDI_DEV_T_ANY, kept,
5335 			    DDI_PROP_DONTPASS, dp->pdr_kept)) {
5336 				/*
5337 				 * Dont allow self dependency.
5338 				 */
5339 				if (strcmp(dp->pdr_keeper, keptp) == 0)
5340 					continue;
5341 				keeper = pm_name_to_dip(dp->pdr_keeper, 1);
5342 				if (keeper == NULL)
5343 					continue;
5344 				PMD(PMD_KEEPS, ("%s: adding to kepts path list "
5345 				    "%p\n", pmf, (void *)kept))
5346 #ifdef DEBUG
5347 				if (pm_debug & PMD_DEP)
5348 					prdeps("Before Adding from pm_kept\n");
5349 #endif
5350 				/*
5351 				 * Add ourselves to the dip list.
5352 				 */
5353 				if (dp->pdr_kept_count == 0) {
5354 					length = strlen(keptp) + 1;
5355 					path =
5356 					    kmem_alloc(length, KM_SLEEP);
5357 					paths = kmem_alloc(sizeof (char **),
5358 					    KM_SLEEP);
5359 					(void) strcpy(path, keptp);
5360 					paths[0] = path;
5361 					dp->pdr_kept_paths = paths;
5362 					dp->pdr_kept_count++;
5363 				} else {
5364 					/* Check to see if already on list */
5365 					for (i = 0; i < dp->pdr_kept_count;
5366 					    i++) {
5367 						if (strcmp(keptp,
5368 						    dp->pdr_kept_paths[i])
5369 						    == 0) {
5370 							found++;
5371 							break;
5372 						}
5373 					}
5374 					if (found) {
5375 						ddi_release_devi(keeper);
5376 						continue;
5377 					}
5378 					length = dp->pdr_kept_count *
5379 					    sizeof (char **);
5380 					paths = kmem_alloc(
5381 					    length + sizeof (char **),
5382 					    KM_SLEEP);
5383 					if (dp->pdr_kept_count) {
5384 						bcopy(dp->pdr_kept_paths,
5385 						    paths, length);
5386 						kmem_free(dp->pdr_kept_paths,
5387 						    length);
5388 					}
5389 					dp->pdr_kept_paths = paths;
5390 					length = strlen(keptp) + 1;
5391 					path =
5392 					    kmem_alloc(length, KM_SLEEP);
5393 					(void) strcpy(path, keptp);
5394 					dp->pdr_kept_paths[i] = path;
5395 					dp->pdr_kept_count++;
5396 				}
5397 #ifdef DEBUG
5398 				if (pm_debug & PMD_DEP)
5399 					prdeps("After from pm_kept\n");
5400 #endif
5401 				if (keeper) {
5402 					ret += pm_set_keeping(keeper, kept);
5403 					ddi_release_devi(keeper);
5404 				}
5405 			}
5406 		} else {
5407 			/*
5408 			 * pm_keeper would be called later to do
5409 			 * the actual pm_set_keeping.
5410 			 */
5411 			PMD(PMD_KEEPS, ("%s: adding to kepts path list %p\n",
5412 			    pmf, (void *)kept))
5413 #ifdef DEBUG
5414 			if (pm_debug & PMD_DEP)
5415 				prdeps("Before Adding from pm_kept\n");
5416 #endif
5417 			if (strcmp(keptp, dp->pdr_kept) == 0) {
5418 				if (dp->pdr_kept_paths == NULL) {
5419 					length = strlen(keptp) + 1;
5420 					path =
5421 					    kmem_alloc(length, KM_SLEEP);
5422 					paths = kmem_alloc(sizeof (char **),
5423 					    KM_SLEEP);
5424 					(void) strcpy(path, keptp);
5425 					paths[0] = path;
5426 					dp->pdr_kept_paths = paths;
5427 					dp->pdr_kept_count++;
5428 				}
5429 			}
5430 #ifdef DEBUG
5431 			if (pm_debug & PMD_DEP)
5432 				prdeps("After from pm_kept\n");
5433 #endif
5434 		}
5435 	}
5436 	ddi_release_devi(kept);
5437 	return (ret);
5438 }
5439 
5440 /*
5441  * Apply a recorded dependency.  dp specifies the dependency, and
5442  * keeper is already known to be the device that keeps up the other (kept) one.
5443  * We have to the whole tree for the "kept" device, then apply
5444  * the dependency (which may already be applied).
5445  */
5446 int
5447 pm_apply_recorded_dep(dev_info_t *keeper, pm_pdr_t *dp)
5448 {
5449 	PMD_FUNC(pmf, "apply_recorded_dep")
5450 	dev_info_t *kept = NULL;
5451 	int ret = 0;
5452 	char *keptp = NULL;
5453 
5454 	/*
5455 	 * Device to Device dependency can only be 1 to 1.
5456 	 */
5457 	if (dp->pdr_kept_paths == NULL)
5458 		return (0);
5459 	keptp = dp->pdr_kept_paths[0];
5460 	if (keptp == NULL)
5461 		return (0);
5462 	ASSERT(*keptp != '\0');
5463 	kept = pm_name_to_dip(keptp, 1);
5464 	if (kept == NULL)
5465 		return (0);
5466 	if (kept) {
5467 		PMD(PMD_KEEPS, ("%s: keeper=%s, kept=%s\n", pmf,
5468 		    dp->pdr_keeper, keptp))
5469 		if (pm_set_keeping(keeper, kept)) {
5470 			ASSERT(dp->pdr_satisfied == 0);
5471 			dp->pdr_satisfied = 1;
5472 			ASSERT(pm_unresolved_deps);
5473 			pm_unresolved_deps--;
5474 			ret++;
5475 		}
5476 	}
5477 	ddi_release_devi(kept);
5478 
5479 	return (ret);
5480 }
5481 
5482 /*
5483  * Called from common/io/pm.c
5484  */
5485 int
5486 pm_cur_power(pm_component_t *cp)
5487 {
5488 	return (cur_power(cp));
5489 }
5490 
5491 /*
5492  * External interface to sanity-check a power level.
5493  */
5494 int
5495 pm_valid_power(dev_info_t *dip, int comp, int level)
5496 {
5497 	PMD_FUNC(pmf, "valid_power")
5498 
5499 	if (comp >= 0 && comp < PM_NUMCMPTS(dip) && level >= 0)
5500 		return (e_pm_valid_power(dip, comp, level));
5501 	else {
5502 		PMD(PMD_FAIL, ("%s: comp=%d, ncomp=%d, level=%d\n",
5503 		    pmf, comp, PM_NUMCMPTS(dip), level))
5504 		return (0);
5505 	}
5506 }
5507 
5508 /*
5509  * Called when a device that is direct power managed needs to change state.
5510  * This routine arranges to block the request until the process managing
5511  * the device makes the change (or some other incompatible change) or
5512  * the process closes /dev/pm.
5513  */
5514 static int
5515 pm_block(dev_info_t *dip, int comp, int newpower, int oldpower)
5516 {
5517 	pm_rsvp_t *new = kmem_zalloc(sizeof (*new), KM_SLEEP);
5518 	int ret = 0;
5519 	void pm_dequeue_blocked(pm_rsvp_t *);
5520 	void pm_enqueue_blocked(pm_rsvp_t *);
5521 
5522 	ASSERT(!pm_processes_stopped);
5523 	ASSERT(PM_IAM_LOCKING_DIP(dip));
5524 	new->pr_dip = dip;
5525 	new->pr_comp = comp;
5526 	new->pr_newlevel = newpower;
5527 	new->pr_oldlevel = oldpower;
5528 	cv_init(&new->pr_cv, NULL, CV_DEFAULT, NULL);
5529 	mutex_enter(&pm_rsvp_lock);
5530 	pm_enqueue_blocked(new);
5531 	pm_enqueue_notify(PSC_PENDING_CHANGE, dip, comp, newpower, oldpower,
5532 	    PM_CANBLOCK_BLOCK);
5533 	PM_UNLOCK_DIP(dip);
5534 	/*
5535 	 * truss may make the cv_wait_sig return prematurely
5536 	 */
5537 	while (ret == 0) {
5538 		/*
5539 		 * Normally there will be no user context involved, but if
5540 		 * there is (e.g. we are here via an ioctl call to a driver)
5541 		 * then we should allow the process to abort the request,
5542 		 * or we get an unkillable process if the same thread does
5543 		 * PM_DIRECT_PM and pm_raise_power
5544 		 */
5545 		if (cv_wait_sig(&new->pr_cv, &pm_rsvp_lock) == 0) {
5546 			ret = PMP_FAIL;
5547 		} else {
5548 			ret = new->pr_retval;
5549 		}
5550 	}
5551 	pm_dequeue_blocked(new);
5552 	mutex_exit(&pm_rsvp_lock);
5553 	cv_destroy(&new->pr_cv);
5554 	kmem_free(new, sizeof (*new));
5555 	return (ret);
5556 }
5557 
5558 /*
5559  * Returns true if the process is interested in power level changes (has issued
5560  * PM_GET_STATE_CHANGE ioctl).
5561  */
5562 int
5563 pm_interest_registered(int clone)
5564 {
5565 	ASSERT(clone >= 0 && clone < PM_MAX_CLONE - 1);
5566 	return (pm_interest[clone]);
5567 }
5568 
5569 static void pm_enqueue_pscc(pscc_t *, pscc_t **);
5570 
5571 /*
5572  * Process with clone has just done PM_DIRECT_PM on dip, or has asked to
5573  * watch all state transitions (dip == NULL).  Set up data
5574  * structs to communicate with process about state changes.
5575  */
5576 void
5577 pm_register_watcher(int clone, dev_info_t *dip)
5578 {
5579 	pscc_t	*p;
5580 	psce_t	*psce;
5581 
5582 	/*
5583 	 * We definitely need a control struct, then we have to search to see
5584 	 * there is already an entries struct (in the dip != NULL case).
5585 	 */
5586 	pscc_t	*pscc = kmem_zalloc(sizeof (*pscc), KM_SLEEP);
5587 	pscc->pscc_clone = clone;
5588 	pscc->pscc_dip = dip;
5589 
5590 	if (dip) {
5591 		int found = 0;
5592 		rw_enter(&pm_pscc_direct_rwlock, RW_WRITER);
5593 		for (p = pm_pscc_direct; p; p = p->pscc_next) {
5594 			/*
5595 			 * Already an entry for this clone, so just use it
5596 			 * for the new one (for the case where a single
5597 			 * process is watching multiple devices)
5598 			 */
5599 			if (p->pscc_clone == clone) {
5600 				pscc->pscc_entries = p->pscc_entries;
5601 				pscc->pscc_entries->psce_references++;
5602 				found++;
5603 				break;
5604 			}
5605 		}
5606 		if (!found) {		/* create a new one */
5607 			psce = kmem_zalloc(sizeof (psce_t), KM_SLEEP);
5608 			mutex_init(&psce->psce_lock, NULL, MUTEX_DEFAULT, NULL);
5609 			psce->psce_first =
5610 			    kmem_zalloc(sizeof (pm_state_change_t) * PSCCOUNT,
5611 			    KM_SLEEP);
5612 			psce->psce_in = psce->psce_out = psce->psce_first;
5613 			psce->psce_last = &psce->psce_first[PSCCOUNT - 1];
5614 			psce->psce_references = 1;
5615 			pscc->pscc_entries = psce;
5616 		}
5617 		pm_enqueue_pscc(pscc, &pm_pscc_direct);
5618 		rw_exit(&pm_pscc_direct_rwlock);
5619 	} else {
5620 		ASSERT(!pm_interest_registered(clone));
5621 		rw_enter(&pm_pscc_interest_rwlock, RW_WRITER);
5622 #ifdef DEBUG
5623 		for (p = pm_pscc_interest; p; p = p->pscc_next) {
5624 			/*
5625 			 * Should not be an entry for this clone!
5626 			 */
5627 			ASSERT(p->pscc_clone != clone);
5628 		}
5629 #endif
5630 		psce = kmem_zalloc(sizeof (psce_t), KM_SLEEP);
5631 		psce->psce_first = kmem_zalloc(sizeof (pm_state_change_t) *
5632 		    PSCCOUNT, KM_SLEEP);
5633 		psce->psce_in = psce->psce_out = psce->psce_first;
5634 		psce->psce_last = &psce->psce_first[PSCCOUNT - 1];
5635 		psce->psce_references = 1;
5636 		pscc->pscc_entries = psce;
5637 		pm_enqueue_pscc(pscc, &pm_pscc_interest);
5638 		pm_interest[clone] = 1;
5639 		rw_exit(&pm_pscc_interest_rwlock);
5640 	}
5641 }
5642 
5643 /*
5644  * Remove the given entry from the blocked list
5645  */
5646 void
5647 pm_dequeue_blocked(pm_rsvp_t *p)
5648 {
5649 	ASSERT(MUTEX_HELD(&pm_rsvp_lock));
5650 	if (pm_blocked_list == p) {
5651 		ASSERT(p->pr_prev == NULL);
5652 		if (p->pr_next != NULL)
5653 			p->pr_next->pr_prev = NULL;
5654 		pm_blocked_list = p->pr_next;
5655 	} else {
5656 		ASSERT(p->pr_prev != NULL);
5657 		p->pr_prev->pr_next = p->pr_next;
5658 		if (p->pr_next != NULL)
5659 			p->pr_next->pr_prev = p->pr_prev;
5660 	}
5661 }
5662 
5663 /*
5664  * Remove the given control struct from the given list
5665  */
5666 static void
5667 pm_dequeue_pscc(pscc_t *p, pscc_t **list)
5668 {
5669 	if (*list == p) {
5670 		ASSERT(p->pscc_prev == NULL);
5671 		if (p->pscc_next != NULL)
5672 			p->pscc_next->pscc_prev = NULL;
5673 		*list = p->pscc_next;
5674 	} else {
5675 		ASSERT(p->pscc_prev != NULL);
5676 		p->pscc_prev->pscc_next = p->pscc_next;
5677 		if (p->pscc_next != NULL)
5678 			p->pscc_next->pscc_prev = p->pscc_prev;
5679 	}
5680 }
5681 
5682 /*
5683  * Stick the control struct specified on the front of the list
5684  */
5685 static void
5686 pm_enqueue_pscc(pscc_t *p, pscc_t **list)
5687 {
5688 	pscc_t *h;	/* entry at head of list */
5689 	if ((h = *list) == NULL) {
5690 		*list = p;
5691 		ASSERT(p->pscc_next == NULL);
5692 		ASSERT(p->pscc_prev == NULL);
5693 	} else {
5694 		p->pscc_next = h;
5695 		ASSERT(h->pscc_prev == NULL);
5696 		h->pscc_prev = p;
5697 		ASSERT(p->pscc_prev == NULL);
5698 		*list = p;
5699 	}
5700 }
5701 
5702 /*
5703  * If dip is NULL, process is closing "clone" clean up all its registrations.
5704  * Otherwise only clean up those for dip because process is just giving up
5705  * control of a direct device.
5706  */
5707 void
5708 pm_deregister_watcher(int clone, dev_info_t *dip)
5709 {
5710 	pscc_t	*p, *pn;
5711 	psce_t	*psce;
5712 	int found = 0;
5713 
5714 	if (dip == NULL) {
5715 		rw_enter(&pm_pscc_interest_rwlock, RW_WRITER);
5716 		for (p = pm_pscc_interest; p; p = pn) {
5717 			pn = p->pscc_next;
5718 			if (p->pscc_clone == clone) {
5719 				pm_dequeue_pscc(p, &pm_pscc_interest);
5720 				psce = p->pscc_entries;
5721 				ASSERT(psce->psce_references == 1);
5722 				mutex_destroy(&psce->psce_lock);
5723 				kmem_free(psce->psce_first,
5724 				    sizeof (pm_state_change_t) * PSCCOUNT);
5725 				kmem_free(psce, sizeof (*psce));
5726 				kmem_free(p, sizeof (*p));
5727 			}
5728 		}
5729 		pm_interest[clone] = 0;
5730 		rw_exit(&pm_pscc_interest_rwlock);
5731 	}
5732 	found = 0;
5733 	rw_enter(&pm_pscc_direct_rwlock, RW_WRITER);
5734 	for (p = pm_pscc_direct; p; p = pn) {
5735 		pn = p->pscc_next;
5736 		if ((dip && p->pscc_dip == dip) ||
5737 		    (dip == NULL && clone == p->pscc_clone)) {
5738 			ASSERT(clone == p->pscc_clone);
5739 			found++;
5740 			/*
5741 			 * Remove from control list
5742 			 */
5743 			pm_dequeue_pscc(p, &pm_pscc_direct);
5744 			/*
5745 			 * If we're the last reference, free the
5746 			 * entries struct.
5747 			 */
5748 			psce = p->pscc_entries;
5749 			ASSERT(psce);
5750 			if (psce->psce_references == 1) {
5751 				kmem_free(psce->psce_first,
5752 				    PSCCOUNT * sizeof (pm_state_change_t));
5753 				kmem_free(psce, sizeof (*psce));
5754 			} else {
5755 				psce->psce_references--;
5756 			}
5757 			kmem_free(p, sizeof (*p));
5758 		}
5759 	}
5760 	ASSERT(dip == NULL || found);
5761 	rw_exit(&pm_pscc_direct_rwlock);
5762 }
5763 
5764 /*
5765  * Search the indicated list for an entry that matches clone, and return a
5766  * pointer to it.  To be interesting, the entry must have something ready to
5767  * be passed up to the controlling process.
5768  * The returned entry will be locked upon return from this call.
5769  */
5770 static psce_t *
5771 pm_psc_find_clone(int clone, pscc_t **list, krwlock_t *lock)
5772 {
5773 	pscc_t	*p;
5774 	psce_t	*psce;
5775 	rw_enter(lock, RW_READER);
5776 	for (p = *list; p; p = p->pscc_next) {
5777 		if (clone == p->pscc_clone) {
5778 			psce = p->pscc_entries;
5779 			mutex_enter(&psce->psce_lock);
5780 			if (psce->psce_out->size) {
5781 				rw_exit(lock);
5782 				return (psce);
5783 			} else {
5784 				mutex_exit(&psce->psce_lock);
5785 			}
5786 		}
5787 	}
5788 	rw_exit(lock);
5789 	return (NULL);
5790 }
5791 
5792 static psce_t *pm_psc_find_clone(int, pscc_t **, krwlock_t *);
5793 /*
5794  * Find an entry for a particular clone in the direct list.
5795  */
5796 psce_t *
5797 pm_psc_clone_to_direct(int clone)
5798 {
5799 	return (pm_psc_find_clone(clone, &pm_pscc_direct,
5800 	    &pm_pscc_direct_rwlock));
5801 }
5802 
5803 /*
5804  * Find an entry for a particular clone in the interest list.
5805  */
5806 psce_t *
5807 pm_psc_clone_to_interest(int clone)
5808 {
5809 	return (pm_psc_find_clone(clone, &pm_pscc_interest,
5810 	    &pm_pscc_interest_rwlock));
5811 }
5812 
5813 /*
5814  * Put the given entry at the head of the blocked list
5815  */
5816 void
5817 pm_enqueue_blocked(pm_rsvp_t *p)
5818 {
5819 	ASSERT(MUTEX_HELD(&pm_rsvp_lock));
5820 	ASSERT(p->pr_next == NULL);
5821 	ASSERT(p->pr_prev == NULL);
5822 	if (pm_blocked_list != NULL) {
5823 		p->pr_next = pm_blocked_list;
5824 		ASSERT(pm_blocked_list->pr_prev == NULL);
5825 		pm_blocked_list->pr_prev = p;
5826 		pm_blocked_list = p;
5827 	} else {
5828 		pm_blocked_list = p;
5829 	}
5830 }
5831 
5832 /*
5833  * Sets every power managed device back to its default threshold
5834  */
5835 void
5836 pm_all_to_default_thresholds(void)
5837 {
5838 	ddi_walk_devs(ddi_root_node(), pm_set_dev_thr_walk,
5839 	    (void *) &pm_system_idle_threshold);
5840 }
5841 
5842 static int
5843 pm_set_dev_thr_walk(dev_info_t *dip, void *arg)
5844 {
5845 	int thr = (int)(*(int *)arg);
5846 
5847 	if (!PM_GET_PM_INFO(dip))
5848 		return (DDI_WALK_CONTINUE);
5849 	pm_set_device_threshold(dip, thr, PMC_DEF_THRESH);
5850 	return (DDI_WALK_CONTINUE);
5851 }
5852 
5853 /*
5854  * Returns the current threshold value (in seconds) for the indicated component
5855  */
5856 int
5857 pm_current_threshold(dev_info_t *dip, int comp, int *threshp)
5858 {
5859 	if (comp < 0 || comp >= PM_NUMCMPTS(dip)) {
5860 		return (DDI_FAILURE);
5861 	} else {
5862 		*threshp = cur_threshold(dip, comp);
5863 		return (DDI_SUCCESS);
5864 	}
5865 }
5866 
5867 /*
5868  * To be called when changing the power level of a component of a device.
5869  * On some platforms, changing power on one device may require that power
5870  * be changed on other, related devices in the same transaction.  Thus, we
5871  * always pass this request to the platform power manager so that all the
5872  * affected devices will be locked.
5873  */
5874 void
5875 pm_lock_power(dev_info_t *dip, int *circp)
5876 {
5877 	power_req_t power_req;
5878 	int result;
5879 
5880 	power_req.request_type = PMR_PPM_LOCK_POWER;
5881 	power_req.req.ppm_lock_power_req.who = dip;
5882 	power_req.req.ppm_lock_power_req.circp = circp;
5883 	(void) pm_ctlops(PPM(dip), dip, DDI_CTLOPS_POWER, &power_req, &result);
5884 }
5885 
5886 /*
5887  * Release the lock (or locks) acquired to change the power of a device.
5888  * See comments for pm_lock_power.
5889  */
5890 void
5891 pm_unlock_power(dev_info_t *dip, int circ)
5892 {
5893 	power_req_t power_req;
5894 	int result;
5895 
5896 	power_req.request_type = PMR_PPM_UNLOCK_POWER;
5897 	power_req.req.ppm_unlock_power_req.who = dip;
5898 	power_req.req.ppm_unlock_power_req.circ = circ;
5899 	(void) pm_ctlops(PPM(dip), dip, DDI_CTLOPS_POWER, &power_req, &result);
5900 }
5901 
5902 
5903 /*
5904  * Attempt (without blocking) to acquire the lock(s) needed to change the
5905  * power of a component of a device.  See comments for pm_lock_power.
5906  *
5907  * Return: 1 if lock(s) acquired, 0 if not.
5908  */
5909 int
5910 pm_try_locking_power(dev_info_t *dip, int *circp)
5911 {
5912 	power_req_t power_req;
5913 	int result;
5914 
5915 	power_req.request_type = PMR_PPM_TRY_LOCK_POWER;
5916 	power_req.req.ppm_lock_power_req.who = dip;
5917 	power_req.req.ppm_lock_power_req.circp = circp;
5918 	(void) pm_ctlops(PPM(dip), dip, DDI_CTLOPS_POWER, &power_req, &result);
5919 	return (result);
5920 }
5921 
5922 
5923 /*
5924  * Lock power state of a device.
5925  *
5926  * The implementation handles a special case where another thread may have
5927  * acquired the lock and created/launched this thread to do the work.  If
5928  * the lock cannot be acquired immediately, we check to see if this thread
5929  * is registered as a borrower of the lock.  If so, we may proceed without
5930  * the lock.  This assumes that the lending thread blocks on the completion
5931  * of this thread.
5932  *
5933  * Note 1: for use by ppm only.
5934  *
5935  * Note 2: On failing to get the lock immediately, we search lock_loan list
5936  * for curthread (as borrower of the lock).  On a hit, we check that the
5937  * lending thread already owns the lock we want.  It is safe to compare
5938  * devi_busy_thread and thread id of the lender because in the == case (the
5939  * only one we care about) we know that the owner is blocked.  Similarly,
5940  * If we find that curthread isn't registered as a lock borrower, it is safe
5941  * to use the blocking call (ndi_devi_enter) because we know that if we
5942  * weren't already listed as a borrower (upstream on the call stack) we won't
5943  * become one.
5944  */
5945 void
5946 pm_lock_power_single(dev_info_t *dip, int *circp)
5947 {
5948 	lock_loan_t *cur;
5949 
5950 	/* if the lock is available, we are done. */
5951 	if (ndi_devi_tryenter(dip, circp))
5952 		return;
5953 
5954 	mutex_enter(&pm_loan_lock);
5955 	/* see if our thread is registered as a lock borrower. */
5956 	for (cur = lock_loan_head.pmlk_next; cur; cur = cur->pmlk_next)
5957 		if (cur->pmlk_borrower == curthread)
5958 			break;
5959 	mutex_exit(&pm_loan_lock);
5960 
5961 	/* if this thread not already registered, it is safe to block */
5962 	if (cur == NULL)
5963 		ndi_devi_enter(dip, circp);
5964 	else {
5965 		/* registered: does lender own the lock we want? */
5966 		if (cur->pmlk_lender == DEVI(dip)->devi_busy_thread) {
5967 			ASSERT(cur->pmlk_dip == NULL || cur->pmlk_dip == dip);
5968 			cur->pmlk_dip = dip;
5969 		} else /* no: just block for it */
5970 			ndi_devi_enter(dip, circp);
5971 
5972 	}
5973 }
5974 
5975 /*
5976  * Drop the lock on the device's power state.  See comment for
5977  * pm_lock_power_single() for special implementation considerations.
5978  *
5979  * Note: for use by ppm only.
5980  */
5981 void
5982 pm_unlock_power_single(dev_info_t *dip, int circ)
5983 {
5984 	lock_loan_t *cur;
5985 
5986 	/* optimization: mutex not needed to check empty list */
5987 	if (lock_loan_head.pmlk_next == NULL) {
5988 		ndi_devi_exit(dip, circ);
5989 		return;
5990 	}
5991 
5992 	mutex_enter(&pm_loan_lock);
5993 	/* see if our thread is registered as a lock borrower. */
5994 	for (cur = lock_loan_head.pmlk_next; cur; cur = cur->pmlk_next)
5995 		if (cur->pmlk_borrower == curthread)
5996 			break;
5997 	mutex_exit(&pm_loan_lock);
5998 
5999 	if (cur == NULL || cur->pmlk_dip != dip)
6000 		/* we acquired the lock directly, so return it */
6001 		ndi_devi_exit(dip, circ);
6002 }
6003 
6004 /*
6005  * Try to take the lock for changing the power level of a component.
6006  *
6007  * Note: for use by ppm only.
6008  */
6009 int
6010 pm_try_locking_power_single(dev_info_t *dip, int *circp)
6011 {
6012 	return (ndi_devi_tryenter(dip, circp));
6013 }
6014 
6015 #ifdef	DEBUG
6016 /*
6017  * The following are used only to print out data structures for debugging
6018  */
6019 void
6020 prdeps(char *msg)
6021 {
6022 
6023 	pm_pdr_t *rp;
6024 	int i;
6025 
6026 	pm_log("pm_dep_head %s %p\n", msg, (void *)pm_dep_head);
6027 	for (rp = pm_dep_head; rp; rp = rp->pdr_next) {
6028 		pm_log("%p: %s keeper %s, kept %s, kept count %d, next %p\n",
6029 		    (void *)rp, (rp->pdr_isprop ? "property" : "device"),
6030 		    rp->pdr_keeper, rp->pdr_kept, rp->pdr_kept_count,
6031 		    (void *)rp->pdr_next);
6032 		if (rp->pdr_kept_count != 0) {
6033 			pm_log("kept list = ");
6034 			i = 0;
6035 			while (i < rp->pdr_kept_count) {
6036 				pm_log("%s ", rp->pdr_kept_paths[i]);
6037 				i++;
6038 			}
6039 			pm_log("\n");
6040 		}
6041 	}
6042 }
6043 
6044 void
6045 pr_noinvol(char *hdr)
6046 {
6047 	pm_noinvol_t *ip;
6048 
6049 	pm_log("%s\n", hdr);
6050 	rw_enter(&pm_noinvol_rwlock, RW_READER);
6051 	for (ip = pm_noinvol_head; ip; ip = ip->ni_next)
6052 		pm_log("\tmaj %d, flags %x, noinvolpm %d %s\n",
6053 		    ip->ni_major, ip->ni_flags, ip->ni_noinvolpm, ip->ni_path);
6054 	rw_exit(&pm_noinvol_rwlock);
6055 }
6056 #endif
6057 
6058 /*
6059  * Attempt to apply the thresholds indicated by rp to the node specified by
6060  * dip.
6061  */
6062 void
6063 pm_apply_recorded_thresh(dev_info_t *dip, pm_thresh_rec_t *rp)
6064 {
6065 	PMD_FUNC(pmf, "apply_recorded_thresh")
6066 	int i, j;
6067 	int comps = PM_NUMCMPTS(dip);
6068 	struct pm_component *cp;
6069 	pm_pte_t *ep;
6070 	int pm_valid_thresh(dev_info_t *, pm_thresh_rec_t *);
6071 
6072 	PMD(PMD_THRESH, ("%s: part: %s@%s(%s#%d), rp %p, %s\n", pmf,
6073 	    PM_DEVICE(dip), (void *)rp, rp->ptr_physpath))
6074 	PM_LOCK_DIP(dip);
6075 	if (!PM_GET_PM_INFO(dip) || PM_ISBC(dip) || !pm_valid_thresh(dip, rp)) {
6076 		PMD(PMD_FAIL, ("%s: part: %s@%s(%s#%d) PM_GET_PM_INFO %p\n",
6077 		    pmf, PM_DEVICE(dip), (void*)PM_GET_PM_INFO(dip)))
6078 		PMD(PMD_FAIL, ("%s: part: %s@%s(%s#%d) PM_ISBC %d\n",
6079 		    pmf, PM_DEVICE(dip), PM_ISBC(dip)))
6080 		PMD(PMD_FAIL, ("%s: part: %s@%s(%s#%d) pm_valid_thresh %d\n",
6081 		    pmf, PM_DEVICE(dip), pm_valid_thresh(dip, rp)))
6082 		PM_UNLOCK_DIP(dip);
6083 		return;
6084 	}
6085 
6086 	ep = rp->ptr_entries;
6087 	/*
6088 	 * Here we do the special case of a device threshold
6089 	 */
6090 	if (rp->ptr_numcomps == 0) {	/* PM_SET_DEVICE_THRESHOLD product */
6091 		ASSERT(ep && ep->pte_numthresh == 1);
6092 		PMD(PMD_THRESH, ("%s: set dev thr %s@%s(%s#%d) to 0x%x\n",
6093 		    pmf, PM_DEVICE(dip), ep->pte_thresh[0]))
6094 		PM_UNLOCK_DIP(dip);
6095 		pm_set_device_threshold(dip, ep->pte_thresh[0], PMC_DEV_THRESH);
6096 		if (PM_SCANABLE(dip))
6097 			pm_rescan(dip);
6098 		return;
6099 	}
6100 	for (i = 0; i < comps; i++) {
6101 		cp = PM_CP(dip, i);
6102 		for (j = 0; j < ep->pte_numthresh; j++) {
6103 			PMD(PMD_THRESH, ("%s: set thr %d for %s@%s(%s#%d)[%d] "
6104 			    "to %x\n", pmf, j, PM_DEVICE(dip),
6105 			    i, ep->pte_thresh[j]))
6106 			cp->pmc_comp.pmc_thresh[j + 1] = ep->pte_thresh[j];
6107 		}
6108 		ep++;
6109 	}
6110 	DEVI(dip)->devi_pm_flags &= PMC_THRESH_NONE;
6111 	DEVI(dip)->devi_pm_flags |= PMC_COMP_THRESH;
6112 	PM_UNLOCK_DIP(dip);
6113 
6114 	if (PM_SCANABLE(dip))
6115 		pm_rescan(dip);
6116 }
6117 
6118 /*
6119  * Returns true if the threshold specified by rp could be applied to dip
6120  * (that is, the number of components and transitions are the same)
6121  */
6122 int
6123 pm_valid_thresh(dev_info_t *dip, pm_thresh_rec_t *rp)
6124 {
6125 	PMD_FUNC(pmf, "valid_thresh")
6126 	int comps, i;
6127 	pm_component_t *cp;
6128 	pm_pte_t *ep;
6129 
6130 	if (!PM_GET_PM_INFO(dip) || PM_ISBC(dip)) {
6131 		PMD(PMD_ERROR, ("%s: %s: no pm_info or BC\n", pmf,
6132 		    rp->ptr_physpath))
6133 		return (0);
6134 	}
6135 	/*
6136 	 * Special case: we represent the PM_SET_DEVICE_THRESHOLD case by
6137 	 * an entry with numcomps == 0, (since we don't know how many
6138 	 * components there are in advance).  This is always a valid
6139 	 * spec.
6140 	 */
6141 	if (rp->ptr_numcomps == 0) {
6142 		ASSERT(rp->ptr_entries && rp->ptr_entries->pte_numthresh == 1);
6143 		return (1);
6144 	}
6145 	if (rp->ptr_numcomps != (comps = PM_NUMCMPTS(dip))) {
6146 		PMD(PMD_ERROR, ("%s: comp # mm (dip %d cmd %d) for %s\n",
6147 		    pmf, PM_NUMCMPTS(dip), rp->ptr_numcomps, rp->ptr_physpath))
6148 		return (0);
6149 	}
6150 	ep = rp->ptr_entries;
6151 	for (i = 0; i < comps; i++) {
6152 		cp = PM_CP(dip, i);
6153 		if ((ep + i)->pte_numthresh !=
6154 		    cp->pmc_comp.pmc_numlevels - 1) {
6155 			PMD(PMD_ERROR, ("%s: %s[%d]: thresh=%d, record=%d\n",
6156 			    pmf, rp->ptr_physpath, i,
6157 			    cp->pmc_comp.pmc_numlevels - 1,
6158 			    (ep + i)->pte_numthresh))
6159 			return (0);
6160 		}
6161 	}
6162 	return (1);
6163 }
6164 
6165 /*
6166  * Remove any recorded threshold for device physpath
6167  * We know there will be at most one.
6168  */
6169 void
6170 pm_unrecord_threshold(char *physpath)
6171 {
6172 	pm_thresh_rec_t *pptr, *ptr;
6173 
6174 	rw_enter(&pm_thresh_rwlock, RW_WRITER);
6175 	for (pptr = NULL, ptr = pm_thresh_head; ptr; ptr = ptr->ptr_next) {
6176 		if (strcmp(physpath, ptr->ptr_physpath) == 0) {
6177 			if (pptr) {
6178 				pptr->ptr_next = ptr->ptr_next;
6179 			} else {
6180 				ASSERT(pm_thresh_head == ptr);
6181 				pm_thresh_head = ptr->ptr_next;
6182 			}
6183 			kmem_free(ptr, ptr->ptr_size);
6184 			break;
6185 		}
6186 		pptr = ptr;
6187 	}
6188 	rw_exit(&pm_thresh_rwlock);
6189 }
6190 
6191 /*
6192  * Discard all recorded thresholds.  We are returning to the default pm state.
6193  */
6194 void
6195 pm_discard_thresholds(void)
6196 {
6197 	pm_thresh_rec_t *rp;
6198 	rw_enter(&pm_thresh_rwlock, RW_WRITER);
6199 	while (pm_thresh_head) {
6200 		rp = pm_thresh_head;
6201 		pm_thresh_head = rp->ptr_next;
6202 		kmem_free(rp, rp->ptr_size);
6203 	}
6204 	rw_exit(&pm_thresh_rwlock);
6205 }
6206 
6207 /*
6208  * Discard all recorded dependencies.  We are returning to the default pm state.
6209  */
6210 void
6211 pm_discard_dependencies(void)
6212 {
6213 	pm_pdr_t *rp;
6214 	int i;
6215 	size_t length;
6216 
6217 #ifdef DEBUG
6218 	if (pm_debug & PMD_DEP)
6219 		prdeps("Before discard\n");
6220 #endif
6221 	ddi_walk_devs(ddi_root_node(), pm_discard_dep_walk, NULL);
6222 
6223 #ifdef DEBUG
6224 	if (pm_debug & PMD_DEP)
6225 		prdeps("After discard\n");
6226 #endif
6227 	while (pm_dep_head) {
6228 		rp = pm_dep_head;
6229 		if (!rp->pdr_isprop) {
6230 			ASSERT(rp->pdr_satisfied == 0);
6231 			ASSERT(pm_unresolved_deps);
6232 			pm_unresolved_deps--;
6233 		} else {
6234 			ASSERT(pm_prop_deps);
6235 			pm_prop_deps--;
6236 		}
6237 		pm_dep_head = rp->pdr_next;
6238 		if (rp->pdr_kept_count)  {
6239 			for (i = 0; i < rp->pdr_kept_count; i++) {
6240 				length = strlen(rp->pdr_kept_paths[i]) + 1;
6241 				kmem_free(rp->pdr_kept_paths[i], length);
6242 			}
6243 			kmem_free(rp->pdr_kept_paths,
6244 			    rp->pdr_kept_count * sizeof (char **));
6245 		}
6246 		kmem_free(rp, rp->pdr_size);
6247 	}
6248 }
6249 
6250 
6251 static int
6252 pm_discard_dep_walk(dev_info_t *dip, void *arg)
6253 {
6254 	_NOTE(ARGUNUSED(arg))
6255 	char *pathbuf;
6256 
6257 	if (PM_GET_PM_INFO(dip) == NULL)
6258 		return (DDI_WALK_CONTINUE);
6259 	pathbuf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
6260 	(void) ddi_pathname(dip, pathbuf);
6261 	pm_free_keeper(pathbuf, 0);
6262 	kmem_free(pathbuf, MAXPATHLEN);
6263 	return (DDI_WALK_CONTINUE);
6264 }
6265 
6266 static int
6267 pm_kept_walk(dev_info_t *dip, void *arg)
6268 {
6269 	_NOTE(ARGUNUSED(arg))
6270 	char *pathbuf;
6271 
6272 	pathbuf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
6273 	(void) ddi_pathname(dip, pathbuf);
6274 	(void) pm_kept(pathbuf);
6275 	kmem_free(pathbuf, MAXPATHLEN);
6276 
6277 	return (DDI_WALK_CONTINUE);
6278 }
6279 
6280 static int
6281 pm_keeper_walk(dev_info_t *dip, void *arg)
6282 {
6283 	_NOTE(ARGUNUSED(arg))
6284 	char *pathbuf;
6285 
6286 	pathbuf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
6287 	(void) ddi_pathname(dip, pathbuf);
6288 	(void) pm_keeper(pathbuf);
6289 	kmem_free(pathbuf, MAXPATHLEN);
6290 
6291 	return (DDI_WALK_CONTINUE);
6292 }
6293 
6294 static char *
6295 pdw_type_decode(int type)
6296 {
6297 	switch (type) {
6298 	case PM_DEP_WK_POWER_ON:
6299 		return ("power on");
6300 	case PM_DEP_WK_POWER_OFF:
6301 		return ("power off");
6302 	case PM_DEP_WK_DETACH:
6303 		return ("detach");
6304 	case PM_DEP_WK_REMOVE_DEP:
6305 		return ("remove dep");
6306 	case PM_DEP_WK_BRINGUP_SELF:
6307 		return ("bringup self");
6308 	case PM_DEP_WK_RECORD_KEEPER:
6309 		return ("add dependent");
6310 	case PM_DEP_WK_RECORD_KEEPER_PROP:
6311 		return ("add dependent property");
6312 	case PM_DEP_WK_KEPT:
6313 		return ("kept");
6314 	case PM_DEP_WK_KEEPER:
6315 		return ("keeper");
6316 	case PM_DEP_WK_ATTACH:
6317 		return ("attach");
6318 	case PM_DEP_WK_CHECK_KEPT:
6319 		return ("check kept");
6320 	case PM_DEP_WK_CPR_SUSPEND:
6321 		return ("suspend");
6322 	case PM_DEP_WK_CPR_RESUME:
6323 		return ("resume");
6324 	default:
6325 		return ("unknown");
6326 	}
6327 
6328 }
6329 
6330 static void
6331 pm_rele_dep(char *keeper)
6332 {
6333 	PMD_FUNC(pmf, "rele_dep")
6334 	pm_pdr_t *dp;
6335 	char *kept_path = NULL;
6336 	dev_info_t *kept = NULL;
6337 	int count = 0;
6338 
6339 	for (dp = pm_dep_head; dp; dp = dp->pdr_next) {
6340 		if (strcmp(dp->pdr_keeper, keeper) != 0)
6341 			continue;
6342 		for (count = 0; count < dp->pdr_kept_count; count++) {
6343 			kept_path = dp->pdr_kept_paths[count];
6344 			if (kept_path == NULL)
6345 				continue;
6346 			kept = pm_name_to_dip(kept_path, 1);
6347 			if (kept) {
6348 				PMD(PMD_KEEPS, ("%s: release kept=%s@%s(%s#%d) "
6349 				    "of keeper=%s\n", pmf, PM_DEVICE(kept),
6350 				    keeper))
6351 				ASSERT(DEVI(kept)->devi_pm_kidsupcnt > 0);
6352 				pm_rele_power(kept);
6353 				ddi_release_devi(kept);
6354 			}
6355 		}
6356 	}
6357 }
6358 
6359 /*
6360  * Called when we are just released from direct PM.  Bring ourself up
6361  * if our keeper is up since dependency is not honored while a kept
6362  * device is under direct PM.
6363  */
6364 static void
6365 pm_bring_self_up(char *keptpath)
6366 {
6367 	PMD_FUNC(pmf, "bring_self_up")
6368 	dev_info_t *kept;
6369 	dev_info_t *keeper;
6370 	pm_pdr_t *dp;
6371 	int i, j;
6372 	int up = 0, circ;
6373 
6374 	kept = pm_name_to_dip(keptpath, 1);
6375 	if (kept == NULL)
6376 		return;
6377 	PMD(PMD_KEEPS, ("%s: kept=%s@%s(%s#%d)\n", pmf, PM_DEVICE(kept)))
6378 	for (dp = pm_dep_head; dp; dp = dp->pdr_next) {
6379 		if (dp->pdr_kept_count == 0)
6380 			continue;
6381 		for (i = 0; i < dp->pdr_kept_count; i++) {
6382 			if (strcmp(dp->pdr_kept_paths[i], keptpath) != 0)
6383 				continue;
6384 			keeper = pm_name_to_dip(dp->pdr_keeper, 1);
6385 			if (keeper) {
6386 				PMD(PMD_KEEPS, ("%s: keeper=%s@%s(%s#%d)\n",
6387 				    pmf, PM_DEVICE(keeper)))
6388 				PM_LOCK_POWER(keeper, &circ);
6389 				for (j = 0; j < PM_NUMCMPTS(keeper);
6390 				    j++) {
6391 					if (PM_CURPOWER(keeper, j)) {
6392 						PMD(PMD_KEEPS, ("%s: comp="
6393 						    "%d is up\n", pmf, j))
6394 						up++;
6395 					}
6396 				}
6397 				if (up) {
6398 					if (PM_SKBU(kept))
6399 						DEVI(kept)->devi_pm_flags &=
6400 						    ~PMC_SKIP_BRINGUP;
6401 					bring_pmdep_up(kept, 1);
6402 				}
6403 				PM_UNLOCK_POWER(keeper, circ);
6404 				ddi_release_devi(keeper);
6405 			}
6406 		}
6407 	}
6408 	ddi_release_devi(kept);
6409 }
6410 
6411 static void
6412 pm_process_dep_request(pm_dep_wk_t *work)
6413 {
6414 	PMD_FUNC(pmf, "dep_req")
6415 	int ret;
6416 
6417 	PMD(PMD_DEP, ("%s: work=%s\n", pmf,
6418 	    pdw_type_decode(work->pdw_type)))
6419 	PMD(PMD_DEP, ("%s: keeper=%s, kept=%s\n", pmf,
6420 	    (work->pdw_keeper ? work->pdw_keeper : "NULL"),
6421 	    (work->pdw_kept ? work->pdw_kept : "NULL")))
6422 
6423 	switch (work->pdw_type) {
6424 	case PM_DEP_WK_POWER_ON:
6425 		/* Bring up the kept devices and put a hold on them */
6426 		bring_wekeeps_up(work->pdw_keeper);
6427 		break;
6428 	case PM_DEP_WK_POWER_OFF:
6429 		/* Release the kept devices */
6430 		pm_rele_dep(work->pdw_keeper);
6431 		break;
6432 	case PM_DEP_WK_DETACH:
6433 		pm_free_keeps(work->pdw_keeper, work->pdw_pwr);
6434 		break;
6435 	case PM_DEP_WK_REMOVE_DEP:
6436 		pm_discard_dependencies();
6437 		break;
6438 	case PM_DEP_WK_BRINGUP_SELF:
6439 		/*
6440 		 * We deferred satisfying our dependency till now, so satisfy
6441 		 * it again and bring ourselves up.
6442 		 */
6443 		pm_bring_self_up(work->pdw_kept);
6444 		break;
6445 	case PM_DEP_WK_RECORD_KEEPER:
6446 		(void) pm_record_keeper(work->pdw_kept, work->pdw_keeper, 0);
6447 		ddi_walk_devs(ddi_root_node(), pm_kept_walk, NULL);
6448 		ddi_walk_devs(ddi_root_node(), pm_keeper_walk, NULL);
6449 		break;
6450 	case PM_DEP_WK_RECORD_KEEPER_PROP:
6451 		(void) pm_record_keeper(work->pdw_kept, work->pdw_keeper, 1);
6452 		ddi_walk_devs(ddi_root_node(), pm_keeper_walk, NULL);
6453 		ddi_walk_devs(ddi_root_node(), pm_kept_walk, NULL);
6454 		break;
6455 	case PM_DEP_WK_KEPT:
6456 		ret = pm_kept(work->pdw_kept);
6457 		PMD(PMD_DEP, ("%s: PM_DEP_WK_KEPT: pm_kept returns %d\n", pmf,
6458 		    ret))
6459 		break;
6460 	case PM_DEP_WK_KEEPER:
6461 		ret = pm_keeper(work->pdw_keeper);
6462 		PMD(PMD_DEP, ("%s: PM_DEP_WK_KEEPER: pm_keeper returns %d\n",
6463 		    pmf, ret))
6464 		break;
6465 	case PM_DEP_WK_ATTACH:
6466 		ret = pm_keeper(work->pdw_keeper);
6467 		PMD(PMD_DEP, ("%s: PM_DEP_WK_ATTACH: pm_keeper returns %d\n",
6468 		    pmf, ret))
6469 		ret = pm_kept(work->pdw_kept);
6470 		PMD(PMD_DEP, ("%s: PM_DEP_WK_ATTACH: pm_kept returns %d\n",
6471 		    pmf, ret))
6472 		break;
6473 	case PM_DEP_WK_CHECK_KEPT:
6474 		ret = pm_is_kept(work->pdw_kept);
6475 		PMD(PMD_DEP, ("%s: PM_DEP_WK_CHECK_KEPT: kept=%s, ret=%d\n",
6476 		    pmf, work->pdw_kept, ret))
6477 		break;
6478 	case PM_DEP_WK_CPR_SUSPEND:
6479 		pm_discard_dependencies();
6480 		break;
6481 	case PM_DEP_WK_CPR_RESUME:
6482 		ddi_walk_devs(ddi_root_node(), pm_kept_walk, NULL);
6483 		ddi_walk_devs(ddi_root_node(), pm_keeper_walk, NULL);
6484 		break;
6485 	default:
6486 		ASSERT(0);
6487 		break;
6488 	}
6489 	/*
6490 	 * Free the work structure if the requester is not waiting
6491 	 * Otherwise it is the requester's responsiblity to free it.
6492 	 */
6493 	if (!work->pdw_wait) {
6494 		if (work->pdw_keeper)
6495 			kmem_free(work->pdw_keeper,
6496 			    strlen(work->pdw_keeper) + 1);
6497 		if (work->pdw_kept)
6498 			kmem_free(work->pdw_kept, strlen(work->pdw_kept) + 1);
6499 		kmem_free(work, sizeof (pm_dep_wk_t));
6500 	} else {
6501 		/*
6502 		 * Notify requester if it is waiting for it.
6503 		 */
6504 		work->pdw_ret = ret;
6505 		work->pdw_done = 1;
6506 		cv_signal(&work->pdw_cv);
6507 	}
6508 }
6509 
6510 /*
6511  * Process PM dependency requests.
6512  */
6513 static void
6514 pm_dep_thread(void)
6515 {
6516 	pm_dep_wk_t *work;
6517 	callb_cpr_t cprinfo;
6518 
6519 	CALLB_CPR_INIT(&cprinfo, &pm_dep_thread_lock, callb_generic_cpr,
6520 	    "pm_dep_thread");
6521 	for (;;) {
6522 		mutex_enter(&pm_dep_thread_lock);
6523 		if (pm_dep_thread_workq == NULL) {
6524 			CALLB_CPR_SAFE_BEGIN(&cprinfo);
6525 			cv_wait(&pm_dep_thread_cv, &pm_dep_thread_lock);
6526 			CALLB_CPR_SAFE_END(&cprinfo, &pm_dep_thread_lock);
6527 		}
6528 		work = pm_dep_thread_workq;
6529 		pm_dep_thread_workq = work->pdw_next;
6530 		if (pm_dep_thread_tail == work)
6531 			pm_dep_thread_tail = work->pdw_next;
6532 		mutex_exit(&pm_dep_thread_lock);
6533 		pm_process_dep_request(work);
6534 
6535 	}
6536 	/*NOTREACHED*/
6537 }
6538 
6539 /*
6540  * Set the power level of the indicated device to unknown (if it is not a
6541  * backwards compatible device), as it has just been resumed, and it won't
6542  * know if the power was removed or not. Adjust parent's kidsupcnt if necessary.
6543  */
6544 void
6545 pm_forget_power_level(dev_info_t *dip)
6546 {
6547 	dev_info_t *pdip = ddi_get_parent(dip);
6548 	int i, count = 0;
6549 
6550 	if (!PM_ISBC(dip)) {
6551 		for (i = 0; i < PM_NUMCMPTS(dip); i++)
6552 			count += (PM_CURPOWER(dip, i) == 0);
6553 
6554 		if (count && pdip && !PM_WANTS_NOTIFICATION(pdip))
6555 			e_pm_hold_rele_power(pdip, count);
6556 
6557 		/*
6558 		 * Count this as a power cycle if we care
6559 		 */
6560 		if (DEVI(dip)->devi_pm_volpmd &&
6561 		    PM_CP(dip, 0)->pmc_cur_pwr == 0)
6562 			DEVI(dip)->devi_pm_volpmd = 0;
6563 		for (i = 0; i < PM_NUMCMPTS(dip); i++)
6564 			e_pm_set_cur_pwr(dip, PM_CP(dip, i), PM_LEVEL_UNKNOWN);
6565 	}
6566 }
6567 
6568 /*
6569  * This function advises the caller whether it should make a power-off
6570  * transition at this time or not.  If the transition is not advised
6571  * at this time, the time that the next power-off transition can
6572  * be made from now is returned through "intervalp" pointer.
6573  * This function returns:
6574  *
6575  *  1  power-off advised
6576  *  0  power-off not advised, intervalp will point to seconds from
6577  *	  now that a power-off is advised.  If it is passed the number
6578  *	  of years that policy specifies the device should last,
6579  *	  a large number is returned as the time interval.
6580  *  -1  error
6581  */
6582 int
6583 pm_trans_check(struct pm_trans_data *datap, time_t *intervalp)
6584 {
6585 	PMD_FUNC(pmf, "pm_trans_check")
6586 	char dbuf[DC_SCSI_MFR_LEN];
6587 	struct pm_scsi_cycles *scp;
6588 	int service_years, service_weeks, full_years;
6589 	time_t now, service_seconds, tdiff;
6590 	time_t within_year, when_allowed;
6591 	char *ptr;
6592 	int lower_bound_cycles, upper_bound_cycles, cycles_allowed;
6593 	int cycles_diff, cycles_over;
6594 	struct pm_smart_count *smart_p;
6595 
6596 	if (datap == NULL) {
6597 		PMD(PMD_TCHECK, ("%s: NULL data pointer!\n", pmf))
6598 		return (-1);
6599 	}
6600 
6601 	if (datap->format == DC_SCSI_FORMAT) {
6602 		/*
6603 		 * Power cycles of the scsi drives are distributed
6604 		 * over 5 years with the following percentage ratio:
6605 		 *
6606 		 *	30%, 25%, 20%, 15%, and 10%
6607 		 *
6608 		 * The power cycle quota for each year is distributed
6609 		 * linearly through out the year.  The equation for
6610 		 * determining the expected cycles is:
6611 		 *
6612 		 *	e = a * (n / y)
6613 		 *
6614 		 * e = expected cycles
6615 		 * a = allocated cycles for this year
6616 		 * n = number of seconds since beginning of this year
6617 		 * y = number of seconds in a year
6618 		 *
6619 		 * Note that beginning of the year starts the day that
6620 		 * the drive has been put on service.
6621 		 *
6622 		 * If the drive has passed its expected cycles, we
6623 		 * can determine when it can start to power cycle
6624 		 * again to keep it on track to meet the 5-year
6625 		 * life expectancy.  The equation for determining
6626 		 * when to power cycle is:
6627 		 *
6628 		 *	w = y * (c / a)
6629 		 *
6630 		 * w = when it can power cycle again
6631 		 * y = number of seconds in a year
6632 		 * c = current number of cycles
6633 		 * a = allocated cycles for the year
6634 		 *
6635 		 */
6636 		char pcnt[DC_SCSI_NPY] = { 30, 55, 75, 90, 100 };
6637 
6638 		scp = &datap->un.scsi_cycles;
6639 		PMD(PMD_TCHECK, ("%s: format=%d, lifemax=%d, ncycles=%d, "
6640 		    "svc_date=%s, svc_flag=%d\n", pmf, datap->format,
6641 		    scp->lifemax, scp->ncycles, scp->svc_date, scp->flag))
6642 		if (scp->ncycles < 0 || scp->flag != 0) {
6643 			PMD(PMD_TCHECK, ("%s: ncycles < 0 || flag != 0\n", pmf))
6644 			return (-1);
6645 		}
6646 
6647 		if (scp->ncycles > scp->lifemax) {
6648 			*intervalp = (LONG_MAX / hz);
6649 			return (0);
6650 		}
6651 
6652 		/*
6653 		 * convert service date to time_t
6654 		 */
6655 		bcopy(scp->svc_date, dbuf, DC_SCSI_YEAR_LEN);
6656 		dbuf[DC_SCSI_YEAR_LEN] = '\0';
6657 		ptr = dbuf;
6658 		service_years = stoi(&ptr) - EPOCH_YEAR;
6659 		bcopy(&scp->svc_date[DC_SCSI_YEAR_LEN], dbuf,
6660 		    DC_SCSI_WEEK_LEN);
6661 		dbuf[DC_SCSI_WEEK_LEN] = '\0';
6662 
6663 		/*
6664 		 * scsi standard does not specify WW data,
6665 		 * could be (00-51) or (01-52)
6666 		 */
6667 		ptr = dbuf;
6668 		service_weeks = stoi(&ptr);
6669 		if (service_years < 0 ||
6670 		    service_weeks < 0 || service_weeks > 52) {
6671 			PMD(PMD_TCHECK, ("%s: service year %d and week %d\n",
6672 			    pmf, service_years, service_weeks))
6673 			return (-1);
6674 		}
6675 
6676 		/*
6677 		 * calculate service date in seconds-since-epoch,
6678 		 * adding one day for each leap-year.
6679 		 *
6680 		 * (years-since-epoch + 2) fixes integer truncation,
6681 		 * example: (8) leap-years during [1972, 2000]
6682 		 * (2000 - 1970) = 30;  and  (30 + 2) / 4 = 8;
6683 		 */
6684 		service_seconds = (service_years * DC_SPY) +
6685 		    (service_weeks * DC_SPW) +
6686 		    (((service_years + 2) / 4) * DC_SPD);
6687 
6688 		now = gethrestime_sec();
6689 		/*
6690 		 * since the granularity of 'svc_date' is day not second,
6691 		 * 'now' should be rounded up to full day.
6692 		 */
6693 		now = ((now + DC_SPD -1) / DC_SPD) * DC_SPD;
6694 		if (service_seconds > now) {
6695 			PMD(PMD_TCHECK, ("%s: service date (%ld) later "
6696 			    "than now (%ld)!\n", pmf, service_seconds, now))
6697 			return (-1);
6698 		}
6699 
6700 		tdiff = now - service_seconds;
6701 		PMD(PMD_TCHECK, ("%s: age is %ld sec\n", pmf, tdiff))
6702 
6703 		/*
6704 		 * NOTE - Leap years are not considered in the calculations
6705 		 * below.
6706 		 */
6707 		full_years = (tdiff / DC_SPY);
6708 		if ((full_years >= DC_SCSI_NPY) &&
6709 		    (scp->ncycles <= scp->lifemax))
6710 			return (1);
6711 
6712 		/*
6713 		 * Determine what is the normal cycle usage for the
6714 		 * device at the beginning and the end of this year.
6715 		 */
6716 		lower_bound_cycles = (!full_years) ? 0 :
6717 		    ((scp->lifemax * pcnt[full_years - 1]) / 100);
6718 		upper_bound_cycles = (scp->lifemax * pcnt[full_years]) / 100;
6719 
6720 		if (scp->ncycles <= lower_bound_cycles)
6721 			return (1);
6722 
6723 		/*
6724 		 * The linear slope that determines how many cycles
6725 		 * are allowed this year is number of seconds
6726 		 * passed this year over total number of seconds in a year.
6727 		 */
6728 		cycles_diff = (upper_bound_cycles - lower_bound_cycles);
6729 		within_year = (tdiff % DC_SPY);
6730 		cycles_allowed = lower_bound_cycles +
6731 		    (((uint64_t)cycles_diff * (uint64_t)within_year) / DC_SPY);
6732 		PMD(PMD_TCHECK, ("%s: lived %d yrs and %ld secs\n", pmf,
6733 		    full_years, within_year))
6734 		PMD(PMD_TCHECK, ("%s: # of cycles allowed %d\n", pmf,
6735 		    cycles_allowed))
6736 
6737 		if (scp->ncycles <= cycles_allowed)
6738 			return (1);
6739 
6740 		/*
6741 		 * The transition is not advised now but we can
6742 		 * determine when the next transition can be made.
6743 		 *
6744 		 * Depending on how many cycles the device has been
6745 		 * over-used, we may need to skip years with
6746 		 * different percentage quota in order to determine
6747 		 * when the next transition can be made.
6748 		 */
6749 		cycles_over = (scp->ncycles - lower_bound_cycles);
6750 		while (cycles_over > cycles_diff) {
6751 			full_years++;
6752 			if (full_years >= DC_SCSI_NPY) {
6753 				*intervalp = (LONG_MAX / hz);
6754 				return (0);
6755 			}
6756 			cycles_over -= cycles_diff;
6757 			lower_bound_cycles = upper_bound_cycles;
6758 			upper_bound_cycles =
6759 			    (scp->lifemax * pcnt[full_years]) / 100;
6760 			cycles_diff = (upper_bound_cycles - lower_bound_cycles);
6761 		}
6762 
6763 		/*
6764 		 * The linear slope that determines when the next transition
6765 		 * can be made is the relative position of used cycles within a
6766 		 * year over total number of cycles within that year.
6767 		 */
6768 		when_allowed = service_seconds + (full_years * DC_SPY) +
6769 		    (((uint64_t)DC_SPY * (uint64_t)cycles_over) / cycles_diff);
6770 		*intervalp = (when_allowed - now);
6771 		if (*intervalp > (LONG_MAX / hz))
6772 			*intervalp = (LONG_MAX / hz);
6773 		PMD(PMD_TCHECK, ("%s: no cycle is allowed in %ld secs\n", pmf,
6774 		    *intervalp))
6775 		return (0);
6776 	} else if (datap->format == DC_SMART_FORMAT) {
6777 		/*
6778 		 * power cycles of SATA disks are reported from SMART
6779 		 * attributes.
6780 		 */
6781 		smart_p = &datap->un.smart_count;
6782 		if (smart_p->consumed >= smart_p->allowed) {
6783 			*intervalp = (LONG_MAX / hz);
6784 			PMD(PMD_TCHECK, ("%s: exceeded lifemax cycles.\n", pmf))
6785 			return (0);
6786 		} else
6787 			return (1);
6788 	}
6789 
6790 	PMD(PMD_TCHECK, ("%s: unknown format!\n", pmf))
6791 	return (-1);
6792 }
6793 
6794 /*
6795  * Nexus drivers call into pm framework to indicate which child driver is about
6796  * to be installed.  In some platforms, ppm may need to configure the hardware
6797  * for successful installation of a driver.
6798  */
6799 int
6800 pm_init_child(dev_info_t *dip)
6801 {
6802 	power_req_t power_req;
6803 
6804 	ASSERT(ddi_binding_name(dip));
6805 	ASSERT(ddi_get_name_addr(dip));
6806 	pm_ppm_claim(dip);
6807 	if (pm_ppm_claimed(dip)) {	/* if ppm driver claims the node */
6808 		power_req.request_type = PMR_PPM_INIT_CHILD;
6809 		power_req.req.ppm_config_req.who = dip;
6810 		ASSERT(PPM(dip) != NULL);
6811 		return (pm_ctlops(PPM(dip), dip, DDI_CTLOPS_POWER, &power_req,
6812 		    NULL));
6813 	} else {
6814 #ifdef DEBUG
6815 		/* pass it to the default handler so we can debug things */
6816 		power_req.request_type = PMR_PPM_INIT_CHILD;
6817 		power_req.req.ppm_config_req.who = dip;
6818 		(void) pm_ctlops(NULL, dip,
6819 		    DDI_CTLOPS_POWER, &power_req, NULL);
6820 #endif
6821 	}
6822 	return (DDI_SUCCESS);
6823 }
6824 
6825 /*
6826  * Bring parent of a node that is about to be probed up to full power, and
6827  * arrange for it to stay up until pm_post_probe() or pm_post_attach() decide
6828  * it is time to let it go down again
6829  */
6830 void
6831 pm_pre_probe(dev_info_t *dip, pm_ppm_cookie_t *cp)
6832 {
6833 	int result;
6834 	power_req_t power_req;
6835 
6836 	bzero(cp, sizeof (*cp));
6837 	cp->ppc_dip = dip;
6838 
6839 	pm_ppm_claim(dip);
6840 	if (pm_ppm_claimed(dip)) {	/* if ppm driver claims the node */
6841 		power_req.request_type = PMR_PPM_PRE_PROBE;
6842 		power_req.req.ppm_config_req.who = dip;
6843 		ASSERT(PPM(dip) != NULL);
6844 		(void) pm_ctlops(PPM(dip), dip,
6845 		    DDI_CTLOPS_POWER, &power_req, &result);
6846 		cp->ppc_ppm = PPM(dip);
6847 	} else {
6848 #ifdef DEBUG
6849 		/* pass it to the default handler so we can debug things */
6850 		power_req.request_type = PMR_PPM_PRE_PROBE;
6851 		power_req.req.ppm_config_req.who = dip;
6852 		(void) pm_ctlops(NULL, dip,
6853 		    DDI_CTLOPS_POWER, &power_req, &result);
6854 #endif
6855 		cp->ppc_ppm = NULL;
6856 	}
6857 }
6858 
6859 int
6860 pm_pre_config(dev_info_t *dip, char *devnm)
6861 {
6862 	PMD_FUNC(pmf, "pre_config")
6863 	int ret;
6864 
6865 	if (MDI_VHCI(dip)) {
6866 		PMD(PMD_SET, ("%s: %s@%s(%s#%d)\n", pmf, PM_DEVICE(dip)))
6867 		ret = mdi_power(dip, MDI_PM_PRE_CONFIG, NULL, devnm, 0);
6868 		return (ret == MDI_SUCCESS ? DDI_SUCCESS : DDI_FAILURE);
6869 	} else if (!PM_GET_PM_INFO(dip))
6870 		return (DDI_SUCCESS);
6871 
6872 	PMD(PMD_SET, ("%s: %s@%s(%s#%d)\n", pmf, PM_DEVICE(dip)))
6873 	pm_hold_power(dip);
6874 	ret = pm_all_to_normal(dip, PM_CANBLOCK_BLOCK);
6875 	if (ret != DDI_SUCCESS)
6876 		pm_rele_power(dip);
6877 	return (ret);
6878 }
6879 
6880 /*
6881  * This routine is called by devfs during its walk to unconfigue a node.
6882  * If the call is due to auto mod_unloads and the dip is not at its
6883  * full power, we return DDI_FAILURE to terminate the walk, otherwise
6884  * return DDI_SUCCESS.
6885  */
6886 int
6887 pm_pre_unconfig(dev_info_t *dip, int flags, int *held, char *devnm)
6888 {
6889 	PMD_FUNC(pmf, "pre_unconfig")
6890 	int ret;
6891 
6892 	if (MDI_VHCI(dip)) {
6893 		PMD(PMD_SET, ("%s: %s@%s(%s#%d), flags=%x\n", pmf,
6894 		    PM_DEVICE(dip), flags))
6895 		ret = mdi_power(dip, MDI_PM_PRE_UNCONFIG, held, devnm, flags);
6896 		return (ret == MDI_SUCCESS ? DDI_SUCCESS : DDI_FAILURE);
6897 	} else if (!PM_GET_PM_INFO(dip))
6898 		return (DDI_SUCCESS);
6899 
6900 	PMD(PMD_SET, ("%s: %s@%s(%s#%d), flags=%x\n", pmf, PM_DEVICE(dip),
6901 	    flags))
6902 	*held = 0;
6903 
6904 	/*
6905 	 * If the dip is a leaf node, don't power it up.
6906 	 */
6907 	if (!ddi_get_child(dip))
6908 		return (DDI_SUCCESS);
6909 
6910 	/*
6911 	 * Do not power up the node if it is called due to auto-modunload.
6912 	 */
6913 	if ((flags & NDI_AUTODETACH) && !pm_all_at_normal(dip))
6914 		return (DDI_FAILURE);
6915 
6916 	pm_hold_power(dip);
6917 	*held = 1;
6918 	ret = pm_all_to_normal(dip, PM_CANBLOCK_BLOCK);
6919 	if (ret != DDI_SUCCESS) {
6920 		pm_rele_power(dip);
6921 		*held = 0;
6922 	}
6923 	return (ret);
6924 }
6925 
6926 /*
6927  * Notify ppm of attach action.  Parent is already held at full power by
6928  * probe action.
6929  */
6930 void
6931 pm_pre_attach(dev_info_t *dip, pm_ppm_cookie_t *cp, ddi_attach_cmd_t cmd)
6932 {
6933 	static char *me = "pm_pre_attach";
6934 	power_req_t power_req;
6935 	int result;
6936 
6937 	/*
6938 	 * Initialize and fill in the PPM cookie
6939 	 */
6940 	bzero(cp, sizeof (*cp));
6941 	cp->ppc_cmd = (int)cmd;
6942 	cp->ppc_ppm = PPM(dip);
6943 	cp->ppc_dip = dip;
6944 
6945 	/*
6946 	 * DDI_ATTACH and DDI_RESUME cmds need to call platform specific
6947 	 * Power Management stuff. DDI_RESUME also has to purge it's
6948 	 * powerlevel information.
6949 	 */
6950 	switch (cmd) {
6951 	case DDI_ATTACH:
6952 		if (cp->ppc_ppm) {	/* if ppm driver claims the node */
6953 			power_req.request_type = PMR_PPM_PRE_ATTACH;
6954 			power_req.req.ppm_config_req.who = dip;
6955 			ASSERT(PPM(dip));
6956 			(void) pm_ctlops(cp->ppc_ppm, dip, DDI_CTLOPS_POWER,
6957 			    &power_req, &result);
6958 		}
6959 #ifdef DEBUG
6960 		else {
6961 			power_req.request_type = PMR_PPM_PRE_ATTACH;
6962 			power_req.req.ppm_config_req.who = dip;
6963 			(void) pm_ctlops(NULL, dip,
6964 			    DDI_CTLOPS_POWER, &power_req, &result);
6965 		}
6966 #endif
6967 		break;
6968 	case DDI_RESUME:
6969 		pm_forget_power_level(dip);
6970 
6971 		if (cp->ppc_ppm) {	/* if ppm driver claims the node */
6972 			power_req.request_type = PMR_PPM_PRE_RESUME;
6973 			power_req.req.resume_req.who = cp->ppc_dip;
6974 			power_req.req.resume_req.cmd =
6975 			    (ddi_attach_cmd_t)cp->ppc_cmd;
6976 			ASSERT(PPM(cp->ppc_dip) == cp->ppc_ppm);
6977 			(void) pm_ctlops(cp->ppc_ppm, cp->ppc_dip,
6978 			    DDI_CTLOPS_POWER, &power_req, &result);
6979 		}
6980 #ifdef DEBUG
6981 		else {
6982 			power_req.request_type = PMR_PPM_PRE_RESUME;
6983 			power_req.req.resume_req.who = cp->ppc_dip;
6984 			power_req.req.resume_req.cmd =
6985 			    (ddi_attach_cmd_t)cp->ppc_cmd;
6986 			(void) pm_ctlops(NULL, cp->ppc_dip,
6987 			    DDI_CTLOPS_POWER, &power_req, &result);
6988 		}
6989 #endif
6990 		break;
6991 
6992 	case DDI_PM_RESUME:
6993 		break;
6994 
6995 	default:
6996 		panic(me);
6997 	}
6998 }
6999 
7000 /*
7001  * Nexus drivers call into pm framework to indicate which child driver is
7002  * being uninstalled.  In some platforms, ppm may need to reconfigure the
7003  * hardware since the device driver is no longer installed.
7004  */
7005 int
7006 pm_uninit_child(dev_info_t *dip)
7007 {
7008 	power_req_t power_req;
7009 
7010 	ASSERT(ddi_binding_name(dip));
7011 	ASSERT(ddi_get_name_addr(dip));
7012 	pm_ppm_claim(dip);
7013 	if (pm_ppm_claimed(dip)) {	/* if ppm driver claims the node */
7014 		power_req.request_type = PMR_PPM_UNINIT_CHILD;
7015 		power_req.req.ppm_config_req.who = dip;
7016 		ASSERT(PPM(dip));
7017 		return (pm_ctlops(PPM(dip), dip, DDI_CTLOPS_POWER, &power_req,
7018 		    NULL));
7019 	} else {
7020 #ifdef DEBUG
7021 		/* pass it to the default handler so we can debug things */
7022 		power_req.request_type = PMR_PPM_UNINIT_CHILD;
7023 		power_req.req.ppm_config_req.who = dip;
7024 		(void) pm_ctlops(NULL, dip, DDI_CTLOPS_POWER, &power_req, NULL);
7025 #endif
7026 	}
7027 	return (DDI_SUCCESS);
7028 }
7029 /*
7030  * Decrement kidsupcnt so scan can turn the parent back off if it is idle
7031  * Also notify ppm of result of probe if there is a ppm that cares
7032  */
7033 void
7034 pm_post_probe(pm_ppm_cookie_t *cp, int ret, int probe_failed)
7035 {
7036 	_NOTE(ARGUNUSED(probe_failed))
7037 	int result;
7038 	power_req_t power_req;
7039 
7040 	if (cp->ppc_ppm) {	/* if ppm driver claims the node */
7041 		power_req.request_type = PMR_PPM_POST_PROBE;
7042 		power_req.req.ppm_config_req.who = cp->ppc_dip;
7043 		power_req.req.ppm_config_req.result = ret;
7044 		ASSERT(PPM(cp->ppc_dip) == cp->ppc_ppm);
7045 		(void) pm_ctlops(cp->ppc_ppm, cp->ppc_dip, DDI_CTLOPS_POWER,
7046 		    &power_req, &result);
7047 	}
7048 #ifdef DEBUG
7049 	else {
7050 		power_req.request_type = PMR_PPM_POST_PROBE;
7051 		power_req.req.ppm_config_req.who = cp->ppc_dip;
7052 		power_req.req.ppm_config_req.result = ret;
7053 		(void) pm_ctlops(NULL, cp->ppc_dip, DDI_CTLOPS_POWER,
7054 		    &power_req, &result);
7055 	}
7056 #endif
7057 }
7058 
7059 void
7060 pm_post_config(dev_info_t *dip, char *devnm)
7061 {
7062 	PMD_FUNC(pmf, "post_config")
7063 
7064 	if (MDI_VHCI(dip)) {
7065 		PMD(PMD_SET, ("%s: %s@%s(%s#%d)\n", pmf, PM_DEVICE(dip)))
7066 		(void) mdi_power(dip, MDI_PM_POST_CONFIG, NULL, devnm, 0);
7067 		return;
7068 	} else if (!PM_GET_PM_INFO(dip))
7069 		return;
7070 
7071 	PMD(PMD_SET, ("%s: %s@%s(%s#%d)\n", pmf, PM_DEVICE(dip)))
7072 	pm_rele_power(dip);
7073 }
7074 
7075 void
7076 pm_post_unconfig(dev_info_t *dip, int held, char *devnm)
7077 {
7078 	PMD_FUNC(pmf, "post_unconfig")
7079 
7080 	if (MDI_VHCI(dip)) {
7081 		PMD(PMD_SET, ("%s: %s@%s(%s#%d), held = %d\n", pmf,
7082 		    PM_DEVICE(dip), held))
7083 		(void) mdi_power(dip, MDI_PM_POST_UNCONFIG, &held, devnm, 0);
7084 		return;
7085 	} else if (!PM_GET_PM_INFO(dip))
7086 		return;
7087 
7088 	PMD(PMD_SET, ("%s: %s@%s(%s#%d), held = %d\n", pmf, PM_DEVICE(dip),
7089 	    held))
7090 	if (!held)
7091 		return;
7092 	/*
7093 	 * We have held power in pre_unconfig, release it here.
7094 	 */
7095 	pm_rele_power(dip);
7096 }
7097 
7098 /*
7099  * Notify ppm of result of attach if there is a ppm that cares
7100  */
7101 void
7102 pm_post_attach(pm_ppm_cookie_t *cp, int ret)
7103 {
7104 	int result;
7105 	power_req_t power_req;
7106 	dev_info_t	*dip;
7107 
7108 	if (cp->ppc_cmd != DDI_ATTACH)
7109 		return;
7110 
7111 	dip = cp->ppc_dip;
7112 
7113 	if (ret == DDI_SUCCESS) {
7114 		/*
7115 		 * Attach succeeded, so proceed to doing post-attach pm tasks
7116 		 */
7117 		if (PM_GET_PM_INFO(dip) == NULL)
7118 			(void) pm_start(dip);
7119 	} else {
7120 		/*
7121 		 * Attach may have got pm started before failing
7122 		 */
7123 		pm_stop(dip);
7124 	}
7125 
7126 	if (cp->ppc_ppm) {	/* if ppm driver claims the node */
7127 		power_req.request_type = PMR_PPM_POST_ATTACH;
7128 		power_req.req.ppm_config_req.who = cp->ppc_dip;
7129 		power_req.req.ppm_config_req.result = ret;
7130 		ASSERT(PPM(cp->ppc_dip) == cp->ppc_ppm);
7131 		(void) pm_ctlops(cp->ppc_ppm, cp->ppc_dip,
7132 		    DDI_CTLOPS_POWER, &power_req, &result);
7133 	}
7134 #ifdef DEBUG
7135 	else {
7136 		power_req.request_type = PMR_PPM_POST_ATTACH;
7137 		power_req.req.ppm_config_req.who = cp->ppc_dip;
7138 		power_req.req.ppm_config_req.result = ret;
7139 		(void) pm_ctlops(NULL, cp->ppc_dip,
7140 		    DDI_CTLOPS_POWER, &power_req, &result);
7141 	}
7142 #endif
7143 }
7144 
7145 /*
7146  * Notify ppm of attach action.  Parent is already held at full power by
7147  * probe action.
7148  */
7149 void
7150 pm_pre_detach(dev_info_t *dip, ddi_detach_cmd_t cmd, pm_ppm_cookie_t *cp)
7151 {
7152 	int result;
7153 	power_req_t power_req;
7154 
7155 	bzero(cp, sizeof (*cp));
7156 	cp->ppc_dip = dip;
7157 	cp->ppc_cmd = (int)cmd;
7158 
7159 	switch (cmd) {
7160 	case DDI_DETACH:
7161 		pm_detaching(dip);		/* suspend pm while detaching */
7162 		if (pm_ppm_claimed(dip)) {	/* if ppm driver claims node */
7163 			power_req.request_type = PMR_PPM_PRE_DETACH;
7164 			power_req.req.ppm_config_req.who = dip;
7165 			ASSERT(PPM(dip));
7166 			(void) pm_ctlops(PPM(dip), dip, DDI_CTLOPS_POWER,
7167 			    &power_req, &result);
7168 			cp->ppc_ppm = PPM(dip);
7169 		} else {
7170 #ifdef DEBUG
7171 			/* pass to the default handler so we can debug things */
7172 			power_req.request_type = PMR_PPM_PRE_DETACH;
7173 			power_req.req.ppm_config_req.who = dip;
7174 			(void) pm_ctlops(NULL, dip,
7175 			    DDI_CTLOPS_POWER, &power_req, &result);
7176 #endif
7177 			cp->ppc_ppm = NULL;
7178 		}
7179 		break;
7180 
7181 	default:
7182 		break;
7183 	}
7184 }
7185 
7186 /*
7187  * Dip is either a leaf node that exported "no-involuntary-power-cycles" prop.,
7188  * (if devi_pm_noinvol count is 0) or an ancestor of such a node.  We need to
7189  * make an entry to record the details, which includes certain flag settings.
7190  */
7191 static void
7192 pm_record_invol_path(char *path, int flags, int noinvolpm, int volpmd,
7193     int wasvolpmd, major_t major)
7194 {
7195 	PMD_FUNC(pmf, "record_invol_path")
7196 	major_t pm_path_to_major(char *);
7197 	size_t plen;
7198 	pm_noinvol_t *ip, *np, *pp;
7199 	pp = NULL;
7200 
7201 	plen = strlen(path) + 1;
7202 	np = kmem_zalloc(sizeof (*np), KM_SLEEP);
7203 	np->ni_size = plen;
7204 	np->ni_path = kmem_alloc(plen, KM_SLEEP);
7205 	np->ni_noinvolpm = noinvolpm;
7206 	np->ni_volpmd = volpmd;
7207 	np->ni_wasvolpmd = wasvolpmd;
7208 	np->ni_flags = flags;
7209 	(void) strcpy(np->ni_path, path);
7210 	/*
7211 	 * If we haven't actually seen the node attached, it is hard to figure
7212 	 * out its major.  If we could hold the node by path, we would be much
7213 	 * happier here.
7214 	 */
7215 	if (major == DDI_MAJOR_T_NONE) {
7216 		np->ni_major = pm_path_to_major(path);
7217 	} else {
7218 		np->ni_major = major;
7219 	}
7220 	rw_enter(&pm_noinvol_rwlock, RW_WRITER);
7221 	for (ip = pm_noinvol_head; ip; pp = ip, ip = ip->ni_next) {
7222 		int comp = strcmp(path, ip->ni_path);
7223 		if (comp < 0) {
7224 			PMD(PMD_NOINVOL, ("%s: %s insert before %s\n",
7225 			    pmf, path, ip->ni_path))
7226 			/* insert before current entry */
7227 			np->ni_next = ip;
7228 			if (pp) {
7229 				pp->ni_next = np;
7230 			} else {
7231 				pm_noinvol_head = np;
7232 			}
7233 			rw_exit(&pm_noinvol_rwlock);
7234 #ifdef DEBUG
7235 			if (pm_debug & PMD_NOINVOL)
7236 				pr_noinvol("record_invol_path exit0");
7237 #endif
7238 			return;
7239 		} else if (comp == 0) {
7240 			panic("%s already in pm_noinvol list", path);
7241 		}
7242 	}
7243 	/*
7244 	 * If we did not find an entry in the list that this should go before,
7245 	 * then it must go at the end
7246 	 */
7247 	if (pp) {
7248 		PMD(PMD_NOINVOL, ("%s: %s append after %s\n", pmf, path,
7249 		    pp->ni_path))
7250 		ASSERT(pp->ni_next == 0);
7251 		pp->ni_next = np;
7252 	} else {
7253 		PMD(PMD_NOINVOL, ("%s: %s added to end-of-list\n", pmf, path))
7254 		ASSERT(!pm_noinvol_head);
7255 		pm_noinvol_head = np;
7256 	}
7257 	rw_exit(&pm_noinvol_rwlock);
7258 #ifdef DEBUG
7259 	if (pm_debug & PMD_NOINVOL)
7260 		pr_noinvol("record_invol_path exit");
7261 #endif
7262 }
7263 
7264 void
7265 pm_record_invol(dev_info_t *dip)
7266 {
7267 	char *pathbuf;
7268 	int pm_all_components_off(dev_info_t *);
7269 	int volpmd = (PM_NUMCMPTS(dip) > 0) && pm_all_components_off(dip);
7270 
7271 	pathbuf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
7272 	(void) ddi_pathname(dip, pathbuf);
7273 
7274 	pm_record_invol_path(pathbuf, (DEVI(dip)->devi_pm_flags &
7275 	    (PMC_NO_INVOL | PMC_CONSOLE_FB)), DEVI(dip)->devi_pm_noinvolpm,
7276 	    DEVI(dip)->devi_pm_volpmd, volpmd, PM_MAJOR(dip));
7277 
7278 	/*
7279 	 * If this child's detach will be holding up its ancestors, then we
7280 	 * allow for an exception to that if all children of this type have
7281 	 * gone down voluntarily.
7282 	 * Now walk down the tree incrementing devi_pm_noinvolpm
7283 	 */
7284 	(void) pm_noinvol_update(PM_BP_NOINVOL_DETACH, 0, volpmd, pathbuf,
7285 	    dip);
7286 	kmem_free(pathbuf, MAXPATHLEN);
7287 }
7288 
7289 void
7290 pm_post_detach(pm_ppm_cookie_t *cp, int ret)
7291 {
7292 	dev_info_t *dip = cp->ppc_dip;
7293 	int result;
7294 	power_req_t power_req;
7295 
7296 	switch (cp->ppc_cmd) {
7297 	case DDI_DETACH:
7298 		if (cp->ppc_ppm) {	/* if ppm driver claims the node */
7299 			power_req.request_type = PMR_PPM_POST_DETACH;
7300 			power_req.req.ppm_config_req.who = cp->ppc_dip;
7301 			power_req.req.ppm_config_req.result = ret;
7302 			ASSERT(PPM(cp->ppc_dip) == cp->ppc_ppm);
7303 			(void) pm_ctlops(cp->ppc_ppm, cp->ppc_dip,
7304 			    DDI_CTLOPS_POWER, &power_req, &result);
7305 		}
7306 #ifdef DEBUG
7307 		else {
7308 			power_req.request_type = PMR_PPM_POST_DETACH;
7309 			power_req.req.ppm_config_req.who = cp->ppc_dip;
7310 			power_req.req.ppm_config_req.result = ret;
7311 			(void) pm_ctlops(NULL, cp->ppc_dip,
7312 			    DDI_CTLOPS_POWER, &power_req, &result);
7313 		}
7314 #endif
7315 		if (ret == DDI_SUCCESS) {
7316 			/*
7317 			 * For hotplug detach we assume it is *really* gone
7318 			 */
7319 			if (cp->ppc_cmd == DDI_DETACH &&
7320 			    ((DEVI(dip)->devi_pm_flags &
7321 			    (PMC_NO_INVOL | PMC_CONSOLE_FB)) ||
7322 			    DEVI(dip)->devi_pm_noinvolpm))
7323 				pm_record_invol(dip);
7324 			DEVI(dip)->devi_pm_flags &=
7325 			    ~(PMC_NO_INVOL | PMC_NOINVOL_DONE);
7326 
7327 			/*
7328 			 * If console fb is detaching, then we don't need to
7329 			 * worry any more about it going off (pm_detaching has
7330 			 * brought up all components)
7331 			 */
7332 			if (PM_IS_CFB(dip)) {
7333 				mutex_enter(&pm_cfb_lock);
7334 				ASSERT(cfb_dip_detaching);
7335 				ASSERT(cfb_dip == NULL);
7336 				ASSERT(pm_cfb_comps_off == 0);
7337 				cfb_dip_detaching = NULL;
7338 				mutex_exit(&pm_cfb_lock);
7339 			}
7340 			pm_stop(dip);	/* make it permanent */
7341 		} else {
7342 			if (PM_IS_CFB(dip)) {
7343 				mutex_enter(&pm_cfb_lock);
7344 				ASSERT(cfb_dip_detaching);
7345 				ASSERT(cfb_dip == NULL);
7346 				ASSERT(pm_cfb_comps_off == 0);
7347 				cfb_dip = cfb_dip_detaching;
7348 				cfb_dip_detaching = NULL;
7349 				mutex_exit(&pm_cfb_lock);
7350 			}
7351 			pm_detach_failed(dip);	/* resume power management */
7352 		}
7353 		break;
7354 	case DDI_PM_SUSPEND:
7355 		break;
7356 	case DDI_SUSPEND:
7357 		break;				/* legal, but nothing to do */
7358 	default:
7359 #ifdef DEBUG
7360 		panic("pm_post_detach: unrecognized cmd %d for detach",
7361 		    cp->ppc_cmd);
7362 		/*NOTREACHED*/
7363 #else
7364 		break;
7365 #endif
7366 	}
7367 }
7368 
7369 /*
7370  * Called after vfs_mountroot has got the clock started to fix up timestamps
7371  * that were set when root bush drivers attached.  hresttime was 0 then, so the
7372  * devices look busy but have a 0 busycnt
7373  */
7374 int
7375 pm_adjust_timestamps(dev_info_t *dip, void *arg)
7376 {
7377 	_NOTE(ARGUNUSED(arg))
7378 
7379 	pm_info_t *info = PM_GET_PM_INFO(dip);
7380 	struct pm_component *cp;
7381 	int i;
7382 
7383 	if (!info)
7384 		return (DDI_WALK_CONTINUE);
7385 	PM_LOCK_BUSY(dip);
7386 	for (i = 0; i < PM_NUMCMPTS(dip); i++) {
7387 		cp = PM_CP(dip, i);
7388 		if (cp->pmc_timestamp == 0 && cp->pmc_busycount == 0)
7389 			cp->pmc_timestamp = gethrestime_sec();
7390 	}
7391 	PM_UNLOCK_BUSY(dip);
7392 	return (DDI_WALK_CONTINUE);
7393 }
7394 
7395 /*
7396  * Called at attach time to see if the device being attached has a record in
7397  * the no involuntary power cycles list.  If so, we do some bookkeeping on the
7398  * parents and set a flag in the dip
7399  */
7400 void
7401 pm_noinvol_specd(dev_info_t *dip)
7402 {
7403 	PMD_FUNC(pmf, "noinvol_specd")
7404 	char *pathbuf;
7405 	pm_noinvol_t *ip, *pp = NULL;
7406 	int wasvolpmd;
7407 	int found = 0;
7408 
7409 	if (DEVI(dip)->devi_pm_flags & PMC_NOINVOL_DONE)
7410 		return;
7411 	DEVI(dip)->devi_pm_flags |=  PMC_NOINVOL_DONE;
7412 	pathbuf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
7413 	(void) ddi_pathname(dip, pathbuf);
7414 
7415 	PM_LOCK_DIP(dip);
7416 	DEVI(dip)->devi_pm_volpmd = 0;
7417 	DEVI(dip)->devi_pm_noinvolpm = 0;
7418 	rw_enter(&pm_noinvol_rwlock, RW_READER);
7419 	for (ip = pm_noinvol_head; ip; pp = ip, ip = ip->ni_next) {
7420 		PMD(PMD_NOINVOL, ("%s: comparing '%s' to '%s'\n",
7421 		    pmf, pathbuf, ip->ni_path))
7422 		if (strcmp(pathbuf, ip->ni_path) == 0) {
7423 			found++;
7424 			break;
7425 		}
7426 	}
7427 	rw_exit(&pm_noinvol_rwlock);
7428 	if (!found) {
7429 		PM_UNLOCK_DIP(dip);
7430 		kmem_free(pathbuf, MAXPATHLEN);
7431 		return;
7432 	}
7433 	rw_enter(&pm_noinvol_rwlock, RW_WRITER);
7434 	pp = NULL;
7435 	for (ip = pm_noinvol_head; ip; pp = ip, ip = ip->ni_next) {
7436 		PMD(PMD_NOINVOL, ("%s: comparing '%s' to '%s'\n",
7437 		    pmf, pathbuf, ip->ni_path))
7438 		if (strcmp(pathbuf, ip->ni_path) == 0) {
7439 			ip->ni_flags &= ~PMC_DRIVER_REMOVED;
7440 			DEVI(dip)->devi_pm_flags |= ip->ni_flags;
7441 			/*
7442 			 * Handle special case of console fb
7443 			 */
7444 			if (PM_IS_CFB(dip)) {
7445 				mutex_enter(&pm_cfb_lock);
7446 				cfb_dip = dip;
7447 				PMD(PMD_CFB, ("%s: %s@%s(%s#%d) setting "
7448 				    "cfb_dip\n", pmf, PM_DEVICE(dip)))
7449 				mutex_exit(&pm_cfb_lock);
7450 			}
7451 			DEVI(dip)->devi_pm_noinvolpm = ip->ni_noinvolpm;
7452 			ASSERT((DEVI(dip)->devi_pm_flags &
7453 			    (PMC_NO_INVOL | PMC_CONSOLE_FB)) ||
7454 			    DEVI(dip)->devi_pm_noinvolpm);
7455 			DEVI(dip)->devi_pm_volpmd = ip->ni_volpmd;
7456 			PMD(PMD_NOINVOL, ("%s: noinvol=%d, volpmd=%d, "
7457 			    "wasvolpmd=%d, flags=%x, path=%s\n", pmf,
7458 			    ip->ni_noinvolpm, ip->ni_volpmd,
7459 			    ip->ni_wasvolpmd, ip->ni_flags, ip->ni_path))
7460 			/*
7461 			 * free the entry in hopes the list will now be empty
7462 			 * and we won't have to search it any more until the
7463 			 * device detaches
7464 			 */
7465 			if (pp) {
7466 				PMD(PMD_NOINVOL, ("%s: free %s, prev %s\n",
7467 				    pmf, ip->ni_path, pp->ni_path))
7468 				pp->ni_next = ip->ni_next;
7469 			} else {
7470 				PMD(PMD_NOINVOL, ("%s: free %s head\n",
7471 				    pmf, ip->ni_path))
7472 				ASSERT(pm_noinvol_head == ip);
7473 				pm_noinvol_head = ip->ni_next;
7474 			}
7475 			PM_UNLOCK_DIP(dip);
7476 			wasvolpmd = ip->ni_wasvolpmd;
7477 			rw_exit(&pm_noinvol_rwlock);
7478 			kmem_free(ip->ni_path, ip->ni_size);
7479 			kmem_free(ip, sizeof (*ip));
7480 			/*
7481 			 * Now walk up the tree decrementing devi_pm_noinvolpm
7482 			 * (and volpmd if appropriate)
7483 			 */
7484 			(void) pm_noinvol_update(PM_BP_NOINVOL_ATTACH, 0,
7485 			    wasvolpmd, pathbuf, dip);
7486 #ifdef DEBUG
7487 			if (pm_debug & PMD_NOINVOL)
7488 				pr_noinvol("noinvol_specd exit");
7489 #endif
7490 			kmem_free(pathbuf, MAXPATHLEN);
7491 			return;
7492 		}
7493 	}
7494 	kmem_free(pathbuf, MAXPATHLEN);
7495 	rw_exit(&pm_noinvol_rwlock);
7496 	PM_UNLOCK_DIP(dip);
7497 }
7498 
7499 int
7500 pm_all_components_off(dev_info_t *dip)
7501 {
7502 	int i;
7503 	pm_component_t *cp;
7504 
7505 	for (i = 0; i < PM_NUMCMPTS(dip); i++) {
7506 		cp = PM_CP(dip, i);
7507 		if (cp->pmc_cur_pwr == PM_LEVEL_UNKNOWN ||
7508 		    cp->pmc_comp.pmc_lvals[cp->pmc_cur_pwr])
7509 			return (0);
7510 	}
7511 	return (1);	/* all off */
7512 }
7513 
7514 /*
7515  * Make sure that all "no involuntary power cycles" devices are attached.
7516  * Called before doing a cpr suspend to make sure the driver has a say about
7517  * the power cycle
7518  */
7519 int
7520 pm_reattach_noinvol(void)
7521 {
7522 	PMD_FUNC(pmf, "reattach_noinvol")
7523 	pm_noinvol_t *ip;
7524 	char *path;
7525 	dev_info_t *dip;
7526 
7527 	/*
7528 	 * Prevent the modunload thread from unloading any modules until we
7529 	 * have completely stopped all kernel threads.
7530 	 */
7531 	modunload_disable();
7532 	for (ip = pm_noinvol_head; ip; ip = ip->ni_next) {
7533 		/*
7534 		 * Forget we'v ever seen any entry
7535 		 */
7536 		ip->ni_persistent = 0;
7537 	}
7538 restart:
7539 	rw_enter(&pm_noinvol_rwlock, RW_READER);
7540 	for (ip = pm_noinvol_head; ip; ip = ip->ni_next) {
7541 #ifdef PMDDEBUG
7542 		major_t maj;
7543 		maj = ip->ni_major;
7544 #endif
7545 		path = ip->ni_path;
7546 		if (path != NULL && !(ip->ni_flags & PMC_DRIVER_REMOVED)) {
7547 			if (ip->ni_persistent) {
7548 				/*
7549 				 * If we weren't able to make this entry
7550 				 * go away, then we give up, as
7551 				 * holding/attaching the driver ought to have
7552 				 * resulted in this entry being deleted
7553 				 */
7554 				PMD(PMD_NOINVOL, ("%s: can't reattach %s "
7555 				    "(%s|%d)\n", pmf, ip->ni_path,
7556 				    ddi_major_to_name(maj), (int)maj))
7557 				cmn_err(CE_WARN, "cpr: unable to reattach %s ",
7558 				    ip->ni_path);
7559 				modunload_enable();
7560 				rw_exit(&pm_noinvol_rwlock);
7561 				return (0);
7562 			}
7563 			ip->ni_persistent++;
7564 			rw_exit(&pm_noinvol_rwlock);
7565 			PMD(PMD_NOINVOL, ("%s: holding %s\n", pmf, path))
7566 			dip = e_ddi_hold_devi_by_path(path, 0);
7567 			if (dip == NULL) {
7568 				PMD(PMD_NOINVOL, ("%s: can't hold (%s|%d)\n",
7569 				    pmf, path, (int)maj))
7570 				cmn_err(CE_WARN, "cpr: unable to hold %s "
7571 				    "driver", path);
7572 				modunload_enable();
7573 				return (0);
7574 			} else {
7575 				PMD(PMD_DHR, ("%s: release %s\n", pmf, path))
7576 				/*
7577 				 * Since the modunload thread is stopped, we
7578 				 * don't have to keep the driver held, which
7579 				 * saves a ton of bookkeeping
7580 				 */
7581 				ddi_release_devi(dip);
7582 				goto restart;
7583 			}
7584 		} else {
7585 			PMD(PMD_NOINVOL, ("%s: skip %s; unknown major\n",
7586 			    pmf, ip->ni_path))
7587 			continue;
7588 		}
7589 	}
7590 	rw_exit(&pm_noinvol_rwlock);
7591 	return (1);
7592 }
7593 
7594 void
7595 pm_reattach_noinvol_fini(void)
7596 {
7597 	modunload_enable();
7598 }
7599 
7600 /*
7601  * Display pm support code
7602  */
7603 
7604 
7605 /*
7606  * console frame-buffer power-mgmt gets enabled when debugging
7607  * services are not present or console fbpm override is set
7608  */
7609 void
7610 pm_cfb_setup(const char *stdout_path)
7611 {
7612 	PMD_FUNC(pmf, "cfb_setup")
7613 	extern int obpdebug;
7614 	char *devname;
7615 	dev_info_t *dip;
7616 	int devname_len;
7617 	extern dev_info_t *fbdip;
7618 
7619 	/*
7620 	 * By virtue of this function being called (from consconfig),
7621 	 * we know stdout is a framebuffer.
7622 	 */
7623 	stdout_is_framebuffer = 1;
7624 
7625 	if (obpdebug || (boothowto & RB_DEBUG)) {
7626 		if (pm_cfb_override == 0) {
7627 			/*
7628 			 * Console is frame buffer, but we want to suppress
7629 			 * pm on it because of debugging setup
7630 			 */
7631 			pm_cfb_enabled = 0;
7632 			cmn_err(CE_NOTE, "Kernel debugger present: disabling "
7633 			    "console power management.");
7634 			/*
7635 			 * however, we still need to know which is the console
7636 			 * fb in order to suppress pm on it
7637 			 */
7638 		} else {
7639 			cmn_err(CE_WARN, "Kernel debugger present: see "
7640 			    "kmdb(1M) for interaction with power management.");
7641 		}
7642 	}
7643 #ifdef DEBUG
7644 	/*
7645 	 * IF console is fb and is power managed, don't do prom_printfs from
7646 	 * pm debug macro
7647 	 */
7648 	if (pm_cfb_enabled && !pm_debug_to_console) {
7649 		if (pm_debug)
7650 			prom_printf("pm debug output will be to log only\n");
7651 		pm_divertdebug++;
7652 	}
7653 #endif
7654 	devname = i_ddi_strdup((char *)stdout_path, KM_SLEEP);
7655 	devname_len = strlen(devname) + 1;
7656 	PMD(PMD_CFB, ("%s: stripped %s\n", pmf, devname))
7657 	/* if the driver is attached */
7658 	if ((dip = fbdip) != NULL) {
7659 		PMD(PMD_CFB, ("%s: attached: %s@%s(%s#%d)\n", pmf,
7660 		    PM_DEVICE(dip)))
7661 		/*
7662 		 * We set up here as if the driver were power manageable in case
7663 		 * we get a later attach of a pm'able driver (which would result
7664 		 * in a panic later)
7665 		 */
7666 		cfb_dip = dip;
7667 		DEVI(dip)->devi_pm_flags |= (PMC_CONSOLE_FB | PMC_NO_INVOL);
7668 		PMD(PMD_CFB, ("%s: cfb_dip -> %s@%s(%s#%d)\n", pmf,
7669 		    PM_DEVICE(dip)))
7670 #ifdef DEBUG
7671 		if (!(PM_GET_PM_INFO(dip) != NULL && PM_NUMCMPTS(dip))) {
7672 			PMD(PMD_CFB, ("%s: %s@%s(%s#%d) not power-managed\n",
7673 			    pmf, PM_DEVICE(dip)))
7674 		}
7675 #endif
7676 	} else {
7677 		char *ep;
7678 		PMD(PMD_CFB, ("%s: pntd %s failed\n", pmf, devname))
7679 		pm_record_invol_path(devname,
7680 		    (PMC_CONSOLE_FB | PMC_NO_INVOL), 1, 0, 0,
7681 		    DDI_MAJOR_T_NONE);
7682 		for (ep = strrchr(devname, '/'); ep != devname;
7683 		    ep = strrchr(devname, '/')) {
7684 			PMD(PMD_CFB, ("%s: devname %s\n", pmf, devname))
7685 			*ep = '\0';
7686 			dip = pm_name_to_dip(devname, 0);
7687 			if (dip != NULL) {
7688 				/*
7689 				 * Walk up the tree incrementing
7690 				 * devi_pm_noinvolpm
7691 				 */
7692 				(void) pm_noinvol_update(PM_BP_NOINVOL_CFB,
7693 				    0, 0, devname, dip);
7694 				break;
7695 			} else {
7696 				pm_record_invol_path(devname,
7697 				    PMC_NO_INVOL, 1, 0, 0, DDI_MAJOR_T_NONE);
7698 			}
7699 		}
7700 	}
7701 	kmem_free(devname, devname_len);
7702 }
7703 
7704 void
7705 pm_cfb_rele(void)
7706 {
7707 	mutex_enter(&pm_cfb_lock);
7708 	/*
7709 	 * this call isn't using the console any  more, it is ok to take it
7710 	 * down if the count goes to 0
7711 	 */
7712 	cfb_inuse--;
7713 	mutex_exit(&pm_cfb_lock);
7714 }
7715 
7716 /*
7717  * software interrupt handler for fbpm; this function exists because we can't
7718  * bring up the frame buffer power from above lock level.  So if we need to,
7719  * we instead schedule a softint that runs this routine and takes us into
7720  * debug_enter (a bit delayed from the original request, but avoiding a panic).
7721  */
7722 static uint_t
7723 pm_cfb_softint(caddr_t int_handler_arg)
7724 {
7725 	_NOTE(ARGUNUSED(int_handler_arg))
7726 	int rval = DDI_INTR_UNCLAIMED;
7727 
7728 	mutex_enter(&pm_cfb_lock);
7729 	if (pm_soft_pending) {
7730 		mutex_exit(&pm_cfb_lock);
7731 		debug_enter((char *)NULL);
7732 		/* acquired in debug_enter before calling pm_cfb_trigger */
7733 		pm_cfb_rele();
7734 		mutex_enter(&pm_cfb_lock);
7735 		pm_soft_pending = 0;
7736 		mutex_exit(&pm_cfb_lock);
7737 		rval = DDI_INTR_CLAIMED;
7738 	} else
7739 		mutex_exit(&pm_cfb_lock);
7740 
7741 	return (rval);
7742 }
7743 
7744 void
7745 pm_cfb_setup_intr(void)
7746 {
7747 	PMD_FUNC(pmf, "cfb_setup_intr")
7748 	extern void prom_set_outfuncs(void (*)(void), void (*)(void));
7749 	void pm_cfb_check_and_powerup(void);
7750 
7751 	mutex_init(&pm_cfb_lock, NULL, MUTEX_SPIN, (void *)ipltospl(SPL8));
7752 #ifdef PMDDEBUG
7753 	mutex_init(&pm_debug_lock, NULL, MUTEX_SPIN, (void *)ipltospl(SPL8));
7754 #endif
7755 
7756 	if (!stdout_is_framebuffer) {
7757 		PMD(PMD_CFB, ("%s: console not fb\n", pmf))
7758 		return;
7759 	}
7760 
7761 	/*
7762 	 * setup software interrupt handler
7763 	 */
7764 	if (ddi_add_softintr(ddi_root_node(), DDI_SOFTINT_HIGH, &pm_soft_id,
7765 	    NULL, NULL, pm_cfb_softint, NULL) != DDI_SUCCESS)
7766 		panic("pm: unable to register soft intr.");
7767 
7768 	prom_set_outfuncs(pm_cfb_check_and_powerup, pm_cfb_rele);
7769 }
7770 
7771 /*
7772  * Checks to see if it is safe to write to the console wrt power management
7773  * (i.e. if the console is a framebuffer, then it must be at full power)
7774  * returns 1 when power is off (power-up is needed)
7775  * returns 0 when power is on (power-up not needed)
7776  */
7777 int
7778 pm_cfb_check_and_hold(void)
7779 {
7780 	/*
7781 	 * cfb_dip is set iff console is a power manageable frame buffer
7782 	 * device
7783 	 */
7784 	extern int modrootloaded;
7785 
7786 	mutex_enter(&pm_cfb_lock);
7787 	cfb_inuse++;
7788 	ASSERT(cfb_inuse);	/* wrap? */
7789 	if (modrootloaded && cfb_dip) {
7790 		/*
7791 		 * don't power down the frame buffer, the prom is using it
7792 		 */
7793 		if (pm_cfb_comps_off) {
7794 			mutex_exit(&pm_cfb_lock);
7795 			return (1);
7796 		}
7797 	}
7798 	mutex_exit(&pm_cfb_lock);
7799 	return (0);
7800 }
7801 
7802 /*
7803  * turn on cfb power (which is known to be off).
7804  * Must be called below lock level!
7805  */
7806 void
7807 pm_cfb_powerup(void)
7808 {
7809 	pm_info_t *info;
7810 	int norm;
7811 	int ccount, ci;
7812 	int unused;
7813 #ifdef DEBUG
7814 	/*
7815 	 * Can't reenter prom_prekern, so suppress pm debug messages
7816 	 * (still go to circular buffer).
7817 	 */
7818 	mutex_enter(&pm_debug_lock);
7819 	pm_divertdebug++;
7820 	mutex_exit(&pm_debug_lock);
7821 #endif
7822 	info = PM_GET_PM_INFO(cfb_dip);
7823 	ASSERT(info);
7824 
7825 	ccount = PM_NUMCMPTS(cfb_dip);
7826 	for (ci = 0; ci < ccount; ci++) {
7827 		norm = pm_get_normal_power(cfb_dip, ci);
7828 		(void) pm_set_power(cfb_dip, ci, norm, PM_LEVEL_UPONLY,
7829 		    PM_CANBLOCK_BYPASS, 0, &unused);
7830 	}
7831 #ifdef DEBUG
7832 	mutex_enter(&pm_debug_lock);
7833 	pm_divertdebug--;
7834 	mutex_exit(&pm_debug_lock);
7835 #endif
7836 }
7837 
7838 /*
7839  * Check if the console framebuffer is powered up.  If not power it up.
7840  * Note: Calling pm_cfb_check_and_hold has put a hold on the power state which
7841  * must be released by calling pm_cfb_rele when the console fb operation
7842  * is completed.
7843  */
7844 void
7845 pm_cfb_check_and_powerup(void)
7846 {
7847 	if (pm_cfb_check_and_hold())
7848 		pm_cfb_powerup();
7849 }
7850 
7851 /*
7852  * Trigger a low level interrupt to power up console frame buffer.
7853  */
7854 void
7855 pm_cfb_trigger(void)
7856 {
7857 	if (cfb_dip == NULL)
7858 		return;
7859 
7860 	mutex_enter(&pm_cfb_lock);
7861 	/*
7862 	 * If machine appears to be hung, pulling the keyboard connector of
7863 	 * the console will cause a high level interrupt and go to debug_enter.
7864 	 * But, if the fb is powered down, this routine will be called to bring
7865 	 * it up (by generating a softint to do the work).  If soft interrupts
7866 	 * are not running, and the keyboard connector is pulled again, the
7867 	 * following code detects this condition and calls panic which allows
7868 	 * the fb to be brought up from high level.
7869 	 *
7870 	 * If two nearly simultaneous calls to debug_enter occur (both from
7871 	 * high level) the code described above will cause a panic.
7872 	 */
7873 	if (lbolt <= pm_soft_pending) {
7874 		panicstr = "pm_cfb_trigger: lbolt not advancing";
7875 		panic(panicstr);	/* does a power up at any intr level */
7876 		/* NOTREACHED */
7877 	}
7878 	pm_soft_pending = lbolt;
7879 	mutex_exit(&pm_cfb_lock);
7880 	ddi_trigger_softintr(pm_soft_id);
7881 }
7882 
7883 static major_t i_path_to_major(char *, char *);
7884 
7885 major_t
7886 pm_path_to_major(char *path)
7887 {
7888 	PMD_FUNC(pmf, "path_to_major")
7889 	char *np, *ap, *bp;
7890 	major_t ret;
7891 	size_t len;
7892 
7893 	PMD(PMD_NOINVOL, ("%s: %s\n", pmf, path))
7894 
7895 	np = strrchr(path, '/');
7896 	if (np != NULL)
7897 		np++;
7898 	else
7899 		np = path;
7900 	len = strlen(np) + 1;
7901 	bp = kmem_alloc(len, KM_SLEEP);
7902 	(void) strcpy(bp, np);
7903 	if ((ap = strchr(bp, '@')) != NULL) {
7904 		*ap = '\0';
7905 	}
7906 	PMD(PMD_NOINVOL, ("%s: %d\n", pmf, ddi_name_to_major(np)))
7907 	ret = i_path_to_major(path, np);
7908 	kmem_free(bp, len);
7909 	return (ret);
7910 }
7911 
7912 #ifdef DEBUG
7913 #ifndef sparc
7914 clock_t pt_sleep = 1;
7915 #endif
7916 
7917 char	*pm_msgp;
7918 char	*pm_bufend;
7919 char	*pm_msgbuf = NULL;
7920 int	pm_logpages = 0x100;
7921 #include <sys/sunldi.h>
7922 #include <sys/uio.h>
7923 clock_t	pm_log_sleep = 1000;
7924 int	pm_extra_cr = 1;
7925 volatile int pm_tty = 1;
7926 
7927 #define	PMLOGPGS	pm_logpages
7928 
7929 #if defined(__x86)
7930 void pm_printf(char *s);
7931 #endif
7932 
7933 /*PRINTFLIKE1*/
7934 void
7935 pm_log(const char *fmt, ...)
7936 {
7937 	va_list adx;
7938 	size_t size;
7939 
7940 	mutex_enter(&pm_debug_lock);
7941 	if (pm_msgbuf == NULL) {
7942 		pm_msgbuf = kmem_zalloc(mmu_ptob(PMLOGPGS), KM_SLEEP);
7943 		pm_bufend = pm_msgbuf + mmu_ptob(PMLOGPGS) - 1;
7944 		pm_msgp = pm_msgbuf;
7945 	}
7946 	va_start(adx, fmt);
7947 	size = vsnprintf(NULL, 0, fmt, adx) + 1;
7948 	va_end(adx);
7949 	va_start(adx, fmt);
7950 	if (size > (pm_bufend - pm_msgp)) {		/* wraps */
7951 		bzero(pm_msgp, pm_bufend - pm_msgp);
7952 		(void) vsnprintf(pm_msgbuf, size, fmt, adx);
7953 		if (!pm_divertdebug)
7954 			prom_printf("%s", pm_msgp);
7955 #if defined(__x86)
7956 		if (pm_tty) {
7957 			pm_printf(pm_msgp);
7958 			if (pm_extra_cr)
7959 				pm_printf("\r");
7960 		}
7961 #endif
7962 		pm_msgp = pm_msgbuf + size;
7963 	} else {
7964 		(void) vsnprintf(pm_msgp, size, fmt, adx);
7965 #if defined(__x86)
7966 		if (pm_tty) {
7967 			pm_printf(pm_msgp);
7968 			if (pm_extra_cr)
7969 				pm_printf("\r");
7970 		}
7971 #endif
7972 		if (!pm_divertdebug)
7973 			prom_printf("%s", pm_msgp);
7974 		pm_msgp += size;
7975 	}
7976 	va_end(adx);
7977 	mutex_exit(&pm_debug_lock);
7978 	drv_usecwait((clock_t)pm_log_sleep);
7979 }
7980 #endif	/* DEBUG */
7981 
7982 /*
7983  * We want to save the state of any directly pm'd devices over the suspend/
7984  * resume process so that we can put them back the way the controlling
7985  * process left them.
7986  */
7987 void
7988 pm_save_direct_levels(void)
7989 {
7990 	pm_processes_stopped = 1;
7991 	ddi_walk_devs(ddi_root_node(), pm_save_direct_lvl_walk, 0);
7992 }
7993 
7994 static int
7995 pm_save_direct_lvl_walk(dev_info_t *dip, void *arg)
7996 {
7997 	_NOTE(ARGUNUSED(arg))
7998 	int i;
7999 	int *ip;
8000 	pm_info_t *info = PM_GET_PM_INFO(dip);
8001 
8002 	if (!info)
8003 		return (DDI_WALK_CONTINUE);
8004 
8005 	if (PM_ISDIRECT(dip) && !PM_ISBC(dip)) {
8006 		if (PM_NUMCMPTS(dip) > 2) {
8007 			info->pmi_lp = kmem_alloc(PM_NUMCMPTS(dip) *
8008 			    sizeof (int), KM_SLEEP);
8009 			ip = info->pmi_lp;
8010 		} else {
8011 			ip = info->pmi_levels;
8012 		}
8013 		/* autopm and processes are stopped, ok not to lock power */
8014 		for (i = 0; i < PM_NUMCMPTS(dip); i++)
8015 			*ip++ = PM_CURPOWER(dip, i);
8016 		/*
8017 		 * There is a small window between stopping the
8018 		 * processes and setting pm_processes_stopped where
8019 		 * a driver could get hung up in a pm_raise_power()
8020 		 * call.  Free any such driver now.
8021 		 */
8022 		pm_proceed(dip, PMP_RELEASE, -1, -1);
8023 	}
8024 
8025 	return (DDI_WALK_CONTINUE);
8026 }
8027 
8028 void
8029 pm_restore_direct_levels(void)
8030 {
8031 	/*
8032 	 * If cpr didn't call pm_save_direct_levels, (because stopping user
8033 	 * threads failed) then we don't want to try to restore them
8034 	 */
8035 	if (!pm_processes_stopped)
8036 		return;
8037 
8038 	ddi_walk_devs(ddi_root_node(), pm_restore_direct_lvl_walk, 0);
8039 	pm_processes_stopped = 0;
8040 }
8041 
8042 static int
8043 pm_restore_direct_lvl_walk(dev_info_t *dip, void *arg)
8044 {
8045 	_NOTE(ARGUNUSED(arg))
8046 	PMD_FUNC(pmf, "restore_direct_lvl_walk")
8047 	int i, nc, result;
8048 	int *ip;
8049 
8050 	pm_info_t *info = PM_GET_PM_INFO(dip);
8051 	if (!info)
8052 		return (DDI_WALK_CONTINUE);
8053 
8054 	if (PM_ISDIRECT(dip) && !PM_ISBC(dip)) {
8055 		if ((nc = PM_NUMCMPTS(dip)) > 2) {
8056 			ip = &info->pmi_lp[nc - 1];
8057 		} else {
8058 			ip = &info->pmi_levels[nc - 1];
8059 		}
8060 		/*
8061 		 * Because fb drivers fail attempts to turn off the
8062 		 * fb when the monitor is on, but treat a request to
8063 		 * turn on the monitor as a request to turn on the
8064 		 * fb too, we process components in descending order
8065 		 * Because autopm is disabled and processes aren't
8066 		 * running, it is ok to examine current power outside
8067 		 * of the power lock
8068 		 */
8069 		for (i = nc - 1; i >= 0; i--, ip--) {
8070 			if (PM_CURPOWER(dip, i) == *ip)
8071 				continue;
8072 			if (pm_set_power(dip, i, *ip, PM_LEVEL_EXACT,
8073 			    PM_CANBLOCK_BYPASS, 0, &result) != DDI_SUCCESS) {
8074 				cmn_err(CE_WARN, "cpr: unable "
8075 				    "to restore power level of "
8076 				    "component %d of directly "
8077 				    "power manged device %s@%s"
8078 				    " to %d",
8079 				    i, PM_NAME(dip),
8080 				    PM_ADDR(dip), *ip);
8081 				PMD(PMD_FAIL, ("%s: failed to restore "
8082 				    "%s@%s(%s#%d)[%d] exact(%d)->%d, "
8083 				    "errno %d\n", pmf, PM_DEVICE(dip), i,
8084 				    PM_CURPOWER(dip, i), *ip, result))
8085 			}
8086 		}
8087 		if (nc > 2) {
8088 			kmem_free(info->pmi_lp, nc * sizeof (int));
8089 			info->pmi_lp = NULL;
8090 		}
8091 	}
8092 	return (DDI_WALK_CONTINUE);
8093 }
8094 
8095 /*
8096  * Stolen from the bootdev module
8097  * attempt to convert a path to a major number
8098  */
8099 static major_t
8100 i_path_to_major(char *path, char *leaf_name)
8101 {
8102 	extern major_t path_to_major(char *pathname);
8103 	major_t maj;
8104 
8105 	if ((maj = path_to_major(path)) == DDI_MAJOR_T_NONE) {
8106 		maj = ddi_name_to_major(leaf_name);
8107 	}
8108 
8109 	return (maj);
8110 }
8111 
8112 static void i_pm_driver_removed(major_t major);
8113 
8114 /*
8115  * When user calls rem_drv, we need to forget no-involuntary-power-cycles state
8116  * An entry in the list means that the device is detached, so we need to
8117  * adjust its ancestors as if they had just seen this attach, and any detached
8118  * ancestors need to have their list entries adjusted.
8119  */
8120 void
8121 pm_driver_removed(major_t major)
8122 {
8123 
8124 	/*
8125 	 * Serialize removal of drivers. This is to keep ancestors of
8126 	 * a node that is being deleted from getting deleted and added back
8127 	 * with different counters.
8128 	 */
8129 	mutex_enter(&pm_remdrv_lock);
8130 	i_pm_driver_removed(major);
8131 	mutex_exit(&pm_remdrv_lock);
8132 }
8133 
8134 static void adjust_ancestors(char *, int);
8135 static int pm_is_noinvol_ancestor(pm_noinvol_t *);
8136 static void pm_noinvol_process_ancestors(char *);
8137 
8138 /*
8139  * This routine is called recursively by pm_noinvol_process_ancestors()
8140  */
8141 static void
8142 i_pm_driver_removed(major_t major)
8143 {
8144 	PMD_FUNC(pmf, "driver_removed")
8145 	pm_noinvol_t *ip, *pp = NULL;
8146 	int wasvolpmd;
8147 	ASSERT(major != DDI_MAJOR_T_NONE);
8148 	PMD(PMD_NOINVOL, ("%s: %s\n", pmf, ddi_major_to_name(major)))
8149 again:
8150 	rw_enter(&pm_noinvol_rwlock, RW_WRITER);
8151 	for (ip = pm_noinvol_head; ip; pp = ip, ip = ip->ni_next) {
8152 		if (major != ip->ni_major)
8153 			continue;
8154 		/*
8155 		 * If it is an ancestor of no-invol node, which is
8156 		 * not removed, skip it. This is to cover the case of
8157 		 * ancestor removed without removing its descendants.
8158 		 */
8159 		if (pm_is_noinvol_ancestor(ip)) {
8160 			ip->ni_flags |= PMC_DRIVER_REMOVED;
8161 			continue;
8162 		}
8163 		wasvolpmd = ip->ni_wasvolpmd;
8164 		/*
8165 		 * remove the entry from the list
8166 		 */
8167 		if (pp) {
8168 			PMD(PMD_NOINVOL, ("%s: freeing %s, prev is %s\n",
8169 			    pmf, ip->ni_path, pp->ni_path))
8170 			pp->ni_next = ip->ni_next;
8171 		} else {
8172 			PMD(PMD_NOINVOL, ("%s: free %s head\n", pmf,
8173 			    ip->ni_path))
8174 			ASSERT(pm_noinvol_head == ip);
8175 			pm_noinvol_head = ip->ni_next;
8176 		}
8177 		rw_exit(&pm_noinvol_rwlock);
8178 		adjust_ancestors(ip->ni_path, wasvolpmd);
8179 		/*
8180 		 * Had an ancestor been removed before this node, it would have
8181 		 * been skipped. Adjust the no-invol counters for such skipped
8182 		 * ancestors.
8183 		 */
8184 		pm_noinvol_process_ancestors(ip->ni_path);
8185 		kmem_free(ip->ni_path, ip->ni_size);
8186 		kmem_free(ip, sizeof (*ip));
8187 		goto again;
8188 	}
8189 	rw_exit(&pm_noinvol_rwlock);
8190 }
8191 
8192 /*
8193  * returns 1, if *aip is a ancestor of a no-invol node
8194  *	   0, otherwise
8195  */
8196 static int
8197 pm_is_noinvol_ancestor(pm_noinvol_t *aip)
8198 {
8199 	pm_noinvol_t *ip;
8200 
8201 	ASSERT(strlen(aip->ni_path) != 0);
8202 	for (ip = pm_noinvol_head; ip; ip = ip->ni_next) {
8203 		if (ip == aip)
8204 			continue;
8205 		/*
8206 		 * To be an ancestor, the path must be an initial substring of
8207 		 * the descendent, and end just before a '/' in the
8208 		 * descendent's path.
8209 		 */
8210 		if ((strstr(ip->ni_path, aip->ni_path) == ip->ni_path) &&
8211 		    (ip->ni_path[strlen(aip->ni_path)] == '/'))
8212 			return (1);
8213 	}
8214 	return (0);
8215 }
8216 
8217 /*
8218  * scan through the pm_noinvolpm list adjusting ancestors of the current
8219  * node;  Modifies string *path.
8220  */
8221 static void
8222 adjust_ancestors(char *path, int wasvolpmd)
8223 {
8224 	PMD_FUNC(pmf, "adjust_ancestors")
8225 	char *cp;
8226 	pm_noinvol_t *lp;
8227 	pm_noinvol_t *pp = NULL;
8228 	major_t locked = DDI_MAJOR_T_NONE;
8229 	dev_info_t *dip;
8230 	char	*pathbuf;
8231 	size_t pathbuflen = strlen(path) + 1;
8232 
8233 	/*
8234 	 * First we look up the ancestor's dip.  If we find it, then we
8235 	 * adjust counts up the tree
8236 	 */
8237 	PMD(PMD_NOINVOL, ("%s: %s wasvolpmd %d\n", pmf, path, wasvolpmd))
8238 	pathbuf = kmem_alloc(pathbuflen, KM_SLEEP);
8239 	(void) strcpy(pathbuf, path);
8240 	cp = strrchr(pathbuf, '/');
8241 	if (cp == NULL)	{
8242 		/* if no ancestors, then nothing to do */
8243 		kmem_free(pathbuf, pathbuflen);
8244 		return;
8245 	}
8246 	*cp = '\0';
8247 	dip = pm_name_to_dip(pathbuf, 1);
8248 	if (dip != NULL) {
8249 		locked = PM_MAJOR(dip);
8250 
8251 		(void) pm_noinvol_update(PM_BP_NOINVOL_REMDRV, 0, wasvolpmd,
8252 		    path, dip);
8253 
8254 		if (locked != DDI_MAJOR_T_NONE)
8255 			ddi_release_devi(dip);
8256 	} else {
8257 		char *apath;
8258 		size_t len = strlen(pathbuf) + 1;
8259 		int  lock_held = 1;
8260 
8261 		/*
8262 		 * Now check for ancestors that exist only in the list
8263 		 */
8264 		apath = kmem_alloc(len, KM_SLEEP);
8265 		(void) strcpy(apath, pathbuf);
8266 		rw_enter(&pm_noinvol_rwlock, RW_WRITER);
8267 		for (lp = pm_noinvol_head; lp; pp = lp, lp = lp->ni_next) {
8268 			/*
8269 			 * This can only happen once.  Since we have to drop
8270 			 * the lock, we need to extract the relevant info.
8271 			 */
8272 			if (strcmp(pathbuf, lp->ni_path) == 0) {
8273 				PMD(PMD_NOINVOL, ("%s: %s no %d -> %d\n", pmf,
8274 				    lp->ni_path, lp->ni_noinvolpm,
8275 				    lp->ni_noinvolpm - 1))
8276 				lp->ni_noinvolpm--;
8277 				if (wasvolpmd && lp->ni_volpmd) {
8278 					PMD(PMD_NOINVOL, ("%s: %s vol %d -> "
8279 					    "%d\n", pmf, lp->ni_path,
8280 					    lp->ni_volpmd, lp->ni_volpmd - 1))
8281 					lp->ni_volpmd--;
8282 				}
8283 				/*
8284 				 * remove the entry from the list, if there
8285 				 * are no more no-invol descendants and node
8286 				 * itself is not a no-invol node.
8287 				 */
8288 				if (!(lp->ni_noinvolpm ||
8289 				    (lp->ni_flags & PMC_NO_INVOL))) {
8290 					ASSERT(lp->ni_volpmd == 0);
8291 					if (pp) {
8292 						PMD(PMD_NOINVOL, ("%s: freeing "
8293 						    "%s, prev is %s\n", pmf,
8294 						    lp->ni_path, pp->ni_path))
8295 						pp->ni_next = lp->ni_next;
8296 					} else {
8297 						PMD(PMD_NOINVOL, ("%s: free %s "
8298 						    "head\n", pmf, lp->ni_path))
8299 						ASSERT(pm_noinvol_head == lp);
8300 						pm_noinvol_head = lp->ni_next;
8301 					}
8302 					lock_held = 0;
8303 					rw_exit(&pm_noinvol_rwlock);
8304 					adjust_ancestors(apath, wasvolpmd);
8305 					/* restore apath */
8306 					(void) strcpy(apath, pathbuf);
8307 					kmem_free(lp->ni_path, lp->ni_size);
8308 					kmem_free(lp, sizeof (*lp));
8309 				}
8310 				break;
8311 			}
8312 		}
8313 		if (lock_held)
8314 			rw_exit(&pm_noinvol_rwlock);
8315 		adjust_ancestors(apath, wasvolpmd);
8316 		kmem_free(apath, len);
8317 	}
8318 	kmem_free(pathbuf, pathbuflen);
8319 }
8320 
8321 /*
8322  * Do no-invol processing for any ancestors i.e. adjust counters of ancestors,
8323  * which were skipped even though their drivers were removed.
8324  */
8325 static void
8326 pm_noinvol_process_ancestors(char *path)
8327 {
8328 	pm_noinvol_t *lp;
8329 
8330 	rw_enter(&pm_noinvol_rwlock, RW_READER);
8331 	for (lp = pm_noinvol_head; lp; lp = lp->ni_next) {
8332 		if (strstr(path, lp->ni_path) &&
8333 		    (lp->ni_flags & PMC_DRIVER_REMOVED)) {
8334 			rw_exit(&pm_noinvol_rwlock);
8335 			i_pm_driver_removed(lp->ni_major);
8336 			return;
8337 		}
8338 	}
8339 	rw_exit(&pm_noinvol_rwlock);
8340 }
8341 
8342 /*
8343  * Returns true if (detached) device needs to be kept up because it exported the
8344  * "no-involuntary-power-cycles" property or we're pretending it did (console
8345  * fb case) or it is an ancestor of such a device and has used up the "one
8346  * free cycle" allowed when all such leaf nodes have voluntarily powered down
8347  * upon detach.  In any event, we need an exact hit on the path or we return
8348  * false.
8349  */
8350 int
8351 pm_noinvol_detached(char *path)
8352 {
8353 	PMD_FUNC(pmf, "noinvol_detached")
8354 	pm_noinvol_t *ip;
8355 	int ret = 0;
8356 
8357 	rw_enter(&pm_noinvol_rwlock, RW_READER);
8358 	for (ip = pm_noinvol_head; ip; ip = ip->ni_next) {
8359 		if (strcmp(path, ip->ni_path) == 0) {
8360 			if (ip->ni_flags & PMC_CONSOLE_FB) {
8361 				PMD(PMD_NOINVOL | PMD_CFB, ("%s: inhibits CFB "
8362 				    "%s\n", pmf, path))
8363 				ret = 1;
8364 				break;
8365 			}
8366 #ifdef	DEBUG
8367 			if (ip->ni_noinvolpm != ip->ni_volpmd)
8368 				PMD(PMD_NOINVOL, ("%s: (%d != %d) inhibits %s"
8369 				    "\n", pmf, ip->ni_noinvolpm, ip->ni_volpmd,
8370 				    path))
8371 #endif
8372 			ret = (ip->ni_noinvolpm != ip->ni_volpmd);
8373 			break;
8374 		}
8375 	}
8376 	rw_exit(&pm_noinvol_rwlock);
8377 	return (ret);
8378 }
8379 
8380 int
8381 pm_is_cfb(dev_info_t *dip)
8382 {
8383 	return (dip == cfb_dip);
8384 }
8385 
8386 #ifdef	DEBUG
8387 /*
8388  * Return true if all components of the console frame buffer are at
8389  * "normal" power, i.e., fully on.  For the case where the console is not
8390  * a framebuffer, we also return true
8391  */
8392 int
8393 pm_cfb_is_up(void)
8394 {
8395 	return (pm_cfb_comps_off == 0);
8396 }
8397 #endif
8398 
8399 /*
8400  * Preventing scan from powering down the node by incrementing the
8401  * kidsupcnt.
8402  */
8403 void
8404 pm_hold_power(dev_info_t *dip)
8405 {
8406 	e_pm_hold_rele_power(dip, 1);
8407 }
8408 
8409 /*
8410  * Releasing the hold by decrementing the kidsupcnt allowing scan
8411  * to power down the node if all conditions are met.
8412  */
8413 void
8414 pm_rele_power(dev_info_t *dip)
8415 {
8416 	e_pm_hold_rele_power(dip, -1);
8417 }
8418 
8419 /*
8420  * A wrapper of pm_all_to_normal() to power up a dip
8421  * to its normal level
8422  */
8423 int
8424 pm_powerup(dev_info_t *dip)
8425 {
8426 	PMD_FUNC(pmf, "pm_powerup")
8427 
8428 	PMD(PMD_ALLNORM, ("%s: %s@%s(%s#%d)\n", pmf, PM_DEVICE(dip)))
8429 	ASSERT(!(servicing_interrupt()));
8430 
8431 	/*
8432 	 * in case this node is not already participating pm
8433 	 */
8434 	if (!PM_GET_PM_INFO(dip)) {
8435 		if (!DEVI_IS_ATTACHING(dip))
8436 			return (DDI_SUCCESS);
8437 		if (pm_start(dip) != DDI_SUCCESS)
8438 			return (DDI_FAILURE);
8439 		if (!PM_GET_PM_INFO(dip))
8440 			return (DDI_SUCCESS);
8441 	}
8442 
8443 	return (pm_all_to_normal(dip, PM_CANBLOCK_BLOCK));
8444 }
8445 
8446 int
8447 pm_rescan_walk(dev_info_t *dip, void *arg)
8448 {
8449 	_NOTE(ARGUNUSED(arg))
8450 
8451 	if (!PM_GET_PM_INFO(dip) || PM_ISBC(dip))
8452 		return (DDI_WALK_CONTINUE);
8453 
8454 	/*
8455 	 * Currently pm_cpr_callb/resume code is the only caller
8456 	 * and it needs to make sure that stopped scan get
8457 	 * reactivated. Otherwise, rescan walk needn't reactive
8458 	 * stopped scan.
8459 	 */
8460 	pm_scan_init(dip);
8461 
8462 	(void) pm_rescan(dip);
8463 	return (DDI_WALK_CONTINUE);
8464 }
8465 
8466 static dev_info_t *
8467 pm_get_next_descendent(dev_info_t *dip, dev_info_t *tdip)
8468 {
8469 	dev_info_t *wdip, *pdip;
8470 
8471 	for (wdip = tdip; wdip != dip; wdip = pdip) {
8472 		pdip = ddi_get_parent(wdip);
8473 		if (pdip == dip)
8474 			return (wdip);
8475 	}
8476 	return (NULL);
8477 }
8478 
8479 int
8480 pm_busop_bus_power(dev_info_t *dip, void *impl_arg, pm_bus_power_op_t op,
8481     void *arg, void *result)
8482 {
8483 	PMD_FUNC(pmf, "bp_bus_power")
8484 	dev_info_t	*cdip;
8485 	pm_info_t	*cinfo;
8486 	pm_bp_child_pwrchg_t	*bpc;
8487 	pm_sp_misc_t		*pspm;
8488 	pm_bp_nexus_pwrup_t *bpn;
8489 	pm_bp_child_pwrchg_t new_bpc;
8490 	pm_bp_noinvol_t *bpi;
8491 	dev_info_t *tdip;
8492 	char *pathbuf;
8493 	int		ret = DDI_SUCCESS;
8494 	int		errno = 0;
8495 	pm_component_t *cp;
8496 
8497 	PMD(PMD_SET, ("%s: %s@%s(%s#%d) %s\n", pmf, PM_DEVICE(dip),
8498 	    pm_decode_op(op)))
8499 	switch (op) {
8500 	case BUS_POWER_CHILD_PWRCHG:
8501 		bpc = (pm_bp_child_pwrchg_t *)arg;
8502 		pspm = (pm_sp_misc_t *)bpc->bpc_private;
8503 		tdip = bpc->bpc_dip;
8504 		cdip = pm_get_next_descendent(dip, tdip);
8505 		cinfo = PM_GET_PM_INFO(cdip);
8506 		if (cdip != tdip) {
8507 			/*
8508 			 * If the node is an involved parent, it needs to
8509 			 * power up the node as it is needed.  There is nothing
8510 			 * else the framework can do here.
8511 			 */
8512 			if (PM_WANTS_NOTIFICATION(cdip)) {
8513 				PMD(PMD_SET, ("%s: call bus_power for "
8514 				    "%s@%s(%s#%d)\n", pmf, PM_DEVICE(cdip)))
8515 				return ((*PM_BUS_POWER_FUNC(cdip))(cdip,
8516 				    impl_arg, op, arg, result));
8517 			}
8518 			ASSERT(pspm->pspm_direction == PM_LEVEL_UPONLY ||
8519 			    pspm->pspm_direction == PM_LEVEL_DOWNONLY ||
8520 			    pspm->pspm_direction == PM_LEVEL_EXACT);
8521 			/*
8522 			 * we presume that the parent needs to be up in
8523 			 * order for the child to change state (either
8524 			 * because it must already be on if the child is on
8525 			 * (and the pm_all_to_normal_nexus() will be a nop)
8526 			 * or because it will need to be on for the child
8527 			 * to come on; so we make the call regardless
8528 			 */
8529 			pm_hold_power(cdip);
8530 			if (cinfo) {
8531 				pm_canblock_t canblock = pspm->pspm_canblock;
8532 				ret = pm_all_to_normal_nexus(cdip, canblock);
8533 				if (ret != DDI_SUCCESS) {
8534 					pm_rele_power(cdip);
8535 					return (ret);
8536 				}
8537 			}
8538 			PMD(PMD_SET, ("%s: walk down to %s@%s(%s#%d)\n", pmf,
8539 			    PM_DEVICE(cdip)))
8540 			ret = pm_busop_bus_power(cdip, impl_arg, op, arg,
8541 			    result);
8542 			pm_rele_power(cdip);
8543 		} else {
8544 			ret = pm_busop_set_power(cdip, impl_arg, op, arg,
8545 			    result);
8546 		}
8547 		return (ret);
8548 
8549 	case BUS_POWER_NEXUS_PWRUP:
8550 		bpn = (pm_bp_nexus_pwrup_t *)arg;
8551 		pspm = (pm_sp_misc_t *)bpn->bpn_private;
8552 
8553 		if (!e_pm_valid_info(dip, NULL) ||
8554 		    !e_pm_valid_comp(dip, bpn->bpn_comp, &cp) ||
8555 		    !e_pm_valid_power(dip, bpn->bpn_comp, bpn->bpn_level)) {
8556 			PMD(PMD_SET, ("%s: %s@%s(%s#%d) has no pm info; EIO\n",
8557 			    pmf, PM_DEVICE(dip)))
8558 			*pspm->pspm_errnop = EIO;
8559 			*(int *)result = DDI_FAILURE;
8560 			return (DDI_FAILURE);
8561 		}
8562 
8563 		ASSERT(bpn->bpn_dip == dip);
8564 		PMD(PMD_SET, ("%s: nexus powerup for %s@%s(%s#%d)\n", pmf,
8565 		    PM_DEVICE(dip)))
8566 		new_bpc.bpc_dip = dip;
8567 		pathbuf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
8568 		new_bpc.bpc_path = ddi_pathname(dip, pathbuf);
8569 		new_bpc.bpc_comp = bpn->bpn_comp;
8570 		new_bpc.bpc_olevel = PM_CURPOWER(dip, bpn->bpn_comp);
8571 		new_bpc.bpc_nlevel = bpn->bpn_level;
8572 		new_bpc.bpc_private = bpn->bpn_private;
8573 		((pm_sp_misc_t *)(new_bpc.bpc_private))->pspm_direction =
8574 		    PM_LEVEL_UPONLY;
8575 		((pm_sp_misc_t *)(new_bpc.bpc_private))->pspm_errnop =
8576 		    &errno;
8577 		ret = pm_busop_set_power(dip, impl_arg, BUS_POWER_CHILD_PWRCHG,
8578 		    (void *)&new_bpc, result);
8579 		kmem_free(pathbuf, MAXPATHLEN);
8580 		return (ret);
8581 
8582 	case BUS_POWER_NOINVOL:
8583 		bpi = (pm_bp_noinvol_t *)arg;
8584 		tdip = bpi->bpni_dip;
8585 		cdip = pm_get_next_descendent(dip, tdip);
8586 
8587 		/* In case of rem_drv, the leaf node has been removed */
8588 		if (cdip == NULL)
8589 			return (DDI_SUCCESS);
8590 
8591 		cinfo = PM_GET_PM_INFO(cdip);
8592 		if (cdip != tdip) {
8593 			if (PM_WANTS_NOTIFICATION(cdip)) {
8594 				PMD(PMD_NOINVOL,
8595 				    ("%s: call bus_power for %s@%s(%s#%d)\n",
8596 				    pmf, PM_DEVICE(cdip)))
8597 				ret = (*PM_BUS_POWER_FUNC(cdip))
8598 				    (cdip, NULL, op, arg, result);
8599 				if ((cinfo) && (ret == DDI_SUCCESS))
8600 					(void) pm_noinvol_update_node(cdip,
8601 					    bpi);
8602 				return (ret);
8603 			} else {
8604 				PMD(PMD_NOINVOL,
8605 				    ("%s: walk down to %s@%s(%s#%d)\n", pmf,
8606 				    PM_DEVICE(cdip)))
8607 				ret = pm_busop_bus_power(cdip, NULL, op,
8608 				    arg, result);
8609 				/*
8610 				 * Update the current node.
8611 				 */
8612 				if ((cinfo) && (ret == DDI_SUCCESS))
8613 					(void) pm_noinvol_update_node(cdip,
8614 					    bpi);
8615 				return (ret);
8616 			}
8617 		} else {
8618 			/*
8619 			 * For attach, detach, power up:
8620 			 * Do nothing for leaf node since its
8621 			 * counts are already updated.
8622 			 * For CFB and driver removal, since the
8623 			 * path and the target dip passed in is up to and incl.
8624 			 * the immediate ancestor, need to do the update.
8625 			 */
8626 			PMD(PMD_NOINVOL, ("%s: target %s@%s(%s#%d) is "
8627 			    "reached\n", pmf, PM_DEVICE(cdip)))
8628 			if (cinfo && ((bpi->bpni_cmd == PM_BP_NOINVOL_REMDRV) ||
8629 			    (bpi->bpni_cmd == PM_BP_NOINVOL_CFB)))
8630 				(void) pm_noinvol_update_node(cdip, bpi);
8631 			return (DDI_SUCCESS);
8632 		}
8633 
8634 	default:
8635 		PMD(PMD_SET, ("%s: operation %d is not supported!\n", pmf, op))
8636 		return (DDI_FAILURE);
8637 	}
8638 }
8639 
8640 static int
8641 pm_busop_set_power(dev_info_t *dip, void *impl_arg, pm_bus_power_op_t op,
8642     void *arg, void *resultp)
8643 {
8644 	_NOTE(ARGUNUSED(impl_arg))
8645 	PMD_FUNC(pmf, "bp_set_power")
8646 	pm_ppm_devlist_t *devl = NULL;
8647 	int clevel, circ;
8648 #ifdef	DEBUG
8649 	int circ_db, ccirc_db;
8650 #endif
8651 	int ret = DDI_SUCCESS;
8652 	dev_info_t *cdip;
8653 	pm_bp_child_pwrchg_t *bpc = (pm_bp_child_pwrchg_t *)arg;
8654 	pm_sp_misc_t *pspm = (pm_sp_misc_t *)bpc->bpc_private;
8655 	pm_canblock_t canblock = pspm->pspm_canblock;
8656 	int scan = pspm->pspm_scan;
8657 	int comp = bpc->bpc_comp;
8658 	int olevel = bpc->bpc_olevel;
8659 	int nlevel = bpc->bpc_nlevel;
8660 	int comps_off_incr = 0;
8661 	dev_info_t *pdip = ddi_get_parent(dip);
8662 	int dodeps;
8663 	int direction = pspm->pspm_direction;
8664 	int *errnop = pspm->pspm_errnop;
8665 #ifdef PMDDEBUG
8666 	char *dir = pm_decode_direction(direction);
8667 #endif
8668 	int *iresp = (int *)resultp;
8669 	time_t	idletime, thresh;
8670 	pm_component_t *cp = PM_CP(dip, comp);
8671 	int work_type;
8672 
8673 	*iresp = DDI_SUCCESS;
8674 	*errnop = 0;
8675 	ASSERT(op == BUS_POWER_CHILD_PWRCHG);
8676 	PMD(PMD_SET, ("%s: %s@%s(%s#%d) %s\n", pmf, PM_DEVICE(dip),
8677 	    pm_decode_op(op)))
8678 
8679 	/*
8680 	 * The following set of conditions indicate we are here to handle a
8681 	 * driver's pm_[raise|lower]_power request, but the device is being
8682 	 * power managed (PM_DIRECT_PM) by a user process.  For that case
8683 	 * we want to pm_block and pass a status back to the caller based
8684 	 * on whether the controlling process's next activity on the device
8685 	 * matches the current request or not.  This distinction tells
8686 	 * downstream functions to avoid calling into a driver or changing
8687 	 * the framework's power state.  To actually block, we need:
8688 	 *
8689 	 * PM_ISDIRECT(dip)
8690 	 *	no reason to block unless a process is directly controlling dev
8691 	 * direction != PM_LEVEL_EXACT
8692 	 *	EXACT is used by controlling proc's PM_SET_CURRENT_POWER ioctl
8693 	 * !pm_processes_stopped
8694 	 *	don't block if controlling proc already be stopped for cpr
8695 	 * canblock != PM_CANBLOCK_BYPASS
8696 	 *	our caller must not have explicitly prevented blocking
8697 	 */
8698 	if (direction != PM_LEVEL_EXACT && canblock != PM_CANBLOCK_BYPASS) {
8699 		PM_LOCK_DIP(dip);
8700 		while (PM_ISDIRECT(dip) && !pm_processes_stopped) {
8701 			/* releases dip lock */
8702 			ret = pm_busop_match_request(dip, bpc);
8703 			if (ret == EAGAIN) {
8704 				PM_LOCK_DIP(dip);
8705 				continue;
8706 			}
8707 			return (*iresp = ret);
8708 		}
8709 		PM_UNLOCK_DIP(dip);
8710 	}
8711 	/* BC device is never scanned, so power will stick until we are done */
8712 	if (PM_ISBC(dip) && comp != 0 && nlevel != 0 &&
8713 	    direction != PM_LEVEL_DOWNONLY) {
8714 		int nrmpwr0 = pm_get_normal_power(dip, 0);
8715 		if (pm_set_power(dip, 0, nrmpwr0, direction,
8716 		    canblock, 0, resultp) != DDI_SUCCESS) {
8717 			/* *resultp set by pm_set_power */
8718 			return (DDI_FAILURE);
8719 		}
8720 	}
8721 	if (PM_WANTS_NOTIFICATION(pdip)) {
8722 		PMD(PMD_SET, ("%s: pre_notify %s@%s(%s#%d) for child "
8723 		    "%s@%s(%s#%d)\n", pmf, PM_DEVICE(pdip), PM_DEVICE(dip)))
8724 		ret = (*PM_BUS_POWER_FUNC(pdip))(pdip, NULL,
8725 		    BUS_POWER_PRE_NOTIFICATION, bpc, resultp);
8726 		if (ret != DDI_SUCCESS) {
8727 			PMD(PMD_SET, ("%s: failed to pre_notify %s@%s(%s#%d)\n",
8728 			    pmf, PM_DEVICE(pdip)))
8729 			return (DDI_FAILURE);
8730 		}
8731 	} else {
8732 		/*
8733 		 * Since we don't know what the actual power level is,
8734 		 * we place a power hold on the parent no matter what
8735 		 * component and level is changing.
8736 		 */
8737 		pm_hold_power(pdip);
8738 	}
8739 	PM_LOCK_POWER(dip, &circ);
8740 	clevel = PM_CURPOWER(dip, comp);
8741 	/*
8742 	 * It's possible that a call was made to pm_update_maxpower()
8743 	 * on another thread before we took the lock above. So, we need to
8744 	 * make sure that this request isn't processed after the
8745 	 * change of power executed on behalf of pm_update_maxpower().
8746 	 */
8747 	if (nlevel > pm_get_normal_power(dip, comp)) {
8748 		PMD(PMD_SET, ("%s: requested level is higher than normal.\n",
8749 		    pmf))
8750 		ret = DDI_FAILURE;
8751 		*iresp = DDI_FAILURE;
8752 		goto post_notify;
8753 	}
8754 	PMD(PMD_SET, ("%s: %s@%s(%s#%d), cmp=%d, olvl=%d, nlvl=%d, clvl=%d, "
8755 	    "dir=%s\n", pmf, PM_DEVICE(dip), comp, bpc->bpc_olevel, nlevel,
8756 	    clevel, dir))
8757 	switch (direction) {
8758 	case PM_LEVEL_UPONLY:
8759 		/* Powering up */
8760 		if (clevel >= nlevel) {
8761 			PMD(PMD_SET, ("%s: current level is already "
8762 			    "at or above the requested level.\n", pmf))
8763 			*iresp = DDI_SUCCESS;
8764 			ret = DDI_SUCCESS;
8765 			goto post_notify;
8766 		}
8767 		break;
8768 	case PM_LEVEL_EXACT:
8769 		/* specific level request */
8770 		if (clevel == nlevel && !PM_ISBC(dip)) {
8771 			PMD(PMD_SET, ("%s: current level is already "
8772 			    "at the requested level.\n", pmf))
8773 			*iresp = DDI_SUCCESS;
8774 			ret = DDI_SUCCESS;
8775 			goto post_notify;
8776 		} else if (PM_IS_CFB(dip) && (nlevel < clevel)) {
8777 			PMD(PMD_CFB, ("%s: powerdown of console\n", pmf))
8778 			if (!pm_cfb_enabled) {
8779 				PMD(PMD_ERROR | PMD_CFB,
8780 				    ("%s: !pm_cfb_enabled, fails\n", pmf))
8781 				*errnop = EINVAL;
8782 				*iresp = DDI_FAILURE;
8783 				ret = DDI_FAILURE;
8784 				goto post_notify;
8785 			}
8786 			mutex_enter(&pm_cfb_lock);
8787 			while (cfb_inuse) {
8788 				mutex_exit(&pm_cfb_lock);
8789 				if (delay_sig(1) == EINTR) {
8790 					ret = DDI_FAILURE;
8791 					*iresp = DDI_FAILURE;
8792 					*errnop = EINTR;
8793 					goto post_notify;
8794 				}
8795 				mutex_enter(&pm_cfb_lock);
8796 			}
8797 			mutex_exit(&pm_cfb_lock);
8798 		}
8799 		break;
8800 	case PM_LEVEL_DOWNONLY:
8801 		/* Powering down */
8802 		thresh = cur_threshold(dip, comp);
8803 		idletime = gethrestime_sec() - cp->pmc_timestamp;
8804 		if (scan && ((PM_KUC(dip) != 0) ||
8805 		    (cp->pmc_busycount > 0) ||
8806 		    ((idletime < thresh) && !PM_IS_PID(dip)))) {
8807 #ifdef	DEBUG
8808 			if (DEVI(dip)->devi_pm_kidsupcnt != 0)
8809 				PMD(PMD_SET, ("%s: scan failed: "
8810 				    "kidsupcnt != 0\n", pmf))
8811 			if (cp->pmc_busycount > 0)
8812 				PMD(PMD_SET, ("%s: scan failed: "
8813 				    "device become busy\n", pmf))
8814 			if (idletime < thresh)
8815 				PMD(PMD_SET, ("%s: scan failed: device "
8816 				    "hasn't been idle long enough\n", pmf))
8817 #endif
8818 			*iresp = DDI_FAILURE;
8819 			*errnop = EBUSY;
8820 			ret = DDI_FAILURE;
8821 			goto post_notify;
8822 		} else if (clevel != PM_LEVEL_UNKNOWN && clevel <= nlevel) {
8823 			PMD(PMD_SET, ("%s: current level is already at "
8824 			    "or below the requested level.\n", pmf))
8825 			*iresp = DDI_SUCCESS;
8826 			ret = DDI_SUCCESS;
8827 			goto post_notify;
8828 		}
8829 		break;
8830 	}
8831 
8832 	if (PM_IS_CFB(dip) && (comps_off_incr =
8833 	    calc_cfb_comps_incr(dip, comp, clevel, nlevel)) > 0) {
8834 		/*
8835 		 * Pre-adjust pm_cfb_comps_off if lowering a console fb
8836 		 * component from full power.  Remember that we tried to
8837 		 * lower power in case it fails and we need to back out
8838 		 * the adjustment.
8839 		 */
8840 		update_comps_off(comps_off_incr, dip);
8841 		PMD(PMD_CFB, ("%s: %s@%s(%s#%d)[%d] %d->%d cfb_comps_off->%d\n",
8842 		    pmf, PM_DEVICE(dip), comp, clevel, nlevel,
8843 		    pm_cfb_comps_off))
8844 	}
8845 
8846 	if ((*iresp = power_dev(dip,
8847 	    comp, nlevel, clevel, canblock, &devl)) == DDI_SUCCESS) {
8848 #ifdef DEBUG
8849 		/*
8850 		 * All descendents of this node should already be powered off.
8851 		 */
8852 		if (PM_CURPOWER(dip, comp) == 0) {
8853 			pm_desc_pwrchk_t pdpchk;
8854 			pdpchk.pdpc_dip = dip;
8855 			pdpchk.pdpc_par_involved = PM_WANTS_NOTIFICATION(dip);
8856 			ndi_devi_enter(dip, &circ_db);
8857 			for (cdip = ddi_get_child(dip); cdip != NULL;
8858 			    cdip = ddi_get_next_sibling(cdip)) {
8859 				ndi_devi_enter(cdip, &ccirc_db);
8860 				ddi_walk_devs(cdip, pm_desc_pwrchk_walk,
8861 				    (void *)&pdpchk);
8862 				ndi_devi_exit(cdip, ccirc_db);
8863 			}
8864 			ndi_devi_exit(dip, circ_db);
8865 		}
8866 #endif
8867 		/*
8868 		 * Post-adjust pm_cfb_comps_off if we brought an fb component
8869 		 * back up to full power.
8870 		 */
8871 		if (PM_IS_CFB(dip) && comps_off_incr < 0) {
8872 			update_comps_off(comps_off_incr, dip);
8873 			PMD(PMD_CFB, ("%s: %s@%s(%s#%d)[%d] %d->%d "
8874 			    "cfb_comps_off->%d\n", pmf, PM_DEVICE(dip),
8875 			    comp, clevel, nlevel, pm_cfb_comps_off))
8876 		}
8877 		dodeps = 0;
8878 		if (POWERING_OFF(clevel, nlevel)) {
8879 			if (PM_ISBC(dip)) {
8880 				dodeps = (comp == 0);
8881 			} else {
8882 				int i;
8883 				dodeps = 1;
8884 				for (i = 0; i < PM_NUMCMPTS(dip); i++) {
8885 					/* if some component still on */
8886 					if (PM_CURPOWER(dip, i)) {
8887 						dodeps = 0;
8888 						break;
8889 					}
8890 				}
8891 			}
8892 			if (dodeps)
8893 				work_type = PM_DEP_WK_POWER_OFF;
8894 		} else if (POWERING_ON(clevel, nlevel)) {
8895 			if (PM_ISBC(dip)) {
8896 				dodeps = (comp == 0);
8897 			} else {
8898 				int i;
8899 				dodeps = 1;
8900 				for (i = 0; i < PM_NUMCMPTS(dip); i++) {
8901 					if (i == comp)
8902 						continue;
8903 					if (PM_CURPOWER(dip, i) > 0) {
8904 						dodeps = 0;
8905 						break;
8906 					}
8907 				}
8908 			}
8909 			if (dodeps)
8910 				work_type = PM_DEP_WK_POWER_ON;
8911 		}
8912 
8913 		if (dodeps) {
8914 			char *pathbuf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
8915 
8916 			(void) ddi_pathname(dip, pathbuf);
8917 			pm_dispatch_to_dep_thread(work_type, pathbuf, NULL,
8918 			    PM_DEP_NOWAIT, NULL, 0);
8919 			kmem_free(pathbuf, MAXPATHLEN);
8920 		}
8921 		if ((PM_CURPOWER(dip, comp) == nlevel) && pm_watchers()) {
8922 			int old;
8923 
8924 			/* If old power cached during deadlock, use it. */
8925 			old = (cp->pmc_flags & PM_PHC_WHILE_SET_POWER ?
8926 			    cp->pmc_phc_pwr : olevel);
8927 			mutex_enter(&pm_rsvp_lock);
8928 			pm_enqueue_notify(PSC_HAS_CHANGED, dip, comp, nlevel,
8929 			    old, canblock);
8930 			pm_enqueue_notify_others(&devl, canblock);
8931 			mutex_exit(&pm_rsvp_lock);
8932 		} else {
8933 			pm_ppm_devlist_t *p;
8934 			pm_ppm_devlist_t *next;
8935 			for (p = devl; p != NULL; p = next) {
8936 				next = p->ppd_next;
8937 				kmem_free(p, sizeof (pm_ppm_devlist_t));
8938 			}
8939 			devl = NULL;
8940 		}
8941 
8942 		/*
8943 		 * If we are coming from a scan, don't do it again,
8944 		 * else we can have infinite loops.
8945 		 */
8946 		if (!scan)
8947 			pm_rescan(dip);
8948 	} else {
8949 		/* if we incremented pm_comps_off_count, but failed */
8950 		if (comps_off_incr > 0) {
8951 			update_comps_off(-comps_off_incr, dip);
8952 			PMD(PMD_CFB, ("%s: %s@%s(%s#%d)[%d] %d->%d "
8953 			    "cfb_comps_off->%d\n", pmf, PM_DEVICE(dip),
8954 			    comp, clevel, nlevel, pm_cfb_comps_off))
8955 		}
8956 		*errnop = EIO;
8957 	}
8958 
8959 post_notify:
8960 	/*
8961 	 * This thread may have been in deadlock with pm_power_has_changed.
8962 	 * Before releasing power lock, clear the flag which marks this
8963 	 * condition.
8964 	 */
8965 	cp->pmc_flags &= ~PM_PHC_WHILE_SET_POWER;
8966 
8967 	/*
8968 	 * Update the old power level in the bus power structure with the
8969 	 * actual power level before the transition was made to the new level.
8970 	 * Some involved parents depend on this information to keep track of
8971 	 * their children's power transition.
8972 	 */
8973 	if (*iresp != DDI_FAILURE)
8974 		bpc->bpc_olevel = clevel;
8975 
8976 	if (PM_WANTS_NOTIFICATION(pdip)) {
8977 		ret = (*PM_BUS_POWER_FUNC(pdip))(pdip, NULL,
8978 		    BUS_POWER_POST_NOTIFICATION, bpc, resultp);
8979 		PM_UNLOCK_POWER(dip, circ);
8980 		PMD(PMD_SET, ("%s: post_notify %s@%s(%s#%d) for "
8981 		    "child %s@%s(%s#%d), ret=%d\n", pmf, PM_DEVICE(pdip),
8982 		    PM_DEVICE(dip), ret))
8983 	} else {
8984 		nlevel = cur_power(cp); /* in case phc deadlock updated pwr */
8985 		PM_UNLOCK_POWER(dip, circ);
8986 		/*
8987 		 * Now that we know what power transition has occurred
8988 		 * (if any), release the power hold.  Leave the hold
8989 		 * in effect in the case of OFF->ON transition.
8990 		 */
8991 		if (!(clevel == 0 && nlevel > 0 &&
8992 		    (!PM_ISBC(dip) || comp == 0)))
8993 			pm_rele_power(pdip);
8994 		/*
8995 		 * If the power transition was an ON->OFF transition,
8996 		 * remove the power hold from the parent.
8997 		 */
8998 		if ((clevel > 0 || clevel == PM_LEVEL_UNKNOWN) &&
8999 		    nlevel == 0 && (!PM_ISBC(dip) || comp == 0))
9000 			pm_rele_power(pdip);
9001 	}
9002 	if (*iresp != DDI_SUCCESS || ret != DDI_SUCCESS)
9003 		return (DDI_FAILURE);
9004 	else
9005 		return (DDI_SUCCESS);
9006 }
9007 
9008 /*
9009  * If an app (SunVTS or Xsun) has taken control, then block until it
9010  * gives it up or makes the requested power level change, unless
9011  * we have other instructions about blocking.  Returns DDI_SUCCESS,
9012  * DDI_FAILURE or EAGAIN (owner released device from directpm).
9013  */
9014 static int
9015 pm_busop_match_request(dev_info_t *dip, void *arg)
9016 {
9017 	PMD_FUNC(pmf, "bp_match_request")
9018 	pm_bp_child_pwrchg_t *bpc = (pm_bp_child_pwrchg_t *)arg;
9019 	pm_sp_misc_t *pspm = (pm_sp_misc_t *)bpc->bpc_private;
9020 	int comp = bpc->bpc_comp;
9021 	int nlevel = bpc->bpc_nlevel;
9022 	pm_canblock_t canblock = pspm->pspm_canblock;
9023 	int direction = pspm->pspm_direction;
9024 	int clevel, circ;
9025 
9026 	ASSERT(PM_IAM_LOCKING_DIP(dip));
9027 	PM_LOCK_POWER(dip, &circ);
9028 	clevel = PM_CURPOWER(dip, comp);
9029 	PMD(PMD_SET, ("%s: %s@%s(%s#%d), cmp=%d, nlvl=%d, clvl=%d\n",
9030 	    pmf, PM_DEVICE(dip), comp, nlevel, clevel))
9031 	if (direction == PM_LEVEL_UPONLY) {
9032 		if (clevel >= nlevel) {
9033 			PM_UNLOCK_POWER(dip, circ);
9034 			PM_UNLOCK_DIP(dip);
9035 			return (DDI_SUCCESS);
9036 		}
9037 	} else if (clevel == nlevel) {
9038 		PM_UNLOCK_POWER(dip, circ);
9039 		PM_UNLOCK_DIP(dip);
9040 		return (DDI_SUCCESS);
9041 	}
9042 	if (canblock == PM_CANBLOCK_FAIL) {
9043 		PM_UNLOCK_POWER(dip, circ);
9044 		PM_UNLOCK_DIP(dip);
9045 		return (DDI_FAILURE);
9046 	}
9047 	if (canblock == PM_CANBLOCK_BLOCK) {
9048 		/*
9049 		 * To avoid a deadlock, we must not hold the
9050 		 * power lock when we pm_block.
9051 		 */
9052 		PM_UNLOCK_POWER(dip, circ);
9053 		PMD(PMD_SET, ("%s: blocking\n", pmf))
9054 		/* pm_block releases dip lock */
9055 		switch (pm_block(dip, comp, nlevel, clevel)) {
9056 		case PMP_RELEASE:
9057 			return (EAGAIN);
9058 		case PMP_SUCCEED:
9059 			return (DDI_SUCCESS);
9060 		case PMP_FAIL:
9061 			return (DDI_FAILURE);
9062 		}
9063 	} else {
9064 		ASSERT(0);
9065 	}
9066 	_NOTE(NOTREACHED);
9067 	return (DDI_FAILURE);	/* keep gcc happy */
9068 }
9069 
9070 static int
9071 pm_all_to_normal_nexus(dev_info_t *dip, pm_canblock_t canblock)
9072 {
9073 	PMD_FUNC(pmf, "all_to_normal_nexus")
9074 	int		*normal;
9075 	int		i, ncomps;
9076 	size_t		size;
9077 	int		changefailed = 0;
9078 	int		ret, result = DDI_SUCCESS;
9079 	pm_bp_nexus_pwrup_t	bpn;
9080 	pm_sp_misc_t	pspm;
9081 
9082 	ASSERT(PM_GET_PM_INFO(dip));
9083 	PMD(PMD_ALLNORM, ("%s: %s@%s(%s#%d)\n", pmf, PM_DEVICE(dip)))
9084 	if (pm_get_norm_pwrs(dip, &normal, &size) != DDI_SUCCESS) {
9085 		PMD(PMD_ALLNORM, ("%s: can't get norm pwrs\n", pmf))
9086 		return (DDI_FAILURE);
9087 	}
9088 	ncomps = PM_NUMCMPTS(dip);
9089 	for (i = 0; i < ncomps; i++) {
9090 		bpn.bpn_dip = dip;
9091 		bpn.bpn_comp = i;
9092 		bpn.bpn_level = normal[i];
9093 		pspm.pspm_canblock = canblock;
9094 		pspm.pspm_scan = 0;
9095 		bpn.bpn_private = &pspm;
9096 		ret = pm_busop_bus_power(dip, NULL, BUS_POWER_NEXUS_PWRUP,
9097 		    (void *)&bpn, (void *)&result);
9098 		if (ret != DDI_SUCCESS || result != DDI_SUCCESS) {
9099 			PMD(PMD_FAIL | PMD_ALLNORM, ("%s: %s@%s(%s#%d)[%d] "
9100 			    "->%d failure result %d\n", pmf, PM_DEVICE(dip),
9101 			    i, normal[i], result))
9102 			changefailed++;
9103 		}
9104 	}
9105 	kmem_free(normal, size);
9106 	if (changefailed) {
9107 		PMD(PMD_FAIL, ("%s: failed to set %d comps %s@%s(%s#%d) "
9108 		    "full power\n", pmf, changefailed, PM_DEVICE(dip)))
9109 		return (DDI_FAILURE);
9110 	}
9111 	return (DDI_SUCCESS);
9112 }
9113 
9114 int
9115 pm_noinvol_update(int subcmd, int volpmd, int wasvolpmd, char *path,
9116     dev_info_t *tdip)
9117 {
9118 	PMD_FUNC(pmf, "noinvol_update")
9119 	pm_bp_noinvol_t args;
9120 	int ret;
9121 	int result = DDI_SUCCESS;
9122 
9123 	args.bpni_path = path;
9124 	args.bpni_dip = tdip;
9125 	args.bpni_cmd = subcmd;
9126 	args.bpni_wasvolpmd = wasvolpmd;
9127 	args.bpni_volpmd = volpmd;
9128 	PMD(PMD_NOINVOL, ("%s: update for path %s tdip %p subcmd %d "
9129 	    "volpmd %d wasvolpmd %d\n", pmf,
9130 	    path, (void *)tdip, subcmd, wasvolpmd, volpmd))
9131 	ret = pm_busop_bus_power(ddi_root_node(), NULL, BUS_POWER_NOINVOL,
9132 	    &args, &result);
9133 	return (ret);
9134 }
9135 
9136 void
9137 pm_noinvol_update_node(dev_info_t *dip, pm_bp_noinvol_t *req)
9138 {
9139 	PMD_FUNC(pmf, "noinvol_update_node")
9140 
9141 	PMD(PMD_NOINVOL, ("%s: %s@%s(%s#%d)\n", pmf, PM_DEVICE(dip)))
9142 	switch (req->bpni_cmd) {
9143 	case PM_BP_NOINVOL_ATTACH:
9144 		PMD(PMD_NOINVOL, ("%s: PM_PB_NOINVOL_ATTACH %s@%s(%s#%d) "
9145 		    "noinvol %d->%d\n", pmf, PM_DEVICE(dip),
9146 		    DEVI(dip)->devi_pm_noinvolpm,
9147 		    DEVI(dip)->devi_pm_noinvolpm - 1))
9148 		ASSERT(DEVI(dip)->devi_pm_noinvolpm);
9149 		PM_LOCK_DIP(dip);
9150 		DEVI(dip)->devi_pm_noinvolpm--;
9151 		if (req->bpni_wasvolpmd) {
9152 			PMD(PMD_NOINVOL, ("%s: PM_BP_NOINVOL_ATTACH "
9153 			    "%s@%s(%s#%d) volpmd %d->%d\n", pmf,
9154 			    PM_DEVICE(dip), DEVI(dip)->devi_pm_volpmd,
9155 			    DEVI(dip)->devi_pm_volpmd - 1))
9156 			if (DEVI(dip)->devi_pm_volpmd)
9157 				DEVI(dip)->devi_pm_volpmd--;
9158 		}
9159 		PM_UNLOCK_DIP(dip);
9160 		break;
9161 
9162 	case PM_BP_NOINVOL_DETACH:
9163 		PMD(PMD_NOINVOL, ("%s: PM_BP_NOINVOL_DETACH %s@%s(%s#%d) "
9164 		    "noinvolpm %d->%d\n", pmf, PM_DEVICE(dip),
9165 		    DEVI(dip)->devi_pm_noinvolpm,
9166 		    DEVI(dip)->devi_pm_noinvolpm + 1))
9167 		PM_LOCK_DIP(dip);
9168 		DEVI(dip)->devi_pm_noinvolpm++;
9169 		if (req->bpni_wasvolpmd) {
9170 			PMD(PMD_NOINVOL, ("%s: PM_BP_NOINVOL_DETACH "
9171 			    "%s@%s(%s#%d) volpmd %d->%d\n", pmf,
9172 			    PM_DEVICE(dip), DEVI(dip)->devi_pm_volpmd,
9173 			    DEVI(dip)->devi_pm_volpmd + 1))
9174 			DEVI(dip)->devi_pm_volpmd++;
9175 		}
9176 		PM_UNLOCK_DIP(dip);
9177 		break;
9178 
9179 	case PM_BP_NOINVOL_REMDRV:
9180 		PMD(PMD_NOINVOL, ("%s: PM_BP_NOINVOL_REMDRV %s@%s(%s#%d) "
9181 		    "noinvol %d->%d\n", pmf, PM_DEVICE(dip),
9182 		    DEVI(dip)->devi_pm_noinvolpm,
9183 		    DEVI(dip)->devi_pm_noinvolpm - 1))
9184 		ASSERT(DEVI(dip)->devi_pm_noinvolpm);
9185 		PM_LOCK_DIP(dip);
9186 		DEVI(dip)->devi_pm_noinvolpm--;
9187 		if (req->bpni_wasvolpmd) {
9188 			PMD(PMD_NOINVOL,
9189 			    ("%s: PM_BP_NOINVOL_REMDRV %s@%s(%s#%d) "
9190 			    "volpmd %d->%d\n", pmf, PM_DEVICE(dip),
9191 			    DEVI(dip)->devi_pm_volpmd,
9192 			    DEVI(dip)->devi_pm_volpmd - 1))
9193 			/*
9194 			 * A power up could come in between and
9195 			 * clear the volpmd, if that's the case,
9196 			 * volpmd would be clear.
9197 			 */
9198 			if (DEVI(dip)->devi_pm_volpmd)
9199 				DEVI(dip)->devi_pm_volpmd--;
9200 		}
9201 		PM_UNLOCK_DIP(dip);
9202 		break;
9203 
9204 	case PM_BP_NOINVOL_CFB:
9205 		PMD(PMD_NOINVOL,
9206 		    ("%s: PM_BP_NOIVOL_CFB %s@%s(%s#%d) noinvol %d->%d\n",
9207 		    pmf, PM_DEVICE(dip), DEVI(dip)->devi_pm_noinvolpm,
9208 		    DEVI(dip)->devi_pm_noinvolpm + 1))
9209 		PM_LOCK_DIP(dip);
9210 		DEVI(dip)->devi_pm_noinvolpm++;
9211 		PM_UNLOCK_DIP(dip);
9212 		break;
9213 
9214 	case PM_BP_NOINVOL_POWER:
9215 		PMD(PMD_NOINVOL,
9216 		    ("%s: PM_BP_NOIVOL_PWR %s@%s(%s#%d) volpmd %d->%d\n",
9217 		    pmf, PM_DEVICE(dip),
9218 		    DEVI(dip)->devi_pm_volpmd, DEVI(dip)->devi_pm_volpmd -
9219 		    req->bpni_volpmd))
9220 		PM_LOCK_DIP(dip);
9221 		DEVI(dip)->devi_pm_volpmd -= req->bpni_volpmd;
9222 		PM_UNLOCK_DIP(dip);
9223 		break;
9224 
9225 	default:
9226 		break;
9227 	}
9228 
9229 }
9230 
9231 #ifdef DEBUG
9232 static int
9233 pm_desc_pwrchk_walk(dev_info_t *dip, void *arg)
9234 {
9235 	PMD_FUNC(pmf, "desc_pwrchk")
9236 	pm_desc_pwrchk_t *pdpchk = (pm_desc_pwrchk_t *)arg;
9237 	pm_info_t *info = PM_GET_PM_INFO(dip);
9238 	int i;
9239 	/* LINTED */
9240 	int curpwr, ce_level;
9241 
9242 	if (!info)
9243 		return (DDI_WALK_CONTINUE);
9244 
9245 	PMD(PMD_SET, ("%s: %s@%s(%s#%d)\n", pmf, PM_DEVICE(dip)))
9246 	for (i = 0; i < PM_NUMCMPTS(dip); i++) {
9247 		/* LINTED */
9248 		if ((curpwr = PM_CURPOWER(dip, i)) == 0)
9249 			continue;
9250 		/* E_FUNC_SET_NOT_USED */
9251 		ce_level = (pdpchk->pdpc_par_involved == 0) ? CE_PANIC :
9252 		    CE_WARN;
9253 		PMD(PMD_SET, ("%s: %s@%s(%s#%d) is powered off while desc "
9254 		    "%s@%s(%s#%d)[%d] is at %d\n", pmf,
9255 		    PM_DEVICE(pdpchk->pdpc_dip), PM_DEVICE(dip), i, curpwr))
9256 		cmn_err(ce_level, "!device %s@%s(%s#%d) is powered on, "
9257 		    "while its ancestor, %s@%s(%s#%d), is powering off!",
9258 		    PM_DEVICE(dip), PM_DEVICE(pdpchk->pdpc_dip));
9259 	}
9260 	return (DDI_WALK_CONTINUE);
9261 }
9262 #endif
9263 
9264 /*
9265  * Record the fact that one thread is borrowing the lock on a device node.
9266  * Use is restricted to the case where the lending thread will block until
9267  * the borrowing thread (always curthread) completes.
9268  */
9269 void
9270 pm_borrow_lock(kthread_t *lender)
9271 {
9272 	lock_loan_t *prev = &lock_loan_head;
9273 	lock_loan_t *cur = (lock_loan_t *)kmem_zalloc(sizeof (*cur), KM_SLEEP);
9274 
9275 	cur->pmlk_borrower = curthread;
9276 	cur->pmlk_lender = lender;
9277 	mutex_enter(&pm_loan_lock);
9278 	cur->pmlk_next = prev->pmlk_next;
9279 	prev->pmlk_next = cur;
9280 	mutex_exit(&pm_loan_lock);
9281 }
9282 
9283 /*
9284  * Return the borrowed lock.  A thread can borrow only one.
9285  */
9286 void
9287 pm_return_lock(void)
9288 {
9289 	lock_loan_t *cur;
9290 	lock_loan_t *prev = &lock_loan_head;
9291 
9292 	mutex_enter(&pm_loan_lock);
9293 	ASSERT(prev->pmlk_next != NULL);
9294 	for (cur = prev->pmlk_next; cur; prev = cur, cur = cur->pmlk_next)
9295 		if (cur->pmlk_borrower == curthread)
9296 			break;
9297 
9298 	ASSERT(cur != NULL);
9299 	prev->pmlk_next = cur->pmlk_next;
9300 	mutex_exit(&pm_loan_lock);
9301 	kmem_free(cur, sizeof (*cur));
9302 }
9303 
9304 #if defined(__x86)
9305 
9306 #define	CPR_RXR	0x1
9307 #define	CPR_TXR	0x20
9308 #define	CPR_DATAREG	0x3f8
9309 #define	CPR_LSTAT	0x3fd
9310 #define	CPR_INTRCTL	0x3f9
9311 
9312 char
9313 pm_getchar(void)
9314 {
9315 	while ((inb(CPR_LSTAT) & CPR_RXR) != CPR_RXR)
9316 		drv_usecwait(10);
9317 
9318 	return (inb(CPR_DATAREG));
9319 
9320 }
9321 
9322 void
9323 pm_putchar(char c)
9324 {
9325 	while ((inb(CPR_LSTAT) & CPR_TXR) == 0)
9326 		drv_usecwait(10);
9327 
9328 	outb(CPR_DATAREG, c);
9329 }
9330 
9331 void
9332 pm_printf(char *s)
9333 {
9334 	while (*s) {
9335 		pm_putchar(*s++);
9336 	}
9337 }
9338 
9339 #endif
9340 
9341 int
9342 pm_ppm_searchlist(pm_searchargs_t *sp)
9343 {
9344 	power_req_t power_req;
9345 	int result = 0;
9346 	/* LINTED */
9347 	int ret;
9348 
9349 	power_req.request_type = PMR_PPM_SEARCH_LIST;
9350 	power_req.req.ppm_search_list_req.searchlist = sp;
9351 	ASSERT(DEVI(ddi_root_node())->devi_pm_ppm);
9352 	ret = pm_ctlops((dev_info_t *)DEVI(ddi_root_node())->devi_pm_ppm,
9353 	    ddi_root_node(), DDI_CTLOPS_POWER, &power_req, &result);
9354 	PMD(PMD_SX, ("pm_ppm_searchlist returns %d, result %d\n",
9355 	    ret, result))
9356 	return (result);
9357 }
9358