Author: janderwald
Date: Sat Dec 31 18:22:18 2011
New Revision: 54797
URL:
http://svn.reactos.org/svn/reactos?rev=54797&view=rev
Log:
[USB-BRINGUP]
- Fix bug in HidUsb_AbortPipe, which passed the wrong handle
- Implement reset port routine
- Implement reset worker routine when reading report fails
Modified:
branches/usb-bringup/drivers/hid/hidusb/CMakeLists.txt
branches/usb-bringup/drivers/hid/hidusb/hidusb.c
branches/usb-bringup/drivers/hid/hidusb/hidusb.h
Modified: branches/usb-bringup/drivers/hid/hidusb/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/hid/hidusb/…
==============================================================================
--- branches/usb-bringup/drivers/hid/hidusb/CMakeLists.txt [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/hid/hidusb/CMakeLists.txt [iso-8859-1] Sat Dec 31
18:22:18 2011
@@ -6,6 +6,6 @@
add_library(hidusb SHARED ${SOURCE})
set_module_type(hidusb kernelmodedriver)
-add_importlibs(hidusb hidclass ntoskrnl usbd)
+add_importlibs(hidusb hidclass ntoskrnl usbd hal)
add_cab_target(hidusb 2)
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] Sat Dec 31 18:22:18
2011
@@ -175,6 +175,7 @@
PHID_DEVICE_EXTENSION DeviceExtension;
PURB Urb;
NTSTATUS Status;
+ PUSBD_PIPE_INFORMATION PipeInformation;
//
// get device extension
@@ -193,6 +194,13 @@
//
return STATUS_INSUFFICIENT_RESOURCES;
}
+
+ //
+ // get pipe information
+ //
+ PipeInformation =
HidUsb_GetInputInterruptInterfaceHandle(HidDeviceExtension->InterfaceInfo);
+ ASSERT(PipeInformation);
+ ASSERT(PipeInformation->PipeHandle);
//
// init urb
@@ -200,7 +208,7 @@
RtlZeroMemory(Urb, sizeof(struct _URB_PIPE_REQUEST));
Urb->UrbHeader.Function = URB_FUNCTION_ABORT_PIPE;
Urb->UrbHeader.Length = sizeof(struct _URB_PIPE_REQUEST);
- Urb->UrbPipeRequest.PipeHandle = HidDeviceExtension->ConfigurationHandle;
+ Urb->UrbPipeRequest.PipeHandle = PipeInformation->PipeHandle;
//
// dispatch request
@@ -218,7 +226,56 @@
return Status;
}
-
+NTSTATUS
+HidUsb_ResetPort(
+ IN PDEVICE_OBJECT DeviceObject)
+{
+ KEVENT Event;
+ PIRP Irp;
+ PHID_DEVICE_EXTENSION DeviceExtension;
+ IO_STATUS_BLOCK IoStatusBlock;
+ NTSTATUS Status;
+
+ //
+ // get device extension
+ //
+ DeviceExtension = (PHID_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+ //
+ // init event
+ //
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+ //
+ // build irp
+ //
+ Irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_RESET_PORT,
DeviceExtension->NextDeviceObject, NULL, 0, NULL, 0, TRUE, &Event,
&IoStatusBlock);
+ if (!Irp)
+ {
+ //
+ // no memory
+ //
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ //
+ // send the irp
+ //
+ Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ //
+ // wait for request completion
+ //
+ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+ Status = IoStatusBlock.Status;
+ }
+
+ //
+ // done
+ //
+ return IoStatusBlock.Status;
+}
NTSTATUS
NTAPI
@@ -255,6 +312,92 @@
//
return STATUS_SUCCESS;
}
+
+VOID
+NTAPI
+HidUsb_ResetWorkerRoutine(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PVOID Ctx)
+{
+ NTSTATUS Status;
+ ULONG PortStatus;
+ PHID_USB_RESET_CONTEXT ResetContext;
+ PHID_DEVICE_EXTENSION DeviceExtension;
+
+ DPRINT1("[HIDUSB] ResetWorkerRoutine\n");
+
+ //
+ // get context
+ //
+ ResetContext = (PHID_USB_RESET_CONTEXT)Ctx;
+
+ //
+ // get device extension
+ //
+ DeviceExtension =
(PHID_DEVICE_EXTENSION)ResetContext->DeviceObject->DeviceExtension;
+
+ //
+ // get port status
+ //
+ Status = HidUsb_GetPortStatus(ResetContext->DeviceObject, &PortStatus);
+ DPRINT1("[HIDUSB] ResetWorkerRoutine GetPortStatus %x\n", Status);
+ if (NT_SUCCESS(Status))
+ {
+ if (!(PortStatus & USB_PORT_STATUS_ENABLE))
+ {
+ //
+ // port is disabled
+ //
+ Status = HidUsb_ResetInterruptPipe(ResetContext->DeviceObject);
+ DPRINT1("[HIDUSB] ResetWorkerRoutine ResetPipe %x\n", Status);
+ }
+ else
+ {
+ //
+ // abort pipe
+ //
+ Status = HidUsb_AbortPipe(ResetContext->DeviceObject);
+ DPRINT1("[HIDUSB] ResetWorkerRoutine AbortPipe %x\n", Status);
+ if (NT_SUCCESS(Status))
+ {
+ //
+ // reset port
+ //
+ Status = HidUsb_ResetPort(ResetContext->DeviceObject);
+ DPRINT1("[HIDUSB] ResetPort %x\n", Status);
+ if (Status == STATUS_DEVICE_DATA_ERROR)
+ {
+ //
+ // invalidate device state
+ //
+ IoInvalidateDeviceState(DeviceExtension->PhysicalDeviceObject);
+ }
+
+ //
+ // reset interrupt pipe
+ //
+ if (NT_SUCCESS(Status))
+ {
+ //
+ // reset pipe
+ //
+ Status = HidUsb_ResetInterruptPipe(ResetContext->DeviceObject);
+ DPRINT1("[HIDUSB] ResetWorkerRoutine ResetPipe %x\n",
Status);
+ }
+ }
+ }
+ }
+
+ //
+ // cleanup
+ //
+ ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
+ IoFreeWorkItem(ResetContext->WorkItem);
+ ResetContext->Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(ResetContext->Irp, IO_NO_INCREMENT);
+ ExFreePool(ResetContext);
+}
+
NTSTATUS
NTAPI
@@ -267,6 +410,44 @@
PHID_DEVICE_EXTENSION DeviceExtension;
PURB Urb;
PUCHAR Buffer;
+ PHID_USB_RESET_CONTEXT ResetContext;
+
+ //
+ // get urb
+ //
+ Urb = (PURB)Context;
+ ASSERT(Urb);
+
+ //
+ // did the reading report succeed / cancelled
+ //
+ if (NT_SUCCESS(Irp->IoStatus.Status) || Irp->IoStatus.Status ==
STATUS_CANCELLED || Irp->IoStatus.Status == STATUS_DEVICE_NOT_CONNECTED)
+ {
+ //
+ // store result length
+ //
+ Irp->IoStatus.Information =
Urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
+
+ //
+ // FIXME handle error
+ //
+ 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
+ //
+ ExFreePool(Context);
+
+ //
+ // finish completion
+ //
+ return STATUS_SUCCESS;
+ }
//
// get device extension
@@ -275,30 +456,48 @@
HidDeviceExtension =
(PHID_USB_DEVICE_EXTENSION)DeviceExtension->MiniDeviceExtension;
//
- // get urb
- //
- Urb = (PURB)Context;
- ASSERT(Urb);
-
- //
- // FIXME handle error
- //
- ASSERT(Urb->UrbHeader.Status == USBD_STATUS_SUCCESS);
-
- //
- // FIXME handle error
- //
- ASSERT(Irp->IoStatus.Status == STATUS_SUCCESS);
-
- Buffer = Urb->UrbBulkOrInterruptTransfer.TransferBuffer;
- ASSERT(Urb->UrbBulkOrInterruptTransfer.TransferBufferLength == 4);
-
- //
- // store result
- //
- Irp->IoStatus.Information =
Urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
-
- DPRINT("[HIDUSB] ReadCompletion Information %lu Buffer %x %x %x %x\n",
Buffer[0] & 0xFF, Buffer[1] & 0xFF, Buffer[2] & 0xFF, Buffer[3] & 0xFF);
+ // allocate reset context
+ //
+ ResetContext = (PHID_USB_RESET_CONTEXT)ExAllocatePool(NonPagedPool,
sizeof(HID_USB_RESET_CONTEXT));
+ if (ResetContext)
+ {
+ //
+ // allocate work item
+ //
+ ResetContext->WorkItem = IoAllocateWorkItem(DeviceObject);
+ if (ResetContext->WorkItem)
+ {
+ //
+ // init reset context
+ //
+ ResetContext->Irp = Irp;
+ ResetContext->DeviceObject = DeviceObject;
+
+ //
+ // queue the work item
+ //
+ IoQueueWorkItem(ResetContext->WorkItem, HidUsb_ResetWorkerRoutine,
DelayedWorkQueue, ResetContext);
+
+ //
+ // free urb
+ //
+ ExFreePool(Urb);
+
+ //
+ // defer completion
+ //
+ return STATUS_MORE_PROCESSING_REQUIRED;
+ }
+ //
+ // free context
+ //
+ ExFreePool(ResetContext);
+ }
+
+ //
+ // free urb
+ //
+ ExFreePool(Urb);
//
// complete request
@@ -563,7 +762,7 @@
}
case IOCTL_HID_READ_REPORT:
{
- //DPRINT1("[HIDUSB] IOCTL_HID_READ_REPORT\n");
+ DPRINT1("[HIDUSB] IOCTL_HID_READ_REPORT\n");
Status = HidUsb_ReadReport(DeviceObject, Irp);
return Status;
}
@@ -702,6 +901,7 @@
//
return STATUS_MORE_PROCESSING_REQUIRED;
}
+
NTSTATUS
Hid_DispatchUrb(
@@ -749,11 +949,6 @@
// store urb
//
IoStack->Parameters.Others.Argument1 = (PVOID)Urb;
-
- //
- // set completion routine
- //
- IoSetCompletionRoutine(Irp, Hid_PnpCompletion, (PVOID)&Event, TRUE, TRUE, TRUE);
//
// call driver
@@ -1333,6 +1528,7 @@
// complete request
//
Irp->IoStatus.Status = Status;
+ DPRINT1("[HIDUSB] IRP_MN_START_DEVICE Status %x\n", Status);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
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] Sat Dec 31 18:22:18
2011
@@ -44,6 +44,26 @@
PHID_DESCRIPTOR HidDescriptor;
}HID_USB_DEVICE_EXTENSION, *PHID_USB_DEVICE_EXTENSION;
+typedef struct
+{
+ //
+ // request irp
+ //
+ PIRP Irp;
+
+ //
+ // work item
+ //
+ PIO_WORKITEM WorkItem;
+
+ //
+ // device object
+ //
+ PDEVICE_OBJECT DeviceObject;
+
+}HID_USB_RESET_CONTEXT, *PHID_USB_RESET_CONTEXT;
+
+
NTSTATUS
Hid_GetDescriptor(
IN PDEVICE_OBJECT DeviceObject,