IOUSBRootHubDevice.cpp [plain text]
#include <libkern/OSByteOrder.h>
#include "IOUSBRootHubDevice.h"
#define super IOUSBDevice
#define self this
#define DEBUGGING_LEVEL 0
#define DEBUGLOG IOLog
OSDefineMetaClassAndStructors( IOUSBRootHubDevice, IOUSBDevice )
IOUSBRootHubDevice*
IOUSBRootHubDevice::NewRootHubDevice()
{
return (new IOUSBRootHubDevice);
}
IOReturn
IOUSBRootHubDevice::DeviceRequest(IOUSBDevRequest *request, IOUSBCompletion *completion)
{
return DeviceRequest(request, 0, 0, completion);
}
OSMetaClassDefineReservedUsed(IOUSBRootHubDevice, 0);
IOReturn
IOUSBRootHubDevice::DeviceRequest(IOUSBDevRequest *request, UInt32 noDataTimeout, UInt32 completionTimeout, IOUSBCompletion *completion)
{
IOReturn err = 0;
UInt16 theRequest;
UInt8 dType, dIndex;
if (!request)
return(kIOReturnBadArgument);
#if (DEBUGGING_LEVEL > 0)
DEBUGLOG("%s: deviceRequest([%x,%x],[%x,%x],[%x,%lx])", getName(),
request->bmRequestType,
request->bRequest,
request->wValue, request->wIndex,
request->wLength, (UInt32)request->pData);
#endif
theRequest = (request->bRequest << 8) | request->bmRequestType;
switch (theRequest)
{
case kClearDeviceFeature:
if (request->wIndex == 0)
err = _controller->ClearRootHubFeature(request->wValue);
else
err = kIOReturnBadArgument;
break;
case kGetDescriptor:
dType = request->wValue >> 8;
dIndex = request->wValue & 0x00FF;
switch (dType) {
case kUSBDeviceDesc:
err = _controller->GetRootHubDeviceDescriptor((IOUSBDeviceDescriptor*)request->pData);
request->wLenDone = sizeof(IOUSBDeviceDescriptor);
break;
case kUSBConfDesc:
{
OSData *fullDesc = OSData::withCapacity(1024); UInt16 newLength;
err = _controller->GetRootHubConfDescriptor(fullDesc);
newLength = fullDesc->getLength();
if (newLength < request->wLength)
request->wLength = newLength;
bcopy(fullDesc->getBytesNoCopy(), (char *)request->pData, request->wLength);
request->wLenDone = request->wLength;
fullDesc->free();
break;
}
case kUSBStringDesc:
{
OSData *fullDesc = OSData::withCapacity(1024); UInt16 newLength;
err = _controller->GetRootHubStringDescriptor((request->wValue & 0x00ff), fullDesc);
newLength = fullDesc->getLength();
if (newLength < request->wLength)
request->wLength = newLength;
bcopy(fullDesc->getBytesNoCopy(), (char *)request->pData, request->wLength);
request->wLenDone = request->wLength;
fullDesc->free();
break;
}
default:
err = kIOReturnBadArgument;
}
break;
case kGetDeviceStatus:
if ((request->wValue == 0) && (request->wIndex == 0) && (request->pData != 0))
{
*(UInt16*)(request->pData) = HostToUSBWord(1); request->wLenDone = 2;
}
else
err = kIOReturnBadArgument;
break;
case kSetAddress:
if (request->wIndex == 0)
err = _controller->SetHubAddress(request->wValue);
else
err = kIOReturnBadArgument;
break;
case kSetConfiguration:
if (request->wIndex == 0)
configuration = request->wValue;
else
err = kIOReturnBadArgument;
break;
case kSetDeviceFeature:
if (request->wIndex == 0)
err = _controller->SetRootHubFeature(request->wValue);
else
err = kIOReturnBadArgument;
break;
case kGetConfiguration:
if ((request->wIndex == 0) && (request->pData != 0))
{
*(UInt8*)(request->pData) = configuration;
request->wLenDone = 1;
}
else
err = kIOReturnBadArgument;
break;
case kClearInterfaceFeature:
case kClearEndpointFeature:
case kGetInterface:
case kGetInterfaceStatus:
case kGetEndpointStatus:
case kSetInterfaceFeature:
case kSetEndpointFeature:
case kSetDescriptor:
case kSetInterface:
case kSyncFrame:
err = kIOReturnUnsupported;
break;
case kClearHubFeature:
if (request->wIndex == 0)
err = _controller->ClearRootHubFeature(request->wValue);
else
err = kIOReturnBadArgument;
break;
case kClearPortFeature:
err = _controller->ClearRootHubPortFeature(request->wValue, request->wIndex);
break;
case kGetPortState:
if ((request->wValue == 0) && (request->pData != 0))
err = _controller->GetRootHubPortState((UInt8 *)request->pData, request->wIndex);
else
err = kIOReturnBadArgument;
break;
case kGetHubDescriptor:
if ((request->wValue == ((kUSBHubDescriptorType << 8) + 0)) && (request->pData != 0))
{
err = _controller->GetRootHubDescriptor((IOUSBHubDescriptor *)request->pData);
request->wLenDone = sizeof(IOUSBHubDescriptor);
}
else
err = kIOReturnBadArgument;
break;
case kGetHubStatus:
if ((request->wValue == 0) && (request->wIndex == 0) && (request->pData != 0))
{
err = _controller->GetRootHubStatus((IOUSBHubStatus *)request->pData);
request->wLenDone = sizeof(IOUSBHubStatus);
}
else
err = kIOReturnBadArgument;
break;
case kGetPortStatus:
if ((request->wValue == 0) && (request->pData != 0))
{
err = _controller->GetRootHubPortStatus((IOUSBHubPortStatus *)request->pData, request->wIndex);
request->wLenDone = sizeof(IOUSBHubPortStatus);
}
else
err = kIOReturnBadArgument;
break;
case kSetHubDescriptor:
if (request->pData != 0)
err = _controller->SetRootHubDescriptor((OSData *)request->pData);
else
err = kIOReturnBadArgument;
break;
case kSetHubFeature:
if (request->wIndex == 0)
err = _controller->SetRootHubFeature(request->wValue);
else
err = kIOReturnBadArgument;
break;
case kSetPortFeature:
err = _controller->SetRootHubPortFeature(request->wValue, request->wIndex);
break;
default:
err = kIOReturnBadArgument;
}
return(err);
}
OSMetaClassDefineReservedUnused(IOUSBRootHubDevice, 1);
OSMetaClassDefineReservedUnused(IOUSBRootHubDevice, 2);
OSMetaClassDefineReservedUnused(IOUSBRootHubDevice, 3);
OSMetaClassDefineReservedUnused(IOUSBRootHubDevice, 4);