Author: janderwald Date: Tue Feb 21 01:16:56 2012 New Revision: 55772
URL: http://svn.reactos.org/svn/reactos?rev=55772&view=rev Log: [HIDCLASS] - 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
Modified: trunk/reactos/drivers/hid/hidclass/fdo.c trunk/reactos/drivers/hid/hidclass/hidclass.c trunk/reactos/drivers/hid/hidclass/precomp.h trunk/reactos/drivers/hid/hidusb/hidusb.c trunk/reactos/drivers/hid/hidusb/hidusb.h trunk/reactos/drivers/usb/usbohci/hub_controller.cpp trunk/reactos/drivers/usb/usbohci/usb_device.cpp
Modified: trunk/reactos/drivers/hid/hidclass/fdo.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/hid/hidclass/fdo.c?... ============================================================================== --- trunk/reactos/drivers/hid/hidclass/fdo.c [iso-8859-1] (original) +++ trunk/reactos/drivers/hid/hidclass/fdo.c [iso-8859-1] Tue Feb 21 01:16:56 2012 @@ -384,17 +384,21 @@ IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - PHIDCLASS_FDO_EXTENSION FDODeviceExtension = DeviceObject->DeviceExtension; - NTSTATUS Status; - - /* Pass the IRP down */ + NTSTATUS Status; + + /* FIXME cleanup */ + + // + // dispatch to minidriver + // IoSkipCurrentIrpStackLocation(Irp); - Status = IoCallDriver(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject, Irp); - - /* Now teardown our portion of the device stack */ - IoDetachDevice(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject); - IoDeleteDevice(DeviceObject); - + Status = HidClassFDO_DispatchRequestSynchronous(DeviceObject, Irp); + + // + // complete request + // + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; }
@@ -533,6 +537,7 @@ { PIO_STACK_LOCATION IoStack; PHIDCLASS_FDO_EXTENSION FDODeviceExtension; + NTSTATUS Status;
// // get device extension @@ -554,45 +559,34 @@ { return HidClassFDO_RemoveDevice(DeviceObject, Irp); } + case IRP_MN_QUERY_DEVICE_RELATIONS: + { + return HidClassFDO_DeviceRelations(DeviceObject, Irp); + } case IRP_MN_QUERY_REMOVE_DEVICE: case IRP_MN_QUERY_STOP_DEVICE: - { - // - // set status to succes - // - Irp->IoStatus.Status = STATUS_SUCCESS; - - // - // forward to lower device - // - IoSkipCurrentIrpStackLocation(Irp); - return IoCallDriver(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject, Irp); - } 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; } } }
Modified: trunk/reactos/drivers/hid/hidclass/hidclass.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/hid/hidclass/hidcla... ============================================================================== --- trunk/reactos/drivers/hid/hidclass/hidclass.c [iso-8859-1] (original) +++ trunk/reactos/drivers/hid/hidclass/hidclass.c [iso-8859-1] Tue Feb 21 01:16:56 2012 @@ -203,6 +203,7 @@ KeInitializeSpinLock(&Context->Lock); InitializeListHead(&Context->ReadPendingIrpListHead); InitializeListHead(&Context->IrpCompletedListHead); + KeInitializeEvent(&Context->IrpReadComplete, NotificationEvent, FALSE);
// // store context @@ -226,7 +227,11 @@ { 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 @@ // // get irp context // - IrpContext = (PHIDCLASS_IRP_CONTEXT)IoStack->FileObject->FsContext; - - // - // cancel pending irps - // - UNIMPLEMENTED + IrpContext = (PHIDCLASS_FILEOP_CONTEXT)IoStack->FileObject->FsContext; + ASSERT(IrpContext); + + // + // acquire lock + // + 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 @@ 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 @@ -403,6 +476,11 @@ RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
// + // is list empty + // + IsEmpty = IsListEmpty(&IrpContext->FileOp->ReadPendingIrpListHead); + + // // insert into completed list // InsertTailList(&IrpContext->FileOp->IrpCompletedListHead, &Irp->Tail.Overlay.ListEntry); @@ -416,6 +494,17 @@ // complete original request // 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 @@ -643,6 +732,19 @@ // FIXME support polled devices // 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
Modified: trunk/reactos/drivers/hid/hidclass/precomp.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/hid/hidclass/precom... ============================================================================== --- trunk/reactos/drivers/hid/hidclass/precomp.h [iso-8859-1] (original) +++ trunk/reactos/drivers/hid/hidclass/precomp.h [iso-8859-1] Tue Feb 21 01:16:56 2012 @@ -136,6 +136,16 @@ // LIST_ENTRY IrpCompletedListHead;
+ // + // stop in progress indicator + // + BOOLEAN StopInProgress; + + // + // read complete event + // + KEVENT IrpReadComplete; + }HIDCLASS_FILEOP_CONTEXT, *PHIDCLASS_FILEOP_CONTEXT;
typedef struct
Modified: trunk/reactos/drivers/hid/hidusb/hidusb.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/hid/hidusb/hidusb.c... ============================================================================== --- trunk/reactos/drivers/hid/hidusb/hidusb.c [iso-8859-1] (original) +++ trunk/reactos/drivers/hid/hidusb/hidusb.c [iso-8859-1] Tue Feb 21 01:16:56 2012 @@ -1576,10 +1576,10 @@ // // free resources // - if (HidDeviceExtension->HidDescriptor) + if (HidDeviceExtension->ConfigurationDescriptor) { - ExFreePool(HidDeviceExtension->HidDescriptor); - HidDeviceExtension->HidDescriptor = NULL; + ExFreePool(HidDeviceExtension->ConfigurationDescriptor); + HidDeviceExtension->ConfigurationDescriptor = NULL; }
//
Modified: trunk/reactos/drivers/hid/hidusb/hidusb.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/hid/hidusb/hidusb.h... ============================================================================== --- trunk/reactos/drivers/hid/hidusb/hidusb.h [iso-8859-1] (original) +++ trunk/reactos/drivers/hid/hidusb/hidusb.h [iso-8859-1] Tue Feb 21 01:16:56 2012 @@ -45,6 +45,7 @@ // hid descriptor // PHID_DESCRIPTOR HidDescriptor; + }HID_USB_DEVICE_EXTENSION, *PHID_USB_DEVICE_EXTENSION;
typedef struct
Modified: trunk/reactos/drivers/usb/usbohci/hub_controller.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbohci/hub_con... ============================================================================== --- trunk/reactos/drivers/usb/usbohci/hub_controller.cpp [iso-8859-1] (original) +++ trunk/reactos/drivers/usb/usbohci/hub_controller.cpp [iso-8859-1] Tue Feb 21 01:16:56 2012 @@ -1012,7 +1012,6 @@ // reset port feature // Status = m_Hardware->SetPortFeature(PortId, PORT_RESET); - PC_ASSERT(Status == STATUS_SUCCESS); break; } default:
Modified: trunk/reactos/drivers/usb/usbohci/usb_device.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbohci/usb_dev... ============================================================================== --- trunk/reactos/drivers/usb/usbohci/usb_device.cpp [iso-8859-1] (original) +++ trunk/reactos/drivers/usb/usbohci/usb_device.cpp [iso-8859-1] Tue Feb 21 01:16:56 2012 @@ -65,7 +65,7 @@
// constructor / destructor CUSBDevice(IUnknown *OuterUnknown){} - virtual ~CUSBDevice(){} + virtual ~CUSBDevice();
protected: LONG m_Ref; @@ -84,6 +84,73 @@
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