IOReturn AppleUSBCDC::setPropertiesAction( OSObject *owner, void *arg1, void *arg2, void *arg3, void *arg4 ) { IOReturn result = kIOReturnBadArgument; if ( owner != NULL ) { AppleUSBCDC *me = OSDynamicCast( AppleUSBCDC, owner ); if ( me != NULL ) { result = me->setPropertiesWL( (OSObject *)arg1 ); } } return result; }
/****************************************************************************** * ACPIDebug::init ******************************************************************************/ bool ACPIDebug::init(OSDictionary *dict) { DEBUG_LOG("ACPIDebug::init: Initializing\n"); bool result = super::init(dict); m_pDevice = NULL; m_pWorkLoop = NULL; m_pTimer = NULL; m_pCmdGate = NULL; m_pLock = NULL; m_nPollingInterval = 100; if (OSNumber* num = OSDynamicCast(OSNumber, dict->getObject("PollingInterval"))) { m_nPollingInterval = (int)num->unsigned32BitValue(); //setProperty("PollingInterval", _wakedelay, 32); } return result; }
IOReturn IT87x::callPlatformFunction(const OSSymbol *functionName, bool waitForFunction, void *param1, void *param2, void *param3, void *param4 ) { if (functionName->isEqualTo(kFakeSMCGetValueCallback)) { const char* name = (const char*)param1; void * data = param2; //UInt32 size = (UInt64)param3; if (name && data) if (SuperIOSensor * sensor = getSensor(name)) { UInt16 value = sensor->getValue(); bcopy(&value, data, 2); return kIOReturnSuccess; } return kIOReturnBadArgument; } if (functionName->isEqualTo(kFakeSMCSetValueCallback)) { const char* name = (const char*)param1; void * data = param2; //UInt32 size = (UInt64)param3; if (name && data) if (IT87xSensor *sensor = OSDynamicCast(IT87xSensor, getSensor(name))) { UInt16 value; bcopy(data, &value, 2); sensor->setValue(value); return kIOReturnSuccess; } return kIOReturnBadArgument; } return super::callPlatformFunction(functionName, waitForFunction, param1, param2, param3, param4); }
IOReturn X3100monitor::callPlatformFunction(const OSSymbol *functionName, bool waitForFunction, void *param1, void *param2, void *param3, void *param4 ) { UInt16 t; if (functionName->isEqualTo(kFakeSMCGetValueCallback)) { const char* name = (const char*)param1; void* data = param2; if (name && data) { if (OSNumber *number = OSDynamicCast(OSNumber, sensors->getObject(name))) { UInt32 index = number->unsigned16BitValue(); if (index != numCard) { return kIOReturnBadArgument; } } short value; if (mmio_base) { OUTVID(TIC1, 3); // if ((INVID16(TSC1) & (1<<15)) && !(INVID16(TSC1) & (1<<8)))//enabled and ready for (int i=0; i<1000; i++) { //attempts to ready if (INVID16(TSS1) & (1<<10)) //valid? break; IOSleep(10); } value = INVID8(TR1); } t = 140 - value; bcopy(&t, data, 2); return kIOReturnSuccess; } //DebugLog("bad argument key name or data"); return kIOReturnBadArgument; } return super::callPlatformFunction(functionName, waitForFunction, param1, param2, param3, param4); }
bool NullEthernet::start(IOService *provider) { DebugLog("start() ===>\n"); if (!super::start(provider)) { AlwaysLog("NullEthernet: IOEthernetController::start failed.\n"); return false; } // retain provider... m_pProvider = OSDynamicCast(IOService, provider); if (!m_pProvider) { AlwaysLog("NullEthernet: No provider.\n"); return false; } m_pProvider->retain(); // initialize MAC address: priority is from DSDT, then provider, last is default if (!initMACfromACPI() && !initMACfromProvider()) { AlwaysLog("Using default MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", m_rgMacAddr[0], m_rgMacAddr[1], m_rgMacAddr[2], m_rgMacAddr[3], m_rgMacAddr[4], m_rgMacAddr[5]); } if (!attachInterface(reinterpret_cast<IONetworkInterface**>(&m_netif))) { AlwaysLog("NullEthernet: attachInterface() failed.\n"); goto error1; } AlwaysLog("NullEthernet: NullEthernet v1.0.0 starting.\n"); done: DebugLog("start() <===\n"); return true; error1: OSSafeReleaseNULL(m_pProvider); return false; }
bool CLASS::init( IOService * provider, OSDictionary * properties, IORegistryEntry * dtEntry ) { if ( dtEntry ) { if ( super::init( dtEntry, gIODTPlane ) == false || mergeProperties( properties ) == false ) return false; } else { if ( super::init( properties ) == false ) return false; } fProvider = OSDynamicCast(AppleOnboardPCATARoot, provider); if (fProvider == 0) return false; // Call platform to register the interrupt assigned to each ATA // channel. For PCI interrupts (native mode), each channel will // share the same interrupt vector assigned to the PCI device. // Legacy mode channels will attempt to register IRQ 14 and 15. UInt32 vector = getInterruptVector(); if (provider->callPlatformFunction( "SetDeviceInterrupts", /* waitForFunction */ false, /* nub */ this, /* vectors */ (void *) &vector, /* vectorCount */ (void *) 1, /* exclusive */ (void *) false ) != kIOReturnSuccess) { return false; } setLocation( getChannelNumber() ? "1" : "0" ); return true; }
bool ListHookedKeyboard::Item::restoreEventAction(void) { if (! device_) return false; IOHIKeyboard* kbd = OSDynamicCast(IOHIKeyboard, device_); if (! kbd) return false; bool result = false; // ---------------------------------------- { KeyboardEventCallback callback = reinterpret_cast<KeyboardEventCallback>(kbd->_keyboardEventAction); if (callback == EventInputQueue::push_KeyboardEventCallback) { IOLOG_DEBUG("HookedKeyboard::restoreEventAction (KeyboardEventCallback) device_:%p (%p -> %p)\n", device_, callback, orig_keyboardEventAction_); kbd->_keyboardEventAction = reinterpret_cast<KeyboardEventAction>(orig_keyboardEventAction_); result = true; } } { UpdateEventFlagsCallback callback = reinterpret_cast<UpdateEventFlagsCallback>(kbd->_updateEventFlagsAction); if (callback == EventInputQueue::push_UpdateEventFlagsCallback) { IOLOG_DEBUG("HookedKeyboard::restoreEventAction (UpdateEventFlagsCallback) device_:%p (%p -> %p)\n", device_, callback, orig_updateEventFlagsAction_); kbd->_updateEventFlagsAction = reinterpret_cast<UpdateEventFlagsAction>(orig_updateEventFlagsAction_); result = true; } } orig_keyboardEventAction_ = NULL; orig_keyboardEventTarget_ = NULL; orig_updateEventFlagsAction_ = NULL; orig_updateEventFlagsTarget_ = NULL; return result; }
bool IOHIDDeviceShim::handleStart( IOService * provider ) { IOService *device = 0; if (!super::handleStart(provider)) return false; if ((_hiDevice = OSDynamicCast(IOHIDevice, provider))) { if (_hiDevice->getProperty(kIOHIDVirtualHIDevice) == kOSBooleanTrue) return false; device = _hiDevice; do { if ((_device = (IOService *)device->metaCast("IOHIDDevice"))) { break; } if ((_device = (IOService *)device->metaCast("IOUSBDevice")) || (_device = (IOService *)device->metaCast("IOUSBInterface"))) { _transport = kIOHIDTransportUSB; break; } if (_device = (IOService *)device->metaCast("IOADBDevice")) { _transport = kIOHIDTransportADB; break; } if (_device = (IOService *)device->metaCast("ApplePS2Controller")) { _transport = kIOHIDTransportPS2; break; } } while (device = device->getProvider()); } return true; }
bool ListHookedPointing::Item::restoreEventAction(void) { if (! device_) return false; IOHIPointing* pointing = OSDynamicCast(IOHIPointing, device_); if (! pointing) return false; bool result = false; // ---------------------------------------- { RelativePointerEventCallback callback = reinterpret_cast<RelativePointerEventCallback>(pointing->_relativePointerEventAction); if (callback == EventInputQueue::push_RelativePointerEventCallback) { IOLOG_DEBUG("HookedPointing::restoreEventAction (RelativePointerEventCallback) device_:%p\n", device_); pointing->_relativePointerEventAction = reinterpret_cast<RelativePointerEventAction>(orig_relativePointerEventAction_); result = true; } } { ScrollWheelEventCallback callback = reinterpret_cast<ScrollWheelEventCallback>(pointing->_scrollWheelEventAction); if (callback == EventInputQueue::push_ScrollWheelEventCallback) { IOLOG_DEBUG("HookedPointing::restoreEventAction (ScrollWheelEventCallback) device_:%p\n", device_); pointing->_scrollWheelEventAction = reinterpret_cast<ScrollWheelEventAction>(orig_scrollWheelEventAction_); result = true; } } orig_relativePointerEventAction_ = NULL; orig_scrollWheelEventAction_ = NULL; orig_relativePointerEventTarget_ = NULL; orig_scrollWheelEventTarget_ = NULL; return result; }
bool ListHookedConsumer::Item::replaceEventAction(void) { if (! device_) return false; IOHIKeyboard* kbd = OSDynamicCast(IOHIKeyboard, device_); if (! kbd) return false; KeyboardSpecialEventCallback callback = reinterpret_cast<KeyboardSpecialEventCallback>(kbd->_keyboardSpecialEventAction); if (callback == EventInputQueue::push_KeyboardSpecialEventCallback) return false; // ------------------------------------------------------------ IOLOG_DEBUG("HookedConsumer::replaceEventAction device_:%p\n", device_); orig_keyboardSpecialEventAction_ = callback; orig_keyboardSpecialEventTarget_ = kbd->_keyboardSpecialEventTarget; kbd->_keyboardSpecialEventAction = reinterpret_cast<KeyboardSpecialEventAction>(EventInputQueue::push_KeyboardSpecialEventCallback); return true; }
void EventInputQueue::push_UpdateEventFlagsCallback(OSObject* target, unsigned flags, OSObject* sender, void* refcon) { GlobalLock::ScopedLock lk; if (! lk) return; Params_UpdateEventFlagsCallback::log(true, Flags(flags)); // ------------------------------------------------------------ // update device priority by calling ListHookedKeyboard::instance().get(kbd). IOHIKeyboard* device = OSDynamicCast(IOHIKeyboard, sender); if (! device) return; ListHookedKeyboard::Item* item = static_cast<ListHookedKeyboard::Item*>(ListHookedKeyboard::instance().get(device)); if (! item) return; // Don't push_back for UpdateEventFlagsCallback. }
void IOI2CDevice::performFunctionsWithFlags( UInt32 flags) { UInt32 count, i; IOPlatformFunction *func; if (0 == fPlatformFuncArray) return; // Execute any functions flagged as "on sleep" count = fPlatformFuncArray->getCount(); for (i = 0; i < count; i++) { if (func = OSDynamicCast(IOPlatformFunction, fPlatformFuncArray->getObject(i))) { if (func->getCommandFlags() & flags) performFunction(func); } } }
void ListHookedKeyboard::Item::apply(const Params_UpdateEventFlagsCallback& params) { // ------------------------------------------------------------ UpdateEventFlagsCallback callback = orig_updateEventFlagsAction_; if (!callback) return; OSObject* target = orig_updateEventFlagsTarget_; if (!target) return; OSObject* sender = OSDynamicCast(OSObject, device_); if (!sender) return; OSObject* refcon = nullptr; Params_UpdateEventFlagsCallback::log(false, params.flags); { // We need to unlock the global lock while we are calling the callback function. // For more information, See ListHookedKeyboard::Item::apply(const Params_KeyboardEventCallBack& params) GlobalLock::ScopedUnlock lk; callback(target, params.flags.get(), sender, refcon); } }
bool HookedKeyboard::restoreEventAction(void) { if (! device_) return false; IOHIKeyboard* kbd = OSDynamicCast(IOHIKeyboard, device_); if (! kbd) return false; KeyboardEventCallback callback = reinterpret_cast<KeyboardEventCallback>(kbd->_keyboardEventAction); if (callback != hook_KeyboardEventCallback) return false; // ---------------------------------------- IOLog("KeyRemap4MacBook HookedKeyboard::restoreEventAction (device_ = 0x%p)\n", device_); kbd->_keyboardEventAction = reinterpret_cast<KeyboardEventAction>(orig_keyboardEventAction_); orig_keyboardEventAction_ = NULL; orig_keyboardEventTarget_ = NULL; return true; }
bool com_ximeta_driver_NDASPhysicalUnitDevice::sendNDASFamilyIOMessage(UInt32 type, void * argument, vm_size_t argSize) { if (!fDevice) { return false; } com_ximeta_driver_NDASBusEnumerator *bus; bus = OSDynamicCast(com_ximeta_driver_NDASBusEnumerator, fDevice->getParentEntry(gIOServicePlane)); if (NULL == bus) { DbgIOLog(DEBUG_MASK_NDAS_INFO, ("sendNDASFamilyIIOMessage: Can't Find bus.\n")); return false; } else { bus->messageClients(type, argument, argSize); return true; } }
bool com_ximeta_driver_NDASPhysicalUnitDevice::processSRBCommand(com_ximeta_driver_NDASCommand *command) { com_ximeta_driver_NDASDeviceController *deviceController; // Send Command. deviceController = OSDynamicCast(com_ximeta_driver_NDASDeviceController, getParentEntry(gIOServicePlane)); if (NULL == deviceController) { DbgIOLog(DEBUG_MASK_NDAS_ERROR, ("readSectorsOnce: Can't Find controller.\n")); return false; } // Set Target Number. command->scsiCommand()->targetNo = unitNumber(); command->scsiCommand()->device = this; deviceController->enqueueCommand(command); return true; }
void AppleGPIO::publishStrings(OSCollection *strings) { OSCollectionIterator *strIter; OSSymbol *key; if (!strings) return; strIter = OSCollectionIterator::withCollection(strings); if (strIter) { while ((key = OSDynamicCast(OSSymbol, strIter->getNextObject())) != 0) { //DLOG("AppleGPIO::publishStrings 0x%x %s\n", // fGPIOID, key->getCStringNoCopy()); publishResource(key, this); } strIter->release(); } }
IOReturn IOAudioSelectorControl::validateValue(OSObject *newValue) { IOReturn result = kIOReturnBadArgument; OSNumber *number; number = OSDynamicCast(OSNumber, newValue); if (number) { result = super::validateValue(newValue); if (result == kIOReturnSuccess) { if (valueExists((SInt32)number->unsigned32BitValue())) { result = kIOReturnSuccess; } else { result = kIOReturnNotFound; } } } return result; }
static IORegistryEntry * IODTFindInterruptParent( IORegistryEntry * regEntry, IOItemCount index ) { IORegistryEntry * parent; UInt32 phandle; OSData * data; unsigned int len; if( (data = OSDynamicCast( OSData, regEntry->getProperty( gIODTInterruptParentKey ))) && (sizeof(UInt32) <= (len = data->getLength()))) { if (((index + 1) * sizeof(UInt32)) > len) index = 0; phandle = ((UInt32 *) data->getBytesNoCopy())[index]; parent = FindPHandle( phandle ); } else if( 0 == regEntry->getProperty( "interrupt-controller")) parent = regEntry->getParentEntry( gIODTPlane); else parent = 0; return( parent ); }
void FakeSMCDevice::saveKeyToNVRAM(FakeSMCKey *key) { if (!useNVRAM) return; if (IORegistryEntry *nvram = OSDynamicCast(IORegistryEntry, fromPath("/options", gIODTPlane))) { char name[32]; snprintf(name, 32, "%s-%s-%s", kFakeSMCKeyPropertyPrefix, key->getKey(), key->getType()); const OSSymbol *tempName = OSSymbol::withCString(name); if (genericNVRAM) nvram->IORegistryEntry::setProperty(tempName, OSData::withBytes(key->getValue(), key->getSize())); else nvram->setProperty(tempName, OSData::withBytes(key->getValue(), key->getSize())); OSSafeRelease(tempName); OSSafeRelease(nvram); } }
// ====================================================================== void ListHookedPointing::Item::apply(const Params_RelativePointerEventCallback& params) { RelativePointerEventCallback callback = orig_relativePointerEventAction_; if (!callback) return; OSObject* target = orig_relativePointerEventTarget_; if (!target) return; OSObject* sender = OSDynamicCast(OSObject, device_); if (!sender) return; const AbsoluteTime& ts = CommonData::getcurrent_ts(); OSObject* refcon = nullptr; Params_RelativePointerEventCallback::log(false, params.buttons, params.dx, params.dy); { // We need to unlock the global lock while we are calling the callback function. // For more information, See ListHookedKeyboard::Item::apply(const Params_KeyboardEventCallBack& params) GlobalLock::ScopedUnlock lk; callback(target, params.buttons.get(), params.dx, params.dy, ts, sender, refcon); } }
IOReturn IOATABlockStorageDriver::reportMaxWriteTransfer ( UInt64 blocksize, UInt64 * max ) { OSNumber * size; STATUS_LOG ( ( "IOATABlockStorageDriver::reportMaxWriteTransfer called.\n" ) ); *max = blocksize * kIOATAMaximumBlockCount8Bit; size = OSDynamicCast ( OSNumber, getProperty ( kIOMaximumBlockCountWriteKey ) ); if ( size != NULL ) { *max = size->unsigned64BitValue ( ) * blocksize; } return kIOReturnSuccess; }
//==================================================================================================== // IOHIDEventService::registerEventSource //==================================================================================================== void IOHIDEventSystem::registerEventSource(IOHIDEventService * service) { EventServiceInfoRef tempEventServiceInfoRef; OSData * tempData = NULL; UInt32 index; IOLog("IOHIDEventSystem::registerEventSource\n"); for ( index = 0; index<_eventServiceInfoArray->getCount(); index++ ) { if ( (tempData = OSDynamicCast(OSData, _eventServiceInfoArray->getObject(index))) && (tempEventServiceInfoRef = (EventServiceInfoRef)tempData->getBytesNoCopy()) && (tempEventServiceInfoRef->service == service) ) break; tempData = NULL; } service->open(this, 0, tempData, OSMemberFunctionCast(IOHIDEventService::HIDEventCallback, this, &IOHIDEventSystem::handleHIDEvent)); }
bool darwin_iwi3945::init(OSDictionary *dict) { //priv=(struct iwl_priv*)IOMalloc(sizeof(struct iwl_priv)); /* module parameters */ param_disable_hw_scan = 0; //need to define param_debug better param_debug = 0xffffffff; param_debug &= ~(IWL_DL_IO | IWL_DL_ISR | IWL_DL_TEMP|IWL_DL_POWER); param_debug |=IWL_DL_INFO; param_disable = 0; /* def: enable radio */ param_antenna = 0; /* def: 0 = both antennas (use diversity) */ param_hwcrypto = 0; /* def: using software encryption */ param_qos_enable = 0; param_disable=OSDynamicCast(OSNumber,dict->getObject("param_disable"))->unsigned32BitValue(); //IOLog("debug_level %x sw_disable %d\n",param_debug, param_disable); return super::init(dict); }
void PAEngine::removeVirtualDeviceWithRefcon(void *refCon) { OSCollectionIterator *iter = OSCollectionIterator::withCollection(virtualDeviceArray); PAVirtualDevice *dev; while ((dev = OSDynamicCast(PAVirtualDevice, iter->getNextObject()))) { UInt index = virtualDeviceArray->getNextIndexOfObject((OSMetaClassBase *) dev, 0); if (dev->refCon == refCon) { if (state == kIOAudioEngineRunning) dev->sendNotification(kPAVirtualDeviceUserClientNotificationEngineStopped, 0); dev->detachFromParent(this, gIOServicePlane); dev->stop(this); dev->terminate(0); virtualDeviceArray->removeObject(index); } } iter->release(); }
void OWCDumpIORegistry::dumpIORegistry (void *argument) { IOSleep (DUMP_DELAY_SECONDS * 1000); IORegistryIterator *iter = IORegistryIterator::iterateOver (gIOServicePlane, kIORegistryIterateRecursively); if (iter == NULL) return; int maxBufferSize = 2048; char *buffer = (char *) IOMalloc (maxBufferSize); if (buffer == NULL) return; OSSerialize *s = OSSerialize::withCapacity (maxBufferSize); if (s == NULL) return; IORegistryEntry *object = iter->getCurrentEntry (); while (object) { s->clearText (); int busyState = 0; IOService *ios = OSDynamicCast (IOService, object); if (ios) busyState = ios->getBusyState (); int pathSize = maxBufferSize; object->getPath (buffer, &pathSize, gIOServicePlane); kprintf ("\n--> %s <%s> (%d, %d)\n", buffer, object->getMetaClass ()->getClassName (), object->getRetainCount (), busyState); if (object->serializeProperties (s)) { kprintf ("%s\n", s->text ()); } else { kprintf ("serializeProperties failed\n"); } object = iter->getNextObject (); } IOFree (buffer, maxBufferSize); s->release (); iter->release (); }
/* * Copyright (c) 1998-2013 Apple Inc. All rights reserved. * * @APPLE_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 * compliance with the License. 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, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * 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_LICENSE_HEADER_END@ */ #include <IOKit/IODeviceTreeSupport.h> #include <IOKit/IOMessage.h> #include <IOKit/storage/IOPartitionScheme.h> #define super IOStorage OSDefineMetaClassAndStructors(IOPartitionScheme, IOStorage) #ifndef __LP64__ extern IOStorageAttributes gIOStorageAttributesUnsupported; #endif /* !__LP64__ */ static SInt32 partitionComparison( const OSMetaClassBase * object1, const OSMetaClassBase * object2, void * context ) { // // Internal comparison routine for sorting partitions in an ordered set. // UInt64 base1 = ( ( IOMedia * ) object1 )->getBase( ); UInt64 base2 = ( ( IOMedia * ) object2 )->getBase( ); #if TARGET_OS_EMBEDDED OSString * uuid1 = OSDynamicCast( OSString, ( ( IOMedia * ) object1 )->getProperty( kIOMediaUUIDKey ) ); OSString * uuid2 = OSDynamicCast( OSString, ( ( IOMedia * ) object2 )->getProperty( kIOMediaUUIDKey ) ); if ( uuid1 || uuid2 ) { if ( uuid1 == 0 ) return -1; if ( uuid2 == 0 ) return 1; return strcmp( uuid2->getCStringNoCopy( ), uuid1->getCStringNoCopy( ) ); } #endif /* TARGET_OS_EMBEDDED */ if ( base1 < base2 ) return 1; if ( base1 > base2 ) return -1; return 0; } IOMedia * IOPartitionScheme::getProvider() const { // // Obtain this object's provider. We override the superclass's method // to return a more specific subclass of OSObject -- an IOMedia. This // method serves simply as a convenience to subclass developers. // return (IOMedia *) IOService::getProvider(); } bool IOPartitionScheme::init(OSDictionary * properties) { // // Initialize this object's minimal state. // if (super::init(properties) == false) return false; _openLevel = kIOStorageAccessNone; _openReaders = OSSet::withCapacity(16); _openReaderWriters = OSSet::withCapacity(16); if (_openReaders == 0 || _openReaderWriters == 0) return false; return true; } void IOPartitionScheme::free() { // // Free all of this object's outstanding resources. // if (_openReaders) _openReaders->release(); if (_openReaderWriters) _openReaderWriters->release(); super::free(); } bool IOPartitionScheme::handleOpen(IOService * client, IOOptionBits options, void * argument) { // // The handleOpen method grants or denies permission to access this object // to an interested client. The argument is an IOStorageAccess value that // specifies the level of access desired -- reader or reader-writer. // // This method can be invoked to upgrade or downgrade the access level for // an existing client as well. The previous access level will prevail for // upgrades that fail, of course. A downgrade should never fail. If the // new access level should be the same as the old for a given client, this // method will do nothing and return success. In all cases, one, singular // close-per-client is expected for all opens-per-client received. // // This implementation replaces the IOService definition of handleOpen(). // // We are guaranteed that no other opens or closes will be processed until // we make our decision, change our state, and return from this method. // IOStorageAccess access = (uintptr_t) argument; IOStorageAccess level; assert(client); assert( access == kIOStorageAccessReader || access == kIOStorageAccessReaderWriter ); // // A partition scheme multiplexes the opens it receives from several clients // and sends one open to the level below that satisfies the highest level of // access. // unsigned writers = _openReaderWriters->getCount(); if (_openReaderWriters->containsObject(client)) writers--; if (access == kIOStorageAccessReaderWriter) writers++; level = (writers) ? kIOStorageAccessReaderWriter : kIOStorageAccessReader; // // Determine whether the levels below us accept this open or not (we avoid // the open if the required access is the access we already hold). // if ( _openLevel != level ) { IOStorage * provider; provider = OSDynamicCast( IOStorage, getProvider( ) ); if ( provider ) { bool success; level = ( level | kIOStorageAccessSharedLock ); success = provider->open( this, options, level ); level = ( level & kIOStorageAccessReaderWriter ); if ( success == false ) { return false; } } } // // Process the open. // if (access == kIOStorageAccessReader) { _openReaders->setObject(client); _openReaderWriters->removeObject(client); // (for a downgrade) } else // (access == kIOStorageAccessReaderWriter) { _openReaderWriters->setObject(client); _openReaders->removeObject(client); // (for an upgrade) } _openLevel = level; return true; } bool IOPartitionScheme::handleIsOpen(const IOService * client) const { // // The handleIsOpen method determines whether the specified client, or any // client if none is specificed, presently has an open on this object. // // This implementation replaces the IOService definition of handleIsOpen(). // // We are guaranteed that no other opens or closes will be processed until // we return from this method. // if (client == 0) return (_openLevel != kIOStorageAccessNone); return ( _openReaderWriters->containsObject(client) || _openReaders->containsObject(client) ); } void IOPartitionScheme::handleClose(IOService * client, IOOptionBits options) { // // The handleClose method closes the client's access to this object. // // This implementation replaces the IOService definition of handleClose(). // // We are guaranteed that no other opens or closes will be processed until // we change our state and return from this method. // assert(client); // // Process the close. // if (_openReaderWriters->containsObject(client)) // (is it a reader-writer?) { _openReaderWriters->removeObject(client); } else if (_openReaders->containsObject(client)) // (is the client a reader?) { _openReaders->removeObject(client); } else // (is the client is an imposter?) { assert(0); return; } // // Reevaluate the open we have on the level below us. If no opens remain, // we close, or if no reader-writer remains, but readers do, we downgrade. // IOStorageAccess level; if (_openReaderWriters->getCount()) level = kIOStorageAccessReaderWriter; else if (_openReaders->getCount()) level = kIOStorageAccessReader; else level = kIOStorageAccessNone; if ( _openLevel != level ) { IOStorage * provider; provider = OSDynamicCast( IOStorage, getProvider( ) ); if ( provider ) { if ( level == kIOStorageAccessNone ) { provider->close( this, options ); } else { bool success; level = ( level | kIOStorageAccessSharedLock ); success = provider->open( this, 0, level ); level = ( level & kIOStorageAccessReaderWriter ); assert( success ); } } _openLevel = level; } } void IOPartitionScheme::read(IOService * client, UInt64 byteStart, IOMemoryDescriptor * buffer, IOStorageAttributes * attributes, IOStorageCompletion * completion) { // // Read data from the storage object at the specified byte offset into the // specified buffer, asynchronously. When the read completes, the caller // will be notified via the specified completion action. // // The buffer will be retained for the duration of the read. // // For simple partition schemes, the default behavior is to simply pass the // read through to the provider media. More complex partition schemes such // as RAID will need to do extra processing here. // #ifndef __LP64__ if ( IOStorage::_expansionData ) { if ( attributes == &gIOStorageAttributesUnsupported ) { attributes = NULL; } else { IOStorage::read( client, byteStart, buffer, attributes, completion ); return; } } #endif /* !__LP64__ */ getProvider( )->read( this, byteStart, buffer, attributes, completion ); } void IOPartitionScheme::write(IOService * client, UInt64 byteStart, IOMemoryDescriptor * buffer, IOStorageAttributes * attributes, IOStorageCompletion * completion) { // // Write data into the storage object at the specified byte offset from the // specified buffer, asynchronously. When the write completes, the caller // will be notified via the specified completion action. // // The buffer will be retained for the duration of the write. // // For simple partition schemes, the default behavior is to simply pass the // write through to the provider media. More complex partition schemes such // as RAID will need to do extra processing here. // #ifndef __LP64__ if ( IOStorage::_expansionData ) { if ( attributes == &gIOStorageAttributesUnsupported ) { attributes = NULL; } else { IOStorage::write( client, byteStart, buffer, attributes, completion ); return; } } #endif /* !__LP64__ */ getProvider( )->write( this, byteStart, buffer, attributes, completion ); } IOReturn IOPartitionScheme::synchronizeCache(IOService * client) { // // Flush the cached data in the storage object, if any, synchronously. // return getProvider()->synchronizeCache(this); } IOReturn IOPartitionScheme::unmap(IOService * client, IOStorageExtent * extents, UInt32 extentsCount, UInt32 options) { // // Delete unused data from the storage object at the specified byte offsets, // synchronously. // return getProvider( )->unmap( this, extents, extentsCount, options ); } bool IOPartitionScheme::lockPhysicalExtents(IOService * client) { // // Lock the contents of the storage object against relocation temporarily, // for the purpose of getting physical extents. // return getProvider( )->lockPhysicalExtents( this ); } IOStorage * IOPartitionScheme::copyPhysicalExtent(IOService * client, UInt64 * byteStart, UInt64 * byteCount) { // // Convert the specified byte offset into a physical byte offset, relative // to a physical storage object. This call should only be made within the // context of lockPhysicalExtents(). // return getProvider( )->copyPhysicalExtent( this, byteStart, byteCount ); } void IOPartitionScheme::unlockPhysicalExtents(IOService * client) { // // Unlock the contents of the storage object for relocation again. This // call must balance a successful call to lockPhysicalExtents(). // getProvider( )->unlockPhysicalExtents( this ); } #ifdef __LP64__ bool IOPartitionScheme::attachMediaObjectToDeviceTree(IOMedia * media) #else /* !__LP64__ */ bool IOPartitionScheme::attachMediaObjectToDeviceTree(IOMedia * media, IOOptionBits options) #endif /* !__LP64__ */ { // // Attach the given media object to the device tree plane. // IORegistryEntry * parent = this; while ( (parent = parent->getParentEntry(gIOServicePlane)) ) { if ( parent->inPlane(gIODTPlane) ) { char location[ 32 ]; const char * locationOfParent = parent->getLocation(gIODTPlane); const char * nameOfParent = parent->getName(gIODTPlane); if ( locationOfParent == 0 ) break; if ( OSDynamicCast(IOMedia, parent) == 0 ) break; parent = parent->getParentEntry(gIODTPlane); if ( parent == 0 ) break; if ( media->attachToParent(parent, gIODTPlane) == false ) break; strlcpy(location, locationOfParent, sizeof(location)); if ( strchr(location, ':') ) *(strchr(location, ':') + 1) = 0; strlcat(location, media->getLocation(), sizeof(location) - strlen(location)); media->setLocation(location, gIODTPlane); media->setName(nameOfParent, gIODTPlane); return true; } } return false; }
IOReturn AppleUSBUHCI::GetRootHubDescriptor(IOUSBHubDescriptor *desc) { IOUSBHubDescriptor hubDesc; UInt32 appleCaptive = 0; OSNumber * appleCaptiveProperty = NULL; if (!desc) return(kIOReturnNoMemory); hubDesc.length = sizeof(IOUSBHubDescriptor); hubDesc.hubType = kUSBHubDescriptorType; hubDesc.numPorts = kUHCI_NUM_PORTS; // UHCI all have 2 ports - how convenient _rootHubNumPorts = kUHCI_NUM_PORTS; hubDesc.powerOnToGood = 50; /* 100ms */ hubDesc.hubCurrent = 0; // XXX for now do not support overcurrent, although PIIX chips do support it hubDesc.characteristics = HostToUSBWord(kNoPowerSwitchingBit | kNoOverCurrentBit); assert(kUHCI_NUM_PORTS < 8); // Set removable port flags -- we might have an AAPL property that tells us which ports // are captive. If we don't then we'll assume that all ports are removable appleCaptiveProperty = OSDynamicCast(OSNumber, _device->getProperty(kAppleInternalUSBDevice)); if (appleCaptiveProperty) appleCaptive = appleCaptiveProperty->unsigned32BitValue(); hubDesc.removablePortFlags[0] = (UInt8) appleCaptive; hubDesc.removablePortFlags[1] = 0xFF; // Adjust descriptor length to account for unused bytes // in removable flags and power control flags arrays. hubDesc.length -= (sizeof(hubDesc.removablePortFlags) - 1 + sizeof(hubDesc.pwrCtlPortFlags) - 1); bcopy(&hubDesc, desc, hubDesc.length); return kIOReturnSuccess; }
IORegistryEntry *findEntryByPrefix(IORegistryEntry *entry, const char *prefix, const IORegistryPlane *plane, bool (*proc)(void *, IORegistryEntry *), bool brute, void *user) { bool found {false}; IORegistryEntry *res {nullptr}; size_t bruteCount {0}; do { bruteCount++; auto iterator = entry->getChildIterator(plane); if (iterator) { size_t len = strlen(prefix); while ((res = OSDynamicCast(IORegistryEntry, iterator->getNextObject())) != nullptr) { const char *resname = res->getName(); //DBGLOG("iokit @ iterating over %s", resname); if (!strncmp(prefix, resname, len)) { found = proc ? proc(user, res) : true; if (found) { if (bruteCount > 1) DBGLOG("iokit @ bruted %s value in %zu attempts", prefix, bruteCount); if (!proc) { break; } } } } iterator->release(); } else { SYSLOG("iokit @ failed to iterate over entry"); return nullptr; } } while (brute && bruteCount < bruteMax && !found); if (!found) DBGLOG("iokit @ failed to find %s", prefix); return proc ? nullptr : res; }
void net_habitue_device_SC101::deblock(OSData *addr, IOMemoryDescriptor *buffer, UInt32 block, UInt32 nblks, IOStorageCompletion completion) { bool isWrite = (buffer->getDirection() == kIODirectionOut); const OSSymbol *ioMaxKey = (isWrite ? gSC101DeviceIOMaxWriteSizeKey : gSC101DeviceIOMaxReadSizeKey); UInt64 ioMaxSize = OSDynamicCast(OSNumber, getProperty(ioMaxKey))->unsigned64BitValue(); UInt64 ioSize = (nblks * SECTOR_SIZE); deblock_master_state *master = IONewZero(deblock_master_state, 1); master->addr = addr; master->buffer = buffer; master->block = block; master->nblks = nblks; master->completion = completion; master->status = kIOReturnSuccess; master->addr->retain(); for (UInt64 used = 0, use = min(LSB(ioSize), ioMaxSize); used < ioSize; used += use, use = min(LSB(ioSize - used), ioMaxSize)) { deblock_state *state = IONewZero(deblock_state, 1); state->master = master; state->buffer = IOMemoryDescriptor::withSubRange(master->buffer, used, use, master->buffer->getDirection()); if (!state->buffer) panic("alloc failed"); // TODO(iwade) handle IOStorageCompletion new_completion; new_completion.target = this; new_completion.action = deblockCompletion; new_completion.parameter = state; master->pending++; KDEBUG("deblock %s used=%llu, use=%llu", (isWrite ? "write" : "read"), used, use); prepareAndDoAsyncReadWrite(master->addr, state->buffer, master->block + used / SECTOR_SIZE, use / SECTOR_SIZE, new_completion); } }