Skip to content

Commit a872bb8

Browse files
committed
usb: hub: Add remove synchronization
Added PDO/FDO remove synchronization to prevent device removal while another IRP is in process. As guidelines used ch6 of Walter Oney's "Programming the Microsoft Windows Driver Model 2ed" svn path=/branches/GSoC_2016/USB/; revision=72389
1 parent c2c6b0f commit a872bb8

File tree

3 files changed

+69
-3
lines changed

3 files changed

+69
-3
lines changed

drivers/usb/usbhub/fdo.c

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1324,6 +1324,8 @@ CreateUsbChildDeviceObject(
13241324

13251325
INITIALIZE_PNP_STATE(UsbChildExtension->Common);
13261326

1327+
IoInitializeRemoveLock(&UsbChildExtension->Common.RemoveLock, 'pbuH', 0, 0);
1328+
13271329
KeAcquireGuardedMutex(&HubDeviceExtension->HubMutexLock);
13281330

13291331
//
@@ -2038,6 +2040,14 @@ USBHUB_FdoHandlePnp(
20382040

20392041
Stack = IoGetCurrentIrpStackLocation(Irp);
20402042

2043+
Status = IoAcquireRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp);
2044+
if (!NT_SUCCESS(Status))
2045+
{
2046+
Irp->IoStatus.Status = Status;
2047+
IoCompleteRequest(Irp, IO_NO_INCREMENT);
2048+
return Status;
2049+
}
2050+
20412051
switch (Stack->MinorFunction)
20422052
{
20432053
case IRP_MN_START_DEVICE:
@@ -2057,6 +2067,7 @@ USBHUB_FdoHandlePnp(
20572067

20582068
Irp->IoStatus.Status = Status;
20592069
IoCompleteRequest(Irp, IO_NO_INCREMENT);
2070+
IoReleaseRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp);
20602071
return Status;
20612072
}
20622073

@@ -2083,6 +2094,7 @@ USBHUB_FdoHandlePnp(
20832094
// We should fail an IRP
20842095
Irp->IoStatus.Status = Status;
20852096
IoCompleteRequest(Irp, IO_NO_INCREMENT);
2097+
IoReleaseRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp);
20862098
return Status;
20872099
}
20882100

@@ -2201,7 +2213,9 @@ USBHUB_FdoHandlePnp(
22012213
}
22022214
}
22032215

2204-
return ForwardIrpAndForget(DeviceObject, Irp);
2216+
Status = ForwardIrpAndForget(DeviceObject, Irp);
2217+
IoReleaseRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp);
2218+
return Status;
22052219
}
22062220

