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/hidclas…
==============================================================================
--- 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/hidclas…
==============================================================================
--- 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/hidclas…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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)