[bus] Create boot bus here, introduce init function
authorShao Miller <Shao.Miller@yrdsb.edu.on.ca>
Thu, 20 May 2010 20:19:28 +0000 (16:19 -0400)
committerShao Miller <Shao.Miller@yrdsb.edu.on.ca>
Thu, 20 May 2010 20:53:38 +0000 (16:53 -0400)
The bus module is now responsible for creation of bus PDOs,
such as the boot bus which exposes WinVBlock-supported boot
disks.  We now have bus__init() and bus__finalize() funcs
which are called by the driver module.

We also mimic the device module by having a bus__create()
function, though it is currently unused, also like the
device__create() function.

src/include/bus.h
src/include/device.h
src/winvblock/bus/bus.c
src/winvblock/disk/disk.c
src/winvblock/driver.c

index d09eb85..756caad 100644 (file)
@@ -36,20 +36,42 @@ winvblock__def_struct ( bus__type )
   winvblock__uint32 Children;
   winvblock__uint8_ptr first_child_ptr;
   KSPIN_LOCK SpinLock;
+  LIST_ENTRY tracking;
 };
 
-extern void Bus_Stop (
+extern NTSTATUS STDCALL Bus_GetDeviceCapabilities (
+  IN PDEVICE_OBJECT DeviceObject,
+  IN PDEVICE_CAPABILITIES DeviceCapabilities
+ );
+
+/**
+ * Initialize the global, bus-common environment
+ *
+ * @ret ntstatus        STATUS_SUCCESS or the NTSTATUS for a failure
+ */
+extern STDCALL NTSTATUS bus__init (
   void
  );
 
-extern NTSTATUS STDCALL Bus_AddDevice (
-  IN PDRIVER_OBJECT DriverObject,
-  IN PDEVICE_OBJECT PhysicalDeviceObject
+/**
+ * Tear down the global, bus-common environment
+ */
+extern void bus__finalize (
+  void
  );
 
-extern NTSTATUS STDCALL Bus_GetDeviceCapabilities (
-  IN PDEVICE_OBJECT DeviceObject,
-  IN PDEVICE_CAPABILITIES DeviceCapabilities
+/**
+ * Create a new bus
+ *
+ * @ret bus_ptr         The address of a new bus, or NULL for failure
+ *
+ * This function should not be confused with a PDO creation routine, which is
+ * actually implemented for each device type.  This routine will allocate a
+ * bus__type, track it in a global list, as well as populate the bus
+ * with default values.
+ */
+extern winvblock__lib_func STDCALL bus__type_ptr bus__create (
+  void
  );
 
 /**
index de60f9a..b21b0c1 100644 (file)
@@ -49,6 +49,7 @@ winvblock__def_struct ( device__type );
  * Device PDO creation routine
  *
  * @v dev_ptr           The device whose PDO should be created
+ * @ret pdo_ptr         Points to the new PDO, or is NULL upon failure
  */
 #  define device__create_pdo_decl( x ) \
 \
index 8fd2e3c..bbc7c0c 100644 (file)
 #include "bus_dev_ctl.h"
 #include "debug.h"
 
-PDEVICE_OBJECT bus_fdo = NULL;
+static PDEVICE_OBJECT bus_fdo = NULL;
+static LIST_ENTRY bus_list;
+static KSPIN_LOCK bus_list_lock;
 
+/**
+ * Tear down the global, bus-common environment
+ */
 void
-Bus_Stop (
+bus__finalize (
   void
  )
 {
@@ -226,8 +231,8 @@ Bus_GetDeviceCapabilities (
   return status;
 }
 
-NTSTATUS STDCALL
-Bus_AddDevice (
+static NTSTATUS STDCALL
+attach_fdo (
   IN PDRIVER_OBJECT DriverObject,
   IN PDEVICE_OBJECT PhysicalDeviceObject
  )
@@ -312,6 +317,116 @@ Bus_AddDevice (
   return STATUS_SUCCESS;
 }
 
+/**
+ * Create a new bus
+ *
+ * @ret bus_ptr         The address of a new bus, or NULL for failure
+ *
+ * See the header file for additional details
+ */
+winvblock__lib_func STDCALL bus__type_ptr
+bus__create (
+  void
+ )
+{
+  bus__type_ptr bus_ptr;
+
+  /*
+   * Bus devices might be used for booting and should
+   * not be allocated from a paged memory pool
+   */
+  bus_ptr = ExAllocatePool ( NonPagedPool, sizeof ( device__type ) );
+  if ( bus_ptr == NULL )
+    goto err_nomem;
+  RtlZeroMemory ( bus_ptr, sizeof ( bus__type ) );
+  /*
+   * Track the new device in our global list
+   */
+  ExInterlockedInsertTailList ( &bus_list, &bus_ptr->tracking,
+                               &bus_list_lock );
+  /*
+   * TODO: Populate non-zero device defaults
+   */
+  /*
+   * TODO: Register the default driver IRP handling table
+   */
+
+err_nomem:
+
+  return bus_ptr;
+}
+
+/**
+ * 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
+ *
+ * Returns a Physical Device Object pointer on success, NULL for failure.
+ */
+static
+device__create_pdo_decl (
+  create_pdo
+ )
+{
+  PDEVICE_OBJECT pdo_ptr = NULL;
+  NTSTATUS status;
+
+  /*
+   * Always create the root-enumerated bus device 
+   */
+  IoReportDetectedDevice ( driver__obj_ptr, InterfaceTypeUndefined, -1, -1,
+                          NULL, NULL, FALSE, &pdo_ptr );
+  if ( pdo_ptr == NULL )
+    {
+      DBG ( "IoReportDetectedDevice() went wrong!\n" );
+      return NULL;
+    }
+  /*
+   * Attach FDO to PDO *sigh*
+   */
+  status = attach_fdo ( driver__obj_ptr, pdo_ptr );
+  if ( !NT_SUCCESS ( status ) )
+    {
+      DBG ( "Bus_AddDevice() went wrong!\n" );
+      goto err_add_dev;
+    }
+  return pdo_ptr;
+
+err_add_dev:
+
+  IoDeleteDevice ( pdo_ptr );
+  return NULL;
+}
+
+/**
+ * Initialize the global, bus-common environment
+ *
+ * @ret ntstatus        STATUS_SUCCESS or the NTSTATUS for a failure
+ */
+extern STDCALL NTSTATUS
+bus__init (
+  void
+ )
+{
+  /*
+   * Initialize the global list of devices
+   */
+  InitializeListHead ( &bus_list );
+  KeInitializeSpinLock ( &bus_list_lock );
+  /*
+   * We handle AddDevice call-backs for the driver
+   */
+  driver__obj_ptr->DriverExtension->AddDevice = attach_fdo;
+  /*
+   * Establish the boot bus (required for booting from a WinVBlock disk)
+   */
+  if ( create_pdo ( NULL ) == NULL )   /* TODO: Pass a bus */
+    return STATUS_UNSUCCESSFUL;
+
+  return STATUS_SUCCESS;
+}
+
 /**
  * Get a pointer to the bus device's extension space
  *
index 6ac5acf..07e01e3 100644 (file)
@@ -144,6 +144,7 @@ static irp__handling handling_table[] = {
  * Create a disk PDO filled with the given disk parameters
  *
  * @v dev_ptr           Populate PDO dev. ext. space from these details
+ * @ret dev_obj_ptr     Points to the new PDO, or is NULL upon failure
  *
  * Returns a Physical Device Object pointer on success, NULL for failure.
  */
index a4ec74a..b888e55 100644 (file)
@@ -147,9 +147,8 @@ DriverEntry (
   IN PUNICODE_STRING RegistryPath
  )
 {
-  NTSTATUS Status;
+  NTSTATUS status;
   int i;
-  PDEVICE_OBJECT bus_pdo_ptr = NULL;
 
   DBG ( "Entry\n" );
   if ( driver__obj_ptr )
@@ -161,8 +160,9 @@ DriverEntry (
   if ( Driver_Globals_Started )
     return STATUS_SUCCESS;
   Debug_Initialize (  );
-  if ( !NT_SUCCESS ( Status = registry__note_os_load_opts ( &os_load_opts ) ) )
-    return Error ( "registry__note_os_load_opts", Status );
+  status = registry__note_os_load_opts ( &os_load_opts );
+  if ( !NT_SUCCESS ( status ) )
+    return Error ( "registry__note_os_load_opts", status );
 
   Driver_Globals_StateHandle = NULL;
 
@@ -171,10 +171,6 @@ DriverEntry (
     {
       DBG ( "Could not set system state to ES_CONTINUOUS!!\n" );
     }
-  /*
-   * Initialize various modules
-   */
-  device__init (  );           /* TODO: Check for error */
   /*
    * Set up IRP MajorFunction function table for devices
    * this driver handles
@@ -189,20 +185,14 @@ DriverEntry (
   DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Driver_Dispatch;
   DriverObject->MajorFunction[IRP_MJ_SCSI] = Driver_Dispatch;
   /*
-   * Other functions this driver handles
+   * Set the driver Unload callback
    */
-  DriverObject->DriverExtension->AddDevice = Bus_AddDevice;
   DriverObject->DriverUnload = Driver_Unload;
-
   /*
-   * Always create the root-enumerated bus device 
+   * Initialize various modules
    */
-  IoReportDetectedDevice ( DriverObject, InterfaceTypeUndefined, -1, -1, NULL,
-                          NULL, FALSE, &bus_pdo_ptr );
-  if ( !NT_SUCCESS ( Status = Bus_AddDevice ( DriverObject, bus_pdo_ptr ) ) )
-    {
-      return Error ( "Bus_AddDevice", Status );
-    }
+  device__init (  );           /* TODO: Check for error */
+  bus__init (  );              /* TODO: Check for error */
 
   Driver_Globals_Started = TRUE;
   DBG ( "Exit\n" );
@@ -313,7 +303,7 @@ Driver_Unload (
 {
   if ( Driver_Globals_StateHandle != NULL )
     PoUnregisterSystemState ( Driver_Globals_StateHandle );
-  Bus_Stop (  );
+  bus__finalize (  );
   ExFreePool ( os_load_opts );
   Driver_Globals_Started = FALSE;
   DBG ( "Done\n" );