AppleMediaBayATANub.cpp [plain text]
#include <IOKit/IOLib.h>
#include <IOKit/IODeviceTreeSupport.h>
#include <IOKit/platform/AppleMacIO.h>
extern "C" {
#include <pexpert/pexpert.h>
}
#include "AppleMediaBay.h"
#include "AppleMediaBayATANub.h"
#ifndef TEMINATE_SERVICES
#include <IOKit/ata/IOATATypes.h>
#endif //TEMINATE_SERVICES
#define super AppleMacIODevice
OSDefineMetaClassAndStructors(AppleMediaBayATANub, AppleMacIODevice)
bool
AppleMediaBayATANub::setCorrectPropertyTable()
{
if (parentObject == NULL) {
#ifdef APPLEMB_VERBOSE
IOLog("AppleMediaBayATANub::%s fails because we miss the correct parentObject\n", __FUNCTION__);
#endif // APPLEMB_VERBOSE
return false;
}
#if 1
OSDictionary *dict = parentObject->dictionaryWithProperties();
if (dict != NULL) {
OSSymbol * sym;
OSCollectionIterator * iter;
iter = OSCollectionIterator::withCollection(dict);
if (iter != NULL) {
while ( (sym = (OSSymbol *)iter->getNextObject()) ) {
OSObject * obj;
obj = dict->getObject(sym);
#ifdef APPLEMB_VERBOSE
IOLog("AppleMediaBayATANub::%s adding property %s\n", __FUNCTION__, sym->getCStringNoCopy());
#endif // APPLEMB_VERBOSE
setProperty(sym, obj);
}
iter->release();
return true;
}
}
#else
OSDictionary *currentDictionary = parentObject->dictionaryWithProperties();
OSDictionary *myPropertyTable = getPropertyTable();
if ((currentDictionary != NULL) && (myPropertyTable != NULL)) {
myPropertyTable->merge(currentDictionary);
setPropertyTable(myPropertyTable);
return true;
}
#endif
return false;
}
IORegistryEntry*
AppleMediaBayATANub::findDTMediaBay(IOService *fromHere)
{
IORegistryEntry *parentSymbol = fromHere->getParentEntry(gIODTPlane);
if (parentSymbol == NULL)
return NULL;
else {
const char *parentName = parentSymbol->getName();
if ((parentName == NULL) || (strcmp(parentName, "media-bay")))
return NULL;
}
return parentSymbol;
}
IOService*
AppleMediaBayATANub::probe(IOService *provider, SInt32 * score)
{
if (super::probe( provider, score) == NULL)
return NULL;
if (OSDynamicCast(AppleMediaBayATANub, provider) != NULL)
return NULL;
if (findDTMediaBay(provider) == NULL)
return NULL;
#ifdef APPLEMB_VERBOSE
IOLog("AppleMediaBayATANub::%s return success\n", __FUNCTION__);
#endif // APPLEMB_VERBOSE
*score = 10000;
return this;
}
bool
AppleMediaBayATANub::start(IOService *provider)
{
IOService *tmp;
if (!super::start(provider))
return false;
for (effectiveMacIO = NULL, tmp = provider;
(tmp != NULL) && (effectiveMacIO == NULL);
tmp = tmp->getProvider()) {
effectiveMacIO = OSDynamicCast(AppleMacIO ,tmp);
}
if (effectiveMacIO == NULL) {
#ifdef APPLEMB_VERBOSE
IOLog("AppleMediaBayATANub::%s fails to get effectiveMacIO\n", __FUNCTION__);
#endif // APPLEMB_VERBOSE
return false;
}
#ifdef APPLEMB_VERBOSE
else
IOLog("AppleMediaBayATANub::%s found effectiveMacIO:%s\n", __FUNCTION__, effectiveMacIO->getName());
#endif // APPLEMB_VERBOSE
parentObject = OSDynamicCast(AppleMacIODevice, provider);
if (parentObject == NULL) {
#ifdef APPLEMB_VERBOSE
IOLog("AppleMediaBayATANub::%s fails to get the parent AppleMacIODevice\n", __FUNCTION__);
#endif // APPLEMB_VERBOSE
return false;
}
#ifdef APPLEMB_VERBOSE
else
IOLog("AppleMediaBayATANub::%s found parentObject:%s\n", __FUNCTION__, parentObject->getName());
#endif // APPLEMB_VERBOSE
if (!setCorrectPropertyTable()) {
#ifdef APPLEMB_VERBOSE
IOLog("AppleMediaBayATANub::%s fails to set the correct property table\n", __FUNCTION__);
#endif // APPLEMB_VERBOSE
return false;
}
IORegistryEntry *mediaBayDT = findDTMediaBay(provider);
if (mediaBayDT == NULL) {
#ifdef APPLEMB_VERBOSE
IOLog("AppleMediaBayATANub::%s fails to find a media bay entry\n", __FUNCTION__);
#endif // APPLEMB_VERBOSE
return false;
}
else {
IORegistryEntry *mediaBayDriver = NULL;
while (mediaBayDriver == NULL) {
OSIterator * iter = getMatchingServices(serviceMatching("AppleMediaBay"));
if (iter) {
#ifdef APPLEMB_VERBOSE
int i = 0;
#endif // APPLEMB_VERBOSE
OSObject *tmpObject;
while (((tmpObject = iter->getNextObject()) != NULL) && (mediaBayDriver == NULL)) {
IOService *tmpService = OSDynamicCast(IOService, tmpObject);
#ifdef APPLEMB_VERBOSE
if (tmpService == NULL)
IOLog("AppleMediaBayATANub::%s iterator %d is not IOService\n", __FUNCTION__, i++);
else
IOLog("AppleMediaBayATANub::%s iterator %d parent is 0x%08lx ours is 0x%08lx\n", __FUNCTION__,
i++, (UInt32)tmpService->getProvider(), (UInt32)mediaBayDT);
#endif // APPLEMB_VERBOSE
if ((tmpService != NULL) && (tmpService->getProvider() == mediaBayDT))
mediaBayDriver = tmpService;
}
iter->release();
}
else {
#ifdef APPLEMB_VERBOSE
IOLog("AppleMediaBayATANub::%s fails to get the correct iteraator for the AppleMediaBay\n", __FUNCTION__);
#endif // APPLEMB_VERBOSE
IOSleep(1000);
}
}
effectiveProvider = OSDynamicCast(AppleMediaBay, mediaBayDriver);
}
if (effectiveProvider == NULL) {
#ifdef APPLEMB_VERBOSE
IOLog("AppleMediaBayATANub::%s fails to get the correct AppleMediaBay\n", __FUNCTION__);
#endif // APPLEMB_VERBOSE
return false;
}
if (effectiveProvider->registerMediaNub(this) != kIOReturnSuccess) {
#ifdef APPLEMB_VERBOSE
IOLog("AppleMediaBayATANub::%s fails to register with the media-bay\n", __FUNCTION__);
#endif // APPLEMB_VERBOSE
return false;
}
initForPM(effectiveProvider);
#ifdef APPLEMB_VERBOSE
IOLog("AppleMediaBayATANub::%s return success\n", __FUNCTION__);
#endif // APPLEMB_VERBOSE
return true;
}
void
AppleMediaBayATANub::stop(IOService *provider)
{
if (effectiveProvider->deRegisterMediaNub(this) != kIOReturnSuccess) {
#ifdef APPLEMB_VERBOSE
IOLog("AppleMediaBayATANub::%s fails to de-register with the media-bay\n", __FUNCTION__);
#endif // APPLEMB_VERBOSE
}
handleDeviceEjection();
}
bool
AppleMediaBayATANub::initForPM(IOService *provider)
{
PMinit(); provider->joinPMtree(this);
if (pm_vars == NULL)
return false;
#define number_of_power_states 2
static IOPMPowerState ourPowerStates[number_of_power_states] = {
{1,0,0,0,0,0,0,0,0,0,0,0},
{1,IOPMDeviceUsable,IOPMPowerOn,IOPMPowerOn,0,0,0,0,0,0,0,0}
};
registerPowerDriver(this, ourPowerStates, number_of_power_states);
return true;
}
bool
AppleMediaBayATANub::compareName( OSString * name, OSString ** matched) const
{
return effectiveMacIO->compareNubName( this, name, matched );
}
IOReturn
AppleMediaBayATANub::getResources( void )
{
return effectiveMacIO->getNubResources( this );
}
void
AppleMediaBayATANub::handleDeviceInsertion()
{
if (getChildEntry(gIOServicePlane) == NULL)
registerService();
else {
#ifdef APPLEMB_VERBOSE
IOLog("AppleMediaBayATANub::%s fails to handleDeviceInsertion because nub has already a child\n", __FUNCTION__);
#endif // APPLEMB_VERBOSE
}
}
void
AppleMediaBayATANub::handleDeviceEjection()
{
IORegistryEntry *myTempchild = getChildEntry(gIOServicePlane);
#ifdef APPLEMB_VERBOSE
IOLog("AppleMediaBayATANub::%s handleDeviceEjection\n", __FUNCTION__);
#endif // APPLEMB_VERBOSE
IOService *ioServiceChild = OSDynamicCast(IOService, myTempchild);
if (ioServiceChild != NULL) {
#ifdef TEMINATE_SERVICES
if (ioServiceChild->terminate(kIOServiceSynchronous) == false) {
#ifdef APPLEMB_VERBOSE
IOLog("AppleMediaBayATANub::%s fails to handleDeviceEjection because nub does not have ioservice children\n", __FUNCTION__);
#endif // APPLEMB_VERBOSE
}
#else // ! TEMINATE_SERVICES
if (messageClient(kATARemovedEvent, ioServiceChild, (void*)OSString::withCString( kATAMediaBaySocketString ), 0) != kIOReturnSuccess) {
#ifdef APPLEMB_VERBOSE
IOLog("AppleMediaBayATANub::%s fails to handleDeviceEjection because nub does not have ioservice children\n", __FUNCTION__);
#endif // APPLEMB_VERBOSE
}
#endif // TEMINATE_SERVICES
}
else {
#ifdef APPLEMB_VERBOSE
IOLog("AppleMediaBayATANub::%s fails to handleDeviceEjection because nub does not have ioservice children\n", __FUNCTION__);
#endif // APPLEMB_VERBOSE
}
}