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