/* * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * The contents of this file constitute Original Code as defined in and * are subject to the Apple Public Source License Version 1.1 (the * "License"). You may not use this file except in compliance with the * License. Please obtain a copy of the License at * http://www.apple.com/publicsource and read it before using this file. * * This 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 OR NON-INFRINGEMENT. Please see the * License for the specific language governing rights and limitations * under the License. * * @APPLE_LICENSE_HEADER_END@ */ #include #include #include #include #include #include #include #include /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #undef super #define super IOService OSDefineMetaClassAndAbstractStructors(IOI2CInterface, IOService) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ bool IOI2CInterface::registerI2C( UInt64 id ) { bool result = true; fID = id; setProperty(kIOI2CInterfaceIDKey, id, 64); registerService(); return( result ); } IOReturn IOI2CInterface::newUserClient( task_t owningTask, void * security_id, UInt32 type, IOUserClient ** handler ) { IOReturn err = kIOReturnSuccess; IOUserClient * newConnect = 0; if( type) return( kIOReturnBadArgument ); newConnect = IOI2CInterfaceUserClient::withTask(owningTask); if( newConnect) { if( !newConnect->attach( this ) || !newConnect->start( this )) { newConnect->detach( this ); newConnect->release(); newConnect = 0; } } *handler = newConnect; return( err ); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #undef super #define super IOUserClient OSDefineMetaClassAndStructors(IOI2CInterfaceUserClient, IOUserClient) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ IOI2CInterfaceUserClient * IOI2CInterfaceUserClient::withTask( task_t owningTask ) { IOI2CInterfaceUserClient * inst; inst = new IOI2CInterfaceUserClient; if( inst && !inst->init()) { inst->release(); inst = 0; } if( inst) inst->fTask = owningTask; return( inst ); } bool IOI2CInterfaceUserClient::start( IOService * provider ) { if( !super::start( provider )) return( false ); return( true ); } IOReturn IOI2CInterfaceUserClient::clientClose( void ) { terminate(); return( kIOReturnSuccess ); } IOService * IOI2CInterfaceUserClient::getService( void ) { return( getProvider() ); } IOExternalMethod * IOI2CInterfaceUserClient::getTargetAndMethodForIndex( IOService ** targetP, UInt32 index ) { static const IOExternalMethod methodTemplate[] = { /* 0 */ { NULL, (IOMethod) &IOI2CInterfaceUserClient::extAcquireBus, kIOUCScalarIScalarO, 0, 0 }, /* 1 */ { NULL, (IOMethod) &IOI2CInterfaceUserClient::extReleaseBus, kIOUCScalarIScalarO, 0, 0 }, /* 3 */ { NULL, (IOMethod) &IOI2CInterfaceUserClient::extIO, kIOUCStructIStructO, 0xffffffff, 0xffffffff }, }; if( index > (sizeof(methodTemplate) / sizeof(methodTemplate[0]))) return( NULL ); *targetP = this; return( (IOExternalMethod *)(methodTemplate + index) ); } IOReturn IOI2CInterfaceUserClient::setProperties( OSObject * properties ) { return( kIOReturnUnsupported ); } IOReturn IOI2CInterfaceUserClient::extAcquireBus( void ) { IOReturn ret = kIOReturnNotReady; IOI2CInterface * provider; if( (provider = (IOI2CInterface *) copyParentEntry(gIOServicePlane))) { ret = provider->open( this ) ? kIOReturnSuccess : kIOReturnBusy; provider->release(); } return( ret ); } IOReturn IOI2CInterfaceUserClient::extReleaseBus( void ) { IOReturn ret = kIOReturnNotReady; IOI2CInterface * provider; if( (provider = (IOI2CInterface *) copyParentEntry(gIOServicePlane))) { provider->close( this ); provider->release(); ret = kIOReturnSuccess; } return( ret ); } IOReturn IOI2CInterfaceUserClient::extIO( void * inStruct, void * outStruct, IOByteCount inSize, IOByteCount * outSize ) { IOReturn err = kIOReturnNotReady; IOI2CInterface * provider; IOI2CRequest * request; IOI2CBuffer * buffer; if( inSize < sizeof(IOI2CRequest)) return( kIOReturnNoSpace ); if( *outSize < inSize) return( kIOReturnNoSpace ); if( (provider = (IOI2CInterface *) copyParentEntry(gIOServicePlane))) do { if( !provider->isOpen( this)) { err = kIOReturnNotOpen; continue; } buffer = (IOI2CBuffer *) inStruct; request = &buffer->request; if( request->sendBytes) { if( !request->sendBuffer) request->sendBuffer = (vm_address_t) &buffer->inlineBuffer[0]; else { err = kIOReturnMessageTooLarge; continue; } } if( request->replyBytes) { if( !request->replyBuffer) request->replyBuffer = (vm_address_t) &buffer->inlineBuffer[0]; else { err = kIOReturnMessageTooLarge; continue; } } err = provider->startIO( &buffer->request ); } while( false ); if( provider) provider->release(); if( kIOReturnSuccess == err) { *outSize = inSize; bcopy(inStruct, outStruct, inSize); } else *outSize = 0; return( err ); }