/* * 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 "AppleGenericPCATAController.h" #include "AppleGenericPCATAKeys.h" #define super IOService OSDefineMetaClassAndStructors( AppleGenericPCATAController, IOService ) static bool getOSNumberValue( const OSDictionary * dict, const char * key, UInt32 * outValue ) { OSNumber * num = OSDynamicCast( OSNumber, dict->getObject( key ) ); if ( num ) { *outValue = num->unsigned32BitValue(); return true; } return false; } //--------------------------------------------------------------------------- // // Create the interrupt properties. // bool AppleGenericPCATAController::setupInterrupt( UInt32 line ) { OSArray * controller = 0; OSArray * specifier = 0; OSData * tmpData = 0; bool ret = false; extern OSSymbol * gIntelPICName; do { // Create the interrupt specifer array. // This specifies the interrupt line. specifier = OSArray::withCapacity(1); if ( !specifier ) break; tmpData = OSData::withBytes( &line, sizeof(line) ); if ( !tmpData ) break; specifier->setObject( tmpData ); // Next the interrupt controller array. controller = OSArray::withCapacity(1); if ( !controller ) break; controller->setObject( gIntelPICName ); // Put the two arrays into our property table. ret = setProperty( gIOInterruptControllersKey, controller ) && setProperty( gIOInterruptSpecifiersKey, specifier ); } while( false ); if ( controller ) controller->release(); if ( specifier ) specifier->release(); if ( tmpData ) tmpData->release(); return ret; } //--------------------------------------------------------------------------- // // Initialize the ATA controller object. // bool AppleGenericPCATAController::init( OSDictionary * dictionary ) { if ( super::init(dictionary) == false ) return false; // Fetch the port address and interrupt line properties from // the dictionary provided. if ( !getOSNumberValue( dictionary, kPortAddressKey, &_ioPorts ) || !getOSNumberValue( dictionary, kInterruptLineKey, &_irq ) || !getOSNumberValue( dictionary, kPIOModeKey, &_pioMode ) ) return false; if ( !setupInterrupt( _irq ) ) return false; return true; } //--------------------------------------------------------------------------- // // Handle open and close from our client. // bool AppleGenericPCATAController::handleOpen( IOService * client, IOOptionBits options, void * arg ) { bool ret = false; if ( _provider && _provider->open( this, 0, arg ) ) { ret = super::handleOpen( client, options, arg ); if ( ret == false ) _provider->close( this ); } return ret; } void AppleGenericPCATAController::handleClose( IOService * client, IOOptionBits options ) { super::handleClose( client, options ); if ( _provider ) _provider->close( this ); } //--------------------------------------------------------------------------- // // Set and clear our provider reference when attached and detached // to a parent in the service plane. // bool AppleGenericPCATAController::attachToParent( IORegistryEntry * parent, const IORegistryPlane * plane ) { bool ret = super::attachToParent( parent, plane ); if ( ret && (plane == gIOServicePlane) ) _provider = (IOService *) parent; return ret; } void AppleGenericPCATAController::detachFromParent( IORegistryEntry * parent, const IORegistryPlane * plane ) { if ( plane == gIOServicePlane ) _provider = 0; return super::detachFromParent( parent, plane ); } //--------------------------------------------------------------------------- // // Accessor functions to assist our client. // UInt32 AppleGenericPCATAController::getIOPorts() const { return _ioPorts; } UInt32 AppleGenericPCATAController::getInterruptLine() const { return _irq; } UInt32 AppleGenericPCATAController::getPIOMode() const { return _pioMode; }