-bool IOService::actionPMWorkQueueInvoke( IOPMRequest * request, IOPMWorkQueue * queue )
-{
- bool done = false;
- int loop = 0;
-
- assert(request && queue);
-
- while (isPMBlocked(request, loop++) == false)
- {
- PM_LOG1("[W %02x] %p [%p %s] state %d\n",
- request->getType(), OBFUSCATE(request),
- OBFUSCATE(this), getName(), fMachineState);
-
- gIOPMRequest = request;
- gIOPMWorkInvokeCount++;
-
- // Every PM machine states must be handled in one of the cases below.
-
- switch ( fMachineState )
- {
- case kIOPM_Finished:
- start_watchdog_timer();
-
- executePMRequest( request );
- break;
-
- case kIOPM_OurChangeTellClientsPowerDown:
- // Root domain might self cancel due to assertions.
- if (IS_ROOT_DOMAIN)
- {
- bool cancel = (bool) fDoNotPowerDown;
- getPMRootDomain()->askChangeDownDone(
- &fHeadNoteChangeFlags, &cancel);
- fDoNotPowerDown = cancel;
- }
-
- // askChangeDown() done, was it vetoed?
- if (!fDoNotPowerDown)
- {
- // no, we can continue
- OurChangeTellClientsPowerDown();
- }
- else
- {
- OUR_PMLog(kPMLogIdleCancel, (uintptr_t) this, fMachineState);
- PM_ERROR("%s: idle cancel, state %u\n", fName, fMachineState);
- if (IS_ROOT_DOMAIN) {
- // RootDomain already sent "WillSleep" to its clients
- tellChangeUp(fCurrentPowerState);
- }
- else {
- tellNoChangeDown(fHeadNotePowerState);
- }
- // mark the change note un-actioned
- fHeadNoteChangeFlags |= kIOPMNotDone;
- // and we're done
- OurChangeFinish();
- }
- break;
-
- case kIOPM_OurChangeTellUserPMPolicyPowerDown:
- // PMRD: tellChangeDown/kNotifyApps done, was it cancelled?
- if (fDoNotPowerDown)
- {
- OUR_PMLog(kPMLogIdleCancel, (uintptr_t) this, fMachineState);
- PM_ERROR("%s: idle cancel, state %u\n", fName, fMachineState);
- if (IS_ROOT_DOMAIN) {
- // RootDomain already sent "WillSleep" to its clients
- tellChangeUp(fCurrentPowerState);
- }
- else {
- tellNoChangeDown(fHeadNotePowerState);
- }
- // mark the change note un-actioned
- fHeadNoteChangeFlags |= kIOPMNotDone;
- // and we're done
- OurChangeFinish();
- }
- else
- OurChangeTellUserPMPolicyPowerDown();
- break;
-
- case kIOPM_OurChangeTellPriorityClientsPowerDown:
- // PMRD: LastCallBeforeSleep notify done
- // Non-PMRD: tellChangeDown/kNotifyApps done
- if (fDoNotPowerDown)
- {
- OUR_PMLog(kPMLogIdleCancel, (uintptr_t) this, fMachineState);
- PM_ERROR("%s: idle revert, state %u\n", fName, fMachineState);
- // no, tell clients we're back in the old state
- tellChangeUp(fCurrentPowerState);
- // mark the change note un-actioned
- fHeadNoteChangeFlags |= kIOPMNotDone;
- // and we're done
- OurChangeFinish();
- }
- else
- {
- // yes, we can continue
- OurChangeTellPriorityClientsPowerDown();
- }
- break;
-
- case kIOPM_OurChangeNotifyInterestedDriversWillChange:
- OurChangeNotifyInterestedDriversWillChange();
- break;
-
- case kIOPM_OurChangeSetPowerState:
- OurChangeSetPowerState();
- break;
-
- case kIOPM_OurChangeWaitForPowerSettle:
- OurChangeWaitForPowerSettle();
- break;
-
- case kIOPM_OurChangeNotifyInterestedDriversDidChange:
- OurChangeNotifyInterestedDriversDidChange();
- break;
-
- case kIOPM_OurChangeTellCapabilityDidChange:
- OurChangeTellCapabilityDidChange();
- break;
-
- case kIOPM_OurChangeFinish:
- OurChangeFinish();
- break;
-
- case kIOPM_ParentChangeTellPriorityClientsPowerDown:
- ParentChangeTellPriorityClientsPowerDown();
- break;
-
- case kIOPM_ParentChangeNotifyInterestedDriversWillChange:
- ParentChangeNotifyInterestedDriversWillChange();
- break;
-
- case kIOPM_ParentChangeSetPowerState:
- ParentChangeSetPowerState();
- break;
-
- case kIOPM_ParentChangeWaitForPowerSettle:
- ParentChangeWaitForPowerSettle();
- break;
-
- case kIOPM_ParentChangeNotifyInterestedDriversDidChange:
- ParentChangeNotifyInterestedDriversDidChange();
- break;
-
- case kIOPM_ParentChangeTellCapabilityDidChange:
- ParentChangeTellCapabilityDidChange();
- break;
-
- case kIOPM_ParentChangeAcknowledgePowerChange:
- ParentChangeAcknowledgePowerChange();
- break;
-
- case kIOPM_DriverThreadCallDone:
- switch (fDriverCallReason)
- {
- case kDriverCallInformPreChange:
- case kDriverCallInformPostChange:
- notifyInterestedDriversDone();
- break;
- case kDriverCallSetPowerState:
- notifyControllingDriverDone();
- break;
- case kRootDomainInformPreChange:
- notifyRootDomainDone();
- break;
- default:
- panic("%s: bad call reason %x",
- getName(), fDriverCallReason);
- }
- break;
-
- case kIOPM_NotifyChildrenOrdered:
- notifyChildrenOrdered();
- break;
-
- case kIOPM_NotifyChildrenDelayed:
- notifyChildrenDelayed();
- break;
-
- case kIOPM_NotifyChildrenStart:
- // pop notifyAll() state saved by notifyInterestedDriversDone()
- MS_POP();
- notifyRootDomain();
- break;
-
- case kIOPM_SyncTellClientsPowerDown:
- // Root domain might self cancel due to assertions.
- if (IS_ROOT_DOMAIN)
- {
- bool cancel = (bool) fDoNotPowerDown;
- getPMRootDomain()->askChangeDownDone(
- &fHeadNoteChangeFlags, &cancel);
- fDoNotPowerDown = cancel;
- }
- if (!fDoNotPowerDown)
- {
- fMachineState = kIOPM_SyncTellPriorityClientsPowerDown;
- fOutOfBandParameter = kNotifyApps;
- tellChangeDown(fHeadNotePowerState);
- }
- else
- {
- // Cancelled by IOPMrootDomain::askChangeDownDone() or
- // askChangeDown/kNotifyApps
- OUR_PMLog(kPMLogIdleCancel, (uintptr_t) this, fMachineState);
- PM_ERROR("%s: idle cancel, state %u\n", fName, fMachineState);
- tellNoChangeDown(fHeadNotePowerState);
- fHeadNoteChangeFlags |= kIOPMNotDone;
- OurChangeFinish();
- }
- break;
-
- case kIOPM_SyncTellPriorityClientsPowerDown:
- // PMRD: tellChangeDown/kNotifyApps done, was it cancelled?
- if (!fDoNotPowerDown)
- {
- fMachineState = kIOPM_SyncNotifyWillChange;
- fOutOfBandParameter = kNotifyPriority;
- tellChangeDown(fHeadNotePowerState);
- }
- else
- {
- OUR_PMLog(kPMLogIdleCancel, (uintptr_t) this, fMachineState);
- PM_ERROR("%s: idle revert, state %u\n", fName, fMachineState);
- tellChangeUp(fCurrentPowerState);
- fHeadNoteChangeFlags |= kIOPMNotDone;
- OurChangeFinish();
- }
- break;
-
- case kIOPM_SyncNotifyWillChange:
- if (kIOPMSyncNoChildNotify & fHeadNoteChangeFlags)
- {
- fMachineState = kIOPM_SyncFinish;
- continue;
- }
- fMachineState = kIOPM_SyncNotifyDidChange;
- fDriverCallReason = kDriverCallInformPreChange;
- notifyChildren();
- break;
-
- case kIOPM_SyncNotifyDidChange:
- fIsPreChange = false;
-
- if (fHeadNoteChangeFlags & kIOPMParentInitiated)
- {
- fMachineState = kIOPM_SyncFinish;
- }
- else
- {
- assert(IS_ROOT_DOMAIN);
- fMachineState = kIOPM_SyncTellCapabilityDidChange;
- }
-
- fDriverCallReason = kDriverCallInformPostChange;
- notifyChildren();
- break;
-
- case kIOPM_SyncTellCapabilityDidChange:
- tellSystemCapabilityChange( kIOPM_SyncFinish );
- break;
-
- case kIOPM_SyncFinish:
- if (fHeadNoteChangeFlags & kIOPMParentInitiated)
- ParentChangeAcknowledgePowerChange();
- else
- OurChangeFinish();
- break;
-
- case kIOPM_TellCapabilityChangeDone:
- if (fIsPreChange)
- {
- if (fOutOfBandParameter == kNotifyCapabilityChangePriority)
- {
- MS_POP(); // tellSystemCapabilityChange()
- continue;
- }
- fOutOfBandParameter = kNotifyCapabilityChangePriority;
- }
- else
- {
- if (fOutOfBandParameter == kNotifyCapabilityChangeApps)
- {
- MS_POP(); // tellSystemCapabilityChange()
- continue;
- }
- fOutOfBandParameter = kNotifyCapabilityChangeApps;
- }
- tellClientsWithResponse( fOutOfBandMessage );
- break;
-
- default:
- panic("PMWorkQueueInvoke: unknown machine state %x",
- fMachineState);
- }
-
- gIOPMRequest = 0;
-
- if (fMachineState == kIOPM_Finished)
- {
- stop_watchdog_timer();
- done = true;
- break;
- }
- }
-
- return done;
+bool
+IOService::actionPMWorkQueueInvoke( IOPMRequest * request, IOPMWorkQueue * queue )
+{
+ bool done = false;
+ int loop = 0;
+
+ assert(request && queue);
+
+ while (isPMBlocked(request, loop++) == false) {
+ PM_LOG1("[W %02x] %p [%p %s] state %d\n",
+ request->getType(), OBFUSCATE(request),
+ OBFUSCATE(this), getName(), fMachineState);
+
+ gIOPMRequest = request;
+ gIOPMWorkInvokeCount++;
+
+ // Every PM machine states must be handled in one of the cases below.
+
+ switch (fMachineState) {
+ case kIOPM_Finished:
+ start_watchdog_timer();
+
+ executePMRequest( request );
+ break;
+
+ case kIOPM_OurChangeTellClientsPowerDown:
+ // Root domain might self cancel due to assertions.
+ if (IS_ROOT_DOMAIN) {
+ bool cancel = (bool) fDoNotPowerDown;
+ getPMRootDomain()->askChangeDownDone(
+ &fHeadNoteChangeFlags, &cancel);
+ fDoNotPowerDown = cancel;
+ }
+
+ // askChangeDown() done, was it vetoed?
+ if (!fDoNotPowerDown) {
+ // no, we can continue
+ OurChangeTellClientsPowerDown();
+ } else {
+ OUR_PMLog(kPMLogIdleCancel, (uintptr_t) this, fMachineState);
+ PM_ERROR("%s: idle cancel, state %u\n", fName, fMachineState);
+ if (IS_ROOT_DOMAIN) {
+ // RootDomain already sent "WillSleep" to its clients
+ tellChangeUp(fCurrentPowerState);
+ } else {
+ tellNoChangeDown(fHeadNotePowerState);
+ }
+ // mark the change note un-actioned
+ fHeadNoteChangeFlags |= kIOPMNotDone;
+ // and we're done
+ OurChangeFinish();
+ }
+ break;
+
+ case kIOPM_OurChangeTellUserPMPolicyPowerDown:
+ // PMRD: tellChangeDown/kNotifyApps done, was it cancelled?
+ if (fDoNotPowerDown) {
+ OUR_PMLog(kPMLogIdleCancel, (uintptr_t) this, fMachineState);
+ PM_ERROR("%s: idle cancel, state %u\n", fName, fMachineState);
+ if (IS_ROOT_DOMAIN) {
+ // RootDomain already sent "WillSleep" to its clients
+ tellChangeUp(fCurrentPowerState);
+ } else {
+ tellNoChangeDown(fHeadNotePowerState);
+ }
+ // mark the change note un-actioned
+ fHeadNoteChangeFlags |= kIOPMNotDone;
+ // and we're done
+ OurChangeFinish();
+ } else {
+ OurChangeTellUserPMPolicyPowerDown();
+ }
+ break;
+
+ case kIOPM_OurChangeTellPriorityClientsPowerDown:
+ // PMRD: LastCallBeforeSleep notify done
+ // Non-PMRD: tellChangeDown/kNotifyApps done
+ if (fDoNotPowerDown) {
+ OUR_PMLog(kPMLogIdleCancel, (uintptr_t) this, fMachineState);
+ PM_ERROR("%s: idle revert, state %u\n", fName, fMachineState);
+ // no, tell clients we're back in the old state
+ tellChangeUp(fCurrentPowerState);
+ // mark the change note un-actioned
+ fHeadNoteChangeFlags |= kIOPMNotDone;
+ // and we're done
+ OurChangeFinish();
+ } else {
+ // yes, we can continue
+ OurChangeTellPriorityClientsPowerDown();
+ }
+ break;
+
+ case kIOPM_OurChangeNotifyInterestedDriversWillChange:
+ OurChangeNotifyInterestedDriversWillChange();
+ break;
+
+ case kIOPM_OurChangeSetPowerState:
+ OurChangeSetPowerState();
+ break;
+
+ case kIOPM_OurChangeWaitForPowerSettle:
+ OurChangeWaitForPowerSettle();
+ break;
+
+ case kIOPM_OurChangeNotifyInterestedDriversDidChange:
+ OurChangeNotifyInterestedDriversDidChange();
+ break;
+
+ case kIOPM_OurChangeTellCapabilityDidChange:
+ OurChangeTellCapabilityDidChange();
+ break;
+
+ case kIOPM_OurChangeFinish:
+ OurChangeFinish();
+ break;
+
+ case kIOPM_ParentChangeTellPriorityClientsPowerDown:
+ ParentChangeTellPriorityClientsPowerDown();
+ break;
+
+ case kIOPM_ParentChangeNotifyInterestedDriversWillChange:
+ ParentChangeNotifyInterestedDriversWillChange();
+ break;
+
+ case kIOPM_ParentChangeSetPowerState:
+ ParentChangeSetPowerState();
+ break;
+
+ case kIOPM_ParentChangeWaitForPowerSettle:
+ ParentChangeWaitForPowerSettle();
+ break;
+
+ case kIOPM_ParentChangeNotifyInterestedDriversDidChange:
+ ParentChangeNotifyInterestedDriversDidChange();
+ break;
+
+ case kIOPM_ParentChangeTellCapabilityDidChange:
+ ParentChangeTellCapabilityDidChange();
+ break;
+
+ case kIOPM_ParentChangeAcknowledgePowerChange:
+ ParentChangeAcknowledgePowerChange();
+ break;
+
+ case kIOPM_DriverThreadCallDone:
+ switch (fDriverCallReason) {
+ case kDriverCallInformPreChange:
+ case kDriverCallInformPostChange:
+ notifyInterestedDriversDone();
+ break;
+ case kDriverCallSetPowerState:
+ notifyControllingDriverDone();
+ break;
+ case kRootDomainInformPreChange:
+ notifyRootDomainDone();
+ break;
+ default:
+ panic("%s: bad call reason %x",
+ getName(), fDriverCallReason);
+ }
+ break;
+
+ case kIOPM_NotifyChildrenOrdered:
+ notifyChildrenOrdered();
+ break;
+
+ case kIOPM_NotifyChildrenDelayed:
+ notifyChildrenDelayed();
+ break;
+
+ case kIOPM_NotifyChildrenStart:
+ // pop notifyAll() state saved by notifyInterestedDriversDone()
+ MS_POP();
+ notifyRootDomain();
+ break;
+
+ case kIOPM_SyncTellClientsPowerDown:
+ // Root domain might self cancel due to assertions.
+ if (IS_ROOT_DOMAIN) {
+ bool cancel = (bool) fDoNotPowerDown;
+ getPMRootDomain()->askChangeDownDone(
+ &fHeadNoteChangeFlags, &cancel);
+ fDoNotPowerDown = cancel;
+ }
+ if (!fDoNotPowerDown) {
+ fMachineState = kIOPM_SyncTellPriorityClientsPowerDown;
+ fOutOfBandParameter = kNotifyApps;
+ tellChangeDown(fHeadNotePowerState);
+ } else {
+ // Cancelled by IOPMrootDomain::askChangeDownDone() or
+ // askChangeDown/kNotifyApps
+ OUR_PMLog(kPMLogIdleCancel, (uintptr_t) this, fMachineState);
+ PM_ERROR("%s: idle cancel, state %u\n", fName, fMachineState);
+ tellNoChangeDown(fHeadNotePowerState);
+ fHeadNoteChangeFlags |= kIOPMNotDone;
+ OurChangeFinish();
+ }
+ break;
+
+ case kIOPM_SyncTellPriorityClientsPowerDown:
+ // PMRD: tellChangeDown/kNotifyApps done, was it cancelled?
+ if (!fDoNotPowerDown) {
+ fMachineState = kIOPM_SyncNotifyWillChange;
+ fOutOfBandParameter = kNotifyPriority;
+ tellChangeDown(fHeadNotePowerState);
+ } else {
+ OUR_PMLog(kPMLogIdleCancel, (uintptr_t) this, fMachineState);
+ PM_ERROR("%s: idle revert, state %u\n", fName, fMachineState);
+ tellChangeUp(fCurrentPowerState);
+ fHeadNoteChangeFlags |= kIOPMNotDone;
+ OurChangeFinish();
+ }
+ break;
+
+ case kIOPM_SyncNotifyWillChange:
+ if (kIOPMSyncNoChildNotify & fHeadNoteChangeFlags) {
+ fMachineState = kIOPM_SyncFinish;
+ continue;
+ }
+ fMachineState = kIOPM_SyncNotifyDidChange;
+ fDriverCallReason = kDriverCallInformPreChange;
+ notifyChildren();
+ break;
+
+ case kIOPM_SyncNotifyDidChange:
+ fIsPreChange = false;
+
+ if (fHeadNoteChangeFlags & kIOPMParentInitiated) {
+ fMachineState = kIOPM_SyncFinish;
+ } else {
+ assert(IS_ROOT_DOMAIN);
+ fMachineState = kIOPM_SyncTellCapabilityDidChange;
+ }
+
+ fDriverCallReason = kDriverCallInformPostChange;
+ notifyChildren();
+ break;
+
+ case kIOPM_SyncTellCapabilityDidChange:
+ tellSystemCapabilityChange( kIOPM_SyncFinish );
+ break;
+
+ case kIOPM_SyncFinish:
+ if (fHeadNoteChangeFlags & kIOPMParentInitiated) {
+ ParentChangeAcknowledgePowerChange();
+ } else {
+ OurChangeFinish();
+ }
+ break;
+
+ case kIOPM_TellCapabilityChangeDone:
+ if (fIsPreChange) {
+ if (fOutOfBandParameter == kNotifyCapabilityChangePriority) {
+ MS_POP(); // tellSystemCapabilityChange()
+ continue;
+ }
+ fOutOfBandParameter = kNotifyCapabilityChangePriority;
+ } else {
+ if (fOutOfBandParameter == kNotifyCapabilityChangeApps) {
+ MS_POP(); // tellSystemCapabilityChange()
+ continue;
+ }
+ fOutOfBandParameter = kNotifyCapabilityChangeApps;
+ }
+ tellClientsWithResponse( fOutOfBandMessage );
+ break;
+
+ default:
+ panic("PMWorkQueueInvoke: unknown machine state %x",
+ fMachineState);
+ }
+
+ gIOPMRequest = NULL;
+
+ if (fMachineState == kIOPM_Finished) {
+ stop_watchdog_timer();
+ done = true;
+ break;
+ }
+ }
+
+ return done;