[HIDCLASS]
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Tue, 21 Feb 2012 01:16:56 +0000 (01:16 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Tue, 21 Feb 2012 01:16:56 +0000 (01:16 +0000)
- Call mini driver for pnp events
- Wait for all pending irps to complete
[HIDUSB]
- Fix bug when removing device object found by Cameron Gutman
[USBOHCI]
- Remove assert
- Delete configuration descriptors when device is deleted

svn path=/trunk/; revision=55772

reactos/drivers/hid/hidclass/fdo.c
reactos/drivers/hid/hidclass/hidclass.c
reactos/drivers/hid/hidclass/precomp.h
reactos/drivers/hid/hidusb/hidusb.c
reactos/drivers/hid/hidusb/hidusb.h
reactos/drivers/usb/usbohci/hub_controller.cpp
reactos/drivers/usb/usbohci/usb_device.cpp

index 27df904..8986526 100644 (file)
@@ -384,17 +384,21 @@ HidClassFDO_RemoveDevice(
     IN PDEVICE_OBJECT DeviceObject,
     IN PIRP Irp)
 {
-    PHIDCLASS_FDO_EXTENSION FDODeviceExtension = DeviceObject->DeviceExtension;
     NTSTATUS Status;
 
-    /* Pass the IRP down */
-    IoSkipCurrentIrpStackLocation(Irp);
-    Status = IoCallDriver(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject, Irp);
+    /* FIXME cleanup */
 
-    /* Now teardown our portion of the device stack */
-    IoDetachDevice(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject);
-    IoDeleteDevice(DeviceObject);
+    //
+    // dispatch to minidriver
+    //
+    IoSkipCurrentIrpStackLocation(Irp);
+    Status = HidClassFDO_DispatchRequestSynchronous(DeviceObject, Irp);
 
+    //
+    // complete request
+    //
+    Irp->IoStatus.Status = Status;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
     return Status;
 }
 
@@ -533,6 +537,7 @@ HidClassFDO_PnP(
 {
     PIO_STACK_LOCATION IoStack;
     PHIDCLASS_FDO_EXTENSION FDODeviceExtension;
+    NTSTATUS Status;
 
     //
     // get device extension
@@ -554,45 +559,34 @@ HidClassFDO_PnP(
         {
              return HidClassFDO_RemoveDevice(DeviceObject, Irp);
         }
-        case IRP_MN_QUERY_REMOVE_DEVICE:
-        case IRP_MN_QUERY_STOP_DEVICE:
+        case IRP_MN_QUERY_DEVICE_RELATIONS:
         {
-            //
-            // set status to succes
-            //
-            Irp->IoStatus.Status = STATUS_SUCCESS;
-
-            //
-            // forward to lower device
-            //
-            IoSkipCurrentIrpStackLocation(Irp);
-            return IoCallDriver(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject, Irp);
+             return HidClassFDO_DeviceRelations(DeviceObject, Irp);
         }
+        case IRP_MN_QUERY_REMOVE_DEVICE:
+        case IRP_MN_QUERY_STOP_DEVICE:
         case IRP_MN_CANCEL_REMOVE_DEVICE:
         case IRP_MN_CANCEL_STOP_DEVICE:
         {
             //
-            // set status to succes
+            // set status to success and fall through
             //
             Irp->IoStatus.Status = STATUS_SUCCESS;
-
-            //
-            // forward to lower device
-            //
-            IoSkipCurrentIrpStackLocation(Irp);
-            return IoCallDriver(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject, Irp);
-        }
-        case IRP_MN_QUERY_DEVICE_RELATIONS:
-        {
-             return HidClassFDO_DeviceRelations(DeviceObject, Irp);
-        }
+         }
         default:
         {
             //
-            // dispatch to lower device
+            // dispatch to mini driver
             //
-            IoSkipCurrentIrpStackLocation(Irp);
-            return IoCallDriver(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject, Irp);
+           IoSkipCurrentIrpStackLocation(Irp);
+           Status = HidClassFDO_DispatchRequestSynchronous(DeviceObject, Irp);
+
+           //
+           // complete request
+           //
+           Irp->IoStatus.Status = Status;
+           IoCompleteRequest(Irp, IO_NO_INCREMENT);
+           return Status;
         }
     }
 }
index deb67f4..6f9b769 100644 (file)
@@ -203,6 +203,7 @@ HidClass_Create(
     KeInitializeSpinLock(&Context->Lock);
     InitializeListHead(&Context->ReadPendingIrpListHead);
     InitializeListHead(&Context->IrpCompletedListHead);
+    KeInitializeEvent(&Context->IrpReadComplete, NotificationEvent, FALSE);
 
     //
     // store context
@@ -226,7 +227,11 @@ HidClass_Close(
 {
     PIO_STACK_LOCATION IoStack;
     PHIDCLASS_COMMON_DEVICE_EXTENSION CommonDeviceExtension;
-    PHIDCLASS_IRP_CONTEXT IrpContext;
+    PHIDCLASS_FILEOP_CONTEXT IrpContext;
+    BOOLEAN IsRequestPending = FALSE;
+    KIRQL OldLevel;
+    PLIST_ENTRY Entry;
+    PIRP ListIrp;
 
     //
     // get device extension
@@ -260,12 +265,79 @@ HidClass_Close(
     //
     // get irp context
     //
-    IrpContext = (PHIDCLASS_IRP_CONTEXT)IoStack->FileObject->FsContext;
+    IrpContext = (PHIDCLASS_FILEOP_CONTEXT)IoStack->FileObject->FsContext;
+    ASSERT(IrpContext);
 
     //
-    // cancel pending irps
+    // acquire lock
     //
-    UNIMPLEMENTED
+    KeAcquireSpinLock(&IrpContext->Lock, &OldLevel);
+
+    if (!IsListEmpty(&IrpContext->ReadPendingIrpListHead))
+    {
+        //
+        // FIXME cancel irp
+        //
+        IsRequestPending = TRUE;
+    }
+
+    //
+    // signal stop
+    //
+    IrpContext->StopInProgress = TRUE;
+
+    //
+    // release lock
+    //
+    KeReleaseSpinLock(&IrpContext->Lock, OldLevel);
+
+    if (IsRequestPending)
+    {
+        //
+        // wait for request to complete
+        //
+        DPRINT1("[HIDCLASS] Waiting for read irp completion...\n");
+        KeWaitForSingleObject(&IrpContext->IrpReadComplete, Executive, KernelMode, FALSE, NULL);
+    }
+
+    //
+    // acquire lock
+    //
+    KeAcquireSpinLock(&IrpContext->Lock, &OldLevel);
+
+    //
+    // sanity check
+    //
+    ASSERT(IsListEmpty(&IrpContext->ReadPendingIrpListHead));
+
+    //
+    // now free all irps
+    //
+    while(!IsListEmpty(&IrpContext->IrpCompletedListHead))
+    {
+        //
+        // remove head irp
+        //
+        Entry = RemoveHeadList(&IrpContext->IrpCompletedListHead);
+
+        //
+        // get irp
+        //
+        ListIrp = (PIRP)CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
+
+        //
+        // free the irp
+        //
+        IoFreeIrp(ListIrp);
+    }
+
+    //
+    // release lock
+    //
+    KeReleaseSpinLock(&IrpContext->Lock, OldLevel);
+
+
+
 
     //
     // remove context
@@ -323,19 +395,20 @@ HidClass_ReadCompleteIrp(
     ULONG Offset;
     PHIDP_COLLECTION_DESC CollectionDescription;
     PHIDP_REPORT_IDS ReportDescription;
+    BOOLEAN IsEmpty;
 
     //
     // get irp context
     //
     IrpContext = (PHIDCLASS_IRP_CONTEXT)Ctx;
 
-    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);
+    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);
 
     //
     // copy result
@@ -402,6 +475,11 @@ HidClass_ReadCompleteIrp(
     //
     RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
 
+    //
+    // is list empty
+    //
+    IsEmpty = IsListEmpty(&IrpContext->FileOp->ReadPendingIrpListHead);
+
     //
     // insert into completed list
     //
@@ -417,6 +495,17 @@ HidClass_ReadCompleteIrp(
     //
     IoCompleteRequest(IrpContext->OriginalIrp, IO_NO_INCREMENT);
 
+
+    DPRINT1("StopInProgress %x IsEmpty %x\n", IrpContext->FileOp->StopInProgress, IsEmpty);
+    if (IrpContext->FileOp->StopInProgress && IsEmpty)
+    {
+        //
+        // last pending irp
+        //
+        DPRINT1("[HIDCLASS] LastPendingTransfer Signalling\n");
+        KeSetEvent(&IrpContext->FileOp->IrpReadComplete, 0, FALSE);
+    }
+
     //
     // free irp context
     //
@@ -644,6 +733,19 @@ HidClass_Read(
     //
     ASSERT(Context->DeviceExtension->Common.DriverExtension->DevicesArePolled == FALSE);
 
+    if (Context->StopInProgress)
+    {
+         //
+         // stop in progress
+         //
+         DPRINT1("[HIDCLASS] Stop In Progress\n");
+         Irp->IoStatus.Status = STATUS_CANCELLED;
+         IoCompleteRequest(Irp, IO_NO_INCREMENT);
+         return STATUS_CANCELLED;
+
+    }
+
+
     //
     // build irp request
     //
index 23820e6..7dca545 100644 (file)
@@ -136,6 +136,16 @@ typedef struct __HIDCLASS_FILEOP_CONTEXT__
     //
     LIST_ENTRY IrpCompletedListHead;
 
+    //
+    // stop in progress indicator
+    //
+    BOOLEAN StopInProgress;
+
+    //
+    // read complete event
+    //
+    KEVENT IrpReadComplete;
+
 }HIDCLASS_FILEOP_CONTEXT, *PHIDCLASS_FILEOP_CONTEXT;
 
 typedef struct
index 79720ac..a227d09 100644 (file)
@@ -1576,10 +1576,10 @@ HidPnp(
             //
             // free resources
             //
-            if (HidDeviceExtension->HidDescriptor)
+            if (HidDeviceExtension->ConfigurationDescriptor)
             {
-                ExFreePool(HidDeviceExtension->HidDescriptor);
-                HidDeviceExtension->HidDescriptor = NULL;
+                ExFreePool(HidDeviceExtension->ConfigurationDescriptor);
+                HidDeviceExtension->ConfigurationDescriptor = NULL;
             }
 
             //
index 816afb8..ae8a1a4 100644 (file)
@@ -45,6 +45,7 @@ typedef struct
     // hid descriptor
     //
     PHID_DESCRIPTOR HidDescriptor;
+
 }HID_USB_DEVICE_EXTENSION, *PHID_USB_DEVICE_EXTENSION;
 
 typedef struct
index 35a96e2..16fe16e 100644 (file)
@@ -1012,7 +1012,6 @@ CHubController::HandleClassOther(
                     // reset port feature
                     //
                     Status = m_Hardware->SetPortFeature(PortId, PORT_RESET);
-                    PC_ASSERT(Status == STATUS_SUCCESS);
                     break;
                 }
                 default:
index 838f4e6..af1e988 100644 (file)
@@ -65,7 +65,7 @@ public:
 
     // constructor / destructor
     CUSBDevice(IUnknown *OuterUnknown){}
-    virtual ~CUSBDevice(){}
+    virtual ~CUSBDevice();
 
 protected:
     LONG m_Ref;
@@ -85,6 +85,73 @@ protected:
     PUSB_CONFIGURATION m_ConfigurationDescriptors;
 };
 
+CUSBDevice::~CUSBDevice()
+{
+    ULONG Index, InterfaceIndex, EndpointIndex;
+    //NTSTATUS Status;
+
+   if (!m_ConfigurationDescriptors)
+   {
+       //
+       // nothing to do
+       //
+       return;
+   }
+
+
+    //
+    // clean up resources
+    //
+    for(Index = 0; Index < m_DeviceDescriptor.bNumConfigurations; Index++)
+    {
+        for(InterfaceIndex = 0; InterfaceIndex < m_ConfigurationDescriptors[Index].ConfigurationDescriptor->bNumInterfaces; InterfaceIndex++)
+        {
+            //
+            // are there any endpoint descriptors
+            //
+            for(EndpointIndex = 0; EndpointIndex < m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].InterfaceDescriptor.bNumEndpoints; EndpointIndex++)
+            {
+                //
+                // abort pipe
+                //
+                //Status = AbortPipe((PUSB_ENDPOINT_DESCRIPTOR)&m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].EndPoints[EndpointIndex]);
+                //DPRINT1("[USBOHCI] Deleting Device Abort Pipe Status %x\n", Status);
+            }
+
+            if (m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].InterfaceDescriptor.bNumEndpoints)
+            {
+                //
+                // free endpoints
+                //
+                ExFreePool(m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].EndPoints);
+            }
+        }
+
+        if (m_ConfigurationDescriptors[Index].ConfigurationDescriptor->bNumInterfaces)
+        {
+            //
+            // free interface descriptors
+            //
+            ExFreePool(m_ConfigurationDescriptors[Index].Interfaces);
+        }
+
+        if (m_ConfigurationDescriptors[Index].ConfigurationDescriptor)
+        {
+            //
+            // free configuration descriptor
+            //
+            ExFreePool(m_ConfigurationDescriptors[Index].ConfigurationDescriptor);
+        }
+    }
+
+    //
+    // free configuration descriptor
+    //
+    ExFreePool(m_ConfigurationDescriptors);
+}
+
+
+
 //----------------------------------------------------------------------------------------
 NTSTATUS
 STDMETHODCALLTYPE