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/h... ============================================================================== --- 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/h... ============================================================================== --- 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;