[device] Make room for threaded devices
authorShao Miller <Shao.Miller@yrdsb.edu.on.ca>
Thu, 2 Dec 2010 15:06:07 +0000 (10:06 -0500)
committerShao Miller <Shao.Miller@yrdsb.edu.on.ca>
Thu, 2 Dec 2010 15:06:07 +0000 (10:06 -0500)
After thinking about a "handler" scheme for devices which
implement various "interfaces," it looked like it'd be
better to implement threading for devices first and to find
out if that would do.

We make space for queuing IRPs and for a thread wakeup signal.

We also replace a lonely ExFreePool() that was missed in a
previous commit with wv_free().

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

index d4bdae7..53795ee 100644 (file)
@@ -177,10 +177,20 @@ winvblock__def_struct ( device__ops )
   device__free_routine free;
 };
 
+typedef void STDCALL (device__thread_func)(IN void *);
+
 /* Details common to all devices this driver works with */
 struct _device__type
 {
   winvblock__bool IsBus;       /* For debugging */
+  /* The device's thread routine. */
+  device__thread_func * (thread);
+  /* The device's thread wakeup signal. */
+  KEVENT (thread_wakeup);
+  /* The device's IRP queue. */
+  LIST_ENTRY (irp_list);
+  /* The device's IRP queue lock. */
+  KSPIN_LOCK (irp_list_lock);
   PDEVICE_OBJECT Self;
   PDEVICE_OBJECT Parent;
   PDRIVER_OBJECT DriverObject;
index 5542244..dcd05bc 100644 (file)
@@ -189,5 +189,5 @@ device__free_decl (
    */
   ExInterlockedRemoveHeadList ( dev_ptr->tracking.Blink, &dev_list_lock );
 
-  ExFreePool ( dev_ptr );
+  wv_free(dev_ptr);
 }
index a14321a..7104f1f 100644 (file)
@@ -288,7 +288,19 @@ Driver_Dispatch (
       return STATUS_NO_SUCH_DEVICE;
     }
 
-  status = irp__process ( DeviceObject, Irp, Stack, dev_ptr, &completion );
+  /* Enqueue the IRP for threaded devices, or process immediately. */
+  if (dev_ptr->thread) {
+      IoMarkIrpPending(Irp);
+      ExInterlockedInsertTailList(
+          &dev_ptr->irp_list,
+          /* Where IRPs can be linked. */
+          &Irp->Tail.Overlay.ListEntry,
+          &dev_ptr->irp_list_lock
+        );
+      KeSetEvent(&dev_ptr->thread_wakeup, 0, FALSE);
+      status = STATUS_PENDING;
+    } else
+      status = irp__process(DeviceObject, Irp, Stack, dev_ptr, &completion);
 
 #ifdef DEBUGIRPS
   if ( status != STATUS_PENDING )