Author: janderwald
Date: Mon Dec 26 21:51:05 2011
New Revision: 54765
URL:
http://svn.reactos.org/svn/reactos?rev=54765&view=rev
Log:
[USB-BRINGUP]
- Implement retrieving device / configuration descriptor
- Partly implement hid descriptor parsing
- Select configuration when initialization is complete
- Implement starting up device
Modified:
branches/usb-bringup/drivers/hid/hidusb/hidusb.c
branches/usb-bringup/drivers/hid/hidusb/hidusb.h
Modified: branches/usb-bringup/drivers/hid/hidusb/hidusb.c
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/hid/hidusb/…
==============================================================================
--- branches/usb-bringup/drivers/hid/hidusb/hidusb.c [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/hid/hidusb/hidusb.c [iso-8859-1] Mon Dec 26 21:51:05
2011
@@ -86,13 +86,13 @@
//
// store result
//
- ASSERT(HidDeviceExtension->HidDescriptor);
+ ASSERT(HidDeviceExtension->DeviceDescriptor);
Irp->IoStatus.Information = sizeof(HID_DESCRIPTOR);
Attributes = (PHID_DEVICE_ATTRIBUTES)Irp->UserBuffer;
Attributes->Size = sizeof(HID_DEVICE_ATTRIBUTES);
- Attributes->VendorID = HidDeviceExtension->VendorID;
- Attributes->ProductID = HidDeviceExtension->ProductID;
- Attributes->VersionNumber = HidDeviceExtension->VersionNumber;
+ Attributes->VendorID =
HidDeviceExtension->DeviceDescriptor->idVendor;
+ Attributes->ProductID =
HidDeviceExtension->DeviceDescriptor->idProduct;
+ Attributes->VersionNumber =
HidDeviceExtension->DeviceDescriptor->bcdDevice;
//
// complete request
@@ -187,14 +187,6 @@
}
NTSTATUS
-Hid_PnpStart(
- IN PDEVICE_OBJECT DeviceObject)
-{
- UNIMPLEMENTED
- return STATUS_NOT_IMPLEMENTED;
-}
-
-NTSTATUS
NTAPI
Hid_PnpCompletion(
IN PDEVICE_OBJECT DeviceObject,
@@ -211,6 +203,437 @@
//
return STATUS_MORE_PROCESSING_REQUIRED;
}
+
+NTSTATUS
+Hid_DispatchUrb(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PURB Urb)
+{
+ PIRP Irp;
+ KEVENT Event;
+ PHID_USB_DEVICE_EXTENSION HidDeviceExtension;
+ PHID_DEVICE_EXTENSION DeviceExtension;
+ IO_STATUS_BLOCK IoStatus;
+ PIO_STACK_LOCATION IoStack;
+ NTSTATUS Status;
+
+ //
+ // init event
+ //
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+ //
+ // get device extension
+ //
+ DeviceExtension = (PHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ HidDeviceExtension =
(PHID_USB_DEVICE_EXTENSION)DeviceExtension->MiniDeviceExtension;
+
+
+ //
+ // build irp
+ //
+ Irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_SUBMIT_URB,
DeviceExtension->NextDeviceObject, NULL, 0, NULL, 0, TRUE, &Event, &IoStatus);
+ if (!Irp)
+ {
+ //
+ // no memory
+ //
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ //
+ // get next stack location
+ //
+ IoStack = IoGetNextIrpStackLocation(Irp);
+
+ //
+ // store urb
+ //
+ IoStack->Parameters.Others.Argument1 = (PVOID)Urb;
+
+ //
+ // set completion routine
+ //
+ IoSetCompletionRoutine(Irp, Hid_PnpCompletion, (PVOID)&Event, TRUE, TRUE, TRUE);
+
+ //
+ // call driver
+ //
+ Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
+
+ //
+ // wait for the request to finish
+ //
+ if (Status == STATUS_PENDING)
+ {
+ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+ Status = IoStatus.Status;
+ }
+
+ //
+ // complete request
+ //
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ //
+ // done
+ //
+ return Status;
+}
+
+NTSTATUS
+Hid_GetDescriptor(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN USHORT UrbLength,
+ IN OUT PVOID *UrbBuffer,
+ IN OUT PULONG UrbBufferLength,
+ IN UCHAR DescriptorType,
+ IN UCHAR Index,
+ IN USHORT LanguageIndex)
+{
+ PURB Urb;
+ NTSTATUS Status;
+ UCHAR Allocated = FALSE;
+
+ //
+ // allocate urb
+ //
+ Urb = (PURB)ExAllocatePool(NonPagedPool, UrbLength);
+ if (!Urb)
+ {
+ //
+ // no memory
+ //
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ //
+ // is there an urb buffer
+ //
+ if (!*UrbBuffer)
+ {
+ //
+ // allocate buffer
+ //
+ *UrbBuffer = ExAllocatePool(NonPagedPool, *UrbBufferLength);
+ if (!*UrbBuffer)
+ {
+ //
+ // no memory
+ //
+ ExFreePool(Urb);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ //
+ // zero buffer
+ //
+ RtlZeroMemory(*UrbBuffer, *UrbBufferLength);
+ Allocated = TRUE;
+ }
+
+ //
+ // zero urb
+ //
+ RtlZeroMemory(Urb, UrbLength);
+
+ //
+ // build descriptor request
+ //
+ UsbBuildGetDescriptorRequest(Urb, UrbLength, DescriptorType, Index, LanguageIndex,
*UrbBuffer, NULL, *UrbBufferLength, NULL);
+
+ //
+ // dispatch urb
+ //
+ Status = Hid_DispatchUrb(DeviceObject, Urb);
+
+ //
+ // did the request fail
+ //
+ if (!NT_SUCCESS(Status))
+ {
+ if (Allocated)
+ {
+ //
+ // free allocated buffer
+ //
+ ExFreePool(*UrbBuffer);
+ *UrbBuffer = NULL;
+ }
+
+ //
+ // free urb
+ //
+ ExFreePool(Urb);
+ *UrbBufferLength = 0;
+ return Status;
+ }
+
+ //
+ // did urb request fail
+ //
+ if (!NT_SUCCESS(Urb->UrbHeader.Status))
+ {
+ if (Allocated)
+ {
+ //
+ // free allocated buffer
+ //
+ ExFreePool(*UrbBuffer);
+ *UrbBuffer = NULL;
+ }
+
+ //
+ // free urb
+ //
+ ExFreePool(Urb);
+ *UrbBufferLength = 0;
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ //
+ // store result length
+ //
+ *UrbBufferLength = Urb->UrbControlDescriptorRequest.TransferBufferLength;
+
+ //
+ // free urb
+ //
+ ExFreePool(Urb);
+
+ //
+ // completed successfully
+ //
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+Hid_SelectConfiguration(
+ IN PDEVICE_OBJECT DeviceObject)
+{
+ PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
+ NTSTATUS Status;
+ USBD_INTERFACE_LIST_ENTRY InterfaceList[2];
+ PURB Urb;
+ PHID_USB_DEVICE_EXTENSION HidDeviceExtension;
+ PHID_DEVICE_EXTENSION DeviceExtension;
+
+ //
+ // get device extension
+ //
+ DeviceExtension = (PHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ HidDeviceExtension =
(PHID_USB_DEVICE_EXTENSION)DeviceExtension->MiniDeviceExtension;
+
+ //
+ // now parse the descriptors
+ //
+ InterfaceDescriptor =
USBD_ParseConfigurationDescriptorEx(HidDeviceExtension->ConfigurationDescriptor,
+
HidDeviceExtension->ConfigurationDescriptor,
+ -1,
+ -1,
+
USB_DEVICE_CLASS_HUMAN_INTERFACE,
+ -1,
+ -1);
+
+ //
+ // sanity check
+ //
+ ASSERT(InterfaceDescriptor);
+ ASSERT(InterfaceDescriptor->bInterfaceClass == USB_DEVICE_CLASS_HUMAN_INTERFACE);
+ ASSERT(InterfaceDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE);
+ ASSERT(InterfaceDescriptor->bLength == sizeof(USB_INTERFACE_DESCRIPTOR));
+
+ //
+ // setup interface list
+ //
+ RtlZeroMemory(InterfaceList, sizeof(InterfaceList));
+ InterfaceList[0].InterfaceDescriptor = InterfaceDescriptor;
+
+ //
+ // build urb
+ //
+ Urb =
USBD_CreateConfigurationRequestEx(HidDeviceExtension->ConfigurationDescriptor,
InterfaceList);
+ if (!Urb)
+ {
+ //
+ // no memory
+ //
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ //
+ // dispatch request
+ //
+ Status = Hid_DispatchUrb(DeviceObject, Urb);
+ if (NT_SUCCESS(Status))
+ {
+ //
+ // store configuration handle
+ //
+ HidDeviceExtension->ConfigurationHandle =
Urb->UrbSelectConfiguration.ConfigurationHandle;
+
+ //
+ // copy interface info
+ //
+ HidDeviceExtension->InterfaceInfo =
(PUSBD_INTERFACE_INFORMATION)ExAllocatePool(NonPagedPool,
Urb->UrbSelectConfiguration.Interface.Length);
+ if (HidDeviceExtension->InterfaceInfo)
+ {
+ //
+ // copy interface info
+ //
+ RtlCopyMemory(HidDeviceExtension->InterfaceInfo,
&Urb->UrbSelectConfiguration.Interface,
Urb->UrbSelectConfiguration.Interface.Length);
+ }
+ }
+
+ //
+ // free urb request
+ //
+ ExFreePool(Urb);
+
+ //
+ // done
+ //
+ return Status;
+}
+
+
+NTSTATUS
+Hid_PnpStart(
+ IN PDEVICE_OBJECT DeviceObject)
+{
+ PHID_USB_DEVICE_EXTENSION HidDeviceExtension;
+ PHID_DEVICE_EXTENSION DeviceExtension;
+ NTSTATUS Status;
+ ULONG DescriptorLength;
+ PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
+ PHID_DESCRIPTOR HidDescriptor;
+
+ //
+ // get device extension
+ //
+ DeviceExtension = (PHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ HidDeviceExtension =
(PHID_USB_DEVICE_EXTENSION)DeviceExtension->MiniDeviceExtension;
+
+ //
+ // get device descriptor
+ //
+ DescriptorLength = sizeof(USB_DEVICE_DESCRIPTOR);
+ Status = Hid_GetDescriptor(DeviceObject, sizeof(struct
_URB_CONTROL_DESCRIPTOR_REQUEST), (PVOID*)&HidDeviceExtension->DeviceDescriptor,
&DescriptorLength, USB_DEVICE_DESCRIPTOR_TYPE, 0, 0);
+ if (!NT_SUCCESS(Status))
+ {
+ //
+ // failed to obtain device descriptor
+ //
+ DPRINT1("Hid_PnpStart failed to get device descriptor %x\n", Status);
+ return Status;
+ }
+
+ //
+ // now get the configuration descriptor
+ //
+ DescriptorLength = sizeof(USB_CONFIGURATION_DESCRIPTOR);
+ Status = Hid_GetDescriptor(DeviceObject, sizeof(struct
_URB_CONTROL_DESCRIPTOR_REQUEST),
(PVOID*)&HidDeviceExtension->ConfigurationDescriptor, &DescriptorLength,
USB_CONFIGURATION_DESCRIPTOR_TYPE, 0, 0);
+ if (!NT_SUCCESS(Status))
+ {
+ //
+ // failed to obtain device descriptor
+ //
+ DPRINT1("Hid_PnpStart failed to get device descriptor %x\n", Status);
+ return Status;
+ }
+
+ //
+ // sanity check
+ //
+ ASSERT(DescriptorLength);
+ ASSERT(HidDeviceExtension->ConfigurationDescriptor);
+ ASSERT(HidDeviceExtension->ConfigurationDescriptor->bLength);
+
+ //
+ // store full length
+ //
+ DescriptorLength = HidDeviceExtension->ConfigurationDescriptor->wTotalLength;
+
+ //
+ // delete partial configuration descriptor
+ //
+ ExFreePool(HidDeviceExtension->ConfigurationDescriptor);
+ HidDeviceExtension->ConfigurationDescriptor = NULL;
+
+ //
+ // get full configuration descriptor
+ //
+ Status = Hid_GetDescriptor(DeviceObject, sizeof(struct
_URB_CONTROL_DESCRIPTOR_REQUEST),
(PVOID*)&HidDeviceExtension->ConfigurationDescriptor, &DescriptorLength,
USB_CONFIGURATION_DESCRIPTOR_TYPE, 0, 0);
+ if (!NT_SUCCESS(Status))
+ {
+ //
+ // failed to obtain device descriptor
+ //
+ DPRINT1("Hid_PnpStart failed to get device descriptor %x\n", Status);
+ return Status;
+ }
+
+ //
+ // now parse the descriptors
+ //
+ InterfaceDescriptor =
USBD_ParseConfigurationDescriptorEx(HidDeviceExtension->ConfigurationDescriptor,
+
HidDeviceExtension->ConfigurationDescriptor,
+ -1,
+ -1,
+
USB_DEVICE_CLASS_HUMAN_INTERFACE,
+ -1,
+ -1);
+ if (!InterfaceDescriptor)
+ {
+ //
+ // no interface class
+ //
+ DPRINT1("NO HID Class found\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ //
+ // sanity check
+ //
+ ASSERT(InterfaceDescriptor->bInterfaceClass == USB_DEVICE_CLASS_HUMAN_INTERFACE);
+ ASSERT(InterfaceDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE);
+ ASSERT(InterfaceDescriptor->bLength == sizeof(USB_INTERFACE_DESCRIPTOR));
+
+ //
+ // move to next descriptor
+ //
+ HidDescriptor = (PHID_DESCRIPTOR)((ULONG_PTR)InterfaceDescriptor +
InterfaceDescriptor->bLength);
+ ASSERT(HidDescriptor->bLength >= 2);
+
+ //
+ // check if this is the hid descriptor
+ //
+ if (HidDescriptor->bLength == sizeof(HID_DESCRIPTOR) &&
HidDescriptor->bDescriptorType == HID_HID_DESCRIPTOR_TYPE)
+ {
+ //
+ // found
+ //
+ HidDeviceExtension->HidDescriptor = HidDescriptor;
+
+ //
+ // select configuration
+ //
+ Status = Hid_SelectConfiguration(DeviceObject);
+
+ //
+ // done
+ //
+ return Status;
+ }
+
+ //
+ // FIXME parse hid descriptor
+ //
+ UNIMPLEMENTED
+ ASSERT(FALSE);
+ return STATUS_SUCCESS;
+}
+
NTSTATUS
NTAPI
Modified: branches/usb-bringup/drivers/hid/hidusb/hidusb.h
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/hid/hidusb/…
==============================================================================
--- branches/usb-bringup/drivers/hid/hidusb/hidusb.h [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/hid/hidusb/hidusb.h [iso-8859-1] Mon Dec 26 21:51:05
2011
@@ -5,6 +5,11 @@
#include <ntddk.h>
#include <hidport.h>
#include <debug.h>
+#include <hubbusif.h>
+#include <usbbusif.h>
+#include <usbioctl.h>
+#include <usb.h>
+#include <usbdlib.h>
typedef struct
{
@@ -19,13 +24,28 @@
LIST_ENTRY PendingRequests;
//
+ // device descriptor
+ //
+ PUSB_DEVICE_DESCRIPTOR DeviceDescriptor;
+
+ //
+ // configuration descriptor
+ //
+ PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
+
+ //
+ // interface information
+ //
+ PUSBD_INTERFACE_INFORMATION InterfaceInfo;
+
+ //
+ // configuration handle
+ //
+ USBD_CONFIGURATION_HANDLE ConfigurationHandle;
+
+ //
// hid descriptor
//
PHID_DESCRIPTOR HidDescriptor;
-
- USHORT VendorID;
- USHORT ProductID;
- USHORT VersionNumber;
-
}HID_USB_DEVICE_EXTENSION, *PHID_USB_DEVICE_EXTENSION;