mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 16:26:02 +00:00
[USBEHCI_NEW]
- Setup a default device descriptor for the root hub and initialize it with vendor & product id - Partly implement URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE, URB_FUNCTION_CLASS_DEVICE - based on mjmartin usbehci svn path=/branches/usb-bringup/; revision=51384
This commit is contained in:
parent
79bfd697d0
commit
5290479c41
3 changed files with 827 additions and 30 deletions
|
@ -54,6 +54,8 @@ public:
|
||||||
NTSTATUS AddUsbDevice(PUSBDEVICE UsbDevice);
|
NTSTATUS AddUsbDevice(PUSBDEVICE UsbDevice);
|
||||||
NTSTATUS RemoveUsbDevice(PUSBDEVICE UsbDevice);
|
NTSTATUS RemoveUsbDevice(PUSBDEVICE UsbDevice);
|
||||||
VOID SetNotification(PVOID CallbackContext, PRH_INIT_CALLBACK CallbackRoutine);
|
VOID SetNotification(PVOID CallbackContext, PRH_INIT_CALLBACK CallbackRoutine);
|
||||||
|
NTSTATUS HandleGetDescriptor(IN OUT PIRP Irp, PURB Urb);
|
||||||
|
NTSTATUS HandleClassDevice(IN OUT PIRP Irp, PURB Urb);
|
||||||
|
|
||||||
// constructor / destructor
|
// constructor / destructor
|
||||||
CHubController(IUnknown *OuterUnknown){}
|
CHubController(IUnknown *OuterUnknown){}
|
||||||
|
@ -65,7 +67,6 @@ protected:
|
||||||
PUSBHARDWAREDEVICE m_Hardware;
|
PUSBHARDWAREDEVICE m_Hardware;
|
||||||
BOOLEAN m_IsRootHubDevice;
|
BOOLEAN m_IsRootHubDevice;
|
||||||
ULONG m_DeviceAddress;
|
ULONG m_DeviceAddress;
|
||||||
ULONG m_PDODeviceNumber;
|
|
||||||
BOOLEAN m_InterfaceEnabled;
|
BOOLEAN m_InterfaceEnabled;
|
||||||
UNICODE_STRING m_HubDeviceInterfaceString;
|
UNICODE_STRING m_HubDeviceInterfaceString;
|
||||||
PDEVICE_OBJECT m_HubControllerDeviceObject;
|
PDEVICE_OBJECT m_HubControllerDeviceObject;
|
||||||
|
@ -74,6 +75,7 @@ protected:
|
||||||
PVOID m_HubCallbackContext;
|
PVOID m_HubCallbackContext;
|
||||||
PRH_INIT_CALLBACK m_HubCallbackRoutine;
|
PRH_INIT_CALLBACK m_HubCallbackRoutine;
|
||||||
|
|
||||||
|
USB_DEVICE_DESCRIPTOR m_DeviceDescriptor;
|
||||||
|
|
||||||
KSPIN_LOCK m_Lock;
|
KSPIN_LOCK m_Lock;
|
||||||
RTL_BITMAP m_DeviceAddressBitmap;
|
RTL_BITMAP m_DeviceAddressBitmap;
|
||||||
|
@ -87,6 +89,64 @@ typedef struct
|
||||||
PUSBDEVICE Device;
|
PUSBDEVICE Device;
|
||||||
}USBDEVICE_ENTRY, *PUSBDEVICE_ENTRY;
|
}USBDEVICE_ENTRY, *PUSBDEVICE_ENTRY;
|
||||||
|
|
||||||
|
/* Lifted from Linux with slight changes */
|
||||||
|
const UCHAR ROOTHUB2_DEVICE_DESCRIPTOR [] =
|
||||||
|
{
|
||||||
|
0x12, /* bLength; */
|
||||||
|
USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType; Device */
|
||||||
|
0x00, 0x20, /* bcdUSB; v1.1 */
|
||||||
|
USB_DEVICE_CLASS_HUB, /* bDeviceClass; HUB_CLASSCODE */
|
||||||
|
0x01, /* bDeviceSubClass; */
|
||||||
|
0x00, /* bDeviceProtocol; [ low/full speeds only ] */
|
||||||
|
0x08, /* bMaxPacketSize0; 8 Bytes */
|
||||||
|
/* Fill Vendor and Product in when init root hub */
|
||||||
|
0x00, 0x00, /* idVendor; */
|
||||||
|
0x00, 0x00, /* idProduct; */
|
||||||
|
0x00, 0x00, /* bcdDevice */
|
||||||
|
0x00, /* iManufacturer; */
|
||||||
|
0x00, /* iProduct; */
|
||||||
|
0x00, /* iSerialNumber; */
|
||||||
|
0x01 /* bNumConfigurations; */
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const UCHAR ROOTHUB2_CONFIGURATION_DESCRIPTOR [] =
|
||||||
|
{
|
||||||
|
/* one configuration */
|
||||||
|
0x09, /* bLength; */
|
||||||
|
0x02, /* bDescriptorType; Configuration */
|
||||||
|
0x19, 0x00, /* wTotalLength; */
|
||||||
|
0x01, /* bNumInterfaces; (1) */
|
||||||
|
0x23, /* bConfigurationValue; */
|
||||||
|
0x00, /* iConfiguration; */
|
||||||
|
0x40, /* bmAttributes; */
|
||||||
|
0x00 /* MaxPower; */
|
||||||
|
};
|
||||||
|
|
||||||
|
const UCHAR ROOTHUB2_INTERFACE_DESCRIPTOR [] =
|
||||||
|
{
|
||||||
|
/* one interface */
|
||||||
|
0x09, /* bLength: Interface; */
|
||||||
|
0x04, /* bDescriptorType; Interface */
|
||||||
|
0x00, /* bInterfaceNumber; */
|
||||||
|
0x00, /* bAlternateSetting; */
|
||||||
|
0x01, /* bNumEndpoints; */
|
||||||
|
0x09, /* bInterfaceClass; HUB_CLASSCODE */
|
||||||
|
0x01, /* bInterfaceSubClass; */
|
||||||
|
0x00, /* bInterfaceProtocol: */
|
||||||
|
0x00 /* iInterface; */
|
||||||
|
};
|
||||||
|
|
||||||
|
const UCHAR ROOTHUB2_ENDPOINT_DESCRIPTOR [] =
|
||||||
|
{
|
||||||
|
/* one endpoint (status change endpoint) */
|
||||||
|
0x07, /* bLength; */
|
||||||
|
0x05, /* bDescriptorType; Endpoint */
|
||||||
|
0x81, /* bEndpointAddress; IN Endpoint 1 */
|
||||||
|
0x03, /* bmAttributes; Interrupt */
|
||||||
|
0x08, 0x00, /* wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */
|
||||||
|
0xFF /* bInterval; (255ms -- usb 2.0 spec) */
|
||||||
|
};
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -108,6 +168,8 @@ CHubController::Initialize(
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PCOMMON_DEVICE_EXTENSION DeviceExtension;
|
PCOMMON_DEVICE_EXTENSION DeviceExtension;
|
||||||
|
USHORT VendorID, DeviceID;
|
||||||
|
ULONG Dummy1;
|
||||||
|
|
||||||
DPRINT1("CHubController::Initialize\n");
|
DPRINT1("CHubController::Initialize\n");
|
||||||
|
|
||||||
|
@ -120,6 +182,7 @@ CHubController::Initialize(
|
||||||
m_DeviceAddress = DeviceAddress;
|
m_DeviceAddress = DeviceAddress;
|
||||||
m_DriverObject = DriverObject;
|
m_DriverObject = DriverObject;
|
||||||
KeInitializeSpinLock(&m_Lock);
|
KeInitializeSpinLock(&m_Lock);
|
||||||
|
InitializeListHead(&m_UsbDeviceList);
|
||||||
|
|
||||||
//
|
//
|
||||||
// allocate device address bitmap buffer
|
// allocate device address bitmap buffer
|
||||||
|
@ -164,6 +227,22 @@ CHubController::Initialize(
|
||||||
DeviceExtension->IsHub = TRUE; //FIXME
|
DeviceExtension->IsHub = TRUE; //FIXME
|
||||||
DeviceExtension->Dispatcher = PDISPATCHIRP(this);
|
DeviceExtension->Dispatcher = PDISPATCHIRP(this);
|
||||||
|
|
||||||
|
//
|
||||||
|
// intialize device descriptor
|
||||||
|
//
|
||||||
|
C_ASSERT(sizeof(USB_DEVICE_DESCRIPTOR) == sizeof(ROOTHUB2_DEVICE_DESCRIPTOR));
|
||||||
|
RtlMoveMemory(&m_DeviceDescriptor, ROOTHUB2_DEVICE_DESCRIPTOR, sizeof(USB_DEVICE_DESCRIPTOR));
|
||||||
|
|
||||||
|
if (NT_SUCCESS(m_Hardware->GetDeviceDetails(&VendorID, &DeviceID, &Dummy1, &Dummy1)))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// update device descriptor
|
||||||
|
//
|
||||||
|
m_DeviceDescriptor.idVendor = VendorID;
|
||||||
|
m_DeviceDescriptor.idProduct = DeviceID;
|
||||||
|
m_DeviceDescriptor.bcdUSB = 0x200; //FIXME
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// clear init flag
|
// clear init flag
|
||||||
//
|
//
|
||||||
|
@ -510,6 +589,174 @@ CHubController::HandlePower(
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------------------
|
||||||
|
NTSTATUS
|
||||||
|
CHubController::HandleClassDevice(
|
||||||
|
IN OUT PIRP Irp,
|
||||||
|
IN OUT PURB Urb)
|
||||||
|
{
|
||||||
|
NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
PUSB_HUB_DESCRIPTOR UsbHubDescriptor;
|
||||||
|
ULONG PortCount, Dummy2;
|
||||||
|
USHORT Dummy1;
|
||||||
|
|
||||||
|
//
|
||||||
|
// check class request type
|
||||||
|
//
|
||||||
|
switch(Urb->UrbControlVendorClassRequest.Request)
|
||||||
|
{
|
||||||
|
case USB_DEVICE_CLASS_HUB:
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// sanity checks
|
||||||
|
//
|
||||||
|
PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer);
|
||||||
|
PC_ASSERT(Urb->UrbControlVendorClassRequest.TransferBufferLength >= sizeof(USB_HUB_DESCRIPTOR));
|
||||||
|
|
||||||
|
//
|
||||||
|
// get hub descriptor
|
||||||
|
//
|
||||||
|
UsbHubDescriptor = (PUSB_HUB_DESCRIPTOR)Urb->UrbControlVendorClassRequest.TransferBuffer;
|
||||||
|
|
||||||
|
//
|
||||||
|
// one hub is handled
|
||||||
|
//
|
||||||
|
UsbHubDescriptor->bDescriptorLength = sizeof(USB_HUB_DESCRIPTOR);
|
||||||
|
Urb->UrbControlVendorClassRequest.TransferBufferLength = sizeof(USB_HUB_DESCRIPTOR);
|
||||||
|
|
||||||
|
//
|
||||||
|
// type should 0x29 according to msdn
|
||||||
|
//
|
||||||
|
UsbHubDescriptor->bDescriptorType = 0x29;
|
||||||
|
|
||||||
|
//
|
||||||
|
// get port count
|
||||||
|
//
|
||||||
|
Status = m_Hardware->GetDeviceDetails(&Dummy1, &Dummy1, &PortCount, &Dummy2);
|
||||||
|
PC_ASSERT(Status == STATUS_SUCCESS);
|
||||||
|
|
||||||
|
//
|
||||||
|
// FIXME: retrieve values
|
||||||
|
//
|
||||||
|
UsbHubDescriptor->bNumberOfPorts = PortCount;
|
||||||
|
UsbHubDescriptor->wHubCharacteristics = 0x0012;
|
||||||
|
UsbHubDescriptor->bPowerOnToPowerGood = 0x01;
|
||||||
|
UsbHubDescriptor->bHubControlCurrent = 0x00;
|
||||||
|
|
||||||
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
DPRINT1("CHubController::HandleClassDevice Class %x not implemented\n", Urb->UrbControlVendorClassRequest.Request);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------------------
|
||||||
|
NTSTATUS
|
||||||
|
CHubController::HandleGetDescriptor(
|
||||||
|
IN OUT PIRP Irp,
|
||||||
|
IN OUT PURB Urb)
|
||||||
|
{
|
||||||
|
NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
|
||||||
|
PUCHAR Buffer;
|
||||||
|
|
||||||
|
//
|
||||||
|
// check descriptor type
|
||||||
|
//
|
||||||
|
switch(Urb->UrbControlDescriptorRequest.DescriptorType)
|
||||||
|
{
|
||||||
|
case USB_DEVICE_DESCRIPTOR_TYPE:
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// sanity check
|
||||||
|
//
|
||||||
|
PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBufferLength >= sizeof(USB_DEVICE_DESCRIPTOR));
|
||||||
|
|
||||||
|
if (Urb->UrbHeader.UsbdDeviceHandle == NULL)
|
||||||
|
{
|
||||||
|
DPRINT1("Root Hub descriptor\n");
|
||||||
|
//
|
||||||
|
// copy root hub device descriptor
|
||||||
|
//
|
||||||
|
RtlCopyMemory((PUCHAR)Urb->UrbControlDescriptorRequest.TransferBuffer, &m_DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR));
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case USB_CONFIGURATION_DESCRIPTOR_TYPE:
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// sanity checks
|
||||||
|
//
|
||||||
|
PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
|
||||||
|
PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBufferLength >= sizeof(USB_CONFIGURATION_DESCRIPTOR));
|
||||||
|
|
||||||
|
//
|
||||||
|
// FIXME: support devices
|
||||||
|
//
|
||||||
|
PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle == NULL);
|
||||||
|
|
||||||
|
//
|
||||||
|
// copy configuration descriptor template
|
||||||
|
//
|
||||||
|
C_ASSERT(sizeof(ROOTHUB2_CONFIGURATION_DESCRIPTOR) == sizeof(USB_CONFIGURATION_DESCRIPTOR));
|
||||||
|
RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer, ROOTHUB2_CONFIGURATION_DESCRIPTOR, sizeof(USB_CONFIGURATION_DESCRIPTOR));
|
||||||
|
|
||||||
|
//
|
||||||
|
// get configuration descriptor, very retarded!
|
||||||
|
//
|
||||||
|
ConfigurationDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)Urb->UrbControlDescriptorRequest.TransferBuffer;
|
||||||
|
|
||||||
|
//
|
||||||
|
// check if buffer can hold interface and endpoint descriptor
|
||||||
|
//
|
||||||
|
if (ConfigurationDescriptor->wTotalLength > Urb->UrbControlDescriptorRequest.TransferBufferLength)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// buffer too small
|
||||||
|
//
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// copy interface descriptor template
|
||||||
|
//
|
||||||
|
Buffer = (PUCHAR)(ConfigurationDescriptor + 1);
|
||||||
|
C_ASSERT(sizeof(ROOTHUB2_INTERFACE_DESCRIPTOR) == sizeof(USB_INTERFACE_DESCRIPTOR));
|
||||||
|
RtlCopyMemory(Buffer, ROOTHUB2_INTERFACE_DESCRIPTOR, sizeof(USB_INTERFACE_DESCRIPTOR));
|
||||||
|
|
||||||
|
//
|
||||||
|
// copy end point descriptor template
|
||||||
|
//
|
||||||
|
Buffer += sizeof(USB_INTERFACE_DESCRIPTOR);
|
||||||
|
C_ASSERT(sizeof(ROOTHUB2_ENDPOINT_DESCRIPTOR) == sizeof(USB_ENDPOINT_DESCRIPTOR));
|
||||||
|
RtlCopyMemory(Buffer, ROOTHUB2_ENDPOINT_DESCRIPTOR, sizeof(USB_ENDPOINT_DESCRIPTOR));
|
||||||
|
|
||||||
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
DPRINT1("CHubController::HandleGetDescriptor DescriptorType %x unimplemented\n", Urb->UrbControlDescriptorRequest.DescriptorType);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CHubController::HandleDeviceControl(
|
CHubController::HandleDeviceControl(
|
||||||
|
@ -553,10 +800,17 @@ CHubController::HandleDeviceControl(
|
||||||
|
|
||||||
DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_URB Function %x Length %lu Status %x Handle %p Flags %x UNIMPLEMENTED\n", Urb->UrbHeader.Function, Urb->UrbHeader.Length, Urb->UrbHeader.Status, Urb->UrbHeader.UsbdDeviceHandle, Urb->UrbHeader.UsbdFlags);
|
DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_URB Function %x Length %lu Status %x Handle %p Flags %x UNIMPLEMENTED\n", Urb->UrbHeader.Function, Urb->UrbHeader.Length, Urb->UrbHeader.Status, Urb->UrbHeader.UsbdDeviceHandle, Urb->UrbHeader.UsbdFlags);
|
||||||
|
|
||||||
|
switch (Urb->UrbHeader.Function)
|
||||||
|
{
|
||||||
|
case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
|
||||||
|
Status = HandleGetDescriptor(Irp, Urb);
|
||||||
|
break;
|
||||||
|
case URB_FUNCTION_CLASS_DEVICE:
|
||||||
|
Status = HandleClassDevice(Irp, Urb);
|
||||||
|
}
|
||||||
//
|
//
|
||||||
// request completed
|
// request completed
|
||||||
//
|
//
|
||||||
Status = STATUS_NOT_IMPLEMENTED;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE:
|
case IOCTL_INTERNAL_USB_GET_DEVICE_HANDLE:
|
||||||
|
@ -854,7 +1108,6 @@ CHubController::AddUsbDevice(
|
||||||
PUSBDEVICE UsbDevice)
|
PUSBDEVICE UsbDevice)
|
||||||
{
|
{
|
||||||
PUSBDEVICE_ENTRY DeviceEntry;
|
PUSBDEVICE_ENTRY DeviceEntry;
|
||||||
NTSTATUS Status;
|
|
||||||
KIRQL OldLevel;
|
KIRQL OldLevel;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -1004,7 +1257,7 @@ USBHI_CreateUsbDevice(
|
||||||
//
|
//
|
||||||
// now initialize device
|
// now initialize device
|
||||||
//
|
//
|
||||||
Status = NewUsbDevice->Initialize(PHUBCONTROLLER(Controller), Controller->GetUsbHardware(),PVOID(Controller), PortNumber);
|
Status = NewUsbDevice->Initialize(PHUBCONTROLLER(Controller), Controller->GetUsbHardware(),PVOID(Controller), PortNumber, PortStatus);
|
||||||
|
|
||||||
//
|
//
|
||||||
// check for success
|
// check for success
|
||||||
|
@ -1359,9 +1612,8 @@ USBHI_QueryDeviceInformation(
|
||||||
PUSB_DEVICE_INFORMATION_0 DeviceInfo;
|
PUSB_DEVICE_INFORMATION_0 DeviceInfo;
|
||||||
PUSBDEVICE UsbDevice;
|
PUSBDEVICE UsbDevice;
|
||||||
CHubController * Controller;
|
CHubController * Controller;
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
DPRINT1("USBHI_QueryDeviceInformation\n");
|
DPRINT1("USBHI_QueryDeviceInformation %p\n", BusContext);
|
||||||
|
|
||||||
//
|
//
|
||||||
// sanity check
|
// sanity check
|
||||||
|
@ -1382,17 +1634,54 @@ USBHI_QueryDeviceInformation(
|
||||||
UsbDevice = (PUSBDEVICE)DeviceHandle;
|
UsbDevice = (PUSBDEVICE)DeviceHandle;
|
||||||
PC_ASSERT(UsbDevice);
|
PC_ASSERT(UsbDevice);
|
||||||
|
|
||||||
//
|
if (BusContext != DeviceHandle)
|
||||||
// validate device handle
|
|
||||||
//
|
|
||||||
if (!Controller->ValidateUsbDevice(UsbDevice))
|
|
||||||
{
|
{
|
||||||
DPRINT1("USBHI_QueryDeviceInformation invalid device handle %p\n", DeviceHandle);
|
//
|
||||||
|
// validate device handle
|
||||||
|
//
|
||||||
|
if (!Controller->ValidateUsbDevice(UsbDevice))
|
||||||
|
{
|
||||||
|
DPRINT1("USBHI_QueryDeviceInformation invalid device handle %p\n", DeviceHandle);
|
||||||
|
|
||||||
|
//
|
||||||
|
// invalid device handle
|
||||||
|
//
|
||||||
|
return STATUS_DEVICE_NOT_CONNECTED;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// invalid device handle
|
// access information buffer
|
||||||
//
|
//
|
||||||
return STATUS_DEVICE_NOT_CONNECTED;
|
DeviceInfo = (PUSB_DEVICE_INFORMATION_0)DeviceInformationBuffer;
|
||||||
|
|
||||||
|
//
|
||||||
|
// initialize with default values
|
||||||
|
//
|
||||||
|
DeviceInfo->InformationLevel = 0;
|
||||||
|
DeviceInfo->ActualLength = sizeof(USB_DEVICE_INFORMATION_0);
|
||||||
|
DeviceInfo->PortNumber = UsbDevice->GetPort();
|
||||||
|
DeviceInfo->CurrentConfigurationValue = UsbDevice->GetConfigurationValue();
|
||||||
|
DeviceInfo->DeviceAddress = UsbDevice->GetDeviceAddress();
|
||||||
|
DeviceInfo->HubAddress = 0; //FIXME
|
||||||
|
DeviceInfo->DeviceSpeed = UsbDevice->GetSpeed();
|
||||||
|
DeviceInfo->DeviceType = UsbDevice->GetType();
|
||||||
|
DeviceInfo->NumberOfOpenPipes = 0; //FIXME
|
||||||
|
|
||||||
|
//
|
||||||
|
// get device descriptor
|
||||||
|
//
|
||||||
|
UsbDevice->GetDeviceDescriptor(&DeviceInfo->DeviceDescriptor);
|
||||||
|
|
||||||
|
//
|
||||||
|
// FIXME return pipe information
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// store result length
|
||||||
|
//
|
||||||
|
*LengthReturned = sizeof(USB_DEVICE_INFORMATION_0);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -1405,18 +1694,17 @@ USBHI_QueryDeviceInformation(
|
||||||
//
|
//
|
||||||
DeviceInfo->InformationLevel = 0;
|
DeviceInfo->InformationLevel = 0;
|
||||||
DeviceInfo->ActualLength = sizeof(USB_DEVICE_INFORMATION_0);
|
DeviceInfo->ActualLength = sizeof(USB_DEVICE_INFORMATION_0);
|
||||||
DeviceInfo->PortNumber = UsbDevice->GetPort();
|
DeviceInfo->PortNumber = 0;
|
||||||
DeviceInfo->CurrentConfigurationValue = UsbDevice->GetConfigurationValue();
|
DeviceInfo->CurrentConfigurationValue = 0; //FIXME;
|
||||||
DeviceInfo->DeviceAddress = 0; UsbDevice->GetDeviceAddress();
|
DeviceInfo->DeviceAddress = 0;
|
||||||
DeviceInfo->HubAddress = 0; //FIXME
|
DeviceInfo->HubAddress = 0; //FIXME
|
||||||
DeviceInfo->DeviceSpeed = UsbDevice->GetSpeed();
|
DeviceInfo->DeviceSpeed = UsbHighSpeed; //FIXME
|
||||||
DeviceInfo->DeviceType = UsbDevice->GetType();
|
DeviceInfo->DeviceType = Usb20Device; //FIXME
|
||||||
DeviceInfo->NumberOfOpenPipes = 0; //FIXME
|
DeviceInfo->NumberOfOpenPipes = 0; //FIXME
|
||||||
|
|
||||||
//
|
//
|
||||||
// get device descriptor
|
// FIXME get device descriptor
|
||||||
//
|
//
|
||||||
UsbDevice->GetDeviceDescriptor(&DeviceInfo->DeviceDescriptor);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// FIXME return pipe information
|
// FIXME return pipe information
|
||||||
|
@ -1427,6 +1715,9 @@ USBHI_QueryDeviceInformation(
|
||||||
//
|
//
|
||||||
*LengthReturned = sizeof(USB_DEVICE_INFORMATION_0);
|
*LengthReturned = sizeof(USB_DEVICE_INFORMATION_0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2077,12 +2368,7 @@ CHubController::CreatePDO(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
DPRINT1("CHubController::CreatePDO: DeviceName %wZ\n", &DeviceName);
|
||||||
// store PDO number
|
|
||||||
//
|
|
||||||
//m_PDODeviceNumber = UsbDeviceNumber;
|
|
||||||
|
|
||||||
DPRINT1("CreateFDO: DeviceName %wZ\n", &DeviceName);
|
|
||||||
|
|
||||||
/* done */
|
/* done */
|
||||||
return Status;
|
return Status;
|
||||||
|
|
|
@ -344,6 +344,8 @@ DECLARE_INTERFACE_(IUSBRequest, IUnknown)
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef IUSBRequest *PUSBREQUEST;
|
||||||
|
|
||||||
//=========================================================================================
|
//=========================================================================================
|
||||||
//
|
//
|
||||||
// class IUSBQueue
|
// class IUSBQueue
|
||||||
|
@ -399,6 +401,8 @@ DECLARE_INTERFACE_(IUSBQueue, IUnknown)
|
||||||
virtual NTSTATUS CreateUSBRequest(IUSBRequest **OutRequest) = 0;
|
virtual NTSTATUS CreateUSBRequest(IUSBRequest **OutRequest) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef IUSBQueue *PUSBQUEUE;
|
||||||
|
|
||||||
//=========================================================================================
|
//=========================================================================================
|
||||||
//
|
//
|
||||||
// class IHubController
|
// class IHubController
|
||||||
|
@ -495,7 +499,8 @@ DECLARE_INTERFACE_(IUSBDevice, IUnknown)
|
||||||
virtual NTSTATUS Initialize(IN PHUBCONTROLLER HubController,
|
virtual NTSTATUS Initialize(IN PHUBCONTROLLER HubController,
|
||||||
IN PUSBHARDWAREDEVICE Device,
|
IN PUSBHARDWAREDEVICE Device,
|
||||||
IN PVOID Parent,
|
IN PVOID Parent,
|
||||||
IN ULONG Port) = 0;
|
IN ULONG Port,
|
||||||
|
IN ULONG PortStatus) = 0;
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
|
@ -584,7 +589,7 @@ DECLARE_INTERFACE_(IUSBDevice, IUnknown)
|
||||||
//
|
//
|
||||||
// Description: gets current selected configuration index
|
// Description: gets current selected configuration index
|
||||||
|
|
||||||
virtual UCHAR GetConfigurationValue();
|
virtual UCHAR GetConfigurationValue() = 0;
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
|
|
|
@ -11,12 +11,518 @@
|
||||||
#define INITGUID
|
#define INITGUID
|
||||||
#include "usbehci.h"
|
#include "usbehci.h"
|
||||||
|
|
||||||
|
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);
|
||||||
|
virtual ULONG GetDeviceAddress();
|
||||||
|
virtual ULONG GetPort();
|
||||||
|
virtual USB_DEVICE_SPEED GetSpeed();
|
||||||
|
virtual USB_DEVICE_TYPE GetType();
|
||||||
|
virtual ULONG GetState();
|
||||||
|
virtual void SetDeviceHandleData(PVOID Data);
|
||||||
|
virtual NTSTATUS SetDeviceAddress(ULONG DeviceAddress);
|
||||||
|
virtual void GetDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor);
|
||||||
|
virtual UCHAR GetConfigurationValue();
|
||||||
|
virtual NTSTATUS SubmitUrb(PURB Urb);
|
||||||
|
|
||||||
|
// local function
|
||||||
|
virtual NTSTATUS CommitUrb(PURB Urb);
|
||||||
|
virtual NTSTATUS CommitSetupPacket(PUSB_DEFAULT_PIPE_SETUP_PACKET Packet, IN ULONG BufferLength, IN OUT PVOID Buffer, IN OPTIONAL PIRP Irp, IN OPTIONAL PKEVENT pEvent);
|
||||||
|
|
||||||
|
// constructor / destructor
|
||||||
|
CUSBDevice(IUnknown *OuterUnknown){}
|
||||||
|
virtual ~CUSBDevice(){}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
LONG m_Ref;
|
||||||
|
PHUBCONTROLLER m_HubController;
|
||||||
|
PUSBHARDWAREDEVICE m_Device;
|
||||||
|
PVOID m_Parent;
|
||||||
|
ULONG m_Port;
|
||||||
|
ULONG m_DeviceAddress;
|
||||||
|
PVOID m_Data;
|
||||||
|
KSPIN_LOCK m_Lock;
|
||||||
|
USB_DEVICE_DESCRIPTOR m_DeviceDescriptor;
|
||||||
|
ULONG m_PortStatus;
|
||||||
|
PUSBQUEUE m_Queue;
|
||||||
|
};
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CreateUSBDevice(
|
STDMETHODCALLTYPE
|
||||||
PUSBDEVICE *OutDevice)
|
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;
|
||||||
|
USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
//
|
||||||
|
// commit setup packet
|
||||||
|
//
|
||||||
|
Status = CommitSetupPacket(&CtrlSetup, sizeof(USB_DEVICE_DESCRIPTOR), &m_DeviceDescriptor, 0, 0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// check for success
|
||||||
|
//
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("CUSBDevice::Initialize CommitSetupPacket failed with %x\n", Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
ULONG
|
||||||
|
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(
|
||||||
|
ULONG DeviceAddress)
|
||||||
|
{
|
||||||
|
USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
//
|
||||||
|
// zero request
|
||||||
|
//
|
||||||
|
RtlZeroMemory(&CtrlSetup, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
|
||||||
|
|
||||||
|
//
|
||||||
|
// initialize request
|
||||||
|
//
|
||||||
|
CtrlSetup.bRequest = USB_REQUEST_SET_ADDRESS;
|
||||||
|
CtrlSetup.wValue.W = DeviceAddress;
|
||||||
|
|
||||||
|
//
|
||||||
|
// set device address
|
||||||
|
//
|
||||||
|
Status = CommitSetupPacket(&CtrlSetup, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// store device address
|
||||||
|
//
|
||||||
|
m_DeviceAddress = DeviceAddress;
|
||||||
|
|
||||||
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
CUSBDevice::GetDeviceDescriptor(
|
||||||
|
PUSB_DEVICE_DESCRIPTOR DeviceDescriptor)
|
||||||
|
{
|
||||||
|
RtlMoveMemory(DeviceDescriptor, &m_DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR));
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
UCHAR
|
||||||
|
CUSBDevice::GetConfigurationValue()
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED
|
||||||
|
return 0x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
NTSTATUS
|
||||||
|
CUSBDevice::CommitUrb(
|
||||||
|
PURB Urb)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED
|
UNIMPLEMENTED
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
NTSTATUS
|
||||||
|
CUSBDevice::SubmitUrb(
|
||||||
|
PURB Urb)
|
||||||
|
{
|
||||||
|
KIRQL OldLevel;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
//
|
||||||
|
// acquire device lock
|
||||||
|
//
|
||||||
|
KeAcquireSpinLock(&m_Lock, &OldLevel);
|
||||||
|
|
||||||
|
//
|
||||||
|
// commit urb
|
||||||
|
//
|
||||||
|
Status = CommitUrb(Urb);
|
||||||
|
|
||||||
|
//
|
||||||
|
// release lock
|
||||||
|
//
|
||||||
|
KeReleaseSpinLock(&m_Lock, OldLevel);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
NTSTATUS
|
||||||
|
CUSBDevice::CommitSetupPacket(
|
||||||
|
PUSB_DEFAULT_PIPE_SETUP_PACKET Packet,
|
||||||
|
IN ULONG BufferLength,
|
||||||
|
IN OUT PVOID Buffer,
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN PKEVENT pEvent)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PUSBREQUEST Request;
|
||||||
|
KEVENT Event;
|
||||||
|
BOOLEAN Wait = FALSE;
|
||||||
|
|
||||||
|
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
|
||||||
|
//
|
||||||
|
Status = Request->InitializeWithSetupPacket(Packet, BufferLength, Buffer);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// failed to initialize request
|
||||||
|
//
|
||||||
|
DPRINT1("CUSBDevice::CommitSetupPacket> failed to initialize usb request with %x\n", Status);
|
||||||
|
Request->Release();
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// is a irp or event provided ?
|
||||||
|
//
|
||||||
|
if (Irp == NULL && pEvent == NULL)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// no completion details provided, requestor wants synchronized
|
||||||
|
//
|
||||||
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
|
pEvent = &Event;
|
||||||
|
Wait = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// set completion details
|
||||||
|
//
|
||||||
|
Status = Request->SetCompletionDetails(Irp, pEvent);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// failed to set completion details
|
||||||
|
//
|
||||||
|
DPRINT1("CUSBDevice::CommitSetupPacket> failed to set completion details with %x\n", Status);
|
||||||
|
Request->Release();
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Wait)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// wait for the operation to complete
|
||||||
|
//
|
||||||
|
KeWaitForSingleObject(pEvent, Executive, KernelMode, FALSE, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO:
|
||||||
|
// Get result code from operation
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// returns the result code when the operation has been finished
|
||||||
|
//
|
||||||
|
//Status = Request->GetResultCode();
|
||||||
|
|
||||||
|
//
|
||||||
|
// release request
|
||||||
|
//
|
||||||
|
Request->Release();
|
||||||
|
|
||||||
|
//
|
||||||
|
// done
|
||||||
|
//
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
NTSTATUS
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue