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/hidusb.c?rev=54765&r1=54764&r2=54765&view=diff
==============================================================================
--- 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/hidusb.h?rev=54765&r1=54764&r2=54765&view=diff
==============================================================================
--- 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;
 


Reply via email to