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