Skip to content

Commit ba43f5b

Browse files
committed
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. svn path=/branches/GSoC_2016/USB/; revision=72371
1 parent d1f4b36 commit ba43f5b

File tree

1 file changed

+28
-26
lines changed

1 file changed

+28
-26
lines changed

drivers/usb/usbhub/pdo.c

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -570,10 +570,7 @@ USBHUB_PdoHandlePnp(
570570
PIO_STACK_LOCATION Stack;
571571
ULONG_PTR Information = 0;
572572
PHUB_CHILDDEVICE_EXTENSION UsbChildExtension;
573-
ULONG Index;
574-
ULONG bFound;
575573
PDEVICE_RELATIONS DeviceRelation;
576-
PDEVICE_OBJECT ParentDevice;
577574

578575
UsbChildExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
579576
Stack = IoGetCurrentIrpStackLocation(Irp);
@@ -664,42 +661,47 @@ USBHUB_PdoHandlePnp(
664661
{
665662
PHUB_DEVICE_EXTENSION HubDeviceExtension = (PHUB_DEVICE_EXTENSION)UsbChildExtension->ParentDeviceObject->DeviceExtension;
666663
PUSB_BUS_INTERFACE_HUB_V5 HubInterface = &HubDeviceExtension->HubInterface;
667-
ParentDevice = UsbChildExtension->ParentDeviceObject;
668664

669665
DPRINT("IRP_MJ_PNP / IRP_MN_REMOVE_DEVICE\n");
670666

671-
/* remove us from pdo list */
672-
bFound = FALSE;
673-
for(Index = 0; Index < USB_MAXCHILDREN; Index++)
667+
if (!IsValidPDO(DeviceObject))
674668
{
675-
if (HubDeviceExtension->ChildDeviceObject[Index] == DeviceObject)
669+
// Parent or child device was surprise removed, freeing resources allocated for child device.
670+
671+
// Remove the usb device
672+
if (UsbChildExtension->UsbDeviceHandle)
676673
{
677-
/* Remove the device */
678-
Status = HubInterface->RemoveUsbDevice(HubDeviceExtension->UsbDInterface.BusContext, UsbChildExtension->UsbDeviceHandle, 0);
674+
Status = HubInterface->RemoveUsbDevice(HubInterface->BusContext, UsbChildExtension->UsbDeviceHandle, 0);
675+
ASSERT(Status == STATUS_SUCCESS);
676+
}
677+
// Free full configuration descriptor
678+
if (UsbChildExtension->FullConfigDesc)
679+
ExFreePool(UsbChildExtension->FullConfigDesc);
679680

680-
/* FIXME handle error */
681-
ASSERT(Status == STATUS_SUCCESS);
681+
// Free ID buffers
682+
if (UsbChildExtension->usCompatibleIds.Buffer)
683+
ExFreePool(UsbChildExtension->usCompatibleIds.Buffer);
682684

683-
/* remove us */
684-
HubDeviceExtension->ChildDeviceObject[Index] = NULL;
685-
bFound = TRUE;
686-
break;
687-
}
685+
if (UsbChildExtension->usDeviceId.Buffer)
686+
ExFreePool(UsbChildExtension->usDeviceId.Buffer);
687+
688+
if (UsbChildExtension->usHardwareIds.Buffer)
689+
ExFreePool(UsbChildExtension->usHardwareIds.Buffer);
690+
691+
if (UsbChildExtension->usInstanceId.Buffer)
692+
ExFreePool(UsbChildExtension->usInstanceId.Buffer);
693+
694+
// Delete child PDO
695+
IoDeleteDevice(DeviceObject);
688696
}
689697

698+
// Device is physically presented, so we leave its PDO undeleted.
699+
ASSERT(UsbChildExtension->IsRemovePending == TRUE);
700+
690701
/* Complete the IRP */
691702
Irp->IoStatus.Status = STATUS_SUCCESS;
692703
IoCompleteRequest(Irp, IO_NO_INCREMENT);
693704

694-
/* delete device */
695-
IoDeleteDevice(DeviceObject);
696-
697-
if (bFound)
698-
{
699-
/* invalidate device relations */
700-
IoInvalidateDeviceRelations(ParentDevice, BusRelations);
701-
}
702-
703705
return STATUS_SUCCESS;
704706
}
705707
case IRP_MN_QUERY_DEVICE_RELATIONS:

0 commit comments

Comments
 (0)