void IOVideoSampleStream::inputCallback(UInt32 token)
{
    USBLog(1, "IOVideoSampleStream::inputCallback(%d)\n", (int)token);

	IOReturn result;
	if (mStreamMode == kIOStreamModeInput)
	{
		do
		{
			IOStreamBufferQueueEntry entry;
			result = dequeueInputEntry(&entry);
			if (result == kIOReturnSuccess)
			{
				IOStreamBuffer *buf = getBufferWithID(entry.bufferID);
				if (NULL == buf)
				{
					USBLog(1, "IOVideoSampleStream::inputCallback Invalid Buffer ID %d\n", (int)entry.bufferID);
					break;
				}
				
				_filledBuffers->setObject(buf);
			}
		} while (result == kIOReturnSuccess);
	}
}
bool
AppleUSBUHCI::RHAreAllPortsDisconnectedOrSuspended( void )
{
    int i;
    UInt16 status;
    bool result = true;
    
    for (i=0; i<kUHCI_NUM_PORTS; i++) 
	{
        status = ReadPortStatus(i);
        if ((status & kUHCI_PORTSC_CCS) && !(status & kUHCI_PORTSC_SUSPEND))
		{
            result = false;
            break;
        }
    }

	// If we have pending bulk or control transactions, then force the result to false
	if ( result )
	{
		if ( _controlBulkTransactionsOut != 0 )
		{
            USBLog(2, "AppleUSBUHCI[%p]::RHAreAllPortsDisconnectedOrSuspended  everything disconnected, but %d control/bulk transactions are pending. ", this, (uint32_t)_controlBulkTransactionsOut);
			result = false;
		}
	}
	
    USBLog(result ? 2 : 6, "AppleUSBUHCI[%p]::RHAreAllPortsDisconnectedOrSuspended returns %d", this, result);
    return result;
}
IOReturn
AppleUSBUHCI::SetRootHubPortFeature(UInt16 wValue, UInt16 port)
{
    IOReturn result = kIOReturnSuccess;
    
    USBLog(5, "AppleUSBUHCI[%p]::SetRootHubPortFeature %d %d", this, wValue, port);
    switch(wValue)
    {
        case kUSBHubPortSuspendFeature :
            result = RHSuspendPort(port, true);
            break;
            
        case kUSBHubPortResetFeature :
            result = RHResetPort(port);
            break;
            
        case kUSBHubPortEnableFeature :
            RHEnablePort(port, true);
            result = kIOReturnSuccess;
            break;
            
        case kUSBHubPortPowerFeature :
            /* Power is always on. */
            result = kIOReturnSuccess;
            break;
            
        default:
            USBLog(5, "AppleUSBUHCI[%p]: unknown feature %d", this, wValue);
            break;
    }
    
    return result;
}
IOReturn
AppleUSBUHCI::SetRootHubFeature(UInt16 wValue)
{
    switch(wValue) 
    { 
        case kUSBHubLocalPowerChangeFeature : 
            USBLog(3,"AppleUSBUHCI[%p]: unimplemented Set Power Change Feature", this); 
            break; 
 
        case kUSBHubOverCurrentChangeFeature : 
            USBLog(3,"AppleUSBUHCI[%p]: unimplemented Set Overcurrent Change Feature", this);
            /* XXX This is erroneously called by the hub device
             * setting kUSBFeatureDeviceRemoteWakeup.
             */
            break; 
 
        default: 
            USBLog(3,"AppleUSBUHCI[%p]: Unknown set hub feature (%d) in root hub", this, wValue);
            break; 
    } 
 
    /* Return success for all unimplemented features,
     * to avoid spurious error messages on the console.
     */            
    return kIOReturnSuccess;
}
IOReturn			
AppleUSBUHCI::RHResumePortCompletion(UInt32 port)
{
	UInt16			value;
	
	USBLog(5, "AppleUSBUHCI[%p]::RHResumePortCompletion - finishing resume on port %d", this, (int)port);
	if (!_rhPortBeingResumed[port-1])
	{
		USBLog(1, "AppleUSBUHCI[%p]::RHResumePortCompletion - port %d does not appear to be resuming!", this, (int)port);
		USBTrace( kUSBTUHCI, kTPUHCIRHResumePortCompletion, (uintptr_t)this, (int)port, 0, kIOReturnInternalError );
		return kIOReturnInternalError;
	}
	
	if (!_controllerAvailable)
	{
		USBLog(5, "AppleUSBEHCI[%p]::RHResumePortCompletion - cannot finish resume on port %d because the controller is unavailable", this, (int)port);
		_rhPortBeingResumed[port-1] = false;
		return kIOReturnInternalError;
	}
	
	value = ReadPortStatus(port-1) & kUHCI_PORTSC_MASK;
	value &= ~(kUHCI_PORTSC_RD | kUHCI_PORTSC_SUSPEND);
	USBLog(5, "AppleUSBUHCI[%p]: de-asserting resume signal by writing (%p)", this, (void*)value);
	WritePortStatus(port-1, value);
	IOSync();
	IOSleep(2);																	// allow it to kick in

	_rhPortBeingResumed[port-1] = false;
	_portSuspendChange[port-1] = true;
	EnsureUsability();
	return kIOReturnSuccess;
}
IOReturn
com_evoluent_driver_VerticalMouse::setPowerState ( unsigned long powerStateOrdinal, IOService* whatDevice )
{
	USBLog(5, "com_evoluent_driver_VerticalMouse[%p]::setPowerState- powerStateOrdinal[%d] _switchBackOnRestart[%s]", this, (int)powerStateOrdinal, _switchBackOnRestart ? "true" : "false");
	if ((powerStateOrdinal == kUSBHIDPowerStateRestart) && _switchBackOnRestart)
	{
		IOUSBDevRequest		devReq;
		IOReturn			err;
		
		// Tell the driver (using a static variable that will survive across termination)
		// that we don't want to switch to 800 dpi on the next driver start
		//
		switchTo800dpi = false;
		
		// Send switch back command.
		devReq.bmRequestType = 0x40;
		devReq.bRequest = 0x01;
		devReq.wValue = 0x05AC;
		devReq.wIndex = 0x0052;		// switch = 0452; switchback = 0052
		devReq.wLength = 0x0000;
		devReq.pData = NULL;
        
		USBLog(5, "com_evoluent_driver_VerticalMouse[%p]::setPowerState - issuing command to switch back", this);
		err = _device->DeviceRequest(&devReq, 5000, 0);
		if (err)
		{
			USBLog(1, "com_evoluent_driver_VerticalMouse[%p]::setPowerState - err (%p) on DeviceRequest", this, (void*)err);
		}
		else
		{
			USBLog(7, "com_evoluent_driver_VerticalMouse[%p]::setPowerState - command done with no err", this);
		}
	}
	return super::setPowerState(powerStateOrdinal, whatDevice);
}
void
AppleUSBUHCI::RHCheckStatus()
{
    int						i;
    UInt16					status;
	
   /* Read port status registers.
    * Check for resumed ports.
    * If the status changed on either, call the
    * port status changed method.
    */
    for (i=0; i<kUHCI_NUM_PORTS; i++) 
	{
		if (!_rhPortBeingResumed[i])								// only check ports which are not being resumed
		{
			status = ReadPortStatus(i);
			if (status & kUHCI_PORTSC_RD) 
			{
				if (_myPowerState >= kUSBPowerStateLowPower)
				{
					if (_myPowerState == kUSBPowerStateLowPower)
						EnsureUsability();
					USBLog(3, "AppleUSBUHCI[%p]::RHCheckStatus - resume detected on port %d, spawning thread to resume", this, i+1);
					_rhPortBeingResumed[i] = true;
					thread_call_enter1(_rhResumePortTimerThread[i], (void*)(i+1));
				}
				else
				{
					USBLog(3, "AppleUSBUHCI[%p]::RHCheckStatus - resume detected while not below low power state, not changing bits until we are back on", this);
				}
			}
		}
    }
}
void
IOUSBControllerListElement::print(int level)
{
#pragma unused (level)
    USBLog(level, "IOUSBControllerListElement[%p]::print - _sharedPhysical[%p]", this, (void *)_sharedPhysical);
    USBLog(level, "IOUSBControllerListElement::print - _sharedLogical[%p]", _sharedLogical);
    USBLog(level, "IOUSBControllerListElement::print - _logicalNext[%p]", _logicalNext);
}
//================================================================================================
//
//   SaveControllerStateForSleep
//
//================================================================================================
//
IOReturn				
AppleUSBUHCI::SaveControllerStateForSleep(void)
{	
	
    USBLog(5, "AppleUSBUHCI[%p]::SaveControllerStateForSleep cancelling rhTimer", this);
	USBLog(5, "AppleUSBUHCI[%p]::SaveControllerStateForSleep SUSPEND - disabling interrupt", this);
	// put the controller into suspend (which suspends all of the downstream ports)
	SuspendController();
	
	return kIOReturnSuccess;
}
IOReturn 
IOUSBController::Write(IOMemoryDescriptor *buffer, USBDeviceAddress address, Endpoint *endpoint, IOUSBCompletion *completion, UInt32 noDataTimeout, UInt32 completionTimeout)
{
    USBLog(7, "%s[%p]::Write #2", getName(), this);
    // Validate that we have a buffer so that we can call getLength on it
    if (!buffer)
    {
        USBLog(5, "%s[%p]::Write #2 - No buffer!.  Returning kIOReturnBadArgument(0x%x)", getName(), this, kIOReturnBadArgument);
	return kIOReturnBadArgument;
    }

    return Write(buffer, address, endpoint, completion, noDataTimeout, completionTimeout, buffer->getLength());
}
Example #11
0
//================================================================================================
//
//   RestartControllerFromReset
//
//================================================================================================
//
IOReturn
AppleUSBUHCI::RestartControllerFromReset(void)
{
	USBTrace( kUSBTUHCI, KTPUHCIRestartControllerFromReset, (uintptr_t)this, 0, 0, 0);
	USBLog(5, "AppleUSBUHCI[%p]::RestartControllerFromReset - _myBusState(%d) CMD(%p) STS(%p) FRBASEADDR(%p) IOPCIConfigCommand(%p)", this, (int)_myBusState, (void*)ioRead16(kUHCI_CMD), (void*)ioRead16(kUHCI_STS), (void*)ioRead32(kUHCI_FRBASEADDR), (void*)_device->configRead16(kIOPCIConfigCommand));

	Run(true);

	// prepare the _saveInterrupts variable for later enabling
	_saveInterrupts = kUHCI_INTR_TIE | kUHCI_INTR_RIE | kUHCI_INTR_IOCE | kUHCI_INTR_SPIE;
	USBLog(5, "AppleUSBUHCI[%p]::RestartControllerFromReset - I set _saveInterrupts to (%p)", this, (void*)_saveInterrupts);
			
	return kIOReturnSuccess;
}
IOReturn
AppleUSBUHCI::GetRootHubPortState(UInt8 *state, UInt16 port)
{
#pragma unused (state, port)
    USBLog(5,"AppleUSBUHCI[%p]::GetRootHubPortState", this);
    return(kIOReturnSuccess);
}
IOReturn
AppleUSBUHCI::SetRootHubDescriptor(OSData *buffer)
{
#pragma unused (buffer)
    USBLog(3,"AppleUSBUHCI[%p]: unimplemented set root hub descriptor", this); 
    return(kIOReturnSuccess); 
}
void
AppleUSBUHCI::RHResumePortTimer(UInt32 port)
{
	// we are responsible for terminating the resume on a root hub port ourselves
	// and we used to do it inside of the workloop. now we do the timing part of it
	// outside of the WL
	if (!_commandGate)
		return;
	
	USBLog(5, "AppleUSBUHCI[%p]::RHResumePortTimer - timing the resume for port %d", this, (int)port);
	IOSleep(20);								// wait 20 ms for the resume to complete
	USBLog(6, "AppleUSBUHCI[%p]::RHResumePortTimer - Host controller resume about to finish - calling EnsureUsability", this);
	EnsureUsability();		

	_commandGate->runAction(RHResumePortCompletionEntry, (void*)port);
}
/* ==== debugging ==== */
void
AppleUSBUHCI::RHDumpPortStatus(int port)
{
    UInt16 value;
    char buf[64];
    static struct {
        UInt16 mask;
        const char *string;
    } strings[] = {
    {kUHCI_PORTSC_SUSPEND, "SUSPEND "},
    {kUHCI_PORTSC_RESET, "RESET "},
    {kUHCI_PORTSC_LS, "LS "},
    {kUHCI_PORTSC_RD, "RD "},
    {kUHCI_PORTSC_LINE0, "LINE0 "},
    {kUHCI_PORTSC_LINE1, "LINE1 "},
    {kUHCI_PORTSC_PEDC, "PEDC "},
    {kUHCI_PORTSC_PED, "PED "},
    {kUHCI_PORTSC_CSC, "CSC "},
    {kUHCI_PORTSC_CCS, "CCS"},
    {0,0}
    };
    int i;
    
    port--; // convert 1-based to 0-based.
    buf[0] = '\0';
    value = ReadPortStatus(port);
    for (i=0; strings[i].string != 0; i++) 
	{
        if ((value & strings[i].mask) != 0) 
		{
            strlcat(buf, strings[i].string, sizeof(buf));
        }
    }
    USBLog(7, "AppleUSBUHCI[%p]: Port %d: status %x %s", this, port+1, value, buf);
}
void 
AppleUSBUHCI::PollInterrupts(IOUSBCompletionAction safeAction)
{
#pragma unused (safeAction)
   USBLog(1, "AppleUSBUHCI[%p]::PollInterrupts (unused)", this);
    // Not used
}
Example #17
0
// this method will override the Platform specific implementation of joinPMtree
// it will cause any IOUSBDevice and IOUSBInterface clients to join the IOPower tree as
// children of the IOUSHubPolicyMaker for the hub to which they are attached
void
IOUSBNub::joinPMtree ( IOService * driver )
{
	IOUSBHubPolicyMaker			*hubPolicyMaker = NULL;
	IOUSBDevice					*device = OSDynamicCast(IOUSBDevice, this);
	IOUSBInterface				*interface = NULL;
	
	
	// we should be either an IOUSBDevice or an IOUSBInterface
	if (device)
		hubPolicyMaker = device->GetHubParent();
	else
	{
		interface = OSDynamicCast(IOUSBInterface, this);

		if (interface && interface->GetDevice())
			hubPolicyMaker = interface->GetDevice()->GetHubParent();
	}

	if (hubPolicyMaker)
	{
		hubPolicyMaker->joinPMtree(driver);
	}
	else
	{
		USBLog(1, "%s[%p]::joinPMtree - no hub policy maker - calling through to super::joinPMtree", getName(), this);
		super::joinPMtree(driver);
	}
	
}
Example #18
0
//================================================================================================
//
//   callPlatformFunction
//
//================================================================================================
//
IOReturn
AppleUSBUHCI::callPlatformFunction(const OSSymbol *functionName,
                                   bool waitForFunction,
                                   void *param1, void *param2,
                                   void *param3, void *param4)
{
    USBLog(3, "AppleUSBUHCI[%p]::callPlatformFunction(%s)",  this, functionName->getCStringNoCopy());
    

	if (!strncmp(functionName->getCStringNoCopy(), "SetDebugDriverPowerState", 24))
	{
		if (param1)
		{
			// system woke from sleep -- do nothing
		}
		else
		{
			// system is going to sleep
			//
			// check if we are the controller for an expressCard port.  If so, then we need to ignore disconnects on suspend for that port  
			// this will avoid the problem where the ExpressCard power goes away, and it looks like the device detaching -- thus waking the machine!
			if ((_badExpressCardAttached) && (_ExpressCardPort > 0) && (_ERRATA64BITS & kErrataSupportsPortResumeEnable))
			{
				// set PCI_RES register to enable ports to wake the computer.
				_device->configWrite8(kUHCI_PCI_RES, 0x03 & ~(1 << (_ExpressCardPort-1)));	// clear the bit for the ExpressCardPort		
			}
		}
	}

    return super::callPlatformFunction(functionName, waitForFunction, param1, param2, param3, param4);
}
bool IOVideoSampleStream::initWithBuffers(OSArray* buffers, IOStreamMode mode, IOItemCount queueLength, OSDictionary* properties)
{
    USBLog(1, "IOVideoSampleStream::initWithBuffers\n");
	
	OSDictionary* props = (OSDictionary*) properties->copyCollection();
	
    if (!super::initWithBuffers(buffers, mode, queueLength, props))
		return false;
    
    mStreamMode = mode;
	OSNumber* theStreamID = OSDynamicCast(OSNumber, properties->getObject(kIOVideoStreamKey_StreamID));
	if (NULL != theStreamID)
		setProperty(kIOVideoStreamKey_StreamID, (OSObject*)theStreamID);
	
	if (props)
		props->release();
	
	_freeBuffers = OSArray::withArray(buffers);
	if (!_freeBuffers)
		return false;

	_filledBuffers = OSArray::withCapacity(_freeBuffers->getCapacity());
	if (!_filledBuffers)
		return false;
		
    return true;
}
Example #20
0
//================================================================================================
//
//   powerStateDidChangeTo
//
//================================================================================================
//
IOReturn
AppleUSBUHCI::powerStateDidChangeTo ( IOPMPowerFlags capabilities, unsigned long newState, IOService* whichDevice)
{
	USBTrace( kUSBTUHCI, KTPUHCIPowerState, (uintptr_t)this, newState, 0, 2);
	USBLog(5, "AppleUSBUHCI[%p]::powerStateDidChangeTo new state (%d)", this, (int)newState);
	showRegisters(7, "powerStateDidChangeTo");
	return super::powerStateDidChangeTo(capabilities, newState, whichDevice);
}
//================================================================================================
//
//   SaveControllerStateForSleep
//
//================================================================================================
//
IOReturn				
AppleUSBOHCI::SaveControllerStateForSleep(void)
{	
	UInt8			pciPMCapOffset = 0;
	UInt16			pmControlStatus = 0;
	
	// <rdar://problem/6623922>
	// The PCI family will have cleared the kPCIPMCSPMEStatus at this point. However, some OHCI controllers will apparently 
	// set the bit again, probably when we actually put the individual ports into suspend. So we need to clear it before we
	// put the controller into global suspend.
	_device->findPCICapability(kIOPCIPowerManagementCapability, &pciPMCapOffset);
	if (pciPMCapOffset > 0x3f)					// must be > 3f, section 3.1
	{
		pmControlStatus = pciPMCapOffset + 4;
	}	
	
	if (pmControlStatus)
	{
		UInt16			pmcsr = _device->configRead16(pmControlStatus);
		USBLog(7, "AppleUSBOHCI[%p]::SaveControllerStateForSleep before PMCS for device (%p) is (%p)", this, _device, (void*)pmcsr);
		if (pmcsr & kPCIPMCSPMEStatus)
		{
			// this one bit (kPCIPMCSPMEStatus) is Read/Write Clear. All other bits are R/W, so we write back the same value we 
			// read so that it will be clear after the write
			_device->configWrite16(pmControlStatus, pmcsr);
			IOSleep(2);
			USBLog(2, "AppleUSBOHCI[%p]::SaveControllerStateForSleep after PMCS for device (%p) is (%p)", this, _device, (void*)_device->configRead16(pmControlStatus));
		}
	}
	
	USBLog(2, "AppleUSBOHCI[%p]::SaveControllerStateForSleep - suspending the bus", this);
	_remote_wakeup_occurred = false;
	
	SuspendUSBBus(true);

	USBLog(2, "AppleUSBOHCI[%p]::SaveControllerStateForSleep - The bus is now suspended", this);
	_myBusState = kUSBBusStateSuspended;
	
	// on PCI PM machines, arm the PME and go to state D3
	if (_hasPCIPwrMgmt)
	{
		_pOHCIRegisters->hcInterruptDisable = HostToUSBLong (kOHCIHcInterrupt_MIE);			// disable interrupts during D3 state
	}
	
	return kIOReturnSuccess;
}
IOReturn
AppleUSBUHCI::GetRootHubStatus(IOUSBHubStatus *status)
{
    USBLog(5, "AppleUSBUHCI[%p]::GetRootHubStatus", this);
    status->statusFlags = 0;
    status->changeFlags = 0;
    return kIOReturnSuccess;
}
IOReturn
AppleUSBUHCI::SetHubAddress(UInt16 functionNumber)
{
    USBLog(5, "AppleUSBUHCI[%p]::SetHubAddress %d", this, functionNumber);
    // XXX Perhaps this is a good point to allocate the root hub endpoint.
    _rootFunctionNumber = functionNumber;
    return kIOReturnSuccess;
}
bool IOVideoSampleStream::handleOpen(IOService* forClient, IOOptionBits options, void* arg)
{
    USBLog(1, "IOVideoSampleStream::handleOpen\n");

	if (!super::handleOpen(forClient, options, arg))
	{
		USBLog(1, "super::handleOpen failed\n");
		return false;
	}
	
	// free all buffers
	_filledBuffers->flushCollection();
	_freeBuffers->flushCollection();
	_freeBuffers->merge(_buffers);
	
	return true;
}
void
AppleUSBUHCI::RHDumpHubPortStatus(IOUSBHubPortStatus *status)
{
    UInt16 value;
    char buf[128];
    static struct {
        UInt16 mask;
        const char *string;
    } strings[] = {
    {kHubPortConnection, "kHubPortConnection "},
    {kHubPortEnabled,    "kHubPortEnabled "},
    {kHubPortSuspend,    "kHubPortSuspend "},
    {kHubPortOverCurrent,"kHubPortOverCurrent "},
    {kHubPortBeingReset, "kHubPortBeingReset "},
    {kHubPortPower,      "kHubPortPower "},
    {kHubPortLowSpeed,   "kHubPortLowSpeed "},
    {kHubPortHighSpeed,  "kHubPortHighSpeed "},
    {kHubPortTestMode,   "kHubPortTestMode "},
    {kHubPortIndicator,  "kHubPortIndicator "},
    {0,0}
    };
    int i;
    
    buf[0] = '\0';
    value = USBToHostWord(status->statusFlags);
    for (i=0; strings[i].string != 0; i++) 
	{
        if ((value & strings[i].mask) != 0) 
		{
            strlcat(buf, strings[i].string, sizeof(buf));
        }
    }
    USBLog(5, "AppleUSBUHCI[%p]: Hub port status: %s", this, buf);
    buf[0] = '\0';
    value = USBToHostWord(status->changeFlags);
    for (i=0; strings[i].string != 0; i++) 
	{
        if ((value & strings[i].mask) != 0) 
		{
            strlcat(buf, strings[i].string, sizeof(buf));
        }
    }
    USBLog(5, "AppleUSBUHCI[%p]: Hub port change: %s", this, buf);
    
}
Example #26
0
//  This routine will look to see if the OSArray contains any matching keys.  The OSArray has to contain a list of OSNumbers.
bool 
IOUSBNub::USBComparePropertyInArrayWithMask( OSDictionary *matching, const char * arrayName, const char * key, const char * maskKey, UInt32 * theProductIDThatMatched )
{
    // We return success iff we match any entry in the array with the key 
	OSArray *		propertyIDArray = NULL;
	OSNumber *		registryProperty = NULL;
	OSNumber *		propertyFromArrayItem = NULL;
    OSNumber *		dictionaryMask = NULL;
    bool			matches = false;
	unsigned int	index;
	
	*theProductIDThatMatched = 0;
	
	// Get our nub's value for the key
	registryProperty = OSDynamicCast(OSNumber, getProperty(key));
	propertyIDArray = OSDynamicCast(OSArray, matching->getObject(arrayName));
    dictionaryMask = OSDynamicCast(OSNumber, matching->getObject(maskKey));
	
	// Iterate over the array looking for the entries
	if (propertyIDArray && registryProperty && dictionaryMask)
	{
		USBLog(7, "%s[%p]::USBComparePropertyInArrayWithMask - found array with capacity of %d", getName(), this, propertyIDArray->getCount());
		
		for (index = 0; index < propertyIDArray->getCount(); index++)
		{
			propertyFromArrayItem = OSDynamicCast(OSNumber, propertyIDArray->getObject(index));
			if (propertyFromArrayItem)
			{
				UInt32  registryValue = registryProperty->unsigned32BitValue();
				UInt32  arrayValue = propertyFromArrayItem->unsigned32BitValue();
				UInt32  mask = dictionaryMask->unsigned32BitValue();
				
				if ( (registryValue & mask) == (arrayValue & mask) )
				{
					USBLog(7, "%s[%p]::USBComparePropertyInArrayWithMask - 0x%x, 0x%x, mask 0x%x matched", getName(), this, (uint32_t)arrayValue, (uint32_t)registryValue, (uint32_t)mask);
					*theProductIDThatMatched = registryValue;
					matches = true;
				}
			}
		}
	}
	
    return matches;
}
Example #27
0
//  This routine will look to see if the OSArray contains any matching keys.  The OSArray has to contain a list of OSNumbers.
bool 
IOUSBNub::USBComparePropertyInArray( OSDictionary *matching, const char * arrayName, const char * key, UInt32 * theProductIDThatMatched )
{
    // We return success iff we match any entry in the array with the key 
	OSArray *		propertyIDArray = NULL;
	OSNumber *		registryProperty = NULL;
	OSNumber *		propertyFromArrayItem = NULL;
    bool			matches = false;
	unsigned int	index;
	
	*theProductIDThatMatched = 0;
	
	// Get our nub's value for the key
	registryProperty = OSDynamicCast(OSNumber, getProperty(key));
	propertyIDArray = OSDynamicCast(OSArray, matching->getObject(arrayName));
	
	// Iterate over the array looking for the entries
	if (propertyIDArray && registryProperty)
	{
		USBLog(7, "%s[%p]::USBComparePropertyInArray - found array with capacity of %d", getName(), this, propertyIDArray->getCount());
		
		for (index = 0; index < propertyIDArray->getCount(); index++)
		{
			propertyFromArrayItem = OSDynamicCast(OSNumber, propertyIDArray->getObject(index));
			if (propertyFromArrayItem)
			{
				// See if this item has the same value as the one in our registry for this key
				matches = propertyFromArrayItem->isEqualTo( registryProperty);
				if (matches)
				{
					*theProductIDThatMatched = propertyFromArrayItem->unsigned32BitValue();
					USBLog(7, "%s[%p]::USBComparePropertyInArray - item %d matched:  id = 0x%x", getName(), this, index, (uint32_t) *theProductIDThatMatched);
					break;
				}
				else 
				{
					USBLog(7, "%s[%p]::USBComparePropertyInArray - item %d did not match", getName(), this, index);
				}
			}
		}
	}
	
    return matches;
}
//================================================================================================
//
//   EnableInterruptsFromController
//
//================================================================================================
//
IOReturn
AppleUSBOHCI::EnableInterruptsFromController(bool enable)
{
	USBTrace( kUSBTOHCI, KTPOHCIEnableInterrupts, (uintptr_t)this, enable, 0, 0);
	if (enable)
	{
		USBLog(2, "AppleUSBOHCI[%p]::EnableInterruptsFromController - enabling interrupts 0x%x", this, (kOHCIHcInterrupt_MIE | kOHCIDefaultInterrupts));
		_pOHCIRegisters->hcInterruptEnable = HostToUSBLong (kOHCIHcInterrupt_MIE | kOHCIDefaultInterrupts);
		IOSync();
	}
	else
	{
		_pOHCIRegisters->hcInterruptDisable = HostToUSBLong (kOHCIHcInterrupt_MIE);			// disable interrupts during D3 state
		IOSync();
		USBLog(2, "AppleUSBOHCI[%p]::EnableInterruptsFromController - interrupts disabled", this);
	}
	
	return kIOReturnSuccess;
}
void IOVideoSampleStream::returnBufferToFreeQueue(IOStreamBuffer* buffer)
{
	if (NULL == buffer)
	{
		USBLog(1, "IOVideoSampleStream::returnBufferToFreeQueue - NULL == returnBufferToFreeQueue\n");
		return;
	}
	
	_freeBuffers->setObject(buffer);
}
IOStreamBuffer* IOVideoSampleStream::getFilledBuffer()
{
	IOStreamBuffer* streamBuffer = OSDynamicCast(IOStreamBuffer, _filledBuffers->getObject(0));
	USBLog(1, "IOVideoSampleStream::getFilledBuffer buffer=%llx", (long long unsigned int)streamBuffer);
	
	if (NULL != streamBuffer)
		_filledBuffers->removeObject (0);

	return streamBuffer;
}