[aoe] Use floating FDO strategy
authorShao Miller <Shao.Miller@yrdsb.edu.on.ca>
Fri, 31 Dec 2010 21:10:49 +0000 (16:10 -0500)
committerShao Miller <Shao.Miller@yrdsb.edu.on.ca>
Fri, 31 Dec 2010 21:10:49 +0000 (16:10 -0500)
The idea is:

The AoE bus and its FDO will be created during
driver startup.  It won't be attached to any PDO.
Having a device should prevent the AoE driver from
being subsequently unloaded.

The AoE thread will be started during driver startup.
The thread will request a PDO from WinVBlock.

When the PDO is associated with the AoE driver, either
through a CriticalDeviceDatabase entry or via .INF and
the setup API, the "floating" FDO for the AoE bus will
then be attached to the device tree. :)

To do: We need to handle removal and unload.  We should
remove the dummy PDO we requested of WinVBlock.

src/aoe/bus.c
src/aoe/driver.c

index d6e5637..e72eb96 100644 (file)
@@ -47,7 +47,7 @@ extern NTSTATUS STDCALL AoeBusDevCtlMount(IN PIRP);
 
 /* Forward declarations. */
 static WV_F_DEV_PNP_ID AoeBusPnpId_;
-winvblock__bool AoeBusCreate(void);
+winvblock__bool AoeBusCreate(IN PDRIVER_OBJECT);
 void AoeBusFree(void);
 
 /* Globals. */
@@ -62,6 +62,7 @@ static UNICODE_STRING AoeBusDosname_ = {
     sizeof AOE_M_BUS_DOSNAME_,
     AOE_M_BUS_DOSNAME_
   };
