From b398f3fe30d7d5f771e36473d143be7f5fbd9b41 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Tue, 21 Feb 2012 03:03:27 +0000 Subject: [PATCH] [USBCCGP] - Send unconfigure request when the device is removed [USBOHCI] - Handle unconfigure request svn path=/trunk/; revision=55775 --- reactos/drivers/usb/usbccgp/fdo.c | 52 ++++++++++++++++++++++ reactos/drivers/usb/usbohci/usb_device.cpp | 39 +++++++++++----- 2 files changed, 81 insertions(+), 10 deletions(-) diff --git a/reactos/drivers/usb/usbccgp/fdo.c b/reactos/drivers/usb/usbccgp/fdo.c index 74c89eb0845..95e1cc96ce9 100644 --- a/reactos/drivers/usb/usbccgp/fdo.c +++ b/reactos/drivers/usb/usbccgp/fdo.c @@ -408,6 +408,52 @@ FDO_StartDevice( return Status; } +NTSTATUS +FDO_CloseConfiguration( + IN PDEVICE_OBJECT DeviceObject) +{ + NTSTATUS Status; + PURB Urb; + PFDO_DEVICE_EXTENSION FDODeviceExtension; + + // get device extension + FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + ASSERT(FDODeviceExtension->Common.IsFDO); + + // + // now allocate the urb + // + Urb = USBD_CreateConfigurationRequestEx(FDODeviceExtension->ConfigurationDescriptor, FDODeviceExtension->InterfaceList); + if (!Urb) + { + // + // no memory + // + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // clear configuration descriptor to make it an unconfigure request + // + Urb->UrbSelectConfiguration.ConfigurationDescriptor = NULL; + + // + // submit urb + // + Status = USBCCGP_SyncUrbRequest(FDODeviceExtension->NextDeviceObject, Urb); + if (!NT_SUCCESS(Status)) + { + // + // failed to set configuration + // + DPRINT1("USBCCGP_SyncUrbRequest failed to unconfigure device\n", Status); + } + + ExFreePool(Urb); + return Status; +} + + NTSTATUS FDO_HandlePnp( PDEVICE_OBJECT DeviceObject, @@ -429,6 +475,12 @@ FDO_HandlePnp( { case IRP_MN_REMOVE_DEVICE: { + // + // unconfigure device + // + DPRINT1("[USBCCGP] FDO IRP_MN_REMOVE\n"); + FDO_CloseConfiguration(DeviceObject); + /* Send the IRP down the stack */ Status = USBCCGP_SyncForwardIrp(FDODeviceExtension->NextDeviceObject, Irp); if (NT_SUCCESS(Status)) diff --git a/reactos/drivers/usb/usbohci/usb_device.cpp b/reactos/drivers/usb/usbohci/usb_device.cpp index af1e988e3fd..59802447d28 100644 --- a/reactos/drivers/usb/usbohci/usb_device.cpp +++ b/reactos/drivers/usb/usbohci/usb_device.cpp @@ -1103,30 +1103,49 @@ CUSBDevice::SelectConfiguration( ULONG InterfaceIndex, PipeIndex; USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; NTSTATUS Status; + UCHAR bConfigurationValue = 0; - // - // sanity checks - // - ASSERT(ConfigurationDescriptor->iConfiguration < m_DeviceDescriptor.bNumConfigurations); - ASSERT(ConfigurationDescriptor->iConfiguration == m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].ConfigurationDescriptor->iConfiguration); + if (ConfigurationDescriptor) + { + // + // sanity checks + // + ASSERT(ConfigurationDescriptor->iConfiguration < m_DeviceDescriptor.bNumConfigurations); + ASSERT(ConfigurationDescriptor->iConfiguration == m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].ConfigurationDescriptor->iConfiguration); - // - // sanity check - // - ASSERT(ConfigurationDescriptor->bNumInterfaces <= m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].ConfigurationDescriptor->bNumInterfaces); + // + // sanity check + // + ASSERT(ConfigurationDescriptor->bNumInterfaces <= m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].ConfigurationDescriptor->bNumInterfaces); + + // + // get configuration value + // + bConfigurationValue = ConfigurationDescriptor->bConfigurationValue; + } // // now build setup packet // RtlZeroMemory(&CtrlSetup, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET)); CtrlSetup.bRequest = USB_REQUEST_SET_CONFIGURATION; - CtrlSetup.wValue.W = ConfigurationDescriptor->bConfigurationValue; + CtrlSetup.wValue.W = bConfigurationValue; // // select configuration // Status = CommitSetupPacket(&CtrlSetup, 0, 0, 0); + if (!ConfigurationDescriptor) + { + // + // unconfigure request + // + DPRINT1("CUsbDevice::SelectConfiguration Unconfigure Request Status %x\n", Status); + m_ConfigurationIndex = 0; + return Status; + } + // // informal debug print //