Skip to content

Commit 01a0ce0

Browse files
committed
usb: HUB: FDO: Add IRP_MN_REMOVE_DEVICE handler
Added remove handler for usbhub FDO. When FDO is being removed, it should delete all it's child PDOs. Because when PnP sends removes to child devices they are still presented on the bus, so their handler will not delete PDO. svn path=/branches/GSoC_2016/USB/; revision=72390
1 parent a872bb8 commit 01a0ce0

File tree

1 file changed

+59
-3
lines changed

1 file changed

+59
-3
lines changed

drivers/usb/usbhub/fdo.c

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2034,10 +2034,12 @@ USBHUB_FdoHandlePnp(
20342034
NTSTATUS Status = STATUS_SUCCESS;
20352035
PDEVICE_OBJECT ChildDeviceObject;
20362036
PHUB_DEVICE_EXTENSION HubDeviceExtension;
2037+
PUSB_BUS_INTERFACE_HUB_V5 HubInterface;
20372038
PHUB_CHILDDEVICE_EXTENSION ChildDeviceExtension;
20382039

20392040
HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
20402041

2042+
HubInterface = &HubDeviceExtension->HubInterface;
20412043
Stack = IoGetCurrentIrpStackLocation(Irp);
20422044

20432045
Status = IoAcquireRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp);
@@ -2175,15 +2177,69 @@ USBHUB_FdoHandlePnp(
21752177
}
21762178
case IRP_MN_REMOVE_DEVICE:
21772179
{
2178-
// Should be reworked later in this commits set
21792180
DPRINT("IRP_MN_REMOVE_DEVICE\n");
2181+
2182+
SET_NEW_PNP_STATE(HubDeviceExtension->Common, Deleted);
2183+
2184+
IoReleaseRemoveLockAndWait(&HubDeviceExtension->Common.RemoveLock, Irp);
2185+
2186+
//
2187+
// Here we should remove all child PDOs. At this point all children
2188+
// received and returned from IRP_MN_REMOVE so remove synchronization
2189+
// isn't needed here
2190+
//
2191+
2192+
KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
2193+
2194+
for (int i = 0; i < USB_MAXCHILDREN; i++)
2195+
{
2196+
ChildDeviceObject = HubDeviceExtension->ChildDeviceObject[i];
2197+
if (ChildDeviceObject)
2198+
{
2199+
PHUB_CHILDDEVICE_EXTENSION UsbChildExtension = (PHUB_CHILDDEVICE_EXTENSION)ChildDeviceObject->DeviceExtension;
2200+
2201+
SET_NEW_PNP_STATE(UsbChildExtension->Common, Deleted);
2202+
2203+
// Remove the usb device
2204+
if (UsbChildExtension->UsbDeviceHandle)
2205+
{
2206+
Status = HubInterface->RemoveUsbDevice(HubInterface->BusContext, UsbChildExtension->UsbDeviceHandle, 0);
2207+
ASSERT(Status == STATUS_SUCCESS);
2208+
}
2209+
2210+
// Free full configuration descriptor
2211+
if (UsbChildExtension->FullConfigDesc)
2212+
ExFreePool(UsbChildExtension->FullConfigDesc);
2213+
2214+
// Free ID buffers
2215+
if (UsbChildExtension->usCompatibleIds.Buffer)
2216+
ExFreePool(UsbChildExtension->usCompatibleIds.Buffer);
2217+
2218+
if (UsbChildExtension->usDeviceId.Buffer)
2219+
ExFreePool(UsbChildExtension->usDeviceId.Buffer);
2220+
2221+
if (UsbChildExtension->usHardwareIds.Buffer)
2222+
ExFreePool(UsbChildExtension->usHardwareIds.Buffer);
2223+
2224+
if (UsbChildExtension->usInstanceId.Buffer)
2225+
ExFreePool(UsbChildExtension->usInstanceId.Buffer);
2226+
2227+
DPRINT("Deleting child PDO\n");
2228+
IoDeleteDevice(DeviceObject);
2229+
ChildDeviceObject = NULL;
2230+
}
2231+
}
2232+
2233+
KeReleaseGuardedMutex(&HubDeviceExtension->HubMutexLock);
2234+
21802235
Irp->IoStatus.Status = STATUS_SUCCESS;
2181-
IoCompleteRequest(Irp, IO_NO_INCREMENT);
2236+
Status = ForwardIrpAndForget(DeviceObject, Irp);
21822237

21832238
IoDetachDevice(HubDeviceExtension->LowerDeviceObject);
2239+
DPRINT("Deleting FDO 0x%p\n", DeviceObject);
21842240
IoDeleteDevice(DeviceObject);
21852241

2186-
return STATUS_SUCCESS;
2242+
return Status;
21872243
}
21882244
case IRP_MN_QUERY_BUS_INFORMATION:
21892245
{

0 commit comments

Comments
 (0)