[driver,bus] Move the "boot bus" into the driver module
authorShao Miller <Shao.Miller@yrdsb.edu.on.ca>
Thu, 9 Dec 2010 06:53:44 +0000 (01:53 -0500)
committerShao Miller <Shao.Miller@yrdsb.edu.on.ca>
Thu, 9 Dec 2010 16:31:36 +0000 (11:31 -0500)
It's now called driver__bus_fdo_ and is accessible via
driver__bus().  This involved some code shuffling.

Additionally, bus__create_pdo_() has been modified to
actually produce a vanilla bus PDO without hard-coding
the "boot bus" logic into it.

We also adjust bus__module_init() to move the "boot bus"
code out.

This effort is towards modules/drivers creating their
own bus.

src/aoe/driver.c
src/include/bus.h
src/include/driver.h
src/winvblock/bus/bus.c
src/winvblock/driver.c
src/winvblock/filedisk/filedisk.c
src/winvblock/filedisk/grub4dos.c
src/winvblock/ramdisk/grub4dos.c
src/winvblock/ramdisk/memdisk.c

index 92fbfd8..c8f45ba 100644 (file)
@@ -810,7 +810,7 @@ NTSTATUS STDCALL DriverEntry(
       }
   
     {
-      struct bus__type * bus_ptr = bus__boot();
+      struct bus__type * bus_ptr = driver__bus();
       if ( !bus_ptr )
         {
        DBG ( "Unable to register for IOCTLs!\n" );
@@ -917,7 +917,7 @@ static void STDCALL aoe__unload_(IN PDRIVER_OBJECT DriverObject)
     /* Release the global spin-lock. */
     KeReleaseSpinLock ( &aoe__spinlock_, Irql );
     {
-      struct bus__type * bus_ptr = bus__boot();
+      struct bus__type * bus_ptr = driver__bus();
       if ( !bus_ptr )
         {
        DBG ( "Unable to un-register IOCTLs!\n" );
@@ -2096,7 +2096,7 @@ static void aoe__process_abft_(void)
         aoe_disk_ptr->Timeout = 200000;                /* 20 ms. */
         aoe_disk_ptr->disk->BootDrive = TRUE;
         aoe_disk_ptr->disk->media = disk__media_hard;
-        bus__add_child(bus__boot(), aoe_disk_ptr->disk->device);
+        bus__add_child(driver__bus(), aoe_disk_ptr->disk->device);
       }
       else
       {
@@ -2264,7 +2264,7 @@ static NTSTATUS STDCALL mount(
     aoe_disk_ptr->Timeout = 200000;    /* 20 ms. */
     aoe_disk_ptr->disk->BootDrive = FALSE;
     aoe_disk_ptr->disk->media = disk__media_hard;
-    bus__add_child ( bus__boot (  ), aoe_disk_ptr->disk->device );
+    bus__add_child(driver__bus(), aoe_disk_ptr->disk->device);
     Irp->IoStatus.Information = 0;
     *completion_ptr = TRUE;
     return STATUS_SUCCESS;
index 7744731..2d2999b 100644 (file)
@@ -54,7 +54,6 @@ extern winvblock__lib_func winvblock__bool STDCALL bus__add_child(
     IN OUT struct bus__type *,
     IN device__type_ptr
   );
-extern winvblock__lib_func struct bus__type * bus__boot(void);
 extern winvblock__lib_func struct bus__type * bus__get(device__type_ptr);
 
 #endif  /* _BUS_H */
index 10f7986..0e97815 100644 (file)
 
 #define POOLSIZE 2048
 
+/* An unfortunate forward declaration.  Definition resolved in device.h */
+winvblock__def_struct(device__type);
+
 extern PDRIVER_OBJECT driver__obj_ptr;
 extern winvblock__lib_func void STDCALL Driver_CompletePendingIrp(IN PIRP);
 /* Note the exception to the function naming convention. */
 extern winvblock__lib_func NTSTATUS STDCALL Error(IN PCHAR, IN NTSTATUS);
+extern winvblock__lib_func struct bus__type * driver__bus(void);
 /* Note the exception to the function naming convention. */
 extern NTSTATUS STDCALL DriverEntry(
     IN PDRIVER_OBJECT,
     IN PUNICODE_STRING
   );
 
-/* An unfortunate forward declaration.  Definition resolved in device.h */
-winvblock__def_struct(device__type);
-
 /* The physical/function device object's (PDO's/FDO's) DeviceExtension */
 winvblock__def_struct(driver__dev_ext) {
     device__type_ptr device;
index c490e57..694dab8 100644 (file)
@@ -39,7 +39,6 @@
 #include "debug.h"
 
 /* Globals. */
-static PDEVICE_OBJECT bus__boot_fdo_ = NULL;
 static LIST_ENTRY bus__list_;
 static KSPIN_LOCK bus__list_lock_;
 winvblock__bool bus__module_up_ = FALSE;
@@ -52,15 +51,8 @@ static device__create_pdo_func bus__create_pdo_;
  * Tear down the global, bus-common environment.
  */
 void bus__module_shutdown(void) {
-    UNICODE_STRING DosDeviceName;
 
     DBG("Entry\n");
-    RtlInitUnicodeString(
-        &DosDeviceName,
-        L"\\DosDevices\\" winvblock__literal_w
-      );
-    IoDeleteSymbolicLink(&DosDeviceName);
-    bus__boot_fdo_ = NULL;
     bus__module_up_ = FALSE;
     DBG("Exit\n");
     return;
@@ -410,57 +402,69 @@ winvblock__lib_func struct bus__type * bus__create(void) {
 /**
  * Create a bus PDO.
  *
- * @v dev_ptr           Populate PDO dev. ext. space from these details.
- * @ret pdo_ptr         Points to the new PDO, or is NULL upon failure.
+ * @v dev               Populate PDO dev. ext. space from these details.
+ * @ret pdo             Points to the new PDO, or is NULL upon failure.
  *
  * Returns a Physical Device Object pointer on success, NULL for failure.
  */
-static PDEVICE_OBJECT STDCALL bus__create_pdo_(IN device__type_ptr dev_ptr) {
-    PDEVICE_OBJECT pdo_ptr = NULL;
-    struct bus__type * bus_ptr;
+static PDEVICE_OBJECT STDCALL bus__create_pdo_(IN device__type_ptr dev) {
+    PDEVICE_OBJECT pdo = NULL;
+    struct bus__type * bus;
     NTSTATUS status;
 
     /* Note the bus device needing a PDO. */
-    if (dev_ptr == NULL) {
+    if (dev == NULL) {
         DBG("No device passed\n");
         return NULL;
       }
-    bus_ptr = bus__get(dev_ptr);
-    /* Always create the root-enumerated bus device. */
-    IoReportDetectedDevice(
-        driver__obj_ptr,
-        InterfaceTypeUndefined,
-        -1,
-        -1,
-        NULL,
-        NULL,
+    bus = bus__get(dev);
+    /* Create the PDO. */
+    status = IoCreateDevice(
+        dev->DriverObject,
+        sizeof (driver__dev_ext),
+        &bus->dev_name,
+        FILE_DEVICE_CONTROLLER,
+        FILE_DEVICE_SECURE_OPEN,
         FALSE,
-        &pdo_ptr
+        &pdo
       );
-    if (pdo_ptr == NULL) {
-        DBG("IoReportDetectedDevice() went wrong!\n");
-        return NULL;
+    if (pdo == NULL) {
+        DBG("IoCreateDevice() failed!\n");
+        goto err_pdo;
+      }
+    /* DosDevice symlink. */
+    if (bus->named) {
+        status = IoCreateSymbolicLink(
+            &bus->dos_dev_name,
+            &bus->dev_name
+          );
       }
-    /* We have a PDO.  Note it in the bus. */
-    bus_ptr->PhysicalDeviceObject = pdo_ptr;
-    /*
-     * Attach FDO to PDO. *sigh*  Note that we do not own the PDO,
-     * so we must associate the bus structure with the FDO, instead.
-     * Consider that the AddDevice()/attach_fdo() routine takes two parameters,
-     * neither of which are guaranteed to be owned by a caller in this driver.
-     * Since attach_fdo() associates a bus device, it is forced to walk our
-     * global list of bus devices.  Otherwise, it would be easy to pass it here
-     */
-    status = attach_fdo(driver__obj_ptr, pdo_ptr);
     if (!NT_SUCCESS(status)) {
-        DBG("attach_fdo() went wrong!\n");
-        goto err_add_dev;
+        DBG("IoCreateSymbolicLink");
+        goto err_name;
       }
-    return pdo_ptr;
 
-    err_add_dev:
+    /* Set associations for the bus, device, PDO. */
+    device__set(pdo, dev);
+    dev->Self = bus->PhysicalDeviceObject = pdo;
+
+    /* Set some DEVICE_OBJECT status. */
+    pdo->Flags |= DO_DIRECT_IO;         /* FIXME? */
+    pdo->Flags |= DO_POWER_INRUSH;      /* FIXME? */
+    pdo->Flags &= ~DO_DEVICE_INITIALIZING;
+    #ifdef RIS
+    dev->State = Started;
+    #endif
+
+    return pdo;
+
+    err_name:
 
-    IoDeleteDevice(pdo_ptr);
+    IoDeleteDevice(pdo);
+    err_pdo:
+
+    /* Destroy the caller's device! */
+    device__free(dev);
     return NULL;
   }
 
@@ -479,26 +483,6 @@ NTSTATUS bus__module_init(void) {
     driver__obj_ptr->DriverExtension->AddDevice = attach_fdo;
     bus__module_up_ = TRUE;
 
-    /* Establish the boot bus (required for booting from a WinVBlock disk). */
-    boot_bus_ptr = bus__create();
-    if (boot_bus_ptr == NULL)
-      return STATUS_UNSUCCESSFUL;
-    /* In booting, he has a name.  His name is WinVBlock. */
-    RtlInitUnicodeString(
-        &boot_bus_ptr->dev_name,
-        L"\\Device\\" winvblock__literal_w
-      );
-    RtlInitUnicodeString(
-        &boot_bus_ptr->dos_dev_name,
-        L"\\DosDevices\\" winvblock__literal_w
-      );
-    boot_bus_ptr->named = TRUE;
-    /* Create the PDO, which also attaches the FDO *sigh*. */
-    if (bus__create_pdo_(boot_bus_ptr->device) == NULL) {
-        return STATUS_UNSUCCESSFUL;
-      }
-    bus__boot_fdo_ = boot_bus_ptr->device->Self;
-
     return STATUS_SUCCESS;
   }
 
@@ -521,19 +505,6 @@ static void STDCALL bus__free_(IN device__type_ptr dev_ptr) {
     wv_free(bus_ptr);
   }
 
-/**
- * Get a pointer to the boot bus device.
- *
- * @ret         A pointer to the boot bus, or NULL.
- */
-winvblock__lib_func struct bus__type * bus__boot(void) {
-    if (!bus__boot_fdo_) {
-        DBG("No boot bus device!\n");
-        return NULL;
-      }
-    return bus__get(device__get(bus__boot_fdo_));
-  }
-
 /**
  * Get a bus from a device.
  *
index 2946eff..51ce83c 100644 (file)
@@ -49,6 +49,7 @@ PDRIVER_OBJECT driver__obj_ptr = NULL;
 /* Globals. */
 static void * driver__state_handle_;
 static winvblock__bool driver__started_ = FALSE;
+static PDEVICE_OBJECT driver__bus_fdo_ = NULL;
 /* Contains TXTSETUP.SIF/BOOT.INI-style OsLoadOptions parameters. */
 static LPWSTR driver__os_load_opts_ = NULL;
 
@@ -112,6 +113,77 @@ static LPWSTR STDCALL get_opt(IN LPWSTR opt_name) {
     return the_opt;
   }
 
+/* Create the root-enumerated, main bus device. */
+NTSTATUS STDCALL driver__create_bus_(void) {
+    struct bus__type * bus;
+    NTSTATUS status;
+    PDEVICE_OBJECT bus_pdo = NULL;
+
+    bus = bus__create();
+    if (!bus) {
+        DBG("bus__create() failed for the main bus.\n");
+        status = STATUS_INSUFFICIENT_RESOURCES;
+        goto err_bus;
+      }
+    /* In booting, he has a name.  His name is WinVBlock. */
+    RtlInitUnicodeString(
+        &bus->dev_name,
+        L"\\Device\\" winvblock__literal_w
+      );
+    RtlInitUnicodeString(
+        &bus->dos_dev_name,
+        L"\\DosDevices\\" winvblock__literal_w
+      );
+    bus->named = TRUE;
+    /* Create the PDO. */
+    IoReportDetectedDevice(
+        driver__obj_ptr,
+        InterfaceTypeUndefined,
+        -1,
+        -1,
+        NULL,
+        NULL,
+        FALSE,
+        &bus_pdo
+      );
+    if (bus_pdo == NULL) {
+        DBG("IoReportDetectedDevice() went wrong!  Exiting.\n");
+        status = STATUS_UNSUCCESSFUL;
+        goto err_driver_bus;
+      }
+    /* We have a PDO.  Note it.  We need this in order to attach the FDO. */
+    bus->PhysicalDeviceObject = bus_pdo;
+    /*
+     * Attach FDO to PDO. *sigh*  Note that we do not own the PDO,
+     * so we must associate the bus structure with the FDO, instead.
+     * Consider that the AddDevice()/attach_fdo() routine takes two parameters,
+     * neither of which are guaranteed to be owned by a caller in this driver.
+     * Since attach_fdo() associates a bus device, it is forced to walk our
+     * global list of bus devices.  Otherwise, it would be easy to pass it here
+     */
+    status = driver__obj_ptr->DriverExtension->AddDevice(
+        driver__obj_ptr,
+        bus_pdo
+      );
+    if (!NT_SUCCESS(status)) {
+        DBG("attach_fdo() went wrong!\n");
+        goto err_add_dev;
+      }
+    /* Bus created, PDO created, FDO attached.  All done. */
+    driver__bus_fdo_ = bus->device->Self;
+    return STATUS_SUCCESS;
+
+    err_add_dev:
+
+    IoDeleteDevice(bus_pdo);
+    err_driver_bus:
+
+    device__free(bus->device);
+    err_bus:
+
+    return status;
+  }
+
 /*
  * Note the exception to the function naming convention.
  * TODO: See if a Makefile change is good enough.
@@ -166,9 +238,23 @@ NTSTATUS STDCALL DriverEntry(
     filedisk__init();           /* TODO: Check for error. */
     ramdisk__init();            /* TODO: Check for error. */
 
+    /*
+     * Always create the root-enumerated, main bus device.
+     * This is required in order to boot from a WinVBlock disk.
+     */
+    status = driver__create_bus_();
+    if(!NT_SUCCESS(status))
+      goto err_bus;
+
     driver__started_ = TRUE;
     DBG("Exit\n");
     return STATUS_SUCCESS;
+
+    err_bus:
+
+    driver__unload_(DriverObject);
+    DBG("Exit due to failure\n");
+    return status;
   }
 
 static NTSTATUS STDCALL driver__dispatch_not_supported_(
@@ -299,8 +385,17 @@ winvblock__lib_func NTSTATUS STDCALL driver__default_dispatch(
   }
 
 static void STDCALL driver__unload_(IN PDRIVER_OBJECT DriverObject) {
+    UNICODE_STRING DosDeviceName;
+
+    DBG("Unloading...\n");
     if (driver__state_handle_ != NULL)
       PoUnregisterSystemState(driver__state_handle_);
+    RtlInitUnicodeString(
+        &DosDeviceName,
+        L"\\DosDevices\\" winvblock__literal_w
+      );
+    IoDeleteSymbolicLink(&DosDeviceName);
+    driver__bus_fdo_ = NULL;
     bus__module_shutdown();
     wv_free(driver__os_load_opts_);
     driver__started_ = FALSE;
@@ -322,3 +417,16 @@ winvblock__lib_func NTSTATUS STDCALL Error(
     DBG("%s: 0x%08x\n", Message, Status);
     return Status;
   }
+
+/**
+ * Get a pointer to the driver bus device.
+ *
+ * @ret         A pointer to the driver bus, or NULL.
+ */
+winvblock__lib_func struct bus__type * driver__bus(void) {
+    if (!driver__bus_fdo_) {
+        DBG("No driver bus device!\n");
+        return NULL;
+      }
+    return bus__get(device__get(driver__bus_fdo_));
+  }
index dc4a825..064e716 100644 (file)
@@ -224,7 +224,7 @@ NTSTATUS STDCALL filedisk__attach(
   /*
    * FIXME: Check for error below!
    */
-  bus__add_child ( bus__boot (  ), filedisk_ptr->disk->device );
+  bus__add_child(driver__bus(), filedisk_ptr->disk->device);
   return STATUS_SUCCESS;
 
 err_query_info:
index 20e5546..137994d 100644 (file)
@@ -493,7 +493,7 @@ filedisk_grub4dos__find (
            Grub4DosDriveMapSlotPtr[i].SourceDrive;
          filedisk_ptr->disk->BootDrive = TRUE;
          FoundGrub4DosMapping = TRUE;
-         bus__add_child ( bus__boot (  ), filedisk_ptr->disk->device );
+         bus__add_child(driver__bus(), filedisk_ptr->disk->device);
        }
       InterruptVector = &SafeMbrHookPtr->PrevHook;
     }
index d84997a..a2b567b 100644 (file)
@@ -146,7 +146,7 @@ ramdisk_grub4dos__find (
                                               ramdisk_ptr->disk->Sectors );
          ramdisk_ptr->disk->BootDrive = TRUE;
          FoundGrub4DosMapping = TRUE;
-         bus__add_child ( bus__boot (  ), ramdisk_ptr->disk->device );
+         bus__add_child(driver__bus(), ramdisk_ptr->disk->device);
        }
       InterruptVector = &SafeMbrHookPtr->PrevHook;
     }
index 3b57207..48a40a6 100644 (file)
@@ -110,7 +110,7 @@ check_mbft (
   ramdisk_ptr->disk->Heads = mBFT->mdi.heads;
   ramdisk_ptr->disk->Sectors = mBFT->mdi.sectors;
   ramdisk_ptr->disk->BootDrive = TRUE;
-  bus__add_child ( bus__boot (  ), ramdisk_ptr->disk->device );
+  bus__add_child(driver__bus(), ramdisk_ptr->disk->device);
   AssociatedHook->Flags = 1;
   return TRUE;
 }