[USBEHCI_NEW]
- Fix bug in CDMAMemoryManager initialization, which calculated the bitmap length wrong
- Create interface IUSBDevice, which will be used to abstract connected usb devices
- Implement support functions for the device interface.
- Implement USBHI_CreateUsbDevice, USBHI_InitializeUsbDevice, USBHI_GetUsbDescriptors, USBHI_RemoveUsbDevice, USBHI_GetExtendedHubInformation, USBHI_RootHubInitNotification, USBHI_SetDeviceHandleData, USBDI_GetUSBDIVersion, USBDI_IsDeviceHighSpeed
- Partly implement USBHI_QueryDeviceInformation
- Based on mjmartin usbehci
svn path=/branches/usb-bringup/; revision=51372
2011-04-17 08:20:40 +00:00
/*
* PROJECT : ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
* LICENSE : GPL - See COPYING in the top level directory
* FILE : drivers / usb / usbehci / usb_device . cpp
* PURPOSE : USB EHCI device driver .
* PROGRAMMERS :
* Michael Martin ( michael . martin @ reactos . org )
* Johannes Anderwald ( johannes . anderwald @ reactos . org )
*/
# define INITGUID
# include "usbehci.h"
2011-04-19 18:35:40 +00:00
typedef struct _USB_ENDPOINT
{
USB_ENDPOINT_DESCRIPTOR EndPointDescriptor ;
} USB_ENDPOINT , * PUSB_ENDPOINT ;
typedef struct _USB_INTERFACE
{
USB_INTERFACE_DESCRIPTOR InterfaceDescriptor ;
USB_ENDPOINT * EndPoints ;
} USB_INTERFACE , * PUSB_INTERFACE ;
typedef struct _USB_CONFIGURATION
{
USB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor ;
USB_INTERFACE * Interfaces ;
} USB_CONFIGURATION , * PUSB_CONFIGURATION ;
2011-04-17 19:23:13 +00:00
class CUSBDevice : public IUSBDevice
{
public :
STDMETHODIMP QueryInterface ( REFIID InterfaceId , PVOID * Interface ) ;
STDMETHODIMP_ ( ULONG ) AddRef ( )
{
InterlockedIncrement ( & m_Ref ) ;
return m_Ref ;
}
STDMETHODIMP_ ( ULONG ) Release ( )
{
InterlockedDecrement ( & m_Ref ) ;
if ( ! m_Ref )
{
delete this ;
return 0 ;
}
return m_Ref ;
}
// IUSBDevice interface functions
virtual NTSTATUS Initialize ( IN PHUBCONTROLLER HubController , IN PUSBHARDWAREDEVICE Device , IN PVOID Parent , IN ULONG Port , IN ULONG PortStatus ) ;
virtual BOOLEAN IsHub ( ) ;
virtual NTSTATUS GetParent ( PVOID * Parent ) ;
2011-04-19 18:35:40 +00:00
virtual UCHAR GetDeviceAddress ( ) ;
2011-04-17 19:23:13 +00:00
virtual ULONG GetPort ( ) ;
virtual USB_DEVICE_SPEED GetSpeed ( ) ;
virtual USB_DEVICE_TYPE GetType ( ) ;
virtual ULONG GetState ( ) ;
virtual void SetDeviceHandleData ( PVOID Data ) ;
2011-04-19 18:35:40 +00:00
virtual NTSTATUS SetDeviceAddress ( UCHAR DeviceAddress ) ;
2011-04-17 19:23:13 +00:00
virtual void GetDeviceDescriptor ( PUSB_DEVICE_DESCRIPTOR DeviceDescriptor ) ;
virtual UCHAR GetConfigurationValue ( ) ;
2011-04-19 18:35:40 +00:00
virtual NTSTATUS SubmitIrp ( PIRP Irp ) ;
2011-04-24 09:26:22 +00:00
virtual VOID GetConfigurationDescriptors ( IN PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptorBuffer , IN ULONG BufferLength , OUT PULONG OutBufferLength ) ;
2011-04-28 17:45:32 +00:00
virtual ULONG GetConfigurationDescriptorsLength ( ) ;
2011-04-28 23:59:53 +00:00
virtual NTSTATUS SubmitSetupPacket ( IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket , OUT ULONG BufferLength , OUT PVOID Buffer ) ;
2011-04-29 02:46:04 +00:00
virtual NTSTATUS SelectConfiguration ( IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor , IN PUSBD_INTERFACE_INFORMATION Interface , OUT USBD_CONFIGURATION_HANDLE * ConfigurationHandle ) ;
virtual NTSTATUS SelectInterface ( IN USBD_CONFIGURATION_HANDLE ConfigurationHandle , IN OUT PUSBD_INTERFACE_INFORMATION Interface ) ;
2011-04-17 19:23:13 +00:00
// local function
2011-04-19 18:35:40 +00:00
virtual NTSTATUS CommitIrp ( PIRP Irp ) ;
2011-04-29 02:46:04 +00:00
virtual NTSTATUS CommitSetupPacket ( PUSB_DEFAULT_PIPE_SETUP_PACKET Packet , IN OPTIONAL PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor , IN ULONG BufferLength , IN OUT PMDL Mdl ) ;
2011-04-19 18:35:40 +00:00
virtual NTSTATUS CreateConfigurationDescriptor ( ULONG ConfigurationIndex ) ;
virtual NTSTATUS CreateDeviceDescriptor ( ) ;
2011-04-28 15:16:33 +00:00
virtual VOID DumpDeviceDescriptor ( PUSB_DEVICE_DESCRIPTOR DeviceDescriptor ) ;
2011-04-28 17:45:32 +00:00
virtual VOID DumpConfigurationDescriptor ( PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor ) ;
2011-04-17 19:23:13 +00:00
// constructor / destructor
CUSBDevice ( IUnknown * OuterUnknown ) { }
virtual ~ CUSBDevice ( ) { }
protected :
LONG m_Ref ;
PHUBCONTROLLER m_HubController ;
PUSBHARDWAREDEVICE m_Device ;
PVOID m_Parent ;
ULONG m_Port ;
2011-04-19 18:35:40 +00:00
UCHAR m_DeviceAddress ;
2011-04-17 19:23:13 +00:00
PVOID m_Data ;
2011-04-29 02:46:04 +00:00
UCHAR m_ConfigurationIndex ;
2011-04-17 19:23:13 +00:00
KSPIN_LOCK m_Lock ;
USB_DEVICE_DESCRIPTOR m_DeviceDescriptor ;
ULONG m_PortStatus ;
PUSBQUEUE m_Queue ;
2011-04-19 01:21:10 +00:00
PDMAMEMORYMANAGER m_DmaManager ;
2011-04-19 18:35:40 +00:00
PUSB_CONFIGURATION m_ConfigurationDescriptors ;
2011-04-17 19:23:13 +00:00
} ;
[USBEHCI_NEW]
- Fix bug in CDMAMemoryManager initialization, which calculated the bitmap length wrong
- Create interface IUSBDevice, which will be used to abstract connected usb devices
- Implement support functions for the device interface.
- Implement USBHI_CreateUsbDevice, USBHI_InitializeUsbDevice, USBHI_GetUsbDescriptors, USBHI_RemoveUsbDevice, USBHI_GetExtendedHubInformation, USBHI_RootHubInitNotification, USBHI_SetDeviceHandleData, USBDI_GetUSBDIVersion, USBDI_IsDeviceHighSpeed
- Partly implement USBHI_QueryDeviceInformation
- Based on mjmartin usbehci
svn path=/branches/usb-bringup/; revision=51372
2011-04-17 08:20:40 +00:00
2011-04-17 19:23:13 +00:00
//----------------------------------------------------------------------------------------
[USBEHCI_NEW]
- Fix bug in CDMAMemoryManager initialization, which calculated the bitmap length wrong
- Create interface IUSBDevice, which will be used to abstract connected usb devices
- Implement support functions for the device interface.
- Implement USBHI_CreateUsbDevice, USBHI_InitializeUsbDevice, USBHI_GetUsbDescriptors, USBHI_RemoveUsbDevice, USBHI_GetExtendedHubInformation, USBHI_RootHubInitNotification, USBHI_SetDeviceHandleData, USBDI_GetUSBDIVersion, USBDI_IsDeviceHighSpeed
- Partly implement USBHI_QueryDeviceInformation
- Based on mjmartin usbehci
svn path=/branches/usb-bringup/; revision=51372
2011-04-17 08:20:40 +00:00
NTSTATUS
2011-04-17 19:23:13 +00:00
STDMETHODCALLTYPE
CUSBDevice : : QueryInterface (
IN REFIID refiid ,
OUT PVOID * Output )
{
return STATUS_UNSUCCESSFUL ;
}
//----------------------------------------------------------------------------------------
NTSTATUS
CUSBDevice : : Initialize (
IN PHUBCONTROLLER HubController ,
IN PUSBHARDWAREDEVICE Device ,
IN PVOID Parent ,
IN ULONG Port ,
IN ULONG PortStatus )
{
NTSTATUS Status ;
//
// initialize members
//
m_HubController = HubController ;
m_Device = Device ;
m_Parent = Parent ;
m_Port = Port ;
m_PortStatus = PortStatus ;
//
// initialize device lock
//
KeInitializeSpinLock ( & m_Lock ) ;
//
// no device address has been set yet
//
m_DeviceAddress = 0 ;
//
// get usb request queue
//
Status = m_Device - > GetUSBQueue ( & m_Queue ) ;
if ( ! NT_SUCCESS ( Status ) )
{
//
// failed to get usb queue
//
DPRINT1 ( " CUSBDevice::Initialize GetUsbQueue failed with %x \n " , Status ) ;
return Status ;
}
2011-04-19 01:21:10 +00:00
//
2011-04-19 18:35:40 +00:00
// get dma manager
2011-04-19 01:21:10 +00:00
//
2011-04-19 18:35:40 +00:00
Status = m_Device - > GetDMA ( & m_DmaManager ) ;
2011-04-19 01:21:10 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
//
2011-04-19 18:35:40 +00:00
// failed to get dma manager
2011-04-19 01:21:10 +00:00
//
2011-04-19 18:35:40 +00:00
DPRINT1 ( " CUSBDevice::Initialize GetDMA failed with %x \n " , Status ) ;
2011-04-19 01:21:10 +00:00
return Status ;
}
2011-04-17 19:23:13 +00:00
//
2011-04-19 18:35:40 +00:00
// sanity check
2011-04-17 19:23:13 +00:00
//
2011-04-19 18:35:40 +00:00
PC_ASSERT ( m_DmaManager ) ;
2011-04-17 19:23:13 +00:00
//
2011-04-19 18:35:40 +00:00
// get device descriptor
2011-04-17 19:23:13 +00:00
//
2011-04-19 18:35:40 +00:00
Status = CreateDeviceDescriptor ( ) ;
2011-04-17 19:23:13 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
2011-04-19 18:35:40 +00:00
//
// failed to get device descriptor
//
DPRINT1 ( " CUSBDevice::Initialize Failed to get device descriptor with %x \n " , Status ) ;
return Status ;
2011-04-17 19:23:13 +00:00
}
//
// done
//
return Status ;
}
//----------------------------------------------------------------------------------------
BOOLEAN
CUSBDevice : : IsHub ( )
{
//
// USB Standard Device Class see http://www.usb.org/developers/defined_class/#BaseClass09h
// for details
//
return ( m_DeviceDescriptor . bDeviceClass = = 0x09 & & m_DeviceDescriptor . bDeviceSubClass = = 0x00 ) ;
}
//----------------------------------------------------------------------------------------
NTSTATUS
CUSBDevice : : GetParent (
PVOID * Parent )
{
//
// returns parent
//
* Parent = m_Parent ;
//
// done
//
return STATUS_SUCCESS ;
}
//----------------------------------------------------------------------------------------
2011-04-19 18:35:40 +00:00
UCHAR
2011-04-17 19:23:13 +00:00
CUSBDevice : : GetDeviceAddress ( )
{
//
// get device address
//
return m_DeviceAddress ;
}
//----------------------------------------------------------------------------------------
ULONG
CUSBDevice : : GetPort ( )
{
//
// get port to which this device is connected to
//
return m_Port ;
}
//----------------------------------------------------------------------------------------
USB_DEVICE_SPEED
CUSBDevice : : GetSpeed ( )
{
if ( m_PortStatus & USB_PORT_STATUS_LOW_SPEED )
{
//
// low speed device
//
return UsbLowSpeed ;
}
else if ( m_PortStatus & USB_PORT_STATUS_HIGH_SPEED )
{
//
// high speed device
//
return UsbHighSpeed ;
}
//
// default to full speed
//
return UsbFullSpeed ;
}
//----------------------------------------------------------------------------------------
USB_DEVICE_TYPE
CUSBDevice : : GetType ( )
{
//
// device is encoded into bcdUSB
//
if ( m_DeviceDescriptor . bcdUSB = = 0x110 )
{
//
// USB 1.1 device
//
return Usb11Device ;
}
else if ( m_DeviceDescriptor . bcdUSB = = 0x200 )
{
//
// USB 2.0 device
//
return Usb20Device ;
}
DPRINT1 ( " CUSBDevice::GetType Unknown bcdUSB Type %x \n " , m_DeviceDescriptor . bcdUSB ) ;
PC_ASSERT ( FALSE ) ;
return Usb11Device ;
}
//----------------------------------------------------------------------------------------
ULONG
CUSBDevice : : GetState ( )
{
UNIMPLEMENTED
return FALSE ;
}
//----------------------------------------------------------------------------------------
void
CUSBDevice : : SetDeviceHandleData (
PVOID Data )
{
//
// set device data, for debugging issues
//
m_Data = Data ;
}
//----------------------------------------------------------------------------------------
NTSTATUS
CUSBDevice : : SetDeviceAddress (
2011-04-19 18:35:40 +00:00
UCHAR DeviceAddress )
2011-04-17 19:23:13 +00:00
{
2011-04-28 16:40:07 +00:00
PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup ;
2011-04-17 19:23:13 +00:00
NTSTATUS Status ;
2011-04-19 18:35:40 +00:00
UCHAR OldAddress ;
ULONG Index ;
2011-04-17 19:23:13 +00:00
2011-04-28 16:40:07 +00:00
DPRINT1 ( " CUSBDevice::SetDeviceAddress Address %d \n " , DeviceAddress ) ;
CtrlSetup = ( PUSB_DEFAULT_PIPE_SETUP_PACKET ) ExAllocatePoolWithTag ( NonPagedPool , sizeof ( USB_DEFAULT_PIPE_SETUP_PACKET ) , TAG_USBEHCI ) ;
if ( ! CtrlSetup )
return STATUS_INSUFFICIENT_RESOURCES ;
2011-04-17 19:23:13 +00:00
//
// zero request
//
2011-04-28 16:40:07 +00:00
RtlZeroMemory ( CtrlSetup , sizeof ( USB_DEFAULT_PIPE_SETUP_PACKET ) ) ;
2011-04-17 19:23:13 +00:00
//
// initialize request
//
2011-04-28 16:40:07 +00:00
CtrlSetup - > bRequest = USB_REQUEST_SET_ADDRESS ;
CtrlSetup - > wValue . W = ( USHORT ) DeviceAddress ;
2011-04-17 19:23:13 +00:00
//
// set device address
//
2011-04-29 02:46:04 +00:00
Status = CommitSetupPacket ( CtrlSetup , 0 , 0 , 0 ) ;
2011-04-28 16:40:07 +00:00
//
// free setup packet
//
ExFreePoolWithTag ( CtrlSetup , TAG_USBEHCI ) ;
2011-04-17 19:23:13 +00:00
//
// check for success
//
if ( ! NT_SUCCESS ( Status ) )
{
//
// failed to set device address
//
DPRINT1 ( " CUSBDevice::SetDeviceAddress> failed to set device address with %x Address %x \n " , Status , DeviceAddress ) ;
return Status ;
}
2011-04-28 15:16:33 +00:00
//
// lets have a short nap
//
KeStallExecutionProcessor ( 300 ) ;
2011-04-17 19:23:13 +00:00
//
2011-04-19 18:35:40 +00:00
// back up old address
//
OldAddress = m_DeviceAddress ;
//
// store new device address
2011-04-17 19:23:13 +00:00
//
m_DeviceAddress = DeviceAddress ;
2011-04-19 18:35:40 +00:00
//
// check that setting device address succeeded by retrieving the device descriptor
//
Status = CreateDeviceDescriptor ( ) ;
if ( ! NT_SUCCESS ( Status ) )
{
//
// failed to retrieve device descriptor
//
2011-04-28 16:40:07 +00:00
DPRINT1 ( " CUSBbDevice::SetDeviceAddress> failed to retrieve device descriptor with device address set Error %x \n " , Status ) ;
2011-04-19 18:35:40 +00:00
m_DeviceAddress = OldAddress ;
//
// return error status
//
return Status ;
}
//
// sanity checks
//
PC_ASSERT ( m_DeviceDescriptor . bNumConfigurations ) ;
//
// allocate configuration descriptor
//
m_ConfigurationDescriptors = ( PUSB_CONFIGURATION ) ExAllocatePoolWithTag ( NonPagedPool , sizeof ( USB_CONFIGURATION ) * m_DeviceDescriptor . bNumConfigurations , TAG_USBEHCI ) ;
//
// zero configuration descriptor
//
RtlZeroMemory ( m_ConfigurationDescriptors , sizeof ( USB_CONFIGURATION ) * m_DeviceDescriptor . bNumConfigurations ) ;
//
// retrieve the configuration descriptors
//
for ( Index = 0 ; Index < m_DeviceDescriptor . bNumConfigurations ; Index + + )
{
//
// retrieve configuration descriptors from device
//
Status = CreateConfigurationDescriptor ( Index ) ;
if ( ! NT_SUCCESS ( Status ) )
{
DPRINT1 ( " CUSBDevice::SetDeviceAddress> failed to retrieve configuration %lu \n " , Index ) ;
break ;
}
}
2011-04-17 19:23:13 +00:00
//
// done
//
2011-04-19 18:35:40 +00:00
return Status ;
2011-04-17 19:23:13 +00:00
}
//----------------------------------------------------------------------------------------
void
CUSBDevice : : GetDeviceDescriptor (
PUSB_DEVICE_DESCRIPTOR DeviceDescriptor )
{
RtlMoveMemory ( DeviceDescriptor , & m_DeviceDescriptor , sizeof ( USB_DEVICE_DESCRIPTOR ) ) ;
}
//----------------------------------------------------------------------------------------
UCHAR
CUSBDevice : : GetConfigurationValue ( )
{
2011-04-29 02:46:04 +00:00
//
// return configuration index
//
return m_ConfigurationIndex ;
2011-04-17 19:23:13 +00:00
}
//----------------------------------------------------------------------------------------
NTSTATUS
2011-04-19 18:35:40 +00:00
CUSBDevice : : CommitIrp (
PIRP Irp )
[USBEHCI_NEW]
- Fix bug in CDMAMemoryManager initialization, which calculated the bitmap length wrong
- Create interface IUSBDevice, which will be used to abstract connected usb devices
- Implement support functions for the device interface.
- Implement USBHI_CreateUsbDevice, USBHI_InitializeUsbDevice, USBHI_GetUsbDescriptors, USBHI_RemoveUsbDevice, USBHI_GetExtendedHubInformation, USBHI_RootHubInitNotification, USBHI_SetDeviceHandleData, USBDI_GetUSBDIVersion, USBDI_IsDeviceHighSpeed
- Partly implement USBHI_QueryDeviceInformation
- Based on mjmartin usbehci
svn path=/branches/usb-bringup/; revision=51372
2011-04-17 08:20:40 +00:00
{
2011-04-19 18:35:40 +00:00
NTSTATUS Status ;
PUSBREQUEST Request ;
2011-04-29 13:16:03 +00:00
if ( ! m_Queue | | ! m_DmaManager )
2011-04-19 18:35:40 +00:00
{
//
// no queue, wtf?
//
DPRINT1 ( " CUSBDevice::CommitUrb> no queue / dma !!! \n " ) ;
return STATUS_UNSUCCESSFUL ;
}
//
// build usb request
//
Status = m_Queue - > CreateUSBRequest ( & Request ) ;
if ( ! NT_SUCCESS ( Status ) )
{
//
// failed to build request
//
DPRINT1 ( " CUSBDevice::CommitSetupPacket> CreateUSBRequest failed with %x \n " , Status ) ;
return Status ;
}
//
// initialize request
//
Status = Request - > InitializeWithIrp ( m_DmaManager , Irp ) ;
2011-04-30 08:04:35 +00:00
//
// mark irp as pending
//
IoMarkIrpPending ( Irp ) ;
2011-04-19 18:35:40 +00:00
//
// now add the request
//
Status = m_Queue - > AddUSBRequest ( Request ) ;
if ( ! NT_SUCCESS ( Status ) )
{
//
// failed to add request
//
DPRINT1 ( " CUSBDevice::CommitSetupPacket> failed add request to queue with %x \n " , Status ) ;
Request - > Release ( ) ;
return Status ;
}
//
// done
//
2011-04-30 08:04:35 +00:00
return STATUS_PENDING ;
[USBEHCI_NEW]
- Fix bug in CDMAMemoryManager initialization, which calculated the bitmap length wrong
- Create interface IUSBDevice, which will be used to abstract connected usb devices
- Implement support functions for the device interface.
- Implement USBHI_CreateUsbDevice, USBHI_InitializeUsbDevice, USBHI_GetUsbDescriptors, USBHI_RemoveUsbDevice, USBHI_GetExtendedHubInformation, USBHI_RootHubInitNotification, USBHI_SetDeviceHandleData, USBDI_GetUSBDIVersion, USBDI_IsDeviceHighSpeed
- Partly implement USBHI_QueryDeviceInformation
- Based on mjmartin usbehci
svn path=/branches/usb-bringup/; revision=51372
2011-04-17 08:20:40 +00:00
}
2011-04-17 19:23:13 +00:00
//----------------------------------------------------------------------------------------
NTSTATUS
2011-04-19 18:35:40 +00:00
CUSBDevice : : SubmitIrp (
PIRP Irp )
2011-04-17 19:23:13 +00:00
{
KIRQL OldLevel ;
NTSTATUS Status ;
//
// acquire device lock
//
KeAcquireSpinLock ( & m_Lock , & OldLevel ) ;
//
// commit urb
//
2011-04-19 18:35:40 +00:00
Status = CommitIrp ( Irp ) ;
2011-04-17 19:23:13 +00:00
//
// release lock
//
KeReleaseSpinLock ( & m_Lock , OldLevel ) ;
return Status ;
}
//----------------------------------------------------------------------------------------
NTSTATUS
CUSBDevice : : CommitSetupPacket (
2011-04-29 02:46:04 +00:00
IN PUSB_DEFAULT_PIPE_SETUP_PACKET Packet ,
IN OPTIONAL PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor ,
2011-04-17 19:23:13 +00:00
IN ULONG BufferLength ,
2011-04-19 18:35:40 +00:00
IN OUT PMDL Mdl )
2011-04-17 19:23:13 +00:00
{
NTSTATUS Status ;
PUSBREQUEST Request ;
if ( ! m_Queue )
{
//
// no queue, wtf?
//
DPRINT1 ( " CUSBDevice::CommitSetupPacket> no queue!!! \n " ) ;
return STATUS_UNSUCCESSFUL ;
}
//
// build usb request
//
Status = m_Queue - > CreateUSBRequest ( & Request ) ;
if ( ! NT_SUCCESS ( Status ) )
{
//
// failed to build request
//
DPRINT1 ( " CUSBDevice::CommitSetupPacket> CreateUSBRequest failed with %x \n " , Status ) ;
return Status ;
}
//
// initialize request
//
2011-04-29 02:46:04 +00:00
Status = Request - > InitializeWithSetupPacket ( m_DmaManager , Packet , m_DeviceAddress , EndpointDescriptor , BufferLength , Mdl ) ;
2011-04-17 19:23:13 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
//
// failed to initialize request
//
DPRINT1 ( " CUSBDevice::CommitSetupPacket> failed to initialize usb request with %x \n " , Status ) ;
Request - > Release ( ) ;
return Status ;
}
//
2011-04-19 18:35:40 +00:00
// now add the request
2011-04-17 19:23:13 +00:00
//
2011-04-19 18:35:40 +00:00
Status = m_Queue - > AddUSBRequest ( Request ) ;
if ( ! NT_SUCCESS ( Status ) )
2011-04-17 19:23:13 +00:00
{
//
2011-04-19 18:35:40 +00:00
// failed to add request
2011-04-17 19:23:13 +00:00
//
2011-04-19 18:35:40 +00:00
DPRINT1 ( " CUSBDevice::CommitSetupPacket> failed add request to queue with %x \n " , Status ) ;
Request - > Release ( ) ;
return Status ;
2011-04-17 19:23:13 +00:00
}
//
2011-04-19 18:35:40 +00:00
// get the result code when the operation has been finished
2011-04-17 19:23:13 +00:00
//
2011-04-19 18:35:40 +00:00
Request - > GetResultStatus ( & Status , NULL ) ;
//
// release request
//
Request - > Release ( ) ;
//
// done
//
return Status ;
}
//----------------------------------------------------------------------------------------
NTSTATUS
CUSBDevice : : CreateDeviceDescriptor ( )
{
USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup ;
PMDL Mdl ;
NTSTATUS Status ;
//
// zero descriptor
//
RtlZeroMemory ( & m_DeviceDescriptor , sizeof ( USB_DEVICE_DESCRIPTOR ) ) ;
RtlZeroMemory ( & CtrlSetup , sizeof ( USB_DEFAULT_PIPE_SETUP_PACKET ) ) ;
//
// setup request
//
CtrlSetup . bRequest = USB_REQUEST_GET_DESCRIPTOR ;
CtrlSetup . wValue . HiByte = USB_DEVICE_DESCRIPTOR_TYPE ;
CtrlSetup . wLength = sizeof ( USB_DEVICE_DESCRIPTOR ) ;
CtrlSetup . bmRequestType . B = 0x80 ;
//
// allocate mdl describing the device descriptor
//
Mdl = IoAllocateMdl ( & m_DeviceDescriptor , sizeof ( USB_DEVICE_DESCRIPTOR ) , FALSE , FALSE , 0 ) ;
if ( ! Mdl )
2011-04-17 19:23:13 +00:00
{
//
2011-04-19 18:35:40 +00:00
// failed to allocate mdl
2011-04-17 19:23:13 +00:00
//
2011-04-19 18:35:40 +00:00
return STATUS_INSUFFICIENT_RESOURCES ;
2011-04-17 19:23:13 +00:00
}
2011-04-19 18:35:40 +00:00
2011-04-17 19:23:13 +00:00
//
2011-04-19 18:35:40 +00:00
// build mdl for non paged pool
2011-04-17 19:23:13 +00:00
//
2011-04-19 18:35:40 +00:00
MmBuildMdlForNonPagedPool ( Mdl ) ;
//
// commit setup packet
//
2011-04-29 02:46:04 +00:00
Status = CommitSetupPacket ( & CtrlSetup , 0 , sizeof ( USB_DEVICE_DESCRIPTOR ) , Mdl ) ;
2011-04-19 18:35:40 +00:00
//
// now free the mdl
//
IoFreeMdl ( Mdl ) ;
2011-04-28 15:16:33 +00:00
if ( NT_SUCCESS ( Status ) )
{
//
// informal dbg print
//
DumpDeviceDescriptor ( & m_DeviceDescriptor ) ;
}
2011-04-19 18:35:40 +00:00
//
// done
//
return Status ;
}
//----------------------------------------------------------------------------------------
NTSTATUS
CUSBDevice : : CreateConfigurationDescriptor (
ULONG Index )
{
PVOID Buffer ;
USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup ;
NTSTATUS Status ;
PMDL Mdl ;
ULONG InterfaceIndex , EndPointIndex ;
PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor ;
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor ;
PUSB_ENDPOINT_DESCRIPTOR EndPointDescriptor ;
//
// sanity checks
//
PC_ASSERT ( m_ConfigurationDescriptors ) ;
//
// first allocate a buffer which should be enough to store all different interfaces and endpoints
//
Buffer = ExAllocatePoolWithTag ( NonPagedPool , PAGE_SIZE , TAG_USBEHCI ) ;
if ( ! Buffer )
{
//
// failed to allocate buffer
//
return STATUS_INSUFFICIENT_RESOURCES ;
}
//
// build setup packet
//
CtrlSetup . bmRequestType . _BM . Recipient = BMREQUEST_TO_DEVICE ;
CtrlSetup . bmRequestType . _BM . Type = BMREQUEST_STANDARD ;
CtrlSetup . bmRequestType . _BM . Reserved = 0 ;
CtrlSetup . bmRequestType . _BM . Dir = BMREQUEST_DEVICE_TO_HOST ;
CtrlSetup . bRequest = USB_REQUEST_GET_DESCRIPTOR ;
CtrlSetup . wValue . LowByte = 0 ;
CtrlSetup . wValue . HiByte = USB_CONFIGURATION_DESCRIPTOR_TYPE ;
CtrlSetup . wIndex . W = 0 ;
CtrlSetup . wLength = PAGE_SIZE ;
//
// FIXME: where put configuration index?
//
//
// now build MDL describing the buffer
//
Mdl = IoAllocateMdl ( Buffer , PAGE_SIZE , FALSE , FALSE , 0 ) ;
if ( ! Mdl )
{
//
// failed to allocate mdl
//
ExFreePoolWithTag ( Buffer , TAG_USBEHCI ) ;
return STATUS_INSUFFICIENT_RESOURCES ;
}
//
// build mdl for non paged pool
//
MmBuildMdlForNonPagedPool ( Mdl ) ;
//
// commit packet
//
2011-04-29 02:46:04 +00:00
Status = CommitSetupPacket ( & CtrlSetup , 0 , PAGE_SIZE , Mdl ) ;
2011-04-17 19:23:13 +00:00
if ( ! NT_SUCCESS ( Status ) )
{
//
2011-04-19 18:35:40 +00:00
// failed to issue request, cleanup
2011-04-17 19:23:13 +00:00
//
2011-04-19 18:35:40 +00:00
IoFreeMdl ( Mdl ) ;
ExFreePool ( Buffer ) ;
2011-04-17 19:23:13 +00:00
return Status ;
}
2011-04-19 18:35:40 +00:00
//
// now free the mdl
//
IoFreeMdl ( Mdl ) ;
//
// get configuration descriptor
//
ConfigurationDescriptor = ( PUSB_CONFIGURATION_DESCRIPTOR ) Buffer ;
2011-04-28 17:45:32 +00:00
//
// informal debug print
//
DumpConfigurationDescriptor ( ConfigurationDescriptor ) ;
2011-04-19 18:35:40 +00:00
//
// sanity check
//
PC_ASSERT ( ConfigurationDescriptor - > bLength = = sizeof ( USB_CONFIGURATION_DESCRIPTOR ) ) ;
PC_ASSERT ( ConfigurationDescriptor - > wTotalLength < = PAGE_SIZE ) ;
PC_ASSERT ( ConfigurationDescriptor - > bNumInterfaces ) ;
//
// request is complete, initialize configuration descriptor
//
RtlCopyMemory ( & m_ConfigurationDescriptors [ Index ] . ConfigurationDescriptor , ConfigurationDescriptor , ConfigurationDescriptor - > bLength ) ;
//
// now allocate interface descriptors
//
m_ConfigurationDescriptors [ Index ] . Interfaces = ( PUSB_INTERFACE ) ExAllocatePoolWithTag ( NonPagedPool , sizeof ( USB_INTERFACE ) * ConfigurationDescriptor - > bNumInterfaces , TAG_USBEHCI ) ;
if ( ! m_ConfigurationDescriptors [ Index ] . Interfaces )
2011-04-17 19:23:13 +00:00
{
//
2011-04-19 18:35:40 +00:00
// failed to allocate interface descriptors
2011-04-17 19:23:13 +00:00
//
2011-04-19 18:35:40 +00:00
ExFreePool ( Buffer ) ;
return STATUS_INSUFFICIENT_RESOURCES ;
2011-04-17 19:23:13 +00:00
}
//
2011-04-19 18:35:40 +00:00
// zero interface descriptor
//
RtlZeroMemory ( m_ConfigurationDescriptors [ Index ] . Interfaces , sizeof ( USB_INTERFACE ) * ConfigurationDescriptor - > bNumInterfaces ) ;
2011-04-17 19:23:13 +00:00
//
2011-04-19 18:35:40 +00:00
// get first interface descriptor
2011-04-17 19:23:13 +00:00
//
2011-04-19 18:35:40 +00:00
InterfaceDescriptor = ( PUSB_INTERFACE_DESCRIPTOR ) ( ConfigurationDescriptor + 1 ) ;
2011-04-17 19:23:13 +00:00
//
2011-04-19 18:35:40 +00:00
// setup interface descriptors
2011-04-17 19:23:13 +00:00
//
2011-04-19 18:35:40 +00:00
for ( InterfaceIndex = 0 ; InterfaceIndex < ConfigurationDescriptor - > bNumInterfaces ; InterfaceIndex + + )
{
//
// sanity check
//
PC_ASSERT ( InterfaceDescriptor - > bLength = = sizeof ( USB_INTERFACE_DESCRIPTOR ) ) ;
PC_ASSERT ( InterfaceDescriptor - > bNumEndpoints ) ;
//
// copy current interface descriptor
//
RtlCopyMemory ( & m_ConfigurationDescriptors [ Index ] . Interfaces [ InterfaceIndex ] . InterfaceDescriptor , InterfaceDescriptor , InterfaceDescriptor - > bLength ) ;
//
// allocate end point descriptors
//
m_ConfigurationDescriptors [ Index ] . Interfaces [ InterfaceIndex ] . EndPoints = ( PUSB_ENDPOINT ) ExAllocatePoolWithTag ( NonPagedPool , sizeof ( USB_ENDPOINT ) * InterfaceDescriptor - > bNumEndpoints , TAG_USBEHCI ) ;
if ( ! m_ConfigurationDescriptors [ Index ] . Interfaces [ InterfaceIndex ] . EndPoints )
{
//
// failed to allocate endpoint
//
Status = STATUS_INSUFFICIENT_RESOURCES ;
break ;
}
//
// zero memory
//
RtlZeroMemory ( m_ConfigurationDescriptors [ Index ] . Interfaces [ InterfaceIndex ] . EndPoints , sizeof ( USB_ENDPOINT ) * InterfaceDescriptor - > bNumEndpoints ) ;
//
// initialize end point descriptors
//
EndPointDescriptor = ( PUSB_ENDPOINT_DESCRIPTOR ) ( InterfaceDescriptor + 1 ) ;
for ( EndPointIndex = 0 ; EndPointIndex < InterfaceDescriptor - > bNumEndpoints ; EndPointIndex + + )
{
//
// sanity check
//
PC_ASSERT ( EndPointDescriptor - > bLength = = sizeof ( USB_ENDPOINT_DESCRIPTOR ) ) ;
//
// copy endpoint descriptor
//
RtlCopyMemory ( & m_ConfigurationDescriptors [ Index ] . Interfaces [ InterfaceIndex ] . EndPoints [ EndPointIndex ] . EndPointDescriptor , EndPointDescriptor , EndPointDescriptor - > bLength ) ;
//
// move to next offset
//
EndPointDescriptor = ( PUSB_ENDPOINT_DESCRIPTOR ) ( ( ULONG_PTR ) EndPointDescriptor + EndPointDescriptor - > bLength ) ;
}
//
// update interface descriptor offset
//
InterfaceDescriptor = ( PUSB_INTERFACE_DESCRIPTOR ) EndPointDescriptor ;
}
//
// free buffer
//
ExFreePoolWithTag ( Buffer , TAG_USBEHCI ) ;
2011-04-17 19:23:13 +00:00
//
// done
//
return Status ;
}
2011-04-24 09:26:22 +00:00
//----------------------------------------------------------------------------------------
VOID
CUSBDevice : : GetConfigurationDescriptors (
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigDescriptorBuffer ,
IN ULONG BufferLength ,
OUT PULONG OutBufferLength )
{
2011-04-28 17:45:32 +00:00
PVOID Buffer ;
ULONG InterfaceIndex , EndpointIndex ;
2011-04-24 09:26:22 +00:00
//
// sanity check
//
PC_ASSERT ( BufferLength > = sizeof ( USB_CONFIGURATION_DESCRIPTOR ) ) ;
PC_ASSERT ( ConfigDescriptorBuffer ) ;
PC_ASSERT ( OutBufferLength ) ;
2011-04-28 17:45:32 +00:00
//
// reset copied length
//
* OutBufferLength = 0 ;
2011-04-24 09:26:22 +00:00
//
// FIXME: support multiple configurations
//
PC_ASSERT ( m_DeviceDescriptor . bNumConfigurations = = 1 ) ;
//
// copy first configuration descriptor
//
RtlCopyMemory ( ConfigDescriptorBuffer , & m_ConfigurationDescriptors [ 0 ] . ConfigurationDescriptor , sizeof ( USB_CONFIGURATION_DESCRIPTOR ) ) ;
//
2011-04-28 17:45:32 +00:00
// subtract length
//
BufferLength - = sizeof ( USB_CONFIGURATION_DESCRIPTOR ) ;
* OutBufferLength + = sizeof ( USB_CONFIGURATION_DESCRIPTOR ) ;
//
// increment offset
2011-04-24 09:26:22 +00:00
//
2011-04-28 17:45:32 +00:00
Buffer = ( PVOID ) ( ConfigDescriptorBuffer + 1 ) ;
for ( InterfaceIndex = 0 ; InterfaceIndex < m_ConfigurationDescriptors [ 0 ] . ConfigurationDescriptor . bNumInterfaces ; InterfaceIndex + + )
{
if ( BufferLength < sizeof ( USB_INTERFACE_DESCRIPTOR ) )
{
//
// no more room in buffer
//
return ;
}
//
// copy interface descriptor
//
RtlCopyMemory ( Buffer , & m_ConfigurationDescriptors [ 0 ] . Interfaces [ InterfaceIndex ] . InterfaceDescriptor , sizeof ( USB_INTERFACE_DESCRIPTOR ) ) ;
//
// increment offset
//
Buffer = ( PVOID ) ( ( ULONG_PTR ) Buffer + sizeof ( USB_INTERFACE_DESCRIPTOR ) ) ;
BufferLength - = sizeof ( USB_INTERFACE_DESCRIPTOR ) ;
* OutBufferLength + = sizeof ( USB_INTERFACE_DESCRIPTOR ) ;
//
// does the interface have endpoints
//
if ( m_ConfigurationDescriptors [ 0 ] . Interfaces [ InterfaceIndex ] . InterfaceDescriptor . bNumEndpoints )
{
//
// is enough space available
//
if ( BufferLength < sizeof ( USB_ENDPOINT_DESCRIPTOR ) * m_ConfigurationDescriptors [ 0 ] . Interfaces [ InterfaceIndex ] . InterfaceDescriptor . bNumEndpoints )
{
//
// no buffer
//
return ;
}
//
// copy end points
//
for ( EndpointIndex = 0 ; EndpointIndex < m_ConfigurationDescriptors [ 0 ] . Interfaces [ InterfaceIndex ] . InterfaceDescriptor . bNumEndpoints ; EndpointIndex + + )
{
//
// copy endpoint
//
RtlCopyMemory ( Buffer , & m_ConfigurationDescriptors [ 0 ] . Interfaces [ InterfaceIndex ] . EndPoints [ EndpointIndex ] . EndPointDescriptor , sizeof ( USB_ENDPOINT_DESCRIPTOR ) ) ;
//
// increment buffer offset
//
Buffer = ( PVOID ) ( ( ULONG_PTR ) Buffer + sizeof ( USB_ENDPOINT_DESCRIPTOR ) ) ;
BufferLength - = sizeof ( USB_ENDPOINT_DESCRIPTOR ) ;
* OutBufferLength + = sizeof ( USB_ENDPOINT_DESCRIPTOR ) ;
}
}
}
2011-04-24 09:26:22 +00:00
}
2011-04-28 17:45:32 +00:00
//----------------------------------------------------------------------------------------
ULONG
CUSBDevice : : GetConfigurationDescriptorsLength ( )
{
//
// FIXME: support multiple configurations
//
PC_ASSERT ( m_DeviceDescriptor . bNumConfigurations = = 1 ) ;
2011-04-19 18:35:40 +00:00
2011-04-28 17:45:32 +00:00
return m_ConfigurationDescriptors [ 0 ] . ConfigurationDescriptor . wTotalLength ;
}
//----------------------------------------------------------------------------------------
2011-04-28 15:16:33 +00:00
VOID
CUSBDevice : : DumpDeviceDescriptor ( PUSB_DEVICE_DESCRIPTOR DeviceDescriptor )
{
DPRINT1 ( " Dumping Device Descriptor %x \n " , DeviceDescriptor ) ;
DPRINT1 ( " bLength %x \n " , DeviceDescriptor - > bLength ) ;
DPRINT1 ( " bDescriptorType %x \n " , DeviceDescriptor - > bDescriptorType ) ;
DPRINT1 ( " bcdUSB %x \n " , DeviceDescriptor - > bcdUSB ) ;
DPRINT1 ( " bDeviceClass %x \n " , DeviceDescriptor - > bDeviceClass ) ;
DPRINT1 ( " bDeviceSubClass %x \n " , DeviceDescriptor - > bDeviceSubClass ) ;
DPRINT1 ( " bDeviceProtocol %x \n " , DeviceDescriptor - > bDeviceProtocol ) ;
DPRINT1 ( " bMaxPacketSize0 %x \n " , DeviceDescriptor - > bMaxPacketSize0 ) ;
DPRINT1 ( " idVendor %x \n " , DeviceDescriptor - > idVendor ) ;
DPRINT1 ( " idProduct %x \n " , DeviceDescriptor - > idProduct ) ;
DPRINT1 ( " bcdDevice %x \n " , DeviceDescriptor - > bcdDevice ) ;
DPRINT1 ( " iManufacturer %x \n " , DeviceDescriptor - > iManufacturer ) ;
DPRINT1 ( " iProduct %x \n " , DeviceDescriptor - > iProduct ) ;
DPRINT1 ( " iSerialNumber %x \n " , DeviceDescriptor - > iSerialNumber ) ;
DPRINT1 ( " bNumConfigurations %x \n " , DeviceDescriptor - > bNumConfigurations ) ;
}
2011-04-28 17:45:32 +00:00
//----------------------------------------------------------------------------------------
VOID
CUSBDevice : : DumpConfigurationDescriptor ( PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor )
{
DPRINT1 ( " Dumping ConfigurationDescriptor %x \n " , ConfigurationDescriptor ) ;
DPRINT1 ( " bLength %x \n " , ConfigurationDescriptor - > bLength ) ;
DPRINT1 ( " bDescriptorType %x \n " , ConfigurationDescriptor - > bDescriptorType ) ;
DPRINT1 ( " wTotalLength %x \n " , ConfigurationDescriptor - > wTotalLength ) ;
DPRINT1 ( " bNumInterfaces %x \n " , ConfigurationDescriptor - > bNumInterfaces ) ;
DPRINT1 ( " bConfigurationValue %x \n " , ConfigurationDescriptor - > bConfigurationValue ) ;
DPRINT1 ( " iConfiguration %x \n " , ConfigurationDescriptor - > iConfiguration ) ;
DPRINT1 ( " bmAttributes %x \n " , ConfigurationDescriptor - > bmAttributes ) ;
DPRINT1 ( " MaxPower %x \n " , ConfigurationDescriptor - > MaxPower ) ;
}
2011-04-17 19:23:13 +00:00
//----------------------------------------------------------------------------------------
NTSTATUS
2011-04-28 23:59:53 +00:00
CUSBDevice : : SubmitSetupPacket (
IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket ,
IN OUT ULONG BufferLength ,
OUT PVOID Buffer )
{
NTSTATUS Status ;
PMDL Mdl ;
//
// allocate mdl
//
Mdl = IoAllocateMdl ( Buffer , BufferLength , FALSE , FALSE , 0 ) ;
//
// HACK HACK HACK: assume the buffer is build from non paged pool
//
MmBuildMdlForNonPagedPool ( Mdl ) ;
//
// commit setup packet
//
2011-04-29 02:46:04 +00:00
Status = CommitSetupPacket ( SetupPacket , 0 , BufferLength , Mdl ) ;
2011-04-28 23:59:53 +00:00
//
// free mdl
//
IoFreeMdl ( Mdl ) ;
//
// done
//
return Status ;
}
2011-04-29 02:46:04 +00:00
//----------------------------------------------------------------------------------------
NTSTATUS
CUSBDevice : : SelectConfiguration (
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor ,
IN PUSBD_INTERFACE_INFORMATION InterfaceInfo ,
OUT USBD_CONFIGURATION_HANDLE * ConfigurationHandle )
{
ULONG ConfigurationIndex = 0 ;
ULONG InterfaceIndex , PipeIndex ;
USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup ;
NTSTATUS Status ;
//
// FIXME: support multiple configurations
//
PC_ASSERT ( m_DeviceDescriptor . bNumConfigurations = = 1 ) ;
PC_ASSERT ( ConfigurationDescriptor - > iConfiguration = = m_ConfigurationDescriptors [ ConfigurationIndex ] . ConfigurationDescriptor . iConfiguration ) ;
//
// sanity check
//
PC_ASSERT ( ConfigurationDescriptor - > bNumInterfaces < = m_ConfigurationDescriptors [ ConfigurationIndex ] . ConfigurationDescriptor . bNumInterfaces ) ;
//
// copy interface info and pipe info
//
for ( InterfaceIndex = 0 ; InterfaceIndex < ConfigurationDescriptor - > bNumInterfaces ; InterfaceIndex + + )
{
//
// sanity check: is the info pre-layed out
//
PC_ASSERT ( InterfaceInfo - > NumberOfPipes = = m_ConfigurationDescriptors [ ConfigurationIndex ] . Interfaces [ InterfaceIndex ] . InterfaceDescriptor . bNumEndpoints ) ;
PC_ASSERT ( InterfaceInfo - > Length ! = 0 ) ;
# ifdef _MSC_VER
PC_ASSERT ( InterfaceInfo - > Length = = FIELD_OFFSET ( USBD_INTERFACE_INFORMATION , Pipes [ InterfaceInfo - > NumberOfPipes ] ) ) ;
# endif
//
// copy interface info
//
InterfaceInfo - > InterfaceHandle = ( USBD_INTERFACE_HANDLE ) & m_ConfigurationDescriptors [ ConfigurationIndex ] . Interfaces [ InterfaceIndex ] ;
InterfaceInfo - > Class = m_ConfigurationDescriptors [ ConfigurationIndex ] . Interfaces [ InterfaceIndex ] . InterfaceDescriptor . bInterfaceClass ;
InterfaceInfo - > SubClass = m_ConfigurationDescriptors [ ConfigurationIndex ] . Interfaces [ InterfaceIndex ] . InterfaceDescriptor . bInterfaceSubClass ;
InterfaceInfo - > Protocol = m_ConfigurationDescriptors [ ConfigurationIndex ] . Interfaces [ InterfaceIndex ] . InterfaceDescriptor . bInterfaceProtocol ;
InterfaceInfo - > Reserved = 0 ;
//
// copy endpoint info
//
for ( PipeIndex = 0 ; PipeIndex < InterfaceInfo - > NumberOfPipes ; PipeIndex + + )
{
//
// copy pipe info
//
InterfaceInfo - > Pipes [ PipeIndex ] . MaximumPacketSize = m_ConfigurationDescriptors [ ConfigurationIndex ] . Interfaces [ InterfaceIndex ] . EndPoints [ PipeIndex ] . EndPointDescriptor . wMaxPacketSize ;
InterfaceInfo - > Pipes [ PipeIndex ] . EndpointAddress = m_ConfigurationDescriptors [ ConfigurationIndex ] . Interfaces [ InterfaceIndex ] . EndPoints [ PipeIndex ] . EndPointDescriptor . bEndpointAddress ;
InterfaceInfo - > Pipes [ PipeIndex ] . Interval = m_ConfigurationDescriptors [ ConfigurationIndex ] . Interfaces [ InterfaceIndex ] . EndPoints [ PipeIndex ] . EndPointDescriptor . bInterval ;
InterfaceInfo - > Pipes [ PipeIndex ] . PipeType = ( USBD_PIPE_TYPE ) m_ConfigurationDescriptors [ ConfigurationIndex ] . Interfaces [ InterfaceIndex ] . EndPoints [ PipeIndex ] . EndPointDescriptor . bmAttributes ;
InterfaceInfo - > Pipes [ PipeIndex ] . PipeHandle = ( PVOID ) & m_ConfigurationDescriptors [ ConfigurationIndex ] . Interfaces [ InterfaceIndex ] . EndPoints [ PipeIndex ] . EndPointDescriptor ;
}
//
// move offset
//
InterfaceInfo = ( PUSBD_INTERFACE_INFORMATION ) ( ( ULONG_PTR ) PtrToUlong ( InterfaceInfo ) + InterfaceInfo - > Length ) ;
}
//
// now build setup packet
//
RtlZeroMemory ( & CtrlSetup , sizeof ( USB_DEFAULT_PIPE_SETUP_PACKET ) ) ;
CtrlSetup . bRequest = USB_REQUEST_SET_CONFIGURATION ;
2011-04-29 03:17:57 +00:00
CtrlSetup . wValue . W = ConfigurationDescriptor - > bConfigurationValue ;
2011-04-29 02:46:04 +00:00
//
// select configuration
//
Status = CommitSetupPacket ( & CtrlSetup , 0 , 0 , 0 ) ;
//
// informal debug print
//
DPRINT1 ( " CUsbDevice::SelectConfiguration New Configuration %x Old Configuration %x Result %x \n " , ConfigurationDescriptor - > iConfiguration , m_ConfigurationIndex , Status ) ;
if ( NT_SUCCESS ( Status ) )
{
//
// store configuration device index
//
m_ConfigurationIndex = ConfigurationDescriptor - > iConfiguration ;
//
// store configuration handle
//
* ConfigurationHandle = & m_ConfigurationDescriptors [ ConfigurationIndex ] ;
}
//
// done
//
return Status ;
}
//----------------------------------------------------------------------------------------
NTSTATUS
CUSBDevice : : SelectInterface (
IN USBD_CONFIGURATION_HANDLE ConfigurationHandle ,
IN OUT PUSBD_INTERFACE_INFORMATION InterfaceInfo )
{
ULONG ConfigurationIndex = 0 ;
PUSB_CONFIGURATION Configuration ;
ULONG PipeIndex ;
USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup ;
NTSTATUS Status ;
//
// FIXME support multiple configurations
//
PC_ASSERT ( & m_ConfigurationDescriptors [ ConfigurationIndex ] = = ( PUSB_CONFIGURATION ) ConfigurationHandle ) ;
//
// get configuration struct
//
Configuration = ( PUSB_CONFIGURATION ) ConfigurationHandle ;
//
// sanity checks
//
PC_ASSERT ( Configuration - > ConfigurationDescriptor . bNumInterfaces > InterfaceInfo - > InterfaceNumber ) ;
PC_ASSERT ( Configuration - > Interfaces [ InterfaceInfo - > InterfaceNumber ] . InterfaceDescriptor . bNumEndpoints = = InterfaceInfo - > NumberOfPipes ) ;
# ifdef _MSC_VER
PC_ASSERT ( InterfaceInfo - > Length = = FIELD_OFFSET ( USBD_INTERFACE_INFORMATION , Pipes [ InterfaceInfo - > NumberOfPipes ] ) ) ;
# endif
//
// copy pipe handles
//
for ( PipeIndex = 0 ; PipeIndex < InterfaceInfo - > NumberOfPipes ; PipeIndex + + )
{
//
// copy pipe handle
//
2011-04-30 08:04:35 +00:00
DPRINT1 ( " PipeIndex %lu \n " , PipeIndex ) ;
DPRINT1 ( " EndpointAddress %x \n " , InterfaceInfo - > Pipes [ PipeIndex ] . EndpointAddress ) ;
DPRINT1 ( " Interval %d \n " , InterfaceInfo - > Pipes [ PipeIndex ] . Interval ) ;
DPRINT1 ( " MaximumPacketSize %d \n " , InterfaceInfo - > Pipes [ PipeIndex ] . MaximumPacketSize ) ;
DPRINT1 ( " MaximumTransferSize %d \n " , InterfaceInfo - > Pipes [ PipeIndex ] . MaximumTransferSize ) ;
DPRINT1 ( " PipeFlags %d \n " , InterfaceInfo - > Pipes [ PipeIndex ] . PipeFlags ) ;
DPRINT1 ( " PipeType %dd \n " , InterfaceInfo - > Pipes [ PipeIndex ] . PipeType ) ;
DPRINT1 ( " UsbEndPoint %x \n " , Configuration - > Interfaces [ InterfaceInfo - > InterfaceNumber ] . EndPoints [ PipeIndex ] . EndPointDescriptor . bEndpointAddress ) ;
PC_ASSERT ( Configuration - > Interfaces [ InterfaceInfo - > InterfaceNumber ] . EndPoints [ PipeIndex ] . EndPointDescriptor . bEndpointAddress = = InterfaceInfo - > Pipes [ PipeIndex ] . EndpointAddress ) ;
2011-04-29 02:46:04 +00:00
InterfaceInfo - > Pipes [ PipeIndex ] . PipeHandle = & Configuration - > Interfaces [ InterfaceInfo - > InterfaceNumber ] . EndPoints [ PipeIndex ] . EndPointDescriptor ;
if ( Configuration - > Interfaces [ InterfaceInfo - > InterfaceNumber ] . EndPoints [ PipeIndex ] . EndPointDescriptor . bmAttributes & ( USB_ENDPOINT_TYPE_ISOCHRONOUS | USB_ENDPOINT_TYPE_INTERRUPT ) )
{
//
// FIXME: check if enough bandwidth is available
//
}
}
//
// initialize setup packet
//
RtlZeroMemory ( & CtrlSetup , sizeof ( USB_DEFAULT_PIPE_SETUP_PACKET ) ) ;
CtrlSetup . bRequest = USB_REQUEST_SET_INTERFACE ;
2011-04-29 03:17:57 +00:00
CtrlSetup . wValue . W = Configuration - > Interfaces [ InterfaceInfo - > InterfaceNumber ] . InterfaceDescriptor . bAlternateSetting ;
CtrlSetup . wIndex . W = Configuration - > Interfaces [ InterfaceInfo - > InterfaceNumber ] . InterfaceDescriptor . bInterfaceNumber ;
2011-04-29 02:46:04 +00:00
CtrlSetup . bmRequestType . B = 0x01 ;
//
// issue request
//
Status = CommitSetupPacket ( & CtrlSetup , 0 , 0 , 0 ) ;
//
// informal debug print
//
DPRINT1 ( " CUSBDevice::SelectInterface AlternateSetting %x InterfaceNumber %x Status %x \n " , InterfaceInfo - > AlternateSetting , InterfaceInfo - > InterfaceNumber , Status ) ;
//
// done
//
return Status ;
}
2011-04-28 23:59:53 +00:00
//----------------------------------------------------------------------------------------
NTSTATUS
2011-04-17 19:23:13 +00:00
CreateUSBDevice (
PUSBDEVICE * OutDevice )
{
CUSBDevice * This ;
//
// allocate controller
//
This = new ( NonPagedPool , TAG_USBEHCI ) CUSBDevice ( 0 ) ;
if ( ! This )
{
//
// failed to allocate
//
return STATUS_INSUFFICIENT_RESOURCES ;
}
//
// add reference count
//
This - > AddRef ( ) ;
//
// return result
//
* OutDevice = ( PUSBDEVICE ) This ;
//
// done
//
return STATUS_SUCCESS ;
}