bool AppleNForceATARoot::start( IOService * provider )
{
    OSDictionary * match;

    if (super::start(provider) != true)
        return false;

    fProvider = OSDynamicCast( IOPCIDevice, provider );
    if (fProvider == 0)
        return false;

    fProvider->retain();

    // Enable bus master.

    fProvider->setBusMasterEnable( true );

    // Allocate a mutex to serialize access to PCI config space between
    // the primary and secondary ATA channels.

    fPCILock = IOLockAlloc();
    if (fPCILock == 0)
        return false;

    fIsSATA = (getProperty(kSerialATAKey) == kOSBooleanTrue);

    fChannels = createATAChannels();
    if (fChannels == 0)
        return false;

    fOpenChannels = OSSet::withCapacity( fChannels->getCount() );
    if (fOpenChannels == 0)
        return false;

    if (fIsSATA)
    {
        // Register SATA channels without delay.
        fHardwareType  = PCI_HW_SATA;
        fHardwareFlags = 0;
        applyToClients( registerClientApplier, 0 );
    }
    else if ((match = OSDynamicCast(OSDictionary,
                                    getProperty(kISABridgeMatchingKey))))
    {        
        match->retain();  // remove notification will consume a reference
    
        // Provider's PCI device ID does not tell us the hardware features
        // of the ATA controller. We need to locate the PCI-ISA bridge and
        // lookup a table before registering the channel nub(s). If bridge
        // is absent, we're in trouble.

        fISABridgeNotifier = addNotification(
                             /* type    */  gIOFirstPublishNotification,
                             /* match   */  match,
                             /* handler */  isaBridgePublished,
                             /* target  */  this,
                             /* refcon  */  0 );

        if (fISABridgeNotifier == 0)
        {
            match->release();
            return false;
        }
    }
    else
    {
        return false;
    }

    return true;
}
bool
IOFWUserAsyncStreamListener::completeInit( IOFireWireUserClient* userclient, FWUserAsyncStreamListenerCreateParams* params )
{
	Boolean	status = true ;


	fUserRefCon					= params->refCon ;
	fFlags						= params->flags ;
	fWaitingForUserCompletion	= false ;

	// set user client
	fUserClient = userclient ;

	// see if user specified a packet queue and queue size
	if ( !params->queueBuffer )
	{
		DebugLog("IOFWUserAsyncStreamListener::initAll: async stream listener without queue buffer\n") ;
		status = false ;
	}
	
	// make memory descriptor around queue
	if ( status )
	{
		if ( params->queueBuffer )
		{
			fPacketQueueBuffer = IOMemoryDescriptor::withAddressRange(	params->queueBuffer,
																		params->queueSize,
																		kIODirectionOutIn,
																		fUserClient->getOwningTask() ) ;
			if ( !fPacketQueueBuffer )
			{
				DebugLog("%s %u: couldn't make fPacketQueueBuffer memory descriptor\n", __FILE__, __LINE__) ;
				status = false ;
			}
			
			if ( status )
			{
				status =  ( kIOReturnSuccess == fPacketQueueBuffer->prepare() ) ;
		
				fPacketQueuePrepared = status ;
			}

			if ( status )
				fBufferAvailable = fPacketQueueBuffer->getLength() ;
		}
	}
	
	if ( status )
	{		
		// init the easy vars
		fLastReadHeader 			= new IOFWPacketHeader ;
		fLastWrittenHeader			= fLastReadHeader ;

		fLastWrittenHeader->CommonHeader.whichAsyncRef = NULL;
		
		// get a lock for the packet queue
		fLock = IOLockAlloc() ;
		
		if ( !fLock )
		{
			DebugLog("%s %u: couldn't allocate lock\n", __FILE__, __LINE__) ;
			status = false ;
		}
	}
	
	
	if (status)
	{		
		fUserLocks = true ;
	}
	
	return status ;
}
Exemplo n.º 3
0
bool AppleGPIO::start(IOService *provider)
{
	bool					doSleepWake;
	UInt32					i, flags, intCapable;
	IOPlatformFunction		*func;
	const OSSymbol			*functionSymbol = OSSymbol::withCString("InstantiatePlatformFunctions");
	IOReturn				retval;
	IOService				*parentDev;
	OSData					*data;

	if (!super::start(provider)) return(false);
	
	// set my id
	data = OSDynamicCast(OSData, provider->getProperty("reg"));
	if (!data) return(false);
	
	fGPIOID = *(UInt32 *)data->getBytesNoCopy();
	
	// find the gpio parent
	parentDev = OSDynamicCast(IOService, provider->getParentEntry(gIODTPlane));
	if (!parentDev) return(false);

	fParent = OSDynamicCast(IOService, parentDev->getChildEntry(gIOServicePlane));
	if (!fParent) return(false);

	// Create the interrupt register/enable symbols
	fSymIntRegister 	= OSSymbol::withCString(kIOPFInterruptRegister);
	fSymIntUnRegister 	= OSSymbol::withCString(kIOPFInterruptUnRegister);
	fSymIntEnable 		= OSSymbol::withCString(kIOPFInterruptEnable);
	fSymIntDisable		= OSSymbol::withCString(kIOPFInterruptDisable);

	// Allocate our constant callPlatformFunction symbols so we can be called at interrupt time.

	fSymGPIOParentWriteGPIO = OSSymbol::withCString(kSymGPIOParentWriteGPIO);
	fSymGPIOParentReadGPIO = OSSymbol::withCString(kSymGPIOParentReadGPIO);

	// Scan for platform-do-xxx functions
	fPlatformFuncArray = NULL;

	DLOG("AppleGPIO::start(%s@%lx) - calling InstantiatePlatformFunctions\n",
			provider->getName(), fGPIOID);

	retval = provider->getPlatform()->callPlatformFunction(functionSymbol, false,
			(void *)provider, (void *)&fPlatformFuncArray, (void *)0, (void *)0);

	DLOG("AppleGPIO::start(%s@%lx) - InstantiatePlatformFunctions returned %ld, pfArray %sNULL\n",
			provider->getName(), fGPIOID, retval, fPlatformFuncArray ? "NOT " : "");

	if (retval == kIOReturnSuccess && (fPlatformFuncArray != NULL))
	{
		// Find out if the GPIO parent supports interrupt events
		if (fParent->callPlatformFunction(kSymGPIOParentIntCapable, false, &intCapable, 0, 0, 0)
				!= kIOReturnSuccess)
		{
			intCapable = 0;
		}

		DLOG("AppleGPIO::start(%s@%lx) - iterating platformFunc array, count = %ld\n",
			provider->getName(), fGPIOID, fPlatformFuncArray->getCount());

		doSleepWake = false;

		UInt32 count = fPlatformFuncArray->getCount();
		for (i = 0; i < count; i++)
		{
			if (func = OSDynamicCast(IOPlatformFunction, fPlatformFuncArray->getObject(i)))
			{
				flags = func->getCommandFlags();

				DLOG ("AppleGPIO::start(%s@%lx) - functionCheck - got function, flags 0x%lx, pHandle 0x%lx\n", 
					provider->getName(), fGPIOID, flags, func->getCommandPHandle());

				// If this function is flagged to be performed at initialization, do it
				if (flags & kIOPFFlagOnInit)
				{
					performFunction(func, (void *)1, (void *)0, (void *)0, (void *)0);
				}

				if ((flags & kIOPFFlagOnDemand) || ((flags & kIOPFFlagIntGen) && intCapable))
				{
					// Set the flag to indicate whether any of the platform functions are using
					// interrupts -- this is used to allocate some locks that are needed for this
					// functionality
					if ((flags & kIOPFFlagIntGen) && (fIntGen == false))
					{
						fIntGen = true;

						// Allocate event-related state variable locks
						fClientsLock = IOSimpleLockAlloc();
						fAmRegisteredLock = IOLockAlloc();
						fAmEnabledLock = IOSimpleLockAlloc();
					}
					
					// This is a bit of overkill.  Strictly speaking the lock needs to protect
					// individual platformFunc array entries so that only one thread is executing
					// that function at a time.  The way we're using it here is only one of *any*
					// of the platform functions can be executing at a time.
					if (!fPFLock) fPFLock = IOLockAlloc();	// Use for both On-Demand and IntGen functions

					// On-Demand and IntGen functions need to have a resource published
					func->publishPlatformFunction(this);
				}

				// If we need to do anything at sleep/wake time, we'll need to set this
				// flag so we know to register for notifications
				if (flags & (kIOPFFlagOnSleep | kIOPFFlagOnWake))
					doSleepWake = true;
			}
			else
			{
				// This function won't be used -- generate a warning
				IOLog("AppleGPIO::start(%s@%lx) - functionCheck - not an IOPlatformFunction object\n",
						getProvider()->getName(), fGPIOID);
			}
		}

		// Register sleep and wake notifications
		if (doSleepWake)
		{
			mach_timespec_t	waitTimeout;

			waitTimeout.tv_sec = 30;
			waitTimeout.tv_nsec = 0;

			pmRootDomain = OSDynamicCast(IOPMrootDomain,
					waitForService(serviceMatching("IOPMrootDomain"), &waitTimeout));

			if (pmRootDomain != 0)
			{
				DLOG("AppleGPIO::start to acknowledge power changes\n");
				pmRootDomain->registerInterestedDriver(this);
			}
			else
			{
				IOLog("AppleGPIO failed to register PM interest!");
			}
		}
	}


#ifdef OLD_STYLE_COMPAT
	/*
	 * Legacy Support
	 *
	 * In the initial implementation, extra strings were published for event registration
	 * and deregistration as well as enable/disable functions.  In the IOPlatformFunction
	 * implementation, the client access these functions by calling the platform-xxx function
	 * and passing one of four OSSymbol objects (see fSymIntRegister, fSymIntUnRegister,
	 * fSymIntEnable, fSymIntDisable).  For now, we need to continue to support the old
	 * implementation.  The following code will generate and publish resources for these
	 * functions.
	 */

	if (fIntGen)
	{
		const OSSymbol 	*functionSym, *aKey;
		char			funcNameWithPrefix[160];
		const char		*funcName;

		UInt32 count = fPlatformFuncArray->getCount();
		for (i = 0; i < count; i++)
		{
			// Only publish strings for on-demand and int-gen functions
			if ((func = OSDynamicCast(IOPlatformFunction, fPlatformFuncArray->getObject(i))) != NULL &&
				(func->getCommandFlags() & (kIOPFFlagOnDemand | kIOPFFlagIntGen)) != NULL)
			{
				functionSym = func->getPlatformFunctionName();
				if (!functionSym)
					continue;
				else
					funcName = functionSym->getCStringNoCopy() + strlen(kFunctionRequiredPrefix);
			
				// register string list
				strncpy(funcNameWithPrefix, kFunctionRegisterPrefix, strlen (kFunctionRegisterPrefix)+1);
				strncat(funcNameWithPrefix, funcName, sizeof (funcNameWithPrefix) - strlen (funcNameWithPrefix) - 1);
				funcNameWithPrefix[sizeof (funcNameWithPrefix) - 1] = '\0';

				if ((aKey = OSSymbol::withCString(funcNameWithPrefix)) == 0)
					continue;

				ADD_OBJ_TO_SET(aKey, fRegisterStrings);

				// unregister string list
				strncpy(funcNameWithPrefix, kFunctionUnregisterPrefix, strlen (kFunctionUnregisterPrefix)+1);
				strncat(funcNameWithPrefix, funcName, sizeof (funcNameWithPrefix) - strlen (funcNameWithPrefix) - 1);
				funcNameWithPrefix[sizeof (funcNameWithPrefix) - 1] = '\0';
				
				if ((aKey = OSSymbol::withCString(funcNameWithPrefix)) == 0)
					continue;
				
				ADD_OBJ_TO_SET(aKey, fUnregisterStrings);

				// register string list
				strncpy(funcNameWithPrefix, kFunctionEvtEnablePrefix, strlen (kFunctionEvtEnablePrefix)+1);
				strncat(funcNameWithPrefix, funcName, sizeof (funcNameWithPrefix) - strlen (funcNameWithPrefix) - 1);
				funcNameWithPrefix[sizeof (funcNameWithPrefix) - 1] = '\0';

				if ((aKey = OSSymbol::withCString(funcNameWithPrefix)) == 0)
					continue;

				ADD_OBJ_TO_SET(aKey, fEnableStrings);

				// register string list
				strncpy(funcNameWithPrefix, kFunctionEvtDisablePrefix, strlen (kFunctionEvtDisablePrefix)+1);
				strncat(funcNameWithPrefix, funcName, sizeof (funcNameWithPrefix) - strlen (funcNameWithPrefix) - 1);
				funcNameWithPrefix[sizeof (funcNameWithPrefix) - 1] = '\0';

				if ((aKey = OSSymbol::withCString(funcNameWithPrefix)) == 0)
					continue;

				ADD_OBJ_TO_SET(aKey, fDisableStrings);
			}
		}

		publishStrings(fRegisterStrings);
		publishStrings(fUnregisterStrings);
		publishStrings(fEnableStrings);
		publishStrings(fDisableStrings);
	}

#endif

	if (fPlatformFuncArray && fPlatformFuncArray->getCount() > 0)
	{
		registerService();
		return(true);
	}
	else
	{
		// No reason for me to be here
		return(false);
	}
}
Exemplo n.º 4
0
 IOMapperLock() { fWaitLock = IOLockAlloc(); };
