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/CMakeLists.txt?rev=54797&r1=54796&r2=54797&view=diff
==============================================================================
--- 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/hidusb.c?rev=54797&r1=54796&r2=54797&view=diff
==============================================================================
--- 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/hidusb.h?rev=54797&r1=54796&r2=54797&view=diff
==============================================================================
--- 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,


Reply via email to