[PCI][HIDCLASS][HIDUSB][KBDHID][MOUHID][USBCCGP][USBOHCI][USBEHCI][USBHUB][USBSTOR]
authorCameron Gutman <aicommander@gmail.com>
Fri, 3 Feb 2012 22:59:53 +0000 (22:59 +0000)
committerCameron Gutman <aicommander@gmail.com>
Fri, 3 Feb 2012 22:59:53 +0000 (22:59 +0000)
- Handle query remove IRPs
- Fix some other removal bugs

svn path=/branches/usb-bringup-trunk/; revision=55399

14 files changed:
drivers/bus/pci/fdo.c
drivers/bus/pci/pdo.c
drivers/hid/hidclass/fdo.c
drivers/hid/hidusb/hidusb.c
drivers/hid/kbdhid/kbdhid.c
drivers/hid/mouhid/mouhid.c
drivers/usb/usbccgp/fdo.c
drivers/usb/usbccgp/pdo.c
drivers/usb/usbehci_new/hub_controller.cpp
drivers/usb/usbhub_new/fdo.c
drivers/usb/usbhub_new/pdo.c
drivers/usb/usbohci/hub_controller.cpp
drivers/usb/usbstor/fdo.c
drivers/usb/usbstor/pdo.c

index 94f7a5f..4b12ded 100644 (file)
@@ -96,7 +96,6 @@ FdoEnumerateDevices(
 {
   PFDO_DEVICE_EXTENSION DeviceExtension;
   PCI_COMMON_CONFIG PciConfig;
-  PLIST_ENTRY CurrentEntry;
   PPCI_DEVICE Device;
   PCI_SLOT_NUMBER SlotNumber;
   ULONG DeviceNumber;
@@ -108,15 +107,6 @@ FdoEnumerateDevices(
 
   DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
 
-  /* Mark all devices to be removed. If we don't discover them again during
-     enumeration, assume that they have been surprise removed */
-  CurrentEntry = DeviceExtension->DeviceListHead.Flink;
-  while (CurrentEntry != &DeviceExtension->DeviceListHead) {
-    Device = CONTAINING_RECORD(CurrentEntry, PCI_DEVICE, ListEntry);
-    Device->RemovePending = TRUE;
-    CurrentEntry = CurrentEntry->Flink;
-  }
-
   DeviceExtension->DeviceListCount = 0;
 
   /* Enumerate devices on the PCI bus */
@@ -190,9 +180,6 @@ FdoEnumerateDevices(
           &DeviceExtension->DeviceListLock);
       }
 
-      /* Don't remove this device */
-      Device->RemovePending = FALSE;
-
       DeviceExtension->DeviceListCount++;
 
       /* Skip to next device if the current one is not a multifunction device */
index a339179..26569a4 100644 (file)
@@ -1443,11 +1443,34 @@ PdoPnpControl(
   case IRP_MN_STOP_DEVICE:
   case IRP_MN_QUERY_REMOVE_DEVICE:
   case IRP_MN_CANCEL_REMOVE_DEVICE:
-  case IRP_MN_REMOVE_DEVICE:
   case IRP_MN_SURPRISE_REMOVAL:
     Status = STATUS_SUCCESS;
     break;
 
+  case IRP_MN_REMOVE_DEVICE:
+  {
+    PPDO_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
+    PFDO_DEVICE_EXTENSION FdoDeviceExtension = DeviceExtension->Fdo->DeviceExtension;
+    KIRQL OldIrql;
+
+    /* Remove it from the device list */
+    KeAcquireSpinLock(&FdoDeviceExtension->DeviceListLock, &OldIrql);
+    RemoveEntryList(&DeviceExtension->PciDevice->ListEntry);
+    FdoDeviceExtension->DeviceListCount--;
+    KeReleaseSpinLock(&FdoDeviceExtension->DeviceListLock, OldIrql);
+
+    /* Free the device */
+    ExFreePool(DeviceExtension->PciDevice);
+
+    /* Complete the IRP */
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+    /* Delete the DO */
+    IoDeleteDevice(DeviceObject);
+    return STATUS_SUCCESS;
+  }
+
   case IRP_MN_QUERY_INTERFACE:
     DPRINT("IRP_MN_QUERY_INTERFACE received\n");
     Status = PdoQueryInterface(DeviceObject, Irp, IrpSp);
index 7604d51..e909d67 100644 (file)
@@ -554,6 +554,7 @@ HidClassFDO_PnP(
         {
              return HidClassFDO_RemoveDevice(DeviceObject, Irp);
         }
+        case IRP_MN_QUERY_REMOVE_DEVICE:
         case IRP_MN_QUERY_STOP_DEVICE:
         {
             //
@@ -567,6 +568,7 @@ HidClassFDO_PnP(
             IoSkipCurrentIrpStackLocation(Irp);
             return IoCallDriver(FDODeviceExtension->Common.HidDeviceExtension.NextDeviceObject, Irp);
         }
+        case IRP_MN_CANCEL_REMOVE_DEVICE:
         case IRP_MN_CANCEL_STOP_DEVICE:
         {
             //
index f859b2b..f97c9f9 100644 (file)
@@ -1561,8 +1561,11 @@ HidPnp(
             }
 
             //
-            // done
+            // delete and detach device
             //
+            IoDetachDevice(DeviceExtension->NextDeviceObject);
+            IoDeleteDevice(DeviceObject);
+
             return Status;
         }
         case IRP_MN_QUERY_PNP_DEVICE_STATE:
@@ -1583,6 +1586,25 @@ HidPnp(
             //
             return Status;
         }
+        case IRP_MN_QUERY_STOP_DEVICE:
+        case IRP_MN_QUERY_REMOVE_DEVICE:
+        {
+            //
+            // we're fine with it
+            //
+            Irp->IoStatus.Status = STATUS_SUCCESS;
+
+            //
+            // pass request to next driver
+            //
+            IoSkipCurrentIrpStackLocation(Irp);
+            Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
+
+            //
+            // done
+            //
+            return Status;
+        }
         case IRP_MN_STOP_DEVICE:
         {
             //
index eec804b..7871b37 100644 (file)
@@ -737,7 +737,11 @@ KbdHid_Pnp(
     IoStack = IoGetCurrentIrpStackLocation(Irp);
     DPRINT1("[KBDHID] IRP_MJ_PNP Request: %x\n", IoStack->MinorFunction);
 
-    if (IoStack->MinorFunction == IRP_MN_STOP_DEVICE || IoStack->MinorFunction == IRP_MN_CANCEL_REMOVE_DEVICE || IoStack->MinorFunction == IRP_MN_QUERY_STOP_DEVICE || IoStack->MinorFunction == IRP_MN_CANCEL_STOP_DEVICE)
+    if (IoStack->MinorFunction == IRP_MN_STOP_DEVICE ||
+        IoStack->MinorFunction == IRP_MN_CANCEL_REMOVE_DEVICE ||
+        IoStack->MinorFunction == IRP_MN_QUERY_STOP_DEVICE ||
+        IoStack->MinorFunction == IRP_MN_CANCEL_STOP_DEVICE ||
+        IoStack->MinorFunction == IRP_MN_QUERY_REMOVE_DEVICE)
     {
         /* indicate success */
         Irp->IoStatus.Status = STATUS_SUCCESS;
index 350b4ab..013bf80 100644 (file)
@@ -788,7 +788,11 @@ MouHid_Pnp(
     IoStack = IoGetCurrentIrpStackLocation(Irp);
     DPRINT1("[MOUHID] IRP_MJ_PNP Request: %x\n", IoStack->MinorFunction);
 
-    if (IoStack->MinorFunction == IRP_MN_STOP_DEVICE || IoStack->MinorFunction == IRP_MN_CANCEL_REMOVE_DEVICE || IoStack->MinorFunction == IRP_MN_QUERY_STOP_DEVICE || IoStack->MinorFunction == IRP_MN_CANCEL_STOP_DEVICE)
+    if (IoStack->MinorFunction == IRP_MN_STOP_DEVICE ||
+        IoStack->MinorFunction == IRP_MN_CANCEL_REMOVE_DEVICE ||
+        IoStack->MinorFunction == IRP_MN_QUERY_STOP_DEVICE ||
+        IoStack->MinorFunction == IRP_MN_CANCEL_STOP_DEVICE ||
+        IoStack->MinorFunction == IRP_MN_QUERY_REMOVE_DEVICE)
     {
         /* indicate success */
         Irp->IoStatus.Status = STATUS_SUCCESS;
index 04d38e9..c370343 100644 (file)
@@ -481,6 +481,20 @@ FDO_HandlePnp(
             }
             break;
        }
+        case IRP_MN_QUERY_REMOVE_DEVICE:
+        case IRP_MN_QUERY_STOP_DEVICE:
+        {
+            //
+            // sure
+            //
+            Irp->IoStatus.Status = STATUS_SUCCESS;
+
+            //
+            // forward irp to next device object
+            //
+            IoSkipCurrentIrpStackLocation(Irp);
+            return IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp);
+        }
        default:
        {
             //
index 1a2c0be..a78f7ce 100644 (file)
@@ -391,6 +391,15 @@ PDO_HandlePnp(
            IoCompleteRequest(Irp, IO_NO_INCREMENT);
            return STATUS_SUCCESS;
        }
+        case IRP_MN_QUERY_REMOVE_DEVICE:
+        case IRP_MN_QUERY_STOP_DEVICE:
+        {
+            //
+            // sure
+            //
+            Status = STATUS_SUCCESS;
+            break;
+        }
        case IRP_MN_START_DEVICE:
        {
            //
@@ -406,6 +415,7 @@ PDO_HandlePnp(
             // do nothing
             //
             Status = Irp->IoStatus.Status;
+            break;
         }
     }
 
index b24ab7d..8342a7d 100644 (file)
@@ -434,6 +434,15 @@ CHubController::HandlePnp(
             Status = SetDeviceInterface(TRUE);
             break;
         }
+        case IRP_MN_QUERY_STOP_DEVICE:
+        case IRP_MN_QUERY_REMOVE_DEVICE:
+        {
+            //
+            // sure
+            //
+            Status = STATUS_SUCCESS;
+            break;
+        }
         case IRP_MN_QUERY_ID:
         {
             DPRINT1("CHubController::HandlePnp IRP_MN_QUERY_ID Type %x\n", IoStack->Parameters.QueryId.IdType);
index 89b1787..d0f11ca 100644 (file)
@@ -1883,6 +1883,22 @@ USBHUB_FdoHandlePnp(
             }
             break;
         }
+        case IRP_MN_QUERY_REMOVE_DEVICE:
+        case IRP_MN_QUERY_STOP_DEVICE:
+        {
+            Irp->IoStatus.Status = STATUS_SUCCESS;
+            return ForwardIrpAndForget(DeviceObject, Irp);
+        }
+        case IRP_MN_REMOVE_DEVICE:
+        {
+            Irp->IoStatus.Status = STATUS_SUCCESS;
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+            IoDetachDevice(HubDeviceExtension->LowerDeviceObject);
+            IoDeleteDevice(DeviceObject);
+
+            return STATUS_SUCCESS;
+        }
         case IRP_MN_QUERY_BUS_INFORMATION:
         {
             DPRINT1("IRP_MN_QUERY_BUS_INFORMATION\n");
index 48b31d7..e40f1f2 100644 (file)
@@ -586,6 +586,14 @@ USBHUB_PdoHandlePnp(
             IoDeleteDevice(DeviceObject);
             return STATUS_SUCCESS;
         }
+        case IRP_MN_QUERY_STOP_DEVICE:
+        case IRP_MN_QUERY_REMOVE_DEVICE:
+        {
+            /* Sure, no problem */
+            Status = STATUS_SUCCESS;
+            Information = 0;
+            break;
+        }
         default:
         {
             DPRINT1("PDO IRP_MJ_PNP / unknown minor function 0x%lx\n", MinorFunction);
index 8b9b877..aef53d1 100644 (file)
@@ -437,6 +437,15 @@ CHubController::HandlePnp(
             Status = SetDeviceInterface(TRUE);
             break;
         }
+        case IRP_MN_QUERY_STOP_DEVICE:
+        case IRP_MN_QUERY_REMOVE_DEVICE:
+        {
+            //
+            // sure
+            //
+            Status = STATUS_SUCCESS;
+            break;
+        }
         case IRP_MN_QUERY_ID:
         {
             DPRINT1("CHubController::HandlePnp IRP_MN_QUERY_ID Type %x\n", IoStack->Parameters.QueryId.IdType);
index 2d7123f..c3d12b5 100644 (file)
@@ -339,9 +339,11 @@ USBSTOR_FdoHandlePnp(
            break;
        }
        case IRP_MN_STOP_DEVICE:
+       {
            DPRINT1("USBSTOR_FdoHandlePnp: IRP_MN_STOP_DEVICE unimplemented\n");
            Status = STATUS_NOT_SUPPORTED;
            break;
+       }
        case IRP_MN_REMOVE_DEVICE:
        {
            DPRINT1("IRP_MN_REMOVE_DEVICE\n");
@@ -356,6 +358,29 @@ USBSTOR_FdoHandlePnp(
            IoSkipCurrentIrpStackLocation(Irp);
            return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
        }
+       case IRP_MN_QUERY_STOP_DEVICE:
+       case IRP_MN_QUERY_REMOVE_DEVICE:
+       {
+           //
+           // we can if nothing is pending
+           //
+           if (DeviceExtension->IrpPendingCount != 0 ||
+               DeviceExtension->ActiveSrb != NULL)
+           {
+               /* We have pending requests */
+               DPRINT1("Failing removal/stop request due to pending requests present\n");
+               Status = STATUS_UNSUCCESSFUL;
+           }
+           else
+           {
+               /* We're all clear */
+               Irp->IoStatus.Status = STATUS_SUCCESS;
+
+               IoSkipCurrentIrpStackLocation(Irp);
+               return IoCallDriver(DeviceExtension->LowerDeviceObject, Irp);
+           }
+           break;
+       }
        case IRP_MN_START_DEVICE:
        {
            Status = USBSTOR_FdoHandleStartDevice(DeviceObject, DeviceExtension, Irp);
index 4a50a00..3361351 100644 (file)
@@ -873,6 +873,18 @@ USBSTOR_PdoHandlePnp(
            }
            break;
        }
+       case IRP_MN_QUERY_REMOVE_DEVICE:
+       case IRP_MN_QUERY_STOP_DEVICE:
+       {
+           //
+           // if we're not claimed it's ok
+           //
+           if (DeviceExtension->Claimed)
+               Status = STATUS_UNSUCCESSFUL;
+           else
+               Status = STATUS_SUCCESS;
+           break;
+       }
        case IRP_MN_START_DEVICE:
        {
            //