IOPCCardDevices.cpp [plain text]
#include <IOKit/pccard/IOPCCard.h>
#include <IOKit/pci/IOPCIBridge.h>
#include <IOKit/IOPlatformExpert.h>
#include <IOKit/IOUserClient.h>
#ifdef PCMCIA_DEBUG
extern int ds_debug;
MODULE_PARM(ds_debug, "i");
#define DEBUG(n, args...) if (ds_debug>(n)) printk(KERN_DEBUG args)
#else
#define DEBUG(n, args...)
#endif
#define CardServices cardServices
#define cs_error(handle, func, ret) \
{ \
error_info_t err = { func, ret }; \
CardServices(ReportError, handle, &err); \
}
#undef super
#define super IOPCIDevice
OSDefineMetaClassAndStructors(IOCardBusDevice, IOPCIDevice);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 0);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 1);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 2);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 3);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 4);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 5);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 6);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 7);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 8);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 9);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 10);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 11);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 12);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 13);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 14);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 15);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 16);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 17);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 18);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 19);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 20);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 21);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 22);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 23);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 24);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 25);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 26);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 27);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 28);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 29);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 30);
OSMetaClassDefineReservedUnused(IOCardBusDevice, 31);
IOReturn
IOCardBusDevice::setPowerState(unsigned long powerState,
IOService * whatDevice)
{
DEBUG(1, "IOCardBusDevice:setPowerState state=%d\n", powerState);
if ((powerState == kIOPCIDeviceOnState) || (powerState == 1)) {
if (!(state & DEV_SUSPEND)) return IOPMAckImplied;
state &= ~DEV_SUSPEND;
parent->setDevicePowerState(this, 1);
} else if (powerState == kIOPCIDeviceOffState) {
if (state & DEV_SUSPEND) return IOPMAckImplied;
state |= DEV_SUSPEND;
parent->setDevicePowerState(this, 0);
}
return IOPMAckImplied;
}
IOReturn
IOCardBusDevice::setProperties(OSObject * properties)
{
OSDictionary * dict;
int rc;
dict = OSDynamicCast(OSDictionary, properties);
if (dict) {
if (IOUserClient::clientHasPrivilege(current_task(), kIOClientPrivilegeLocalUser)) {
IOLog("IOCardBusDevice::setProperties: failed, the user has insufficient privileges");
return kIOReturnNotPrivileged;
}
if (dict->getObject("eject request")) {
rc = IOPCCardBridge::requestCardEjection(parent->getProvider());
if (rc) {
IOLog("IOCardBusDevice::setProperties(eject request) failed with error = %d\n", rc);
return kIOReturnError;
}
return kIOReturnSuccess;
}
}
return kIOReturnBadArgument;
}
u_int
IOCardBusDevice::getState(void)
{
return state;
}
client_handle_t
IOCardBusDevice::getCardServicesHandle(void)
{
return handle;
}
int
IOCardBusDevice::cardServices(int func, void * arg1 , void * arg2 , void * arg3 )
{
if (func < 0) return CS_UNSUPPORTED_FUNCTION;
return gIOPCCardWorkLoop->runAction((IOWorkLoop::Action)gCardServicesGate, NULL,
(void *)func, arg1, arg2, arg3);
}
int
IOCardBusDevice::eventHandler(cs_event_t event, int priority,
event_callback_args_t *args)
{
DEBUG(1, "IOCardBusDevice::eventHandler(0x%06x, %d, 0x%p)\n",
event, priority, args->client_handle);
IOCardBusDevice *nub = OSDynamicCast(IOCardBusDevice, (OSObject *)args->client_data);
if (!nub) {
IOLog("IOCardBusDevice::eventHandler: bogus event?\n");
return 0;
}
IOReturn ret = nub->messageClients(kIOPCCardCSEventMessage, (void *)event);
if (ret && ret != kIOReturnUnsupported) {
IOLog("IOCardBusDevice::eventHandler: messageClients returned %d\n", ret);
return ret;
} else {
return 0;
}
}
__BEGIN_DECLS
int snprintf __P((char *, size_t, const char *, ...));
__END_DECLS
bool
IOCardBusDevice::bindCardServices(void)
{
int ret;
IOLog("IOCardBusDevice: binding socket %d function %d to card services.\n", socket, function);
snprintf(bindName, sizeof(bindName), "Cardbus Expert");
state = DEV_PRESENT | DEV_CONFIG_PENDING;
bind_req_t bind_req;
bind_req.Socket = socket;
bind_req.Function = function;
bind_req.dev_info = &bindName;
ret = CardServices(BindDevice, &bind_req);
if (ret) return false;
client_reg_t client_reg;
client_reg.dev_info = &bindName;
client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
client_reg.event_handler = &IOCardBusDevice::eventHandler;
client_reg.EventMask =
CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
CS_EVENT_RESET_REQUEST | CS_EVENT_EJECTION_REQUEST;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = (void *)this;
ret = CardServices(RegisterClient, &handle, &client_reg);
if (ret) return false;
state |= DEV_CONFIG;
if (function == 0) {
ret = CardServices(RequestIO, handle, NULL);
if (ret) return false;
memset(&configuration, 0, sizeof(struct config_req_t));
configuration.Vcc = 33;
configuration.IntType = INT_CARDBUS;
ret = ((IOPCCardBridge *)parent)->configureSocket((IOService *)this, &configuration);
if (ret) return false;
}
state &= ~DEV_CONFIG_PENDING;
return true;
}
bool
IOCardBusDevice::unbindCardServices(void)
{
int ret;
IOLog("IOCardBusDevice: releasing socket %d function %d from card services.\n", socket, function);
if (state & DEV_CONFIG) {
if (function == 0) {
ret = ((IOPCCardBridge *)parent)->unconfigureSocket((IOService *)this);
if (ret) return false;
ret = CardServices(ReleaseIO, handle, NULL);
if (ret) return false;
}
ret = CardServices(DeregisterClient, handle);
if (ret) return false;
}
state &= ~DEV_CONFIG;
snprintf(bindName, sizeof(bindName), "not bound");
return true;
}
bool
IOCardBusDevice::finalize(IOOptionBits options)
{
unbindCardServices();
return super::finalize(options);
}
static UInt64
getDebugFlags(OSDictionary * props)
{
OSNumber *debugProp = OSDynamicCast(OSNumber, props->getObject(gIOKitDebugKey));
if (debugProp) {
return debugProp->unsigned64BitValue();
}
return 0;
}
static bool
compareVersionOneInfo(OSDictionary *catalog, OSDictionary *cis, bool debug)
{
OSArray *version1 = OSDynamicCast(OSArray, catalog->getObject(kIOPCCardVersionOneMatchKey));
OSArray *myversion1 = OSDynamicCast(OSArray, cis->getObject(kIOPCCardVersionOneMatchKey));
if (!version1) {
if (debug) IOLog("IOPCCardDevice: the VersionOneInfo match array is not of type OSArray?\n");
return false;
}
if (!myversion1) {
if (debug) IOLog("IOPCCardDevice: there is no VersionOneInfo CIS tuple to match against?\n");
return false;
}
const OSString *wild = OSString::withCString("*");
int max = version1->getCount();
for (int i = 0; i < max; i++) {
OSString *str = OSDynamicCast(OSString, version1->getObject(i));
if (!str) {
IOLog("IOPCCardDevice: the VersionOneInfo[%d] in match array is not of type OSString?\n", i);
wild->release();
return false;
}
if (str->isEqualTo(wild)) continue;
OSString *mystr = OSDynamicCast(OSString, myversion1->getObject(i));
if (mystr && !mystr->isEqualTo(str)) {
if (debug && mystr) {
IOLog("IOPCCardDevice: VersionOneInfo[%d], \"%s\"(match string) != \"%s\"(CIS string).\n",
i, str->getCStringNoCopy(), mystr->getCStringNoCopy());
}
wild->release();
return false;
}
}
wild->release();
if (debug) IOLog("IOPCCardDevice: VersionOneInfo matched.\n");
return true;
}
static bool
compareFunceTuples(OSDictionary *catalog, OSDictionary *cis, bool debug)
{
OSNumber *funcid = OSDynamicCast(OSNumber, cis->getObject(kIOPCCardFunctionIDMatchKey));
OSArray *funceArray = OSDynamicCast(OSArray, cis->getObject(kIOPCCardFunctionExtensionMatchKey));
OSArray *matchArray = OSDynamicCast(OSArray, catalog->getObject(kIOPCCardFunctionExtensionMatchKey));
if (!funcid && !funceArray) {
if (debug) IOLog("IOPCCardDevice: card doesn't appear to have any FUNCE tuples.\n");
return false;
}
int funceArraySize = funceArray->getCount();
if (!funceArraySize) return false;
if (!matchArray) {
IOLog("IOPCCardDevice: FunctionExtensionMatch is not an array?\n");
return false;
}
int matchArraySize = matchArray->getCount();
if (!matchArraySize || matchArraySize & 1) {
IOLog("IOPCCardDevice: FunctionExtensionMatch in match array is empty or has a odd count?\n");
return false;
}
bool matched = false;
bool matchAll = false;
for (int i = 0; i < matchArraySize; i += 2) {
OSData *pattern = OSDynamicCast(OSData, matchArray->getObject(i));
OSData *mask = OSDynamicCast(OSData, matchArray->getObject(i+1));
if (!pattern || !mask) {
IOLog("IOPCCardDevice: FunctionExtensionMatch[%d-%d] pair is bogus?\n", i, i+1);
continue;
}
int matchSize = pattern->getLength();
if (matchSize != (int)mask->getLength()) {
IOLog("IOPCCardDevice: FunctionExtensionMatch[%d-%d] pair have different sizes?\n", i, i+1);
continue;
}
matchSize--;
for (int j=0; j < funceArraySize; j++) {
OSData *funce = OSDynamicCast(OSData, funceArray->getObject(j));
int funceSize = funce->getLength();
if (funceSize < matchSize) continue;
UInt8 *f = (UInt8 *)funce->getBytesNoCopy();
UInt8 *p = (UInt8 *)pattern->getBytesNoCopy();
UInt8 *m = (UInt8 *)mask->getBytesNoCopy();
if (funcid->unsigned8BitValue() != *p) break;
matchAll = *m != 0;
p++; m++;
matched = true;
for (int k=0; k < matchSize; k++) {
if ((p[k] | m[k]) != m[k]) {
if (!j) IOLog("IOPCCardDevice: FunctionExtensionMatch[%d-%d] pair will never match?\n", i, i+1);
matched = false;
break;
}
if ((f[k] & m[k]) != p[k]) {
matched = false;
break;
}
}
if (matched) break;
}
if (matchAll && !matched) break;
if (!matchAll && matched) {
if (debug) IOLog("IOPCCardDevice: FunctionExtensionMatch[%d-%d] pair matched.\n", i, i+1);
return true;
}
}
if (matched) {
if (debug) IOLog("IOPCCardDevice: all FunctionExtensionMatch pairs matched against function extention tuples.\n");
return true;
}
if (debug) IOLog("IOPCCardDevice: FUNCE tuples failed to match.\n");
return false;
}
bool
IOCardBusDevice::matchPropertyTable(OSDictionary *table, SInt32 *score)
{
bool matched = true;
bool debug = getDebugFlags(table) & kIOLogStart != 0;
if (debug) IOLog("IOCardBusDevice::matchPropertyTable entered.\n");
if (table->getObject(kIOPCCardVersionOneMatchKey)) {
matched = compareVersionOneInfo(table, getPropertyTable(), debug);
return matched;
}
return super::matchPropertyTable(table, score);
}
IOService *
IOCardBusDevice::matchLocation(IOService * client)
{
return this;
}
#undef super
#define super IOService
OSDefineMetaClassAndStructors(IOPCCard16Device, IOService);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 0);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 1);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 2);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 3);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 4);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 5);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 6);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 7);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 8);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 9);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 10);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 11);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 12);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 13);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 14);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 15);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 16);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 17);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 18);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 19);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 20);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 21);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 22);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 23);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 24);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 25);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 26);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 27);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 28);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 29);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 30);
OSMetaClassDefineReservedUnused(IOPCCard16Device, 31);
bool
IOPCCard16Device::attach(IOService * provider)
{
static IOPMPowerState powerStates[kIOPCCard16DevicePowerStateCount] = {
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 0, IOPMSoftSleep, IOPMSoftSleep, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 0, IOPMPowerOn, IOPMPowerOn, 0, 0, 0, 0, 0, 0, 0, 0 }
};
bridge = OSDynamicCast(IOPCCardBridge, provider);
if (!bridge) return false;
PMinit();
registerPowerDriver(this, (IOPMPowerState *) powerStates, kIOPCCard16DevicePowerStateCount);
provider->joinPMtree(this);
if (!super::attach(provider)) {
PMstop();
return false;
}
return true;
}
void
IOPCCard16Device::detach(IOService * provider)
{
PMstop();
return super::detach(provider);
}
IOReturn
IOPCCard16Device::setPowerState(unsigned long powerState,
IOService * whatDevice)
{
DEBUG(1, "IOPCCard16Device:setPowerState state=%d\n", powerState);
return enabler ? enabler->setPowerState(powerState, whatDevice) : IOPMAckImplied;
}
IOReturn
IOPCCard16Device::setProperties(OSObject * properties)
{
OSDictionary * dict;
int rc;
dict = OSDynamicCast(OSDictionary, properties);
if (dict) {
if (dict->getObject("eject request")) {
if (IOUserClient::clientHasPrivilege(current_task(), kIOClientPrivilegeLocalUser)) {
IOLog("IOCardBusDevice::setProperties: failed, the user has insufficient privileges");
return kIOReturnNotPrivileged;
}
rc = IOPCCardBridge::requestCardEjection(bridge->getProvider());
if (rc) {
IOLog("IOPCCard16Device::setProperties(eject request) failed with error = %d\n", rc);
return kIOReturnError;
}
return kIOReturnSuccess;
}
}
return kIOReturnBadArgument;
}
u_int
IOPCCard16Device::getState(void)
{
return enabler ? enabler->getState() : 0;
}
client_handle_t
IOPCCard16Device::getCardServicesHandle(void)
{
return handle;
}
int
IOPCCard16Device::cardServices(int func, void * arg1 , void * arg2 , void * arg3 )
{
if (func < 0) return CS_UNSUPPORTED_FUNCTION;
return gIOPCCardWorkLoop->runAction((IOWorkLoop::Action)gCardServicesGate, NULL,
(void *)func, arg1, arg2, arg3);
}
int
IOPCCard16Device::eventHandler(cs_event_t event, int priority,
event_callback_args_t *args)
{
IOReturn ret;
DEBUG(1, "IOPCCard16Device::eventHandler(0x%06x, %d, 0x%p, 0x%p)\n",
event, priority, args->client_handle, args->client_data);
IOPCCard16Device *nub = OSDynamicCast(IOPCCard16Device, (OSObject *)args->client_data);
if (!nub) {
IOLog("IOPCCard16Device::eventHandler: bogus event?\n");
return 0;
}
if (nub->enabler) {
ret = nub->enabler->eventHandler(event, priority, args);
if (ret) return 0;
}
ret = nub->messageClients(kIOPCCardCSEventMessage, (void *)event);
if (ret && ret != kIOReturnUnsupported) {
IOLog("IOPCCard16Device::eventHandler: messageClients returned %d\n", ret);
return ret;
}
return 0;
}
static int bindNameIndex = 0;
bool
IOPCCard16Device::bindCardServices(void)
{
int ret;
IOLog("IOPCCard16Device: binding socket %d function %d to card services.\n", socket, function);
snprintf(bindName, sizeof(bindName), "PCCardExpert%d", bindNameIndex++);
bind_req_t bind_req;
bind_req.Socket = socket;
bind_req.Function = function;
bind_req.dev_info = &bindName;
ret = CardServices(BindDevice, &bind_req);
if (ret) return false;
client_reg_t client_reg;
client_reg.dev_info = &bindName;
client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
client_reg.event_handler = &IOPCCard16Device::eventHandler;
client_reg.EventMask =
CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
CS_EVENT_RESET_REQUEST | CS_EVENT_EJECTION_REQUEST;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = (void *)this;
ret = CardServices(RegisterClient, &handle, &client_reg);
if (ret) return false;
return true;
}
bool
IOPCCard16Device::unbindCardServices(void)
{
int ret;
if (enabler) {
enabler->detach(this);
enabler->release();
enabler = 0;
}
IOLog("IOPCCard16Device: releasing socket %d function %d from card services.\n", socket, function);
ret = CardServices(DeregisterClient, handle);
if (ret) return false;
snprintf(bindName, sizeof(bindName), "not bound");
return true;
}
bool
IOPCCard16Device::finalize(IOOptionBits options)
{
unbindCardServices();
return super::finalize(options);
}
bool
IOPCCard16Device::matchPropertyTable(OSDictionary *table, SInt32 *score)
{
bool matched = false;
bool debug = getDebugFlags(table) & kIOLogStart != 0;
if (debug) IOLog("IOPCCard16Device::matchPropertyTable entered.\n");
if (table->getObject(kIOPCCardVersionOneMatchKey)) {
matched = compareVersionOneInfo(table, getPropertyTable(), debug);
if (!matched) return false;
}
if (table->getObject(kIOPCCardFunctionExtensionMatchKey)) {
matched = compareFunceTuples(table, getPropertyTable(), debug);
if (!matched) return false;
}
if (table->getObject(kIOPCCardMemoryDeviceNameMatchKey)) {
matched = compareProperty(table, kIOPCCardMemoryDeviceNameMatchKey);
if (debug) IOLog("MemoryDeviceName %s.\n", matched ? "matched" : "didn't match");
if (!matched) return false;
}
if (table->getObject(kIOPCCardFunctionNameMatchKey)) {
matched = compareProperty(table, kIOPCCardFunctionNameMatchKey);
if (debug) IOLog("FunctionName %s.\n", matched ? "matched" : "didn't match");
if (!matched) return false;
}
if (table->getObject(kIOPCCardFunctionIDMatchKey)) {
matched = compareProperty(table, kIOPCCardFunctionIDMatchKey);
if (debug) IOLog("FunctionID %s.\n", matched ? "matched" : "didn't match");
if (!matched) return false;
}
if (debug) IOLog("IOPCCard16Device::matchPropertyTable %s a match.\n", matched ? "found" : "didn't find");
return true;
}
IOService *
IOPCCard16Device::matchLocation(IOService * client)
{
return this;
}
bool
IOPCCard16Device::installEnabler(IOPCCard16Enabler *customEnabler )
{
if (enabler) {
if (!enabler->detach(this)) return false;
enabler->release();
enabler = 0;
}
if (customEnabler) {
enabler = OSDynamicCast(IOPCCard16Enabler, customEnabler);
if (!enabler) return false;
enabler->retain();
} else {
enabler = IOPCCard16Enabler::withDevice(this);
if (!enabler) return false;
}
return enabler->attach(this);
}
bool
IOPCCard16Device::configure(UInt32 index )
{
if (!enabler) {
if (!installEnabler()) return false;
}
return enabler->configure(index);
}
bool
IOPCCard16Device::unconfigure(void)
{
bool success = true;
if (enabler) {
success = enabler->detach(this);
enabler->release();
enabler = 0;
}
return success;
}
bool
IOPCCard16Device::getConfigurationInfo(config_info_t *config)
{
return enabler ? enabler->getConfigurationInfo(config) : false;
}
UInt32
IOPCCard16Device::getWindowCount(void)
{
return enabler ? enabler->getWindowCount() : 0;
}
UInt32
IOPCCard16Device::getWindowType(UInt32 index)
{
return enabler ? enabler->getWindowType(index) : 0;
}
UInt32
IOPCCard16Device::getWindowSize(UInt32 index)
{
return enabler ? enabler->getWindowSize(index) : 0;
}
bool
IOPCCard16Device::getWindowAttributes(UInt32 index, UInt32 *attributes)
{
return enabler ? enabler->getWindowAttributes(index, attributes) : false;
}
bool
IOPCCard16Device::getWindowHandle(UInt32 index, window_handle_t *handle)
{
return enabler ? enabler->getWindowHandle(index, handle) : false;
}
bool
IOPCCard16Device::getWindowOffset(UInt32 index, UInt32 *offset)
{
return enabler ? enabler->getWindowOffset(index, offset) : false;
}
bool
IOPCCard16Device::setWindowOffset(UInt32 index, UInt32 newOffset)
{
return enabler ? enabler->setWindowOffset(index, newOffset) : false;
}
IODeviceMemory *
IOPCCard16Device::ioDeviceMemory(void)
{
return bridge->ioDeviceMemory();
}
#ifdef __ppc__
UInt32
IOPCCard16Device::ioRead32( UInt16 offset, IOMemoryMap * map )
{
UInt32 value;
if( 0 == map) {
map = ioMap;
if( 0 == map)
return( 0 );
}
value = OSReadSwapInt32( (volatile void *)map->getVirtualAddress(), offset);
eieio();
return( value );
}
UInt16
IOPCCard16Device::ioRead16( UInt16 offset, IOMemoryMap * map )
{
UInt16 value;
if( 0 == map) {
map = ioMap;
if( 0 == map)
return( 0 );
}
value = OSReadSwapInt16( (volatile void *)map->getVirtualAddress(), offset);
eieio();
return( value );
}
UInt8
IOPCCard16Device::ioRead8( UInt16 offset, IOMemoryMap * map )
{
UInt32 value;
if( 0 == map) {
map = ioMap;
if( 0 == map)
return( 0 );
}
value = ((volatile UInt8 *) map->getVirtualAddress())[ offset ];
eieio();
return( value );
}
void
IOPCCard16Device::ioWrite32( UInt16 offset, UInt32 value,
IOMemoryMap * map )
{
if( 0 == map) {
map = ioMap;
if( 0 == map)
return;
}
OSWriteSwapInt32( (volatile void *)map->getVirtualAddress(), offset, value);
eieio();
}
void
IOPCCard16Device::ioWrite16( UInt16 offset, UInt16 value,
IOMemoryMap * map )
{
if( 0 == map) {
map = ioMap;
if( 0 == map)
return;
}
OSWriteSwapInt16( (volatile void *)map->getVirtualAddress(), offset, value);
eieio();
}
void
IOPCCard16Device::ioWrite8( UInt16 offset, UInt8 value,
IOMemoryMap * map )
{
if( 0 == map) {
map = ioMap;
if( 0 == map)
return;
}
((volatile UInt8 *) map->getVirtualAddress())[ offset ] = value;
eieio();
}
#endif
#ifdef __i386__
#include "pio.h"
UInt32
IOPCCard16Device::ioRead32( UInt16 offset, IOMemoryMap * map )
{
UInt32 value;
if( 0 == map)
map = ioMap;
value = inl( map->getPhysicalAddress() + offset );
return( value );
}
UInt16
IOPCCard16Device::ioRead16( UInt16 offset, IOMemoryMap * map )
{
UInt16 value;
if( 0 == map)
map = ioMap;
value = inw( map->getPhysicalAddress() + offset );
return( value );
}
UInt8
IOPCCard16Device::ioRead8( UInt16 offset, IOMemoryMap * map )
{
UInt32 value;
if( 0 == map)
map = ioMap;
value = inb( map->getPhysicalAddress() + offset );
return( value );
}
void
IOPCCard16Device::ioWrite32( UInt16 offset, UInt32 value,
IOMemoryMap * map )
{
if( 0 == map)
map = ioMap;
outl( map->getPhysicalAddress() + offset, value );
}
void
IOPCCard16Device::ioWrite16( UInt16 offset, UInt16 value,
IOMemoryMap * map )
{
if( 0 == map)
map = ioMap;
outw( map->getPhysicalAddress() + offset, value );
}
void
IOPCCard16Device::ioWrite8( UInt16 offset, UInt8 value,
IOMemoryMap * map )
{
if( 0 == map)
map = ioMap;
outb( map->getPhysicalAddress() + offset, value );
}
#endif