From 80c665d2ac5d05a59ee8506b030a91e3b06fbc7a Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Sat, 4 Feb 2012 14:10:18 +0000 Subject: [PATCH] [HIDCLASS] - Remove PDO from pdo list when it is destroyed - Handle IRP_MN_QUERY_REMOVE_DEVICE, IRP_MN_CANCEL_STOP_DEVICE, IRP_MN_QUERY_STOP_DEVICE, IRP_MN_CANCEL_REMOVE_DEVICE [HIDUSB] - Add driver unload routine [MOUHID] - Wait for completion of pending irp [USBHUB] - Remove pdo from PDO list - Handle IRP_MN_QUERY_DEVICE_RELATIONS - Add stub driver unload routine [USBOHCI] - handle IRP_MN_REMOVE for FDO - remove ASSERT svn path=/branches/usb-bringup-trunk/; revision=55411 --- drivers/hid/hidclass/pdo.c | 29 +++++++++++++++- drivers/hid/hidclass/precomp.h | 5 +++ drivers/hid/hidusb/hidusb.c | 10 ++++++ drivers/hid/mouhid/mouhid.c | 13 +++++++ drivers/usb/usbhub_new/pdo.c | 47 +++++++++++++++++++++++++- drivers/usb/usbhub_new/usbhub.c | 11 ++++++ drivers/usb/usbohci/hcd_controller.cpp | 12 +++++++ drivers/usb/usbohci/usb_request.cpp | 5 --- 8 files changed, 125 insertions(+), 7 deletions(-) diff --git a/drivers/hid/hidclass/pdo.c b/drivers/hid/hidclass/pdo.c index a283a4f3fc2..c5045b8489a 100644 --- a/drivers/hid/hidclass/pdo.c +++ b/drivers/hid/hidclass/pdo.c @@ -344,7 +344,6 @@ HidClassPDO_HandleQueryCompatibleId( return STATUS_SUCCESS; } - NTSTATUS HidClassPDO_PnP( IN PDEVICE_OBJECT DeviceObject, @@ -355,6 +354,7 @@ HidClassPDO_PnP( NTSTATUS Status; PPNP_BUS_INFORMATION BusInformation; PDEVICE_RELATIONS DeviceRelation; + ULONG Index; // // get device extension @@ -532,6 +532,21 @@ HidClassPDO_PnP( if (PDODeviceExtension->DeviceInterface.Length != 0) IoSetDeviceInterfaceState(&PDODeviceExtension->DeviceInterface, FALSE); + // + // remove us from the fdo's pdo list + // + for(Index = 0; Index < PDODeviceExtension->FDODeviceExtension->DeviceRelations->Count; Index++) + { + if (PDODeviceExtension->FDODeviceExtension->DeviceRelations->Objects[Index] == DeviceObject) + { + // + // remove us + // + PDODeviceExtension->FDODeviceExtension->DeviceRelations->Objects[Index] = NULL; + break; + } + } + /* Complete the IRP */ Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); @@ -552,6 +567,17 @@ HidClassPDO_PnP( Status = Irp->IoStatus.Status; break; } + case IRP_MN_QUERY_REMOVE_DEVICE: + case IRP_MN_CANCEL_STOP_DEVICE: + case IRP_MN_QUERY_STOP_DEVICE: + case IRP_MN_CANCEL_REMOVE_DEVICE: + { + // + // no/op + // + Status = STATUS_SUCCESS; + break; + } default: { // @@ -657,6 +683,7 @@ HidClassPDO_CreatePDO( PDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject = FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject; PDODeviceExtension->Common.HidDeviceExtension.PhysicalDeviceObject = FDODeviceExtension->Common.HidDeviceExtension.PhysicalDeviceObject; PDODeviceExtension->Common.IsFDO = FALSE; + PDODeviceExtension->FDODeviceExtension = FDODeviceExtension; PDODeviceExtension->FDODeviceObject = DeviceObject; PDODeviceExtension->Common.DriverExtension = FDODeviceExtension->Common.DriverExtension; PDODeviceExtension->CollectionNumber = FDODeviceExtension->Common.DeviceDescription.CollectionDesc[Index].CollectionNumber; diff --git a/drivers/hid/hidclass/precomp.h b/drivers/hid/hidclass/precomp.h index db0159c3fa3..23820e6938a 100644 --- a/drivers/hid/hidclass/precomp.h +++ b/drivers/hid/hidclass/precomp.h @@ -107,6 +107,11 @@ typedef struct // PDEVICE_OBJECT FDODeviceObject; + // + // fdo device extension + // + PHIDCLASS_FDO_EXTENSION FDODeviceExtension; + }HIDCLASS_PDO_DEVICE_EXTENSION, *PHIDCLASS_PDO_DEVICE_EXTENSION; typedef struct __HIDCLASS_FILEOP_CONTEXT__ diff --git a/drivers/hid/hidusb/hidusb.c b/drivers/hid/hidusb/hidusb.c index f97c9f9fed0..40ac22d29b0 100644 --- a/drivers/hid/hidusb/hidusb.c +++ b/drivers/hid/hidusb/hidusb.c @@ -1764,6 +1764,15 @@ HidAddDevice( return STATUS_SUCCESS; } +VOID +NTAPI +Hid_Unload( + IN PDRIVER_OBJECT DriverObject) +{ + UNIMPLEMENTED +} + + NTSTATUS NTAPI DriverEntry( @@ -1783,6 +1792,7 @@ DriverEntry( DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = HidSystemControl; DriverObject->MajorFunction[IRP_MJ_PNP] = HidPnp; DriverObject->DriverExtension->AddDevice = HidAddDevice; + DriverObject->DriverUnload = Hid_Unload; // // prepare registration info diff --git a/drivers/hid/mouhid/mouhid.c b/drivers/hid/mouhid/mouhid.c index 013bf807908..a9fdd3079d6 100644 --- a/drivers/hid/mouhid/mouhid.c +++ b/drivers/hid/mouhid/mouhid.c @@ -807,6 +807,9 @@ MouHid_Pnp( { /* FIXME synchronization */ + /* request stop */ + DeviceExtension->StopReadReport = TRUE; + /* cancel irp */ IoCancelIrp(DeviceExtension->Irp); @@ -819,9 +822,19 @@ MouHid_Pnp( /* dispatch to lower device */ Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp); + /* wait for completion of stop event */ + KeWaitForSingleObject(&DeviceExtension->ReadCompletionEvent, Executive, KernelMode, FALSE, NULL); + + /* free irp */ IoFreeIrp(DeviceExtension->Irp); + + /* detach device */ IoDetachDevice(DeviceExtension->NextDeviceObject); + + /* delete device */ IoDeleteDevice(DeviceObject); + + /* done */ return Status; } else if (IoStack->MinorFunction == IRP_MN_START_DEVICE) diff --git a/drivers/usb/usbhub_new/pdo.c b/drivers/usb/usbhub_new/pdo.c index e40f1f28436..89e87f77cba 100644 --- a/drivers/usb/usbhub_new/pdo.c +++ b/drivers/usb/usbhub_new/pdo.c @@ -485,6 +485,8 @@ USBHUB_PdoHandlePnp( PIO_STACK_LOCATION Stack; ULONG_PTR Information = 0; PHUB_CHILDDEVICE_EXTENSION UsbChildExtension; + ULONG Index; + PDEVICE_RELATIONS DeviceRelation; UsbChildExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension; Stack = IoGetCurrentIrpStackLocation(Irp); @@ -576,7 +578,21 @@ USBHUB_PdoHandlePnp( DPRINT1("IRP_MJ_PNP / IRP_MN_REMOVE_DEVICE\n"); /* Remove the device */ - HubInterface->RemoveUsbDevice(HubDeviceExtension->UsbDInterface.BusContext, UsbChildExtension->UsbDeviceHandle, 0); + Status = HubInterface->RemoveUsbDevice(HubDeviceExtension->UsbDInterface.BusContext, UsbChildExtension->UsbDeviceHandle, 0); + + /* FIXME handle error */ + ASSERT(Status == STATUS_SUCCESS); + + /* remove us from pdo list */ + for(Index = 0; Index < USB_MAXCHILDREN; Index++) + { + if (HubDeviceExtension->ChildDeviceObject[Index] == DeviceObject) + { + /* remove us */ + HubDeviceExtension->ChildDeviceObject[Index] = NULL; + break; + } + } /* Complete the IRP */ Irp->IoStatus.Status = STATUS_SUCCESS; @@ -586,6 +602,35 @@ USBHUB_PdoHandlePnp( IoDeleteDevice(DeviceObject); return STATUS_SUCCESS; } + case IRP_MN_QUERY_DEVICE_RELATIONS: + { + /* only target relations are supported */ + if (Stack->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation) + { + /* not supported */ + Status = Irp->IoStatus.Status; + break; + } + + /* allocate device relations */ + DeviceRelation = (PDEVICE_RELATIONS)ExAllocatePool(NonPagedPool, sizeof(DEVICE_RELATIONS)); + if (!DeviceRelation) + { + /* no memory */ + Status = STATUS_INSUFFICIENT_RESOURCES; + break; + } + + /* init device relation */ + DeviceRelation->Count = 1; + DeviceRelation->Objects[0] = DeviceObject; + ObReferenceObject(DeviceRelation->Objects[0]); + + /* store result */ + Irp->IoStatus.Information = (ULONG_PTR)DeviceRelation; + Status = STATUS_SUCCESS; + break; + } case IRP_MN_QUERY_STOP_DEVICE: case IRP_MN_QUERY_REMOVE_DEVICE: { diff --git a/drivers/usb/usbhub_new/usbhub.c b/drivers/usb/usbhub_new/usbhub.c index 72de3ecf351..347358e7d3a 100644 --- a/drivers/usb/usbhub_new/usbhub.c +++ b/drivers/usb/usbhub_new/usbhub.c @@ -183,12 +183,23 @@ USBHUB_DispatchPower( return STATUS_NOT_SUPPORTED; } +VOID +NTAPI +USBHUB_Unload( + IN PDRIVER_OBJECT DriverObject) +{ + UNIMPLEMENTED +} + + NTSTATUS NTAPI DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { DriverObject->DriverExtension->AddDevice = USBHUB_AddDevice; + DriverObject->DriverUnload = USBHUB_Unload; + DPRINT1("USBHUB: DriverEntry\n"); DriverObject->MajorFunction[IRP_MJ_CREATE] = USBHUB_Create; diff --git a/drivers/usb/usbohci/hcd_controller.cpp b/drivers/usb/usbohci/hcd_controller.cpp index dc0537ca242..c4539c6c0a2 100644 --- a/drivers/usb/usbohci/hcd_controller.cpp +++ b/drivers/usb/usbohci/hcd_controller.cpp @@ -531,7 +531,19 @@ CHCDController::HandlePnp( // stop lower device // Status = SyncForwardIrp(m_NextDeviceObject, Irp); + if (NT_SUCCESS(Status)) + { + // + // detach device + // + IoDetachDevice(m_NextDeviceObject); + IoDeleteDevice(DeviceObject); + } + } + + + break; } case IRP_MN_QUERY_REMOVE_DEVICE: diff --git a/drivers/usb/usbohci/usb_request.cpp b/drivers/usb/usbohci/usb_request.cpp index 48fc41d29fe..90cadae88a7 100644 --- a/drivers/usb/usbohci/usb_request.cpp +++ b/drivers/usb/usbohci/usb_request.cpp @@ -1672,11 +1672,6 @@ CUSBRequest::CheckError( while(TransferDescriptor) { - // - // the descriptor must have been processed - // - ASSERT(OHCI_TD_GET_CONDITION_CODE(TransferDescriptor->Flags) != OHCI_TD_CONDITION_NOT_ACCESSED); - // // get condition code //