Beispiel #1
0
bool IOWorkLoop::init()
{
    // The super init and gateLock allocation MUST be done first.
    if ( !super::init() )
        return false;
	
	// Allocate our ExpansionData if it hasn't been allocated already.
	if ( !reserved )
	{
		reserved = IONew(ExpansionData,1);
		if ( !reserved )
			return false;
		
		bzero(reserved,sizeof(ExpansionData));
	}
	
#if DEBUG
	OSBacktrace ( reserved->allocationBacktrace, sizeof ( reserved->allocationBacktrace ) / sizeof ( reserved->allocationBacktrace[0] ) );
#endif
	
    if ( gateLock == NULL ) {
        if ( !( gateLock = IORecursiveLockAlloc()) )
            return false;
    }
	
    if ( workToDoLock == NULL ) {
        if ( !(workToDoLock = IOSimpleLockAlloc()) )
            return false;
        IOSimpleLockInit(workToDoLock);
        workToDo = false;
    }

    if (!reserved) {
        reserved = IONew(ExpansionData, 1);
        reserved->options = 0;
    }
	
    IOStatisticsRegisterCounter();

    if ( controlG == NULL ) {
        controlG = IOCommandGate::commandGate(
            this,
            OSMemberFunctionCast(
                IOCommandGate::Action,
                this,
                &IOWorkLoop::_maintRequest));

        if ( !controlG )
            return false;
        // Point the controlGate at the workLoop.  Usually addEventSource
        // does this automatically.  The problem is in this case addEventSource
        // uses the control gate and it has to be bootstrapped.
        controlG->setWorkLoop(this);
        if (addEventSource(controlG) != kIOReturnSuccess)
            return false;
    }

    if ( workThread == NULL ) {
        thread_continue_t cptr = OSMemberFunctionCast(
            thread_continue_t,
            this,
            &IOWorkLoop::threadMain);
        if (KERN_SUCCESS != kernel_thread_start(cptr, this, &workThread))
            return false;
    }

    (void) thread_set_tag(workThread, THREAD_TAG_IOWORKLOOP);
    return true;
}
Beispiel #2
0
IOReturn
IOUSBCommandPool::gatedReturnCommand(IOCommand * command)
{
	IOUSBCommand		*usbCommand		= OSDynamicCast(IOUSBCommand, command);					// only one of these should be non-null
	IOUSBIsocCommand	*isocCommand	= OSDynamicCast(IOUSBIsocCommand, command);

	USBLog(7,"IOUSBCommandPool[%p]::gatedReturnCommand %p", this, command);
	if (!command)
	{
#if DEBUG_LEVEL != DEBUG_LEVEL_PRODUCTION
		panic("IOUSBCommandPool::gatedReturnCommand( NULL )");
#endif
		return kIOReturnBadArgument;
	}
	
	if (command->fCommandChain.next &&
	    (&command->fCommandChain != command->fCommandChain.next || 
		 &command->fCommandChain != command->fCommandChain.prev))
	{
#if DEBUG_LEVEL != DEBUG_LEVEL_PRODUCTION
		kprintf("WARNING: gatedReturnCommand(%p) already on queue [next=%p prev=%p]\n", command, command->fCommandChain.next, command->fCommandChain.prev);
		panic("IOUSBCommandPool::gatedReturnCommand already on queue");
#endif
		char*		bt[8];
		
		OSBacktrace((void**)bt, 8);
		
		USBError(1,"IOUSBCommandPool::gatedReturnCommand  command already in queue, not putting it back into the queue, bt: [%p][%p][%p][%p][%p][%p][%p][%p]", bt[0], bt[1], bt[2], bt[3], bt[4], bt[5], bt[6], bt[7]);
		return kIOReturnBadArgument;
	}
	
	if (usbCommand)
	{
		IODMACommand *dmaCommand = usbCommand->GetDMACommand();
		if (dmaCommand)
		{
			if (dmaCommand->getMemoryDescriptor())
			{
				USBError(1, "IOUSBCommandPool::gatedReturnCommand - command (%p) still has dmaCommand(%p) with an active memory descriptor(%p)", usbCommand, dmaCommand, dmaCommand->getMemoryDescriptor());
#if DEBUG_LEVEL != DEBUG_LEVEL_PRODUCTION
				panic("IOUSBCommandPool::gatedReturnCommand -dmaCommand still has active IOMD");
#endif
			}
		}
		else
		{
			USBError(1,"IOUSBCommandPool::gatedReturnCommand - missing dmaCommand in IOUSBCommand");
		}
		
		// Test to poison the IOUSBCommand when returning it
#if DEBUG_LEVEL != DEBUG_LEVEL_PRODUCTION
		{
		char*					bt[kUSBCommandScratchBuffers];
	
		OSBacktrace((void**)bt, kUSBCommandScratchBuffers);
		for ( int i=0; i < kUSBCommandScratchBuffers; i++)
			usbCommand->SetBT(i, bt[i]);
		}
#endif
		// Clean up the command before returning it
		IOUSBCompletion			nullCompletion;
		nullCompletion.target = (void *) POISONVALUE;
		nullCompletion.action = (IOUSBCompletionAction) NULL;
		nullCompletion.parameter = (void *) POISONVALUE;
				
		usbCommand->SetSelector(INVALID_SELECTOR);
		usbCommand->SetRequest((IOUSBDeviceRequestPtr) POISONVALUE);
		usbCommand->SetAddress(0xFF);
		usbCommand->SetEndpoint(0xFF);
		usbCommand->SetDirection(0xFF);
		usbCommand->SetType(0xFF);
		usbCommand->SetBufferRounding(false);
		usbCommand->SetBuffer((IOMemoryDescriptor *) POISONVALUE);
		usbCommand->SetUSLCompletion(nullCompletion);
		usbCommand->SetClientCompletion(nullCompletion);
		usbCommand->SetDataRemaining(POISONVALUE);
		usbCommand->SetStage(0xFF);
		usbCommand->SetStatus(POISONVALUE);
		usbCommand->SetOrigBuffer((IOMemoryDescriptor *) POISONVALUE);
		usbCommand->SetDisjointCompletion(nullCompletion);
		usbCommand->SetDblBufLength(POISONVALUE);
		usbCommand->SetNoDataTimeout(POISONVALUE);
		usbCommand->SetCompletionTimeout(POISONVALUE);
		usbCommand->SetReqCount(POISONVALUE);
		usbCommand->SetMultiTransferTransaction(true);
		usbCommand->SetFinalTransferInTransaction(true);
		usbCommand->SetUseTimeStamp(true);
		usbCommand->SetIsSyncTransfer(FALSE);
		for ( int i=0; i < kUSBCommandScratchBuffers; i++)
			usbCommand->SetUIMScratch(i, POISONVALUE);
		usbCommand->SetStreamID(POISONVALUE);
		
		if ( usbCommand->GetBufferUSBCommand() != NULL )
		{
			USBError(1,"IOUSBCommandPool::gatedReturnCommand - GetBufferUSBCommand() is not NULL");
		}
		if ( usbCommand->GetRequestMemoryDescriptor() != NULL )
		{
			USBError(1,"IOUSBCommandPool::gatedReturnCommand - GetRequestMemoryDescriptor() is not NULL");
		}
		if ( usbCommand->GetBufferMemoryDescriptor() != NULL )
		{
			USBError(1,"IOUSBCommandPool::gatedReturnCommand - GetBufferMemoryDescriptor() is not NULL");
		}
		
		// Do not see these to anything but NULL as a lot of the code depends on checking for NULLness
		usbCommand->SetBufferUSBCommand(NULL);
		usbCommand->SetRequestMemoryDescriptor(NULL);
		usbCommand->SetBufferMemoryDescriptor(NULL);
	}
	
	if (isocCommand)
	{
		IODMACommand *dmaCommand = isocCommand->GetDMACommand();
		if (dmaCommand)
		{
			if (dmaCommand->getMemoryDescriptor())
			{
				USBError(1, "IOUSBCommandPool::gatedReturnCommand - isocCommand (%p) still has dmaCommand(%p) with an active memory descriptor(%p)", isocCommand, dmaCommand, dmaCommand->getMemoryDescriptor());
#if DEBUG_LEVEL != DEBUG_LEVEL_PRODUCTION
				panic("IOUSBCommandPool::gatedReturnCommand - dmaCommand still has active IOMD (isoc)");
#endif
			}
		}
		else
		{
			USBError(1,"IOUSBCommandPool::gatedReturnCommand - missing dmaCommand in IOUSBIsocCommand");
		}
	}
	return IOCommandPool::gatedReturnCommand(command);
}