Author: vmikayelyan Date: Fri Aug 19 15:43:43 2016 New Revision: 72371
URL: http://svn.reactos.org/svn/reactos?rev=72371&view=rev Log: usb: hub: PDO: Changed handling of IRP_MN_REMOVE_DEVICE
On this IRP we should free recources and delete child's PDO ONLY if it isn't presented physically on the bus.
If it is presented we're leaving as it was, thinking that devices on top of it already frees otained from it resources.
If child PDO is presented physically, then should be already marked as remove_pending when it will receive this IRP.
Modified: branches/GSoC_2016/USB/drivers/usb/usbhub/pdo.c
Modified: branches/GSoC_2016/USB/drivers/usb/usbhub/pdo.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2016/USB/drivers/usb/usbhub... ============================================================================== --- branches/GSoC_2016/USB/drivers/usb/usbhub/pdo.c [iso-8859-1] (original) +++ branches/GSoC_2016/USB/drivers/usb/usbhub/pdo.c [iso-8859-1] Fri Aug 19 15:43:43 2016 @@ -570,10 +570,7 @@ PIO_STACK_LOCATION Stack; ULONG_PTR Information = 0; PHUB_CHILDDEVICE_EXTENSION UsbChildExtension; - ULONG Index; - ULONG bFound; PDEVICE_RELATIONS DeviceRelation; - PDEVICE_OBJECT ParentDevice;
UsbChildExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension; Stack = IoGetCurrentIrpStackLocation(Irp); @@ -664,41 +661,46 @@ { PHUB_DEVICE_EXTENSION HubDeviceExtension = (PHUB_DEVICE_EXTENSION)UsbChildExtension->ParentDeviceObject->DeviceExtension; PUSB_BUS_INTERFACE_HUB_V5 HubInterface = &HubDeviceExtension->HubInterface; - ParentDevice = UsbChildExtension->ParentDeviceObject;
DPRINT("IRP_MJ_PNP / IRP_MN_REMOVE_DEVICE\n");
- /* remove us from pdo list */ - bFound = FALSE; - for(Index = 0; Index < USB_MAXCHILDREN; Index++) - { - if (HubDeviceExtension->ChildDeviceObject[Index] == DeviceObject) + if (!IsValidPDO(DeviceObject)) + { + // Parent or child device was surprise removed, freeing resources allocated for child device. + + // Remove the usb device + if (UsbChildExtension->UsbDeviceHandle) { - /* Remove the device */ - Status = HubInterface->RemoveUsbDevice(HubDeviceExtension->UsbDInterface.BusContext, UsbChildExtension->UsbDeviceHandle, 0); - - /* FIXME handle error */ - ASSERT(Status == STATUS_SUCCESS); - - /* remove us */ - HubDeviceExtension->ChildDeviceObject[Index] = NULL; - bFound = TRUE; - break; + Status = HubInterface->RemoveUsbDevice(HubInterface->BusContext, UsbChildExtension->UsbDeviceHandle, 0); + ASSERT(Status == STATUS_SUCCESS); } - } + // Free full configuration descriptor + if (UsbChildExtension->FullConfigDesc) + ExFreePool(UsbChildExtension->FullConfigDesc); + + // Free ID buffers + if (UsbChildExtension->usCompatibleIds.Buffer) + ExFreePool(UsbChildExtension->usCompatibleIds.Buffer); + + if (UsbChildExtension->usDeviceId.Buffer) + ExFreePool(UsbChildExtension->usDeviceId.Buffer); + + if (UsbChildExtension->usHardwareIds.Buffer) + ExFreePool(UsbChildExtension->usHardwareIds.Buffer); + + if (UsbChildExtension->usInstanceId.Buffer) + ExFreePool(UsbChildExtension->usInstanceId.Buffer); + + // Delete child PDO + IoDeleteDevice(DeviceObject); + } + + // Device is physically presented, so we leave its PDO undeleted. + ASSERT(UsbChildExtension->IsRemovePending == TRUE);
/* Complete the IRP */ Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); - - /* delete device */ - IoDeleteDevice(DeviceObject); - - if (bFound) - { - /* invalidate device relations */ - IoInvalidateDeviceRelations(ParentDevice, BusRelations); - }
return STATUS_SUCCESS; }