Author: janderwald Date: Sun Jan 1 22:48:08 2012 New Revision: 54806
URL: http://svn.reactos.org/svn/reactos?rev=54806&view=rev Log: [USB-BRINGUP] - Fake status success for unimplemented IRP_MN_REMOVE_DEVICE - Fix tons of bugs in the read report completion routine - Implement function to re-use a complete report irp - Use correct device object when invoking the mini driver's dispatch routine in the read function - silence a few traces - Mouse now works with with ReactOS USB stack + ReactOS HID stack (TBD: implement hidparse.sys)
Modified: branches/usb-bringup/drivers/hid/hidclass/hidclass.c branches/usb-bringup/drivers/hid/hidclass/pdo.c branches/usb-bringup/drivers/hid/hidclass/precomp.h branches/usb-bringup/drivers/hid/hidusb/hidusb.c branches/usb-bringup/drivers/hid/hidusb/hidusb.h branches/usb-bringup/drivers/hid/mouhid/mouhid.c
Modified: branches/usb-bringup/drivers/hid/hidclass/hidclass.c URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/hid/hidclass... ============================================================================== --- branches/usb-bringup/drivers/hid/hidclass/hidclass.c [iso-8859-1] (original) +++ branches/usb-bringup/drivers/hid/hidclass/hidclass.c [iso-8859-1] Sun Jan 1 22:48:08 2012 @@ -140,7 +140,6 @@ // // only supported for PDO // - DPRINT1("[HIDCLASS] IRP_MJ_CREATE for FDO\n"); Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_UNSUCCESSFUL; @@ -269,6 +268,31 @@ return STATUS_SUCCESS; }
+PVOID +HidClass_GetSystemAddress( + IN PMDL ReportMDL) +{ + // + // sanity check + // + ASSERT(ReportMDL); + + if (ReportMDL->MdlFlags & (MDL_SOURCE_IS_NONPAGED_POOL | MDL_MAPPED_TO_SYSTEM_VA)) + { + // + // buffer is non paged pool + // + return ReportMDL->MappedSystemVa; + } + else + { + // + // map mdl + // + return MmMapLockedPages(ReportMDL, KernelMode); + } +} + NTSTATUS NTAPI HidClass_ReadCompleteIrp( @@ -278,19 +302,23 @@ { PHIDCLASS_IRP_CONTEXT IrpContext; KIRQL OldLevel; + PUCHAR Address; + ULONG Offset; + PHIDP_DEVICE_DESC DeviceDescription; + ULONG CollectionIndex;
// // get irp context // IrpContext = (PHIDCLASS_IRP_CONTEXT)Ctx;
- DPRINT1("HidClass_ReadCompleteIrp Irql %lu\n", KeGetCurrentIrql()); - DPRINT1("HidClass_ReadCompleteIrp Status %lx\n", Irp->IoStatus.Status); - DPRINT1("HidClass_ReadCompleteIrp Length %lu\n", Irp->IoStatus.Information); - DPRINT1("HidClass_ReadCompleteIrp Irp %p\n", Irp); - DPRINT1("HidClass_ReadCompleteIrp InputReportBuffer %p\n", IrpContext->InputReportBuffer); - DPRINT1("HidClass_ReadCompleteIrp InputReportBufferLength %li\n", IrpContext->InputReportBufferLength); - DPRINT1("HidClass_ReadCompleteIrp OriginalIrp %p\n", IrpContext->OriginalIrp); + DPRINT("HidClass_ReadCompleteIrp Irql %lu\n", KeGetCurrentIrql()); + DPRINT("HidClass_ReadCompleteIrp Status %lx\n", Irp->IoStatus.Status); + DPRINT("HidClass_ReadCompleteIrp Length %lu\n", Irp->IoStatus.Information); + DPRINT("HidClass_ReadCompleteIrp Irp %p\n", Irp); + DPRINT("HidClass_ReadCompleteIrp InputReportBuffer %p\n", IrpContext->InputReportBuffer); + DPRINT("HidClass_ReadCompleteIrp InputReportBufferLength %li\n", IrpContext->InputReportBufferLength); + DPRINT("HidClass_ReadCompleteIrp OriginalIrp %p\n", IrpContext->OriginalIrp);
// // copy result @@ -298,9 +326,28 @@ if (Irp->IoStatus.Information) { // - // copy result - // - RtlCopyMemory(IrpContext->OriginalIrp->UserBuffer, IrpContext->InputReportBuffer, IrpContext->InputReportBufferLength); + // get address + // + Address = HidClass_GetSystemAddress(IrpContext->OriginalIrp->MdlAddress); + if (Address) + { + // + // reports may have a report id prepended + // + CollectionIndex = IrpContext->FileOp->DeviceExtension->CollectionIndex; + DeviceDescription = &IrpContext->FileOp->DeviceExtension->Common.DeviceDescription; + + // + // calculate offset + // + ASSERT(DeviceDescription->CollectionDesc[CollectionIndex].InputLength >= DeviceDescription->ReportIDs[CollectionIndex].InputLength); + Offset = DeviceDescription->CollectionDesc[CollectionIndex].InputLength - DeviceDescription->ReportIDs[CollectionIndex].InputLength; + + // + // copy result + // + RtlCopyMemory(&Address[Offset], IrpContext->InputReportBuffer, IrpContext->InputReportBufferLength); + } }
// @@ -315,34 +362,79 @@ ExFreePool(IrpContext->InputReportBuffer);
// + // remove us from pending list + // + KeAcquireSpinLock(&IrpContext->FileOp->Lock, &OldLevel); + + // + // remove from pending list + // + RemoveEntryList(&Irp->Tail.Overlay.ListEntry); + + // + // insert into completed list + // + InsertTailList(&IrpContext->FileOp->IrpCompletedListHead, &Irp->Tail.Overlay.ListEntry); + + // + // release lock + // + KeReleaseSpinLock(&IrpContext->FileOp->Lock, OldLevel); + + // // complete original request // IoCompleteRequest(IrpContext->OriginalIrp, IO_NO_INCREMENT);
// - // remove us from pending list - // - KeAcquireSpinLock(&IrpContext->FileOp->Lock, &OldLevel); - - // - // remove from pending list - // - RemoveEntryList(&Irp->Tail.Overlay.ListEntry); + // free irp context + // + ExFreePool(IrpContext); + + // + // done + // + return STATUS_MORE_PROCESSING_REQUIRED; +} + +PIRP +HidClass_GetIrp( + IN PHIDCLASS_FILEOP_CONTEXT Context) +{ + KIRQL OldLevel; + PIRP Irp = NULL; + PLIST_ENTRY ListEntry; + + // + // acquire lock + // + KeAcquireSpinLock(&Context->Lock, &OldLevel); + + // + // is list empty? + // + if (!IsListEmpty(&Context->IrpCompletedListHead)) + { + // + // grab first entry + // + ListEntry = RemoveHeadList(&Context->IrpCompletedListHead); + + // + // get irp + // + Irp = (PIRP)CONTAINING_RECORD(ListEntry, IRP, Tail.Overlay.ListEntry); + }
// // release lock // - KeReleaseSpinLock(&IrpContext->FileOp->Lock, OldLevel); - - // - // free irp context - // - ExFreePool(IrpContext); + KeReleaseSpinLock(&Context->Lock, OldLevel);
// // done // - return STATUS_SUCCESS; + return Irp; }
NTSTATUS @@ -358,17 +450,32 @@ PIRP Irp; PIO_STACK_LOCATION IoStack; PHIDCLASS_IRP_CONTEXT IrpContext; - - // - // build new irp - // - Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); + PHIDCLASS_PDO_DEVICE_EXTENSION PDODeviceExtension; + + // + // get an irp from fresh list + // + Irp = HidClass_GetIrp(Context); if (!Irp) { // - // no memory - // - return STATUS_INSUFFICIENT_RESOURCES; + // build new irp + // + Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); + if (!Irp) + { + // + // no memory + // + return STATUS_INSUFFICIENT_RESOURCES; + } + } + else + { + // + // re-use irp + // + IoReuseIrp(Irp, STATUS_SUCCESS); }
// @@ -385,17 +492,31 @@ }
// + // get device extension + // + PDODeviceExtension = (PHIDCLASS_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + ASSERT(PDODeviceExtension->Common.IsFDO == FALSE); + + // + // sanity checks + // + ASSERT(PDODeviceExtension->CollectionIndex < PDODeviceExtension->Common.DeviceDescription.CollectionDescLength); + ASSERT(PDODeviceExtension->CollectionIndex < PDODeviceExtension->Common.DeviceDescription.ReportIDsLength); + ASSERT(PDODeviceExtension->Common.DeviceDescription.ReportIDs[PDODeviceExtension->CollectionIndex].InputLength > 0); + ASSERT(PDODeviceExtension->Common.DeviceDescription.CollectionDesc[PDODeviceExtension->CollectionIndex].InputLength == BufferLength); + + // // init irp context // RtlZeroMemory(IrpContext, sizeof(HIDCLASS_IRP_CONTEXT)); - IrpContext->InputReportBufferLength = BufferLength; + IrpContext->InputReportBufferLength = PDODeviceExtension->Common.DeviceDescription.ReportIDs[PDODeviceExtension->CollectionIndex].InputLength; IrpContext->OriginalIrp = RequestIrp; IrpContext->FileOp = Context;
// // allocate buffer // - IrpContext->InputReportBuffer = ExAllocatePool(NonPagedPool, BufferLength); + IrpContext->InputReportBuffer = ExAllocatePool(NonPagedPool, IrpContext->InputReportBufferLength); if (!IrpContext->InputReportBuffer) { // @@ -428,8 +549,6 @@ *OutIrp = Irp; *OutIrpContext = IrpContext;
- DPRINT1("IRP %p Buffer %p\n", Irp, Irp->UserBuffer); - // // done // @@ -449,11 +568,18 @@ NTSTATUS Status; PIRP NewIrp; PHIDCLASS_IRP_CONTEXT NewIrpContext; + PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension;
// // get current stack location // IoStack = IoGetCurrentIrpStackLocation(Irp); + + // + // get device extension + // + CommonDeviceExtension = (PHIDCLASS_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + ASSERT(CommonDeviceExtension->IsFDO == FALSE);
// // sanity check @@ -472,12 +598,10 @@ // ASSERT(Context->DeviceExtension->Common.DriverExtension->DevicesArePolled == FALSE);
- DPRINT1("[HIDCLASS] IRP_MJ_READ\n"); - // // build irp request // - Status = HidClass_BuildIrp(DeviceObject, Irp, Context, IOCTL_HID_READ_REPORT, IoStack->Parameters.DeviceIoControl.OutputBufferLength, &NewIrp, &NewIrpContext); + Status = HidClass_BuildIrp(DeviceObject, Irp, Context, IOCTL_HID_READ_REPORT, IoStack->Parameters.Read.Length, &NewIrp, &NewIrpContext); if (!NT_SUCCESS(Status)) { // @@ -523,12 +647,12 @@ // lets dispatch the request // ASSERT(Context->DeviceExtension); - Status = Context->DeviceExtension->Common.DriverExtension->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL](DeviceObject, NewIrp); + Status = Context->DeviceExtension->Common.DriverExtension->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL](Context->DeviceExtension->FDODeviceObject, NewIrp);
// // complete // - return Status; + return STATUS_PENDING; }
NTSTATUS @@ -655,6 +779,8 @@ { UNIMPLEMENTED ASSERT(FALSE); + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_NOT_IMPLEMENTED; }
@@ -728,7 +854,7 @@ // // dispatch to lower device object // - return IoCallDriver(CommonDeviceExtension->HidDeviceExtension.NextDeviceObject, Irp); + return IoCallDriver(CommonDeviceExtension->HidDeviceExtension.NextDeviceObject, Irp); }
@@ -744,7 +870,7 @@ // get current stack location // IoStack = IoGetCurrentIrpStackLocation(Irp); - DPRINT1("[HIDCLASS] Dispatch Major %x Minor %x\n", IoStack->MajorFunction, IoStack->MinorFunction); + DPRINT("[HIDCLASS] Dispatch Major %x Minor %x\n", IoStack->MajorFunction, IoStack->MinorFunction);
// // dispatch request based on major function
Modified: branches/usb-bringup/drivers/hid/hidclass/pdo.c URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/hid/hidclass... ============================================================================== --- branches/usb-bringup/drivers/hid/hidclass/pdo.c [iso-8859-1] (original) +++ branches/usb-bringup/drivers/hid/hidclass/pdo.c [iso-8859-1] Sun Jan 1 22:48:08 2012 @@ -453,7 +453,7 @@ // // do nothing // - Status = Irp->IoStatus.Status; + Status = STATUS_SUCCESS; //Irp->IoStatus.Status; break; } case IRP_MN_QUERY_INTERFACE: @@ -544,6 +544,7 @@ PDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject = FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject; PDODeviceExtension->Common.HidDeviceExtension.PhysicalDeviceObject = FDODeviceExtension->Common.HidDeviceExtension.PhysicalDeviceObject; PDODeviceExtension->Common.IsFDO = FALSE; + PDODeviceExtension->FDODeviceObject = DeviceObject; PDODeviceExtension->Common.DriverExtension = FDODeviceExtension->Common.DriverExtension; RtlCopyMemory(&PDODeviceExtension->Common.Attributes, &FDODeviceExtension->Common.Attributes, sizeof(HID_DEVICE_ATTRIBUTES)); RtlCopyMemory(&PDODeviceExtension->Common.DeviceDescription, &FDODeviceExtension->Common.DeviceDescription, sizeof(HIDP_DEVICE_DESC));
Modified: branches/usb-bringup/drivers/hid/hidclass/precomp.h URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/hid/hidclass... ============================================================================== --- branches/usb-bringup/drivers/hid/hidclass/precomp.h [iso-8859-1] (original) +++ branches/usb-bringup/drivers/hid/hidclass/precomp.h [iso-8859-1] Sun Jan 1 22:48:08 2012 @@ -1,6 +1,7 @@ #pragma once
#define _HIDPI_NO_FUNCTION_MACROS_ +#define NDEBUG #include <ntddk.h> #include <initguid.h> #include <hidport.h> @@ -47,7 +48,6 @@ // hid attributes // HID_DEVICE_ATTRIBUTES Attributes; -
}HIDCLASS_COMMON_DEVICE_EXTENSION, *PHIDCLASS_COMMON_DEVICE_EXTENSION;
@@ -101,6 +101,12 @@ // device interface // UNICODE_STRING DeviceInterface; + + // + // FDO device object + // + PDEVICE_OBJECT FDODeviceObject; + }HIDCLASS_PDO_DEVICE_EXTENSION, *PHIDCLASS_PDO_DEVICE_EXTENSION;
typedef struct __HIDCLASS_FILEOP_CONTEXT__
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] Sun Jan 1 22:48:08 2012 @@ -340,7 +340,7 @@ // get port status // Status = HidUsb_GetPortStatus(ResetContext->DeviceObject, &PortStatus); - DPRINT1("[HIDUSB] ResetWorkerRoutine GetPortStatus %x\n", Status); + DPRINT1("[HIDUSB] ResetWorkerRoutine GetPortStatus %x PortStatus %x\n", Status, PortStatus); if (NT_SUCCESS(Status)) { if (!(PortStatus & USB_PORT_STATUS_ENABLE)) @@ -393,7 +393,6 @@ // ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); IoFreeWorkItem(ResetContext->WorkItem); - ResetContext->Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(ResetContext->Irp, IO_NO_INCREMENT); ExFreePool(ResetContext); } @@ -409,7 +408,6 @@ PHID_USB_DEVICE_EXTENSION HidDeviceExtension; PHID_DEVICE_EXTENSION DeviceExtension; PURB Urb; - PUCHAR Buffer; PHID_USB_RESET_CONTEXT ResetContext;
// @@ -418,6 +416,16 @@ Urb = (PURB)Context; ASSERT(Urb);
+ DPRINT("[HIDUSB] HidUsb_ReadReportCompletion %p Status %x Urb Status %x\n", Irp, Irp->IoStatus, Urb->UrbHeader.Status); + + if (Irp->PendingReturned) + { + // + // mark irp pending + // + IoMarkIrpPending(Irp); + } + // // did the reading report succeed / cancelled // @@ -433,11 +441,6 @@ // ASSERT(Urb->UrbHeader.Status == USBD_STATUS_SUCCESS);
- - Buffer = (PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer; - ASSERT(Urb->UrbBulkOrInterruptTransfer.TransferBufferLength == 4); - DPRINT("[HIDUSB] ReadCompletion Information %lu Buffer %x %x %x %x\n", Buffer[0] & 0xFF, Buffer[1] & 0xFF, Buffer[2] & 0xFF, Buffer[3] & 0xFF); - // // free the urb // @@ -446,7 +449,7 @@ // // finish completion // - return STATUS_SUCCESS; + return STATUS_CONTINUE_COMPLETION; }
// @@ -502,7 +505,7 @@ // // complete request // - return STATUS_SUCCESS; + return STATUS_CONTINUE_COMPLETION; }
@@ -558,6 +561,13 @@ // init urb // RtlZeroMemory(Urb, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER)); + + // + // sanity check + // + ASSERT(Irp->UserBuffer); + ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength); + ASSERT(PipeInformation->PipeHandle);
// // build the urb @@ -572,6 +582,11 @@ NULL);
// + // store configuration handle + // + Urb->UrbHeader.UsbdDeviceHandle = HidDeviceExtension->ConfigurationHandle; + + // // get next location to setup irp // IoStack = IoGetNextIrpStackLocation(Irp); @@ -580,8 +595,12 @@ // init irp for lower driver // IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; + IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; + IoStack->Parameters.DeviceIoControl.InputBufferLength = 0; + IoStack->Parameters.DeviceIoControl.OutputBufferLength = 0; + IoStack->Parameters.DeviceIoControl.Type3InputBuffer = NULL; IoStack->Parameters.Others.Argument1 = (PVOID)Urb; - IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; +
// // set completion routine @@ -762,7 +781,7 @@ } case IOCTL_HID_READ_REPORT: { - DPRINT1("[HIDUSB] IOCTL_HID_READ_REPORT\n"); + DPRINT("[HIDUSB] IOCTL_HID_READ_REPORT\n"); Status = HidUsb_ReadReport(DeviceObject, Irp); return Status; } @@ -949,6 +968,11 @@ // store urb // IoStack->Parameters.Others.Argument1 = (PVOID)Urb; + + // + // set completion routine + // + IoSetCompletionRoutine(Irp, Hid_PnpCompletion, (PVOID)&Event, TRUE, TRUE, TRUE);
// // call driver @@ -1329,6 +1353,7 @@ // select configuration // Status = Hid_SelectConfiguration(DeviceObject); + ASSERT(Status == STATUS_SUCCESS);
// // done
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] Sun Jan 1 22:48:08 2012 @@ -2,6 +2,7 @@
#define _HIDPI_ #define _HIDPI_NO_FUNCTION_MACROS_ +#define NDEBUG #include <ntddk.h> #include <hidport.h> #include <debug.h>
Modified: branches/usb-bringup/drivers/hid/mouhid/mouhid.c URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/hid/mouhid/m... ============================================================================== --- branches/usb-bringup/drivers/hid/mouhid/mouhid.c [iso-8859-1] (original) +++ branches/usb-bringup/drivers/hid/mouhid/mouhid.c [iso-8859-1] Sun Jan 1 22:48:08 2012 @@ -637,7 +637,7 @@
/* lets get the caps */ Status = HidP_GetCaps(PreparsedData, &Capabilities); - if (!NT_SUCCESS(Status)) + if (Status != HIDP_STATUS_SUCCESS) { /* failed to get capabilities */ DPRINT1("[MOUHID] failed to obtain caps with %x\n", Status); @@ -645,7 +645,7 @@ return Status; }
- DPRINT1("[MOUHID] Usage %x UsagePage %x\n", Capabilities.Usage, Capabilities.UsagePage, Capabilities.InputReportByteLength); + DPRINT1("[MOUHID] Usage %x UsagePage %x InputReportLength %lu\n", Capabilities.Usage, Capabilities.UsagePage, Capabilities.InputReportByteLength);
/* verify capabilities */ if (Capabilities.Usage != HID_USAGE_GENERIC_POINTER && Capabilities.Usage != HID_USAGE_GENERIC_MOUSE || Capabilities.UsagePage != HID_USAGE_PAGE_GENERIC)