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/…
==============================================================================
--- 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/…
==============================================================================
--- 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;