[device,bus] Further develop device routines
authorShao Miller <Shao.Miller@yrdsb.edu.on.ca>
Fri, 21 May 2010 03:12:12 +0000 (23:12 -0400)
committerShao Miller <Shao.Miller@yrdsb.edu.on.ca>
Fri, 21 May 2010 03:12:12 +0000 (23:12 -0400)
Much of it unused for now, but eventually (seems like it's
always eventually) each device type will create an instance
of a type it would like to derive from, then overrides
whatever operations it wants to.  When the device is asked
to perform operations, it should either have sensible, do-
nothing defaults or meaningful device-specific operations.

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

index 96feff3..c73290c 100644 (file)
@@ -806,7 +806,7 @@ DriverEntry (
     }
 
   {
-    bus__type_ptr bus_ptr = bus__dev (  );
+    bus__type_ptr bus_ptr = bus__boot (  );
     if ( !bus_ptr )
       {
        DBG ( "Unable to register for IOCTLs!\n" );
@@ -940,7 +940,7 @@ unload (
    */
   KeReleaseSpinLock ( &AoE_Globals_SpinLock, Irql );
   {
-    bus__type_ptr bus_ptr = bus__dev (  );
+    bus__type_ptr bus_ptr = bus__boot (  );
     if ( !bus_ptr )
       {
        DBG ( "Unable to un-register IOCTLs!\n" );
index 756caad..f1272c2 100644 (file)
@@ -18,8 +18,8 @@
  * You should have received a copy of the GNU General Public License
  * along with WinVBlock.  If not, see <http://www.gnu.org/licenses/>.
  */
-#ifndef _BUS_H
-#  define _BUS_H
+#ifndef _bus_h
+#  define _bus_h
 
 /**
  * @file
@@ -37,6 +37,8 @@ winvblock__def_struct ( bus__type )
   winvblock__uint8_ptr first_child_ptr;
   KSPIN_LOCK SpinLock;
   LIST_ENTRY tracking;
+  winvblock__any_ptr ext;
+  device__free_routine prev_free;
 };
 
 extern NTSTATUS STDCALL Bus_GetDeviceCapabilities (
@@ -70,7 +72,7 @@ extern void bus__finalize (
  * 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 (
+extern winvblock__lib_func bus__type_ptr bus__create (
   void
  );
 
@@ -90,7 +92,7 @@ extern winvblock__lib_func winvblock__bool STDCALL bus__add_child (
  *
  * @ret         A pointer to the bus device's extension space, or NULL
  */
-extern winvblock__lib_func bus__type_ptr STDCALL bus__dev (
+extern winvblock__lib_func bus__type_ptr bus__boot (
   void
  );
 
@@ -102,4 +104,4 @@ extern winvblock__lib_func bus__type_ptr STDCALL bus__dev (
 #  define get_bus_ptr( dev_ptr ) \
   ( ( bus__type_ptr ) dev_ptr )
 
-#endif                         /* _BUS_H */
+#endif                         /* _bus_h */
index b21b0c1..3ddd1b8 100644 (file)
@@ -64,6 +64,14 @@ x ( \
 typedef device__create_pdo_decl (
    ( *device__create_pdo_routine )
  );
+/**
+ * Create a device PDO
+ *
+ * @v dev_ptr           Points to the device that needs a PDO
+ */
+extern winvblock__lib_func device__create_pdo_decl (
+  device__create_pdo
+ );
 
 /**
  * Device initialization routine
@@ -103,6 +111,33 @@ typedef device__close_decl (
    ( *device__close_routine )
  );
 
+/**
+ * Device deletion routine
+ *
+ * @v dev_ptr           Points to the device to delete
+ */
+#  define device__free_decl( x ) \
+\
+void STDCALL \
+x ( \
+  IN device__type_ptr dev_ptr \
+ )
+/*
+ * Function pointer for a device close routine.
+ * 'indent' mangles this, so it looks weird
+ */
+typedef device__free_decl (
+   ( *device__free_routine )
+ );
+/**
+ * Delete a device
+ *
+ * @v dev_ptr           Points to the device to delete
+ */
+extern winvblock__lib_func STDCALL void device__free (
+  device__type_ptr dev_ptr
+ );
+
 /**
  * Initialize the global, device-common environment
  *
@@ -122,7 +157,7 @@ extern STDCALL NTSTATUS device__init (
  * device__type, track it in a global list, as well as populate the device
  * with default values.
  */
-extern winvblock__lib_func STDCALL device__type_ptr device__create (
+extern winvblock__lib_func device__type_ptr device__create (
   void
  );
 
@@ -131,6 +166,7 @@ winvblock__def_struct ( device__ops )
   device__create_pdo_routine create_pdo;
   device__init_routine init;
   device__close_routine close;
+  device__free_routine free;
 };
 
 /* Details common to all devices this driver works with */
@@ -147,6 +183,7 @@ struct _device__type
   device__type_ptr next_sibling_ptr;
   device__ops ops;
   LIST_ENTRY tracking;
+  winvblock__any_ptr ext;
 };
 
 #endif                         /* _device_h */
index bbc7c0c..8f2b7ae 100644 (file)
 #include "bus_dev_ctl.h"
 #include "debug.h"
 
-static PDEVICE_OBJECT bus_fdo = NULL;
+static PDEVICE_OBJECT boot_bus_fdo = NULL;
 static LIST_ENTRY bus_list;
 static KSPIN_LOCK bus_list_lock;
+/* Forward declaration */
+static device__free_decl (
+  free_bus
+ );
 
 /**
  * Tear down the global, bus-common environment
@@ -56,7 +60,7 @@ bus__finalize (
   RtlInitUnicodeString ( &DosDeviceName,
                         L"\\DosDevices\\" winvblock__literal_w );
   IoDeleteSymbolicLink ( &DosDeviceName );
-  bus_fdo = NULL;
+  boot_bus_fdo = NULL;
   DBG ( "Exit\n" );
 }
 
@@ -82,7 +86,7 @@ bus__add_child (
   device__type_ptr walker;
 
   DBG ( "Entry\n" );
-  if ( !bus_fdo )
+  if ( !boot_bus_fdo )
     {
       DBG ( "No bus device!\n" );
       return FALSE;
@@ -90,12 +94,12 @@ bus__add_child (
   /*
    * Establish a pointer to the bus
    */
-  bus_ptr = get_bus_ptr ( bus_fdo->DeviceExtension );
+  bus_ptr = get_bus_ptr ( boot_bus_fdo->DeviceExtension );
   /*
    * Create the child device
    */
-  dev_obj_ptr = dev_ptr->ops.create_pdo ( dev_ptr );
-  if ( !dev_obj_ptr )
+  dev_obj_ptr = device__create_pdo ( dev_ptr );
+  if ( dev_obj_ptr == NULL )
     {
       DBG ( "bus__add_child() failed!\n" );
       return FALSE;
@@ -106,7 +110,7 @@ bus__add_child (
    * extension space.  We don't need the original details anymore
    */
   dev_ptr = dev_obj_ptr->DeviceExtension;
-  dev_ptr->Parent = bus_fdo;
+  dev_ptr->Parent = boot_bus_fdo;
   dev_ptr->next_sibling_ptr = NULL;
   /*
    * Initialize the device.  For disks, this routine is responsible for
@@ -244,7 +248,7 @@ attach_fdo (
   bus__type_ptr bus_ptr;
 
   DBG ( "Entry\n" );
-  if ( bus_fdo )
+  if ( boot_bus_fdo )
     return STATUS_SUCCESS;
   RtlInitUnicodeString ( &DeviceName, L"\\Device\\" winvblock__literal_w );
   RtlInitUnicodeString ( &DosDeviceName,
@@ -252,7 +256,7 @@ attach_fdo (
   Status =
     IoCreateDevice ( DriverObject, sizeof ( bus__type ), &DeviceName,
                     FILE_DEVICE_CONTROLLER, FILE_DEVICE_SECURE_OPEN, FALSE,
-                    &bus_fdo );
+                    &boot_bus_fdo );
   if ( !NT_SUCCESS ( Status ) )
     {
       return Error ( "Bus_AddDevice IoCreateDevice", Status );
@@ -260,19 +264,19 @@ attach_fdo (
   Status = IoCreateSymbolicLink ( &DosDeviceName, &DeviceName );
   if ( !NT_SUCCESS ( Status ) )
     {
-      IoDeleteDevice ( bus_fdo );
+      IoDeleteDevice ( boot_bus_fdo );
       return Error ( "Bus_AddDevice IoCreateSymbolicLink", Status );
     }
 
   /*
    * Set some default parameters for a bus
    */
-  bus_dev_ptr = ( device__type_ptr ) bus_fdo->DeviceExtension;
+  bus_dev_ptr = ( device__type_ptr ) boot_bus_fdo->DeviceExtension;
   RtlZeroMemory ( bus_dev_ptr, sizeof ( bus__type ) );
   bus_dev_ptr->IsBus = TRUE;
   bus_dev_ptr->size = sizeof ( bus__type );
   bus_dev_ptr->DriverObject = DriverObject;
-  bus_dev_ptr->Self = bus_fdo;
+  bus_dev_ptr->Self = boot_bus_fdo;
   bus_dev_ptr->State = NotStarted;
   bus_dev_ptr->OldState = NotStarted;
   /*
@@ -292,24 +296,24 @@ attach_fdo (
   bus_ptr->Children = 0;
   bus_ptr->first_child_ptr = NULL;
   KeInitializeSpinLock ( &bus_ptr->SpinLock );
-  bus_fdo->Flags |= DO_DIRECT_IO;      /* FIXME? */
-  bus_fdo->Flags |= DO_POWER_INRUSH;   /* FIXME? */
+  boot_bus_fdo->Flags |= DO_DIRECT_IO; /* FIXME? */
+  boot_bus_fdo->Flags |= DO_POWER_INRUSH;      /* FIXME? */
   /*
    * Add the bus to the device tree
    */
   if ( PhysicalDeviceObject != NULL )
     {
       bus_ptr->LowerDeviceObject =
-       IoAttachDeviceToDeviceStack ( bus_fdo, PhysicalDeviceObject );
+       IoAttachDeviceToDeviceStack ( boot_bus_fdo, PhysicalDeviceObject );
       if ( bus_ptr->LowerDeviceObject == NULL )
        {
-         IoDeleteDevice ( bus_fdo );
-         bus_fdo = NULL;
+         IoDeleteDevice ( boot_bus_fdo );
+         boot_bus_fdo = NULL;
          return Error ( "AddDevice IoAttachDeviceToDeviceStack",
                         STATUS_NO_SUCH_DEVICE );
        }
     }
-  bus_fdo->Flags &= ~DO_DEVICE_INITIALIZING;
+  boot_bus_fdo->Flags &= ~DO_DEVICE_INITIALIZING;
 #ifdef RIS
   bus_dev_ptr->State = Started;
 #endif
@@ -324,20 +328,27 @@ attach_fdo (
  *
  * See the header file for additional details
  */
-winvblock__lib_func STDCALL bus__type_ptr
+winvblock__lib_func bus__type_ptr
 bus__create (
   void
  )
 {
+  device__type_ptr dev_ptr;
   bus__type_ptr bus_ptr;
 
+  /*
+   * Try to create a device
+   */
+  dev_ptr = device__create (  );
+  if ( dev_ptr == NULL )
+    goto err_nodev;
   /*
    * Bus devices might be used for booting and should
    * not be allocated from a paged memory pool
    */
-  bus_ptr = ExAllocatePool ( NonPagedPool, sizeof ( device__type ) );
+  bus_ptr = ExAllocatePool ( NonPagedPool, sizeof ( bus__type ) );
   if ( bus_ptr == NULL )
-    goto err_nomem;
+    goto err_nobus;
   RtlZeroMemory ( bus_ptr, sizeof ( bus__type ) );
   /*
    * Track the new device in our global list
@@ -345,15 +356,24 @@ bus__create (
   ExInterlockedInsertTailList ( &bus_list, &bus_ptr->tracking,
                                &bus_list_lock );
   /*
-   * TODO: Populate non-zero device defaults
+   * Populate non-zero device defaults
    */
+  bus_ptr->prev_free = dev_ptr->ops.free;
+  dev_ptr->ops.free = free_bus;
+  dev_ptr->ext = bus_ptr;
   /*
-   * TODO: Register the default driver IRP handling table
+   * Register the default bus IRP handling table
    */
-
-err_nomem:
+  irp__reg_table ( &dev_ptr->irp_handler_chain, handling_table );
 
   return bus_ptr;
+
+err_nobus:
+
+  device__free ( dev_ptr );
+err_nodev:
+
+  return NULL;
 }
 
 /**
@@ -427,20 +447,49 @@ bus__init (
   return STATUS_SUCCESS;
 }
 
+/**
+ * Default bus deletion operation
+ *
+ * @v dev_ptr           Points to the bus device to delete
+ */
+static
+device__free_decl (
+  free_bus
+ )
+{
+  bus__type_ptr bus_ptr = ( bus__type_ptr ) dev_ptr->ext;
+  /*
+   * Un-register the default driver IRP handling table
+   */
+  irp__unreg_table ( &dev_ptr->irp_handler_chain, handling_table );
+  /*
+   * Free the "inherited class"
+   */
+  bus_ptr->prev_free ( dev_ptr );
+  /*
+   * Track the bus deletion in our global list.  Unfortunately,
+   * for now we have faith that a bus won't be deleted twice and
+   * result in a race condition.  Something to keep in mind...
+   */
+  ExInterlockedRemoveHeadList ( bus_ptr->tracking.Blink, &bus_list_lock );
+
+  ExFreePool ( bus_ptr );
+}
+
 /**
  * Get a pointer to the bus device's extension space
  *
  * @ret         A pointer to the bus device's extension space, or NULL
  */
-winvblock__lib_func bus__type_ptr STDCALL
-bus__dev (
+winvblock__lib_func bus__type_ptr
+bus__boot (
   void
  )
 {
-  if ( !bus_fdo )
+  if ( !boot_bus_fdo )
     {
-      DBG ( "No bus device!\n" );
+      DBG ( "No boot bus device!\n" );
       return NULL;
     }
-  return get_bus_ptr ( bus_fdo->DeviceExtension );
+  return get_bus_ptr ( boot_bus_fdo->DeviceExtension );
 }
index 379d9f1..ff9484b 100644 (file)
 #include "irp.h"
 #include "device.h"
 #include "driver.h"
+#include "debug.h"
 
 static LIST_ENTRY dev_list;
 static KSPIN_LOCK dev_list_lock;
+/* Forward declarations */
+static device__free_decl (
+  free_dev
+ );
+static device__create_pdo_decl (
+  make_dev_pdo
+ );
 
 /**
  * Initialize the global, device-common environment
@@ -63,7 +71,7 @@ device__init (
  *
  * See the header file for additional details
  */
-winvblock__lib_func STDCALL device__type_ptr
+winvblock__lib_func device__type_ptr
 device__create (
   void
  )
@@ -76,7 +84,7 @@ device__create (
    */
   dev_ptr = ExAllocatePool ( NonPagedPool, sizeof ( device__type ) );
   if ( dev_ptr == NULL )
-    goto err_nomem;
+    return NULL;
   RtlZeroMemory ( dev_ptr, sizeof ( device__type ) );
   /*
    * Track the new device in our global list
@@ -88,13 +96,83 @@ device__create (
    */
   dev_ptr->size = sizeof ( device__type );
   dev_ptr->DriverObject = driver__obj_ptr;
+  dev_ptr->ops.create_pdo = make_dev_pdo;
+  dev_ptr->ops.free = free_dev;
   /*
    * Register the default driver IRP handling table
    */
   irp__reg_table_s ( &dev_ptr->irp_handler_chain, driver__handling_table,
                     driver__handling_table_size );
 
-err_nomem:
-
   return dev_ptr;
 }
+
+/**
+ * Create a device PDO
+ *
+ * @v dev_ptr           Points to the device that needs a PDO
+ */
+winvblock__lib_func
+device__create_pdo_decl (
+  device__create_pdo
+ )
+{
+  return dev_ptr->ops.create_pdo ( dev_ptr );
+}
+
+/**
+ * Default PDO creation operation
+ *
+ * @v dev_ptr           Points to the device that needs a PDO
+ *
+ * This function does nothing, since it doesn't make sense to create a PDO
+ * for an unknown type of device.
+ */
+static
+device__create_pdo_decl (
+  make_dev_pdo
+ )
+{
+  DBG ( "No specific PDO creation operation for this device!\n" );
+  return NULL;
+}
+
+/**
+ * Delete a device
+ *
+ * @v dev_ptr           Points to the device to delete
+ */
+winvblock__lib_func STDCALL void
+device__free (
+  device__type_ptr dev_ptr
+ )
+{
+  /*
+   * Call the device's free routine
+   */
+  dev_ptr->ops.free ( dev_ptr );
+}
+
+/**
+ * Default device deletion operation
+ *
+ * @v dev_ptr           Points to the device to delete
+ */
+static
+device__free_decl (
+  free_dev
+ )
+{
+  /*
+   * Un-register the default driver IRP handling table
+   */
+  irp__unreg_table ( &dev_ptr->irp_handler_chain, driver__handling_table );
+  /*
+   * Track the device deletion in our global list.  Unfortunately,
+   * for now we have faith that a device won't be deleted twice and
+   * result in a race condition.  Something to keep in mind...
+   */
+  ExInterlockedRemoveHeadList ( dev_ptr->tracking.Blink, &dev_list_lock );
+
+  ExFreePool ( dev_ptr );
+}