[USB-BRINGUP]

- Implement IOCTL_HID_GET_DEVICE_ATTRIBUTES, IOCTL_HID_GET_DEVICE_DESCRIPTOR for hidusb
- Partly implement pnp dispatch routines for hidusb

svn path=/branches/usb-bringup/; revision=54764
This commit is contained in:
Johannes Anderwald 2011-12-26 18:20:32 +00:00
parent 3477d17d4b
commit c626190319
2 changed files with 319 additions and 6 deletions

View file

@ -52,9 +52,103 @@ HidInternalDeviceControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
UNIMPLEMENTED
ASSERT(FALSE);
return STATUS_NOT_IMPLEMENTED;
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
@ -92,15 +186,225 @@ HidSystemControl(
return IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
}
NTSTATUS
Hid_PnpStart(
IN PDEVICE_OBJECT DeviceObject)
{
UNIMPLEMENTED
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
NTAPI
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)
{
UNIMPLEMENTED
ASSERT(FALSE);
return STATUS_NOT_IMPLEMENTED;
NTSTATUS Status;
PIO_STACK_LOCATION IoStack;
PHID_USB_DEVICE_EXTENSION HidDeviceExtension;
PHID_DEVICE_EXTENSION DeviceExtension;
KEVENT Event;
//
// get device extension
//
DeviceExtension = (PHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
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

View file

@ -18,5 +18,14 @@ typedef struct
//
LIST_ENTRY PendingRequests;
//
// hid descriptor
//
PHID_DESCRIPTOR HidDescriptor;
USHORT VendorID;
USHORT ProductID;
USHORT VersionNumber;
}HID_USB_DEVICE_EXTENSION, *PHID_USB_DEVICE_EXTENSION;