22072221
NTSTATUS
@@ -2225,6 +2239,25 @@ USBHUB_FdoHandleDeviceControl(
22252239
// get device extension
22262240
HubDeviceExtension = (PHUB_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
22272241

2242+
Status = IoAcquireRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp);
2243+
if (!NT_SUCCESS(Status))
2244+
{
2245+
Irp->IoStatus.Status = Status;
2246+
IoCompleteRequest(Irp, IO_NO_INCREMENT);
2247+
return Status;
2248+
}
2249+
2250+
// Prevent handling of control requests in remove pending state
2251+
if (HubDeviceExtension->Common.PnPState == RemovePending)
2252+
{
2253+
DPRINT1("[USBHUB] Request for removed device object %p\n", DeviceObject);
2254+
Irp->IoStatus.Status = STATUS_DEVICE_NOT_CONNECTED;
2255+
Irp->IoStatus.Information = 0;
2256+
IoCompleteRequest(Irp, IO_NO_INCREMENT);
2257+
IoReleaseRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp);
2258+
return STATUS_DEVICE_NOT_CONNECTED;
2259+
}
2260+
22282261
if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_USB_GET_NODE_INFORMATION)
22292262
{
22302263
// is the buffer big enough
@@ -2390,6 +2423,7 @@ USBHUB_FdoHandleDeviceControl(
23902423
Irp->IoStatus.Status = Status;
23912424
IoCompleteRequest(Irp, IO_NO_INCREMENT);
23922425

2426+
IoReleaseRemoveLock(&HubDeviceExtension->Common.RemoveLock, Irp);
23932427
return Status;
23942428
}
23952429

drivers/usb/usbhub/pdo.c

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,14 @@ USBHUB_PdoHandleInternalDeviceControl(
200200
ChildDeviceExtension = (PHUB_CHILDDEVICE_EXTENSION)DeviceObject->DeviceExtension;
201201
ASSERT(ChildDeviceExtension->Common.IsFDO == FALSE);
202202

203+
Status = IoAcquireRemoveLock(&ChildDeviceExtension->Common.RemoveLock, Irp);
204+
if (!NT_SUCCESS(Status))
205+
{
206+
Irp->IoStatus.Status = Status;
207+
IoCompleteRequest(Irp, IO_NO_INCREMENT);
208+
return Status;
209+
}
210+
203211
if (ChildDeviceExtension->Common.PnPState == SurpriseRemovePending ||
204212
ChildDeviceExtension->Common.PnPState == RemovePending ||
205213
!IsValidPDO(DeviceObject))
@@ -209,6 +217,7 @@ USBHUB_PdoHandleInternalDeviceControl(
209217
Irp->IoStatus.Status = STATUS_DEVICE_NOT_CONNECTED;
210218
Irp->IoStatus.Information = 0;
211219
IoCompleteRequest(Irp, IO_NO_INCREMENT);
220+
IoReleaseRemoveLock(&ChildDeviceExtension->Common.RemoveLock, Irp);
212221
return STATUS_DEVICE_NOT_CONNECTED;
213222
}
214223

@@ -314,6 +323,7 @@ USBHUB_PdoHandleInternalDeviceControl(
314323
// Send the request to RootHub
315324
//
316325
Status = FowardUrbToRootHub(RootHubDeviceObject, IOCTL_INTERNAL_USB_SUBMIT_URB, Irp, Urb, NULL);
326+
IoReleaseRemoveLock(&ChildDeviceExtension->Common.RemoveLock, Irp);
317327
return Status;
318328
}
319329
//
@@ -410,6 +420,7 @@ USBHUB_PdoHandleInternalDeviceControl(
410420
Irp->IoStatus.Status = Status;
411421
IoCompleteRequest(Irp, IO_NO_INCREMENT);
412422
}
423+
IoReleaseRemoveLock(&ChildDeviceExtension->Common.RemoveLock, Irp);
413424
return Status;
414425
}
415426

@@ -584,6 +595,14 @@ USBHUB_PdoHandlePnp(
584595
Stack = IoGetCurrentIrpStackLocation(Irp);
585596
MinorFunction = Stack->MinorFunction;
586597

598+
Status = IoAcquireRemoveLock(&UsbChildExtension->Common.RemoveLock, Irp);
599+
if (!NT_SUCCESS(Status))
600+
{
601+
Irp->IoStatus.Status = Status;
602+
IoCompleteRequest(Irp, IO_NO_INCREMENT);
603+
return Status;
604+
}
605+
587606
switch (MinorFunction)
588607
{
589608
case IRP_MN_START_DEVICE:
@@ -682,6 +701,8 @@ USBHUB_PdoHandlePnp(
682701
// Parent or child device was surprise removed, freeing resources allocated for child device.
683702
SET_NEW_PNP_STATE(UsbChildExtension->Common, Deleted);
684703

704+
IoReleaseRemoveLockAndWait(&UsbChildExtension->Common.RemoveLock, Irp);
705+
685706
// Remove the usb device
686707
if (UsbChildExtension->UsbDeviceHandle)
687708
{
@@ -705,9 +726,13 @@ USBHUB_PdoHandlePnp(
705726
if (UsbChildExtension->usInstanceId.Buffer)
706727
ExFreePool(UsbChildExtension->usInstanceId.Buffer);
707728

708-
// Delete child PDO
729+
DPRINT("Deleting child PDO\n");
709730
IoDeleteDevice(DeviceObject);
710731
}
732+
else
733+
{
734+
IoReleaseRemoveLock(&UsbChildExtension->Common.RemoveLock, Irp);
735+
}
711736

712737
// If device is physically presented, we leave its PDO undeleted.
713738

@@ -802,7 +827,9 @@ USBHUB_PdoHandlePnp(
802827

803828
// pass irp down
804829
IoSkipCurrentIrpStackLocation(Irp);
805-
return IoCallDriver(UsbChildExtension->ParentDeviceObject, Irp);
830+
Status = IoCallDriver(UsbChildExtension->ParentDeviceObject, Irp);
831+
IoReleaseRemoveLock(&UsbChildExtension->Common.RemoveLock, Irp);
832+
return Status;
806833
}
807834
case IRP_MN_SURPRISE_REMOVAL:
808835
{
@@ -826,6 +853,8 @@ USBHUB_PdoHandlePnp(
826853
}
827854
}
828855

856+
IoReleaseRemoveLock(&UsbChildExtension->Common.RemoveLock, Irp);
857+
829858
Irp->IoStatus.Information = Information;
830859
Irp->IoStatus.Status = Status;
831860
IoCompleteRequest(Irp, IO_NO_INCREMENT);

drivers/usb/usbhub/usbhub.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ USBHUB_AddDevice(
9797
// initialize mutex
9898
KeInitializeGuardedMutex(&HubDeviceExtension->HubMutexLock);
9999

100+
// initialize remove lock
101+
IoInitializeRemoveLock(&HubDeviceExtension->Common.RemoveLock, 'buH', 0, 0);
102+
100103
//
101104
// initialize reset complete event
102105
//

0 commit comments

Comments
 (0)