+const WV_S_DRIVER_DUMMY_IDS * AoeBusDummyIds;
 
 static NTSTATUS STDCALL AoeBusDevCtlDetach_(IN PIRP irp) {
     PIO_STACK_LOCATION io_stack_loc = IoGetCurrentIrpStackLocation(irp);
@@ -142,28 +143,6 @@ NTSTATUS STDCALL AoeBusDevCtl(
   X_(Y_, Compat,   winvblock__literal_w L"\\AoE\0")
 WV_M_DRIVER_DUMMY_ID_GEN(AoeBusDummyIds_, AOE_M_BUS_IDS);
 
-/**
- * Create the AoE bus.
- *
- * @ret         TRUE for success, else FALSE.
- */
-winvblock__bool AoeBusCreate(void) {
-    NTSTATUS status;
-
-    /* Create the PDO for the sub-bus on the WinVBlock bus. */
-    status = WvDriverAddDummy(
-        &AoeBusDummyIds_,
-        FILE_DEVICE_CONTROLLER,
-        FILE_DEVICE_SECURE_OPEN
-      );
-    if (!NT_SUCCESS(status)) {
-        DBG("Couldn't add AoE bus to WinVBlock bus!\n");
-        return FALSE;
-      }
-    /* All done. */
-    return TRUE;
-  }
-
 /* Destroy the AoE bus. */
 void AoeBusFree(void) {
     IoDeleteSymbolicLink(&AoeBusDosname_);
@@ -271,15 +250,53 @@ NTSTATUS STDCALL AoeBusAttachFdo(
     KIRQL irql;
     NTSTATUS status;
     PLIST_ENTRY walker;
-    PDEVICE_OBJECT fdo = NULL;
 
     DBG("Entry\n");
     /* Do we already have our main bus? */
-    if (AoeBusMain.Fdo) {
+    if (AoeBusMain.Pdo) {
         DBG("Already have the main bus.  Refusing.\n");
         status = STATUS_NOT_SUPPORTED;
         goto err_already_established;
       }
+
+    /* Set associations for the bus, FDO, PDO. */
+    AoeBusMain.Pdo = pdo;
+    /* Attach the FDO to the PDO. */
+    AoeBusMain.LowerDeviceObject = IoAttachDeviceToDeviceStack(
+        AoeBusMain.Fdo,
+        pdo
+      );
+    if (AoeBusMain.LowerDeviceObject == NULL) {
+        status = STATUS_NO_SUCH_DEVICE;
+        DBG("IoAttachDeviceToDeviceStack() failed!\n");
+        goto err_attach;
+      }
+
+    /* Ok! */
+    DBG("Exit\n");
+    return STATUS_SUCCESS;
+
+    err_attach:
+
+    err_already_established:
+
+    DBG("Exit with failure\n");
+    return status;
+  }
+
+/**
+ * Create the AoE bus.
+ *
+ * @ret         TRUE for success, else FALSE.
+ */
+winvblock__bool AoeBusCreate(IN PDRIVER_OBJECT driver_obj) {
+    NTSTATUS status;
+
+    /* Do we already have our main bus? */
+    if (AoeBusMain.Fdo) {
+        DBG("AoeBusCreate called twice.\n");
+        return FALSE;
+      }
     /* Initialize the bus. */
     WvBusInit(&AoeBusMain);
     /* Create the bus FDO. */
@@ -290,7 +307,7 @@ NTSTATUS STDCALL AoeBusAttachFdo(
         FILE_DEVICE_CONTROLLER,
         FILE_DEVICE_SECURE_OPEN,
         FALSE,
-        &fdo
+        &AoeBusMain.Fdo
       );
     if (!NT_SUCCESS(status)) {
         DBG("IoCreateDevice() failed!\n");
@@ -305,37 +322,25 @@ NTSTATUS STDCALL AoeBusAttachFdo(
         DBG("IoCreateSymbolicLink() failed!\n");
         goto err_dos_symlink;
       }
-    /* Set associations for the bus, FDO, PDO. */
-    AoeBusMain.Fdo = fdo;
-    AoeBusMain.QueryDevText = AoeBusPnpQueryDevText_;
-    AoeBusMain.Pdo = pdo;
-    fdo->Flags |= DO_DIRECT_IO;         /* FIXME? */
-    fdo->Flags |= DO_POWER_INRUSH;      /* FIXME? */
-    /* Attach the FDO to the PDO. */
-    AoeBusMain.LowerDeviceObject = IoAttachDeviceToDeviceStack(fdo, pdo);
-    if (AoeBusMain.LowerDeviceObject == NULL) {
-        status = STATUS_NO_SUCH_DEVICE;
-        DBG("IoAttachDeviceToDeviceStack() failed!\n");
-        goto err_attach;
-      }
     /* Ok! */
-    fdo->Flags &= ~DO_DEVICE_INITIALIZING;
+    AoeBusDummyIds = &AoeBusDummyIds_;
+    AoeBusMain.QueryDevText = AoeBusPnpQueryDevText_;
+    AoeBusMain.Fdo->Flags |= DO_DIRECT_IO;         /* FIXME? */
+    AoeBusMain.Fdo->Flags |= DO_POWER_INRUSH;      /* FIXME? */
+    AoeBusMain.Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
     #ifdef RIS
     AoeBusMain.State = WvBusStateStarted;
     #endif
+    /* All done. */
     DBG("Exit\n");
-    return STATUS_SUCCESS;
-
-    err_attach:
+    return TRUE;
 
     IoDeleteSymbolicLink(&AoeBusDosname_);
     err_dos_symlink:
 
-    IoDeleteDevice(fdo);
+    IoDeleteDevice(AoeBusMain.Fdo);
     err_fdo:
 
-    err_already_established:
-
     DBG("Exit with failure\n");
-    return status;
+    return FALSE;
   }
index 2e460f2..aeab6d0 100644 (file)
@@ -53,13 +53,14 @@ extern NTSTATUS STDCALL ZwWaitForSingleObject(
 
 /* From aoe/bus.c */
 extern WV_S_BUS_T AoeBusMain;
-extern winvblock__bool AoeBusCreate(void);
+extern winvblock__bool AoeBusCreate(IN PDRIVER_OBJECT);
 extern void AoeBusFree(void);
 extern NTSTATUS STDCALL AoeBusDevCtl(IN PIRP, IN ULONG POINTER_ALIGNMENT);
 extern NTSTATUS STDCALL AoeBusAttachFdo(
     IN PDRIVER_OBJECT,
     IN PDEVICE_OBJECT
   );
+extern const WV_S_DRIVER_DUMMY_IDS * AoeBusDummyIds;
 /* From aoe/registry.c */
 extern winvblock__bool STDCALL AoeRegSetup(OUT PNTSTATUS);
 
@@ -339,7 +340,7 @@ NTSTATUS STDCALL DriverEntry(
     /* Set the driver AddDevice callback. */
     DriverObject->DriverExtension->AddDevice = AoeBusAttachFdo;
     AoeStarted_ = TRUE;
-    if (!AoeBusCreate()) {
+    if (!AoeBusCreate(DriverObject)) {
         DBG("Unable to create AoE bus!\n");
         AoeUnload_(DriverObject);
         return STATUS_INSUFFICIENT_RESOURCES;
@@ -1308,6 +1309,7 @@ void aoe__reset_probe(void)
 
 static void STDCALL AoeThread_(IN void *StartContext)
   {
+    NTSTATUS status;
     LARGE_INTEGER Timeout, CurrentTime, ProbeTime, ReportTime;
     winvblock__uint32 NextTagId = 1;
     AOE_SP_WORK_TAG_ tag;
@@ -1321,6 +1323,19 @@ static void STDCALL AoeThread_(IN void *StartContext)
     AOE_SP_DISK_ aoe_disk_ptr;
 
     DBG ( "Entry\n" );
+
+    /* Create the PDO for the sub-bus on the WinVBlock bus. */
+    status = WvDriverAddDummy(
+        AoeBusDummyIds,
+        FILE_DEVICE_CONTROLLER,
+        FILE_DEVICE_SECURE_OPEN
+      );
+    if (!NT_SUCCESS(status)) {
+        DBG("Couldn't add AoE bus to WinVBlock bus!\n");
+        status = PsTerminateSystemThread(status);
+        return;
+      }
+
     ReportTime.QuadPart = 0LL;
     ProbeTime.QuadPart = 0LL;