- // Check if entry found
- if (kNoReplace != replace) {
- entries[replace].fService = 0; // Null the entry
- ml_set_maxbusdelay(ns);
+static IOReturn
+setLatencyHandler(UInt32 delayType, IOService * target, bool enable)
+{
+ IOReturn result = kIOReturnNotFound;
+ OSArray * array;
+ unsigned int idx;
+
+ IORecursiveLockLock(sCpuDelayLock);
+
+ do
+ {
+ if (enable && !sCpuLatencyHandlers[delayType])
+ sCpuLatencyHandlers[delayType] = OSArray::withCapacity(4);
+ array = sCpuLatencyHandlers[delayType];
+ if (!array)
+ break;
+ idx = array->getNextIndexOfObject(target, 0);
+ if (!enable)
+ {
+ if (-1U != idx)
+ {
+ array->removeObject(idx);
+ result = kIOReturnSuccess;
+ }
+ }
+ else
+ {
+ if (-1U != idx) {
+ result = kIOReturnExclusiveAccess;
+ break;
+ }
+ array->setObject(target);
+
+ UInt count = sCpuDelayData->getLength() / sizeof(CpuDelayEntry);
+ CpuDelayEntry *entries = (CpuDelayEntry *) sCpuDelayData->getBytesNoCopy();
+ UInt32 ns = -1U; // Set to max unsigned, i.e. no restriction
+ IOService * holder = NULL;
+
+ for (UInt i = 0; i < count; i++) {
+ if (entries[i].fService
+ && (delayType == entries[i].fDelayType)
+ && (entries[i].fMaxDelay < ns)) {
+ ns = entries[i].fMaxDelay;
+ holder = entries[i].fService;
+ }
+ }
+ target->callPlatformFunction(sCPULatencyFunctionName[delayType], false,
+ (void *) (uintptr_t) ns, holder,
+ NULL, NULL);
+ result = kIOReturnSuccess;