X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/2d21ac55c334faf3a56e5634905ed6987fc787d4..eb6b6ca394357805f2bdba989abae309f718b4d8:/iokit/Kernel/IODMAEventSource.cpp diff --git a/iokit/Kernel/IODMAEventSource.cpp b/iokit/Kernel/IODMAEventSource.cpp index eeaf70c8a..dd4d186f0 100644 --- a/iokit/Kernel/IODMAEventSource.cpp +++ b/iokit/Kernel/IODMAEventSource.cpp @@ -2,7 +2,7 @@ * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -11,10 +11,10 @@ * unlawful or unlicensed copies of an Apple operating system, or to * circumvent, violate, or enable the circumvention or violation of, any * terms of an Apple operating system software license agreement. - * + * * Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -22,7 +22,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ @@ -35,132 +35,227 @@ #define super IOEventSource OSDefineMetaClassAndStructors(IODMAEventSource, IOEventSource); -bool IODMAEventSource::init(OSObject *inOwner, - IOService *inProvider, - Action inCompletion, - Action inNotification, - UInt32 inDMAIndex) +bool +IODMAEventSource::init(OSObject *inOwner, + IOService *inProvider, + Action inCompletion, + Action inNotification, + UInt32 inDMAIndex) +{ + IOReturn result; + + if (!super::init(inOwner)) { + return false; + } + + if (inProvider == NULL) { + return false; + } + + dmaProvider = inProvider; + dmaIndex = 0xFFFFFFFF; + dmaCompletionAction = inCompletion; + dmaNotificationAction = inNotification; + + dmaController = IODMAController::getController(dmaProvider, inDMAIndex); + if (dmaController == NULL) { + return false; + } + dmaController->retain(); + + result = dmaController->initDMAChannel(dmaProvider, this, &dmaIndex, inDMAIndex); + if (result != kIOReturnSuccess) { + return false; + } + + queue_init(&dmaCommandsCompleted); + dmaCommandsCompletedLock = IOSimpleLockAlloc(); + + return true; +} + +void +IODMAEventSource::free() { - IOReturn result; - - if (!super::init(inOwner)) return false; - - if (inProvider == 0) return false; - - dmaProvider = inProvider; - dmaIndex = 0xFFFFFFFF; - dmaCompletionAction = inCompletion; - dmaNotificationAction = inNotification; - - dmaController = IODMAController::getController(dmaProvider, inDMAIndex); - if (dmaController == 0) return false; - dmaController->retain(); - - result = dmaController->initDMAChannel(dmaProvider, this, &dmaIndex, inDMAIndex); - if (result != kIOReturnSuccess) return false; - - queue_init(&dmaCommandsCompleted); - dmaCommandsCompletedLock = IOSimpleLockAlloc(); - - return true; + if (dmaCommandsCompletedLock != NULL) { + IOSimpleLockFree(dmaCommandsCompletedLock); + } + super::free(); } -IODMAEventSource *IODMAEventSource::dmaEventSource(OSObject *inOwner, - IOService *inProvider, - Action inCompletion, - Action inNotification, - UInt32 inDMAIndex) +IODMAEventSource * +IODMAEventSource::dmaEventSource(OSObject *inOwner, + IOService *inProvider, + Action inCompletion, + Action inNotification, + UInt32 inDMAIndex) { - IODMAEventSource *dmaES = new IODMAEventSource; - - if (dmaES && !dmaES->init(inOwner, inProvider, inCompletion, inNotification, inDMAIndex)) { - dmaES->release(); - return 0; - } - - return dmaES; + IODMAEventSource *dmaES = new IODMAEventSource; + + if (dmaES && !dmaES->init(inOwner, inProvider, inCompletion, inNotification, inDMAIndex)) { + dmaES->release(); + return NULL; + } + + return dmaES; } -IOReturn IODMAEventSource::startDMACommand(IODMACommand *dmaCommand, IODirection direction, IOByteCount byteCount, IOByteCount byteOffset) +IOReturn +IODMAEventSource::startDMACommand(IODMACommand *dmaCommand, IODirection direction, IOByteCount byteCount, IOByteCount byteOffset) { - IOReturn result; - - if ((dmaController == 0) || (dmaIndex == 0xFFFFFFFF)) return kIOReturnError; - - if (dmaSynchBusy) return kIOReturnBusy; - - if (dmaCompletionAction == 0) dmaSynchBusy = true; - - result = dmaController->startDMACommand(dmaIndex, dmaCommand, direction, byteCount, byteOffset); - - if (result != kIOReturnSuccess) { - dmaSynchBusy = false; - return result; - } - - while (dmaSynchBusy) sleepGate(&dmaSynchBusy, THREAD_UNINT); - - return kIOReturnSuccess; + IOReturn result; + + if ((dmaController == NULL) || (dmaIndex == 0xFFFFFFFF)) { + return kIOReturnError; + } + + if (dmaSynchBusy) { + return kIOReturnBusy; + } + + if (dmaCompletionAction == NULL) { + dmaSynchBusy = true; + } + + result = dmaController->startDMACommand(dmaIndex, dmaCommand, direction, byteCount, byteOffset); + + if (result != kIOReturnSuccess) { + dmaSynchBusy = false; + return result; + } + + while (dmaSynchBusy) { + sleepGate(&dmaSynchBusy, THREAD_UNINT); + } + + return kIOReturnSuccess; } -IOReturn IODMAEventSource::stopDMACommand(bool flush, mach_timespec_t *timeout) +IOReturn +IODMAEventSource::stopDMACommand(bool flush, uint64_t timeout) { - if ((dmaController == 0) || (dmaIndex == 0xFFFFFFFF)) return kIOReturnError; - - return dmaController->stopDMACommand(dmaIndex, flush, timeout); + if ((dmaController == NULL) || (dmaIndex == 0xFFFFFFFF)) { + return kIOReturnError; + } + + return dmaController->stopDMACommand(dmaIndex, flush, timeout); } -IOReturn IODMAEventSource::queryDMACommand(IODMACommand **dmaCommand, IOByteCount *transferCount, bool waitForIdle) +IOReturn +IODMAEventSource::queryDMACommand(IODMACommand **dmaCommand, IOByteCount *transferCount, bool waitForIdle) { - if ((dmaController == 0) || (dmaIndex == 0xFFFFFFFF)) return kIOReturnError; - - return dmaController->queryDMACommand(dmaIndex, dmaCommand, transferCount, waitForIdle); + if ((dmaController == NULL) || (dmaIndex == 0xFFFFFFFF)) { + return kIOReturnError; + } + + return dmaController->queryDMACommand(dmaIndex, dmaCommand, transferCount, waitForIdle); } +IOByteCount +IODMAEventSource::getFIFODepth(IODirection direction) +{ + if ((dmaController == NULL) || (dmaIndex == 0xFFFFFFFF)) { + return 0; + } + + return dmaController->getFIFODepth(dmaIndex, direction); +} + + +IOReturn +IODMAEventSource::setFIFODepth(IOByteCount depth) +{ + if ((dmaController == NULL) || (dmaIndex == 0xFFFFFFFF)) { + return kIOReturnError; + } + + return dmaController->setFIFODepth(dmaIndex, depth); +} + + +IOByteCount +IODMAEventSource::validFIFODepth(IOByteCount depth, IODirection direction) +{ + if ((dmaController == NULL) || (dmaIndex == 0xFFFFFFFF)) { + return kIOReturnError; + } + + return dmaController->validFIFODepth(dmaIndex, depth, direction); +} + + +IOReturn +IODMAEventSource::setFrameSize(UInt8 byteCount) +{ + if ((dmaController == NULL) || (dmaIndex == 0xFFFFFFFF)) { + return kIOReturnError; + } + + return dmaController->setFrameSize(dmaIndex, byteCount); +} + // protected -bool IODMAEventSource::checkForWork(void) +bool +IODMAEventSource::checkForWork(void) { - IODMACommand *dmaCommand = NULL; - bool work, again; - - IOSimpleLockLock(dmaCommandsCompletedLock); - work = !queue_empty(&dmaCommandsCompleted); - if (work) { - queue_remove_first(&dmaCommandsCompleted, dmaCommand, IODMACommand *, fCommandChain); - again = !queue_empty(&dmaCommandsCompleted); - } else { - again = false; - } - IOSimpleLockUnlock(dmaCommandsCompletedLock); - - if (work) { - (*dmaCompletionAction)(owner, this, dmaCommand, dmaCommand->reserved->fStatus, dmaCommand->reserved->fActualByteCount); - } - - return again; + IODMACommand *dmaCommand = NULL; + bool work, again; + + IOSimpleLockLock(dmaCommandsCompletedLock); + work = !queue_empty(&dmaCommandsCompleted); + if (work) { + queue_remove_first(&dmaCommandsCompleted, dmaCommand, IODMACommand *, fCommandChain); + again = !queue_empty(&dmaCommandsCompleted); + } else { + again = false; + } + IOSimpleLockUnlock(dmaCommandsCompletedLock); + + if (work) { + (*dmaCompletionAction)(owner, this, dmaCommand, dmaCommand->reserved->fStatus, dmaCommand->reserved->fActualByteCount, dmaCommand->reserved->fTimeStamp); + } + + return again; +} + +void +IODMAEventSource::completeDMACommand(IODMACommand *dmaCommand) +{ + if (dmaCompletionAction != NULL) { + IOSimpleLockLock(dmaCommandsCompletedLock); + queue_enter(&dmaCommandsCompleted, dmaCommand, IODMACommand *, fCommandChain); + IOSimpleLockUnlock(dmaCommandsCompletedLock); + + signalWorkAvailable(); + } else { + dmaSynchBusy = false; + wakeupGate(&dmaSynchBusy, true); + } +} + +void +IODMAEventSource::notifyDMACommand(IODMACommand *dmaCommand, IOReturn status, IOByteCount actualByteCount, AbsoluteTime timeStamp) +{ + dmaCommand->reserved->fStatus = status; + dmaCommand->reserved->fActualByteCount = actualByteCount; + dmaCommand->reserved->fTimeStamp = timeStamp; + + if (dmaNotificationAction != NULL) { + (*dmaNotificationAction)(owner, this, dmaCommand, status, actualByteCount, timeStamp); + } } -void IODMAEventSource::completeDMACommand(IODMACommand *dmaCommand) +IOReturn +IODMAEventSource::setDMAConfig(UInt32 newReqIndex) { - if (dmaCompletionAction != 0) { - IOSimpleLockLock(dmaCommandsCompletedLock); - queue_enter(&dmaCommandsCompleted, dmaCommand, IODMACommand *, fCommandChain); - IOSimpleLockUnlock(dmaCommandsCompletedLock); - - signalWorkAvailable(); - } else { - dmaSynchBusy = false; - wakeupGate(&dmaSynchBusy, true); - } + return dmaController->setDMAConfig(dmaIndex, dmaProvider, newReqIndex); } -void IODMAEventSource::notifyDMACommand(IODMACommand *dmaCommand, IOReturn status, IOByteCount actualByteCount) +bool +IODMAEventSource::validDMAConfig(UInt32 newReqIndex) { - dmaCommand->reserved->fStatus = status; - dmaCommand->reserved->fActualByteCount = actualByteCount; - - if (dmaNotificationAction != 0) (*dmaNotificationAction)(owner, this, dmaCommand, status, actualByteCount); + return dmaController->validDMAConfig(dmaIndex, dmaProvider, newReqIndex); }