Author: janderwald
Date: Mon Dec 26 18:20:32 2011
New Revision: 54764

URL: http://svn.reactos.org/svn/reactos?rev=54764&view=rev
Log:
[USB-BRINGUP]
- Implement IOCTL_HID_GET_DEVICE_ATTRIBUTES, IOCTL_HID_GET_DEVICE_DESCRIPTOR 
for hidusb
- Partly implement pnp dispatch routines for hidusb

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=54764&r1=54763&r2=54764&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 
18:20:32 2011
@@ -52,6 +52,111 @@
     IN PDEVICE_OBJECT DeviceObject,
     IN PIRP Irp)
 {
+    PIO_STACK_LOCATION IoStack;
+    PHID_USB_DEVICE_EXTENSION HidDeviceExtension;
+    PHID_DEVICE_EXTENSION DeviceExtension;
+    PHID_DEVICE_ATTRIBUTES Attributes;
+    ULONG Length;
+    NTSTATUS Status;
+
+    //
+    // get device extension
+    //
+    DeviceExtension = (PHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+    HidDeviceExtension = 
(PHID_USB_DEVICE_EXTENSION)DeviceExtension->MiniDeviceExtension;
+
+    //
+    // get current stack location
+    //
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    switch(IoStack->Parameters.DeviceIoControl.IoControlCode)
+    {
+        case IOCTL_HID_GET_DEVICE_ATTRIBUTES:
+        {
+            if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < 
sizeof(HID_DEVICE_ATTRIBUTES))
+            {
+                //
+                // invalid request
+                //
+                Irp->IoStatus.Status = STATUS_INVALID_BUFFER_SIZE;
+                IoCompleteRequest(Irp, IO_NO_INCREMENT);
+                return STATUS_INVALID_BUFFER_SIZE;
+            }
+            //
+            // store result
+            //
+            ASSERT(HidDeviceExtension->HidDescriptor);
+            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;
+
+            //
+            // complete request
+            //
+            Irp->IoStatus.Status = STATUS_SUCCESS;
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            return STATUS_SUCCESS;
+        }
+        case IOCTL_HID_GET_DEVICE_DESCRIPTOR:
+        {
+            //
+            // sanity check
+            //
+            ASSERT(HidDeviceExtension->HidDescriptor);
+
+            //
+            // store length
+            //
+            Length = min(HidDeviceExtension->HidDescriptor->bLength, 
IoStack->Parameters.DeviceIoControl.OutputBufferLength);
+
+            //
+            // copy descriptor
+            //
+            RtlCopyMemory(Irp->UserBuffer, HidDeviceExtension->HidDescriptor, 
Length);
+
+            //
+            // store result length
+            //
+            Irp->IoStatus.Information = 
HidDeviceExtension->HidDescriptor->bLength;
+            Irp->IoStatus.Status = STATUS_SUCCESS;
+
+            /* complete request */
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            return STATUS_SUCCESS;
+        }
+        case IOCTL_HID_GET_REPORT_DESCRIPTOR:
+        case IOCTL_HID_READ_REPORT:
+        case IOCTL_HID_WRITE_REPORT:
+        case IOCTL_GET_PHYSICAL_DESCRIPTOR:
+        case IOCTL_HID_SEND_IDLE_NOTIFICATION_REQUEST:
+        case IOCTL_HID_GET_FEATURE:
+        case IOCTL_HID_SET_FEATURE:
+        case IOCTL_HID_SET_OUTPUT_REPORT:
+        case IOCTL_HID_GET_INPUT_REPORT:
+        case IOCTL_HID_GET_INDEXED_STRING:
+        case IOCTL_HID_GET_MS_GENRE_DESCRIPTOR:
+        {
+            DPRINT1("UNIMPLEMENTED %x\n", 
IoStack->Parameters.DeviceIoControl.IoControlCode);
+            Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+            ASSERT(FALSE);
+        }
+        default:
+            Status = Irp->IoStatus.Status;
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            return Status;
+    }
+}
+
+NTSTATUS
+NTAPI
+HidPower(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
+{
     UNIMPLEMENTED
     ASSERT(FALSE);
     return STATUS_NOT_IMPLEMENTED;
@@ -59,48 +164,247 @@
 
 NTSTATUS
 NTAPI
-HidPower(
+HidSystemControl(
     IN PDEVICE_OBJECT DeviceObject,
     IN PIRP Irp)
 {
+    PHID_DEVICE_EXTENSION DeviceExtension;
+
+    //
+    // get hid device extension
+    //
+    DeviceExtension = (PHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+    //
+    // copy stack location
+    //
+    IoCopyCurrentIrpStackLocationToNext(Irp);
+
+    //
+    // submit request
+    //
+    return IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
+}
+
+NTSTATUS
+Hid_PnpStart(
+    IN PDEVICE_OBJECT DeviceObject)
+{
     UNIMPLEMENTED
-    ASSERT(FALSE);
     return STATUS_NOT_IMPLEMENTED;
 }
 
 NTSTATUS
 NTAPI
-HidSystemControl(
+Hid_PnpCompletion(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp,
+    IN PVOID Context)
+{
+    //
+    // signal event
+    //
+    KeSetEvent((PRKEVENT)Context, 0, FALSE);
+
+    //
+    // done
+    //
+    return STATUS_MORE_PROCESSING_REQUIRED;
+}
+
+NTSTATUS
+NTAPI
+HidPnp(
     IN PDEVICE_OBJECT DeviceObject,
     IN PIRP Irp)
 {
+    NTSTATUS Status;
+    PIO_STACK_LOCATION IoStack;
+    PHID_USB_DEVICE_EXTENSION HidDeviceExtension;
     PHID_DEVICE_EXTENSION DeviceExtension;
-
-    //
-    // get hid device extension
+    KEVENT Event;
+
+    //
+    // get device extension
     //
     DeviceExtension = (PHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
-    //
-    // copy stack location
-    //
-    IoCopyCurrentIrpStackLocationToNext(Irp);
-
-    //
-    // submit request
-    //
-    return IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
-}
-
-NTSTATUS
-NTAPI
-HidPnp(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp)
-{
-    UNIMPLEMENTED
-    ASSERT(FALSE);
-    return STATUS_NOT_IMPLEMENTED;
+    HidDeviceExtension = 
(PHID_USB_DEVICE_EXTENSION)DeviceExtension->MiniDeviceExtension;
+
+    //
+    // get current stack location
+    //
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    //
+    // handle requests based on request type
+    //
+    switch(IoStack->MinorFunction)
+    {
+        case IRP_MN_REMOVE_DEVICE:
+        {
+            //
+            // pass request onto lower driver
+            //
+            IoSkipCurrentIrpStackLocation(Irp);
+            Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
+ 
+            //
+            // free resources
+            //
+            if (HidDeviceExtension->HidDescriptor)
+            {
+                ExFreePool(HidDeviceExtension->HidDescriptor);
+                HidDeviceExtension->HidDescriptor = NULL;
+            }
+
+            //
+            // done
+            //
+            return Status;
+        }
+        case IRP_MN_QUERY_PNP_DEVICE_STATE:
+        {
+            //
+            // device can not be disabled
+            //
+            Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE;
+
+            //
+            // pass request to next request
+            //
+            IoSkipCurrentIrpStackLocation(Irp);
+            Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
+
+            //
+            // done
+            //
+            return Status;
+        }
+        case IRP_MN_STOP_DEVICE:
+        {
+            //
+            // FIXME: unconfigure the device
+            //
+
+            //
+            // prepare irp
+            //
+            KeInitializeEvent(&Event, NotificationEvent, FALSE);
+            IoCopyCurrentIrpStackLocationToNext(Irp);
+            IoSetCompletionRoutine(Irp, Hid_PnpCompletion, (PVOID)&Event, 
TRUE, TRUE, TRUE);
+
+            //
+            // send irp and wait for completion
+            //
+            Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
+            if (Status == STATUS_PENDING)
+            {
+                KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, 
NULL);
+                Status = Irp->IoStatus.Status;
+            }
+
+            //
+            // free resources
+            //
+            if (HidDeviceExtension->HidDescriptor)
+            {
+                ExFreePool(HidDeviceExtension->HidDescriptor);
+                HidDeviceExtension->HidDescriptor = NULL;
+            }
+
+            //
+            // done
+            //
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            return Status;
+        }
+        case IRP_MN_QUERY_CAPABILITIES:
+        {
+            //
+            // prepare irp
+            //
+            KeInitializeEvent(&Event, NotificationEvent, FALSE);
+            IoCopyCurrentIrpStackLocationToNext(Irp);
+            IoSetCompletionRoutine(Irp, Hid_PnpCompletion, (PVOID)&Event, 
TRUE, TRUE, TRUE);
+
+            //
+            // send irp and wait for completion
+            //
+            Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
+            if (Status == STATUS_PENDING)
+            {
+                KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, 
NULL);
+                Status = Irp->IoStatus.Status;
+            }
+
+            if (NT_SUCCESS(Status))
+            {
+                //
+                // driver supports D1 & D2
+                //
+                IoStack->Parameters.DeviceCapabilities.Capabilities->DeviceD1 
= TRUE;
+                IoStack->Parameters.DeviceCapabilities.Capabilities->DeviceD2 
= TRUE;
+            }
+
+            //
+            // done
+            //
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            return Status;
+        }
+        case IRP_MN_START_DEVICE:
+        {
+            //
+            // prepare irp
+            //
+            KeInitializeEvent(&Event, NotificationEvent, FALSE);
+            IoCopyCurrentIrpStackLocationToNext(Irp);
+            IoSetCompletionRoutine(Irp, Hid_PnpCompletion, (PVOID)&Event, 
TRUE, TRUE, TRUE);
+
+            //
+            // send irp and wait for completion
+            //
+            Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
+            if (Status == STATUS_PENDING)
+            {
+                KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, 
NULL);
+                Status = Irp->IoStatus.Status;
+            }
+
+            //
+            // did the device successfully start
+            //
+            if (!NT_SUCCESS(Status))
+            {
+                //
+                // failed
+                //
+                DPRINT1("HIDUSB: IRP_MN_START_DEVICE failed with %x\n", 
Status);
+                IoCompleteRequest(Irp, IO_NO_INCREMENT);
+                return Status;
+            }
+
+            //
+            // start device
+            //
+            Status = Hid_PnpStart(DeviceObject);
+
+            //
+            // complete request
+            //
+            Irp->IoStatus.Status = Status;
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            return Status;
+        }
+        default:
+        {
+             //
+             // forward and forget request
+             //
+             IoSkipCurrentIrpStackLocation(Irp);
+             return IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
+        }
+    }
 }
 
 NTSTATUS

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=54764&r1=54763&r2=54764&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 
18:20:32 2011
@@ -18,5 +18,14 @@
     //
     LIST_ENTRY PendingRequests;
 
+    //
+    // hid descriptor
+    //
+    PHID_DESCRIPTOR HidDescriptor;
+
+    USHORT VendorID;
+    USHORT ProductID;
+    USHORT VersionNumber;
+
 }HID_USB_DEVICE_EXTENSION, *PHID_USB_DEVICE_EXTENSION;
 


Reply via email to