bool
SCSIPressurePathManager::InitializePathManagerForTarget (
							IOSCSITargetDevice * 		target,
							IOSCSIProtocolServices * 	initialPath )
{
	
	bool	result = false;
	
	STATUS_LOG ( ( "SCSIPressurePathManager::InitializePathManagerForTarget\n" ) );
	
	result = super::InitializePathManagerForTarget ( target, initialPath );
	require ( result, ErrorExit );
	
	STATUS_LOG ( ( "called super\n" ) );
	
	fLock = IOLockAlloc ( );
	require_nonzero ( fLock, ErrorExit );
	
	STATUS_LOG ( ( "allocated lock\n" ) );
	
	fPathSet = SCSIPathSet::withCapacity ( 1 );
	require_nonzero ( fPathSet, FreeLock );
	
	fInactivePathSet = SCSIPathSet::withCapacity ( 1 );
	require_nonzero ( fInactivePathSet, ReleasePathSet );
	
	STATUS_LOG ( ( "allocated path set, adding intial path\n" ) );
	
	result = AddPath ( initialPath );
	require ( result, ReleaseInactivePathSet );
	
	STATUS_LOG ( ( "added intial path, ready to go\n" ) );
	STATUS_LOG ( ( "Called AddPath, fStatistics array has %ld members\n", fStatistics->getCount ( ) ) );
	target->setProperty ( kIOPropertyPathStatisticsKey, fStatistics );	
	
	result = true;
	
	return result;
	
	
ReleaseInactivePathSet:
	
	
	require_nonzero_quiet ( fInactivePathSet, ReleasePathSet );
	fInactivePathSet->release ( );
	fInactivePathSet = NULL;
	
	
ReleasePathSet:
	
	
	require_nonzero_quiet ( fPathSet, FreeLock );
	fPathSet->release ( );
	fPathSet = NULL;
	
	
FreeLock:
	
	
	require_nonzero_quiet ( fLock, ErrorExit );
	IOLockFree ( fLock );
	fLock = NULL;
	
	
ErrorExit:
	
	
	result = false;
	
	return result;
	
}