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