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