Apple16X50BusInterface.cpp [plain text]
#include "Apple16X50BusInterface.h"
#include <IOKit/serial/IOSerialKeys.h>
#include <libkern/OSAtomic.h>
SInt32 nextInterfaceInstance = 0;
#define super IOService
OSDefineMetaClassAndAbstractStructors(com_apple_driver_16X50BusInterface, IOService);
IOService *Apple16X50BusInterface::
probe(IOService *provider, SInt32 *score)
{
DEBUG_IOLog("Apple16X50BusInterface::probe() Compiled with DEBUG defined\n");
#ifdef ASSERT
Debugger("Apple16X50BusInterface::probe() Compiled with ASSERT defined - Entering debugger to set breakpoints");
#endif
return super::probe(provider, score);
}
void Apple16X50BusInterface::setName(const char *name, const IORegistryPlane *plane)
{
DEBUG_IOLog("Apple16X50BusInterface::setName(%s)\n", name);
super::setName(name, plane);
Name=getName();
}
bool Apple16X50BusInterface::start(IOService *provider)
{
DEBUG_IOLog("%s::start() WorkLoop=%p InterruptSource=%p\n", Name, WorkLoop, InterruptSource);
if (!WorkLoop) {
WorkLoop = IOWorkLoop::workLoop();
if (!WorkLoop) return false;
InterruptSource = IOInterruptEventSource::interruptEventSource(
this, (IOInterruptEventAction)&handleInterruptAction, getProvider()
);
DEBUG_IOLog("%s::start() WorkLoop=%p InterruptSource=%p\n", Name, WorkLoop, InterruptSource);
if (!InterruptSource) {
RELEASE(WorkLoop);
return false;
}
WorkLoop->addEventSource(InterruptSource);
InterruptSource->enable();
}
return super::start(provider);
}
void Apple16X50BusInterface::startUARTs(bool noSuffix)
{
unsigned int masterClock=0;
OSNumber *masterClockObj = OSDynamicCast(OSNumber, getProperty(kMasterClock));
if (masterClockObj) {
masterClock = masterClockObj->unsigned32BitValue();
DEBUG_IOLog("%s::startUARTs(): Master Clock specified as %d Hz\n", Name, masterClock);
}
if( !(InterfaceBaseName && (*InterfaceBaseName)) )
InterfaceBaseName="Serial";
for (unsigned int uart=0; uart<UARTInstance; uart++) {
if (!(UART[uart])) continue;
UART[uart]->setProperty(kCFBundleIdentifierKey, getProperty(kCFBundleIdentifierKey));
if (masterClock)
UART[uart]->setMasterClock(masterClock);
else {
masterClock = UART[uart]->determineMasterClock();
if (!masterClock)
continue;
else
DEBUG_IOLog("%s::startUARTs(): Master Clock determined to be %d Hz\n", Name, masterClock);
}
char pre[8], buf[80];
snprintf(pre, sizeof (pre), "%d%c", (int)InterfaceInstance, (UARTInstance>1)?('a'+uart):('\0') );
if ( (!noSuffix) || (uart > 0) )
UART[uart]->setProperty(kIOTTYSuffixKey, pre);
UART[uart]->setProperty(kIOTTYBaseNameKey, getProperty(kIOTTYBaseNameKey));
snprintf(buf, sizeof (buf), "%s (%s)", InterfaceBaseName, pre);
UART[uart]->setProperty(kNPProductNameKey, buf);
if (!(UART[uart]->start(this))) {
UART[uart]->detach(this);
RELEASE(UART[uart]);
}
}
}
void Apple16X50BusInterface::stop(IOService *provider)
{
DEBUG_IOLog("%s::stop()\n", Name);
super::stop(provider);
if (InterruptSource) {
DEBUG_IOLog("%s::stop() releasing InterruptSource\n", Name);
InterruptSource->disable();
WorkLoop->removeEventSource(InterruptSource);
RELEASE(InterruptSource);
}
}
void Apple16X50BusInterface::free()
{
DEBUG_IOLog("%s::free()\n", Name);
if (WorkLoop) {
DEBUG_IOLog("%s::free() releasing WorkLoop\n", Name);
RELEASE(WorkLoop);
}
super::free();
}
Apple16X50UARTSync * Apple16X50BusInterface::
probeUART(void* refCon, Apple16X50UARTSync *uart, OSDictionary *properties)
{
if (UARTInstance >= MAX_UARTS) goto fail;
if (!uart) uart = Apple16X50UARTSync::probeUART(this, refCon);
if (uart) {
if (!properties) properties = OSDictionary::withCapacity(6);
if (properties) {
if (uart->init(properties, refCon)) {
uart->attach(this);
UART[UARTInstance++] = uart;
} else goto fail;
} else goto fail;
}
return uart;
fail :
RELEASE(uart);
RELEASE(properties);
return NULL;
}
IOWorkLoop *Apple16X50BusInterface::getWorkLoop(void *refCon)
{
DEBUG_IOLog("%s::getWorkLoop()=%p\n", Name, WorkLoop);
return WorkLoop;
}
void Apple16X50BusInterface::
handleInterruptAction(OSObject *target, IOInterruptEventSource *source, int count)
{ ((Apple16X50BusInterface *)target)->handleInterrupt(source, count); }
void Apple16X50BusInterface::handleInterrupt(IOInterruptEventSource *source, int count)
{
UInt32 i;
DEBUG_IOLog("I%d+", count);
for (i=0; i<UARTInstance; i++)
if (UART[i]) UART[i]->interrupt();
DEBUG_IOLog("-I\n");
}
#ifdef REFBUG
void Apple16X50BusInterface::retain() const
{
super::retain();
DEBUG_IOLog("%s::retain()==%d\n", Name, getRetainCount());
}
void Apple16X50BusInterface::release() const
{
DEBUG_IOLog("%s::release()==%d\n",Name, getRetainCount());
super::release();
}
#endif