[bus/pnp,disk/pnp,aoe] Get AoE sub-bus to work
authorShao Miller <Shao.Miller@yrdsb.edu.on.ca>
Tue, 14 Dec 2010 05:19:48 +0000 (00:19 -0500)
committerShao Miller <Shao.Miller@yrdsb.edu.on.ca>
Tue, 14 Dec 2010 05:19:48 +0000 (00:19 -0500)
Added some debugging messages to bus/pnp.c and disk/pnp.c.

Added a few PnP routines to bus/pnp.c.

Fixed a bug in aoe/bus.c where a hardware ID string was not
properly terminated.

Changed the IDs reported in aoe/bus.c.

A little note: The main WinVBlock bus might be better off
creating/deleting PDOs in its own thread context.

src/aoe/bus.c
src/winvblock/bus/pnp.c
src/winvblock/disk/pnp.c

index cb1a2d5..ccf2bdb 100644 (file)
@@ -149,16 +149,16 @@ static winvblock__uint32 STDCALL aoe_bus__pnp_id_(
   ) {
     switch (query_type) {
         case BusQueryDeviceID:
-          return swprintf(*buf, L"WinVBlock\\AoEDEVID") + 1;
+          return swprintf(*buf, winvblock__literal_w L"\\AoE") + 1;
 
         case BusQueryInstanceID:
-          return swprintf(*buf, L"WinVBlock\\AoEINSTID") + 1;
+          return swprintf(*buf, L"0") + 1;
 
         case BusQueryHardwareIDs:
-          return swprintf(*buf, L"WinVBlock\\AoEHWID") + 1;
+          return swprintf(*buf, winvblock__literal_w L"\\AoE") + 2;
 
         case BusQueryCompatibleIDs:
-          return swprintf(*buf, L"WinVBlock\\AoECOMPATID") + 4;
+          return swprintf(*buf, winvblock__literal_w L"\\AoE") + 4;
 
         default:
           return 0;
index da974a1..6b0b99c 100644 (file)
@@ -25,7 +25,9 @@
  * Bus PnP IRP handling.
  */
 
+#include <stdio.h>
 #include <ntddk.h>
+#include <initguid.h>
 
 #include "winvblock.h"
 #include "wv_stdlib.h"
@@ -41,6 +43,9 @@
 static device__dispatch_func bus_pnp__start_dev_;
 static device__dispatch_func bus_pnp__remove_dev_;
 static device__dispatch_func bus_pnp__query_dev_relations_;
+static device__dispatch_func bus_pnp__query_capabilities_;
+static device__dispatch_func bus_pnp__query_dev_text_;
+static device__dispatch_func bus_pnp__query_bus_info_;
 static device__pnp_func bus_pnp__simple_;
 device__pnp_func bus_pnp__dispatch;
 
@@ -192,6 +197,150 @@ static NTSTATUS STDCALL bus_pnp__query_dev_relations_(
     return driver__complete_irp(irp, irp->IoStatus.Information, status);
   }
 
+static NTSTATUS STDCALL bus_pnp__query_capabilities_(
+    IN struct device__type * dev,
+    IN PIRP irp
+  ) {
+    PIO_STACK_LOCATION io_stack_loc = IoGetCurrentIrpStackLocation(irp);
+    PDEVICE_CAPABILITIES DeviceCapabilities =
+      io_stack_loc->Parameters.DeviceCapabilities.Capabilities;
+    NTSTATUS status;
+    struct bus__type * bus = bus__get(dev);
+    DEVICE_CAPABILITIES ParentDeviceCapabilities;
+    PDEVICE_OBJECT lower;
+
+    if (DeviceCapabilities->Version != 1 ||
+        DeviceCapabilities->Size < sizeof (DEVICE_CAPABILITIES)
+      )
+      return driver__complete_irp(irp, 0, STATUS_UNSUCCESSFUL);
+    /* If there's a lower DEVICE_OBJECT, let it handle the IRP. */
+    lower = bus->LowerDeviceObject;
+    if (lower) {
+        IoSkipCurrentIrpStackLocation(irp);
+        return IoCallDriver(lower, irp);
+      }
+    /* Otherwise, return our parent's capabilities. */
+    status = bus__get_dev_capabilities(
+        dev->Parent,
+        DeviceCapabilities
+      );
+    if (!NT_SUCCESS(status))
+      return driver__complete_irp(irp, 0, status);
+    return driver__complete_irp(irp, irp->IoStatus.Information, STATUS_SUCCESS);
+  }
+
+static NTSTATUS STDCALL bus_pnp__query_dev_text_(
+    IN struct device__type * dev,
+    IN PIRP irp
+  ) {
+    struct bus__type * bus = bus__get(dev);
+    WCHAR (*str)[512];
+    PIO_STACK_LOCATION io_stack_loc = IoGetCurrentIrpStackLocation(irp);
+    NTSTATUS status;
+    winvblock__uint32 str_len;
+
+    /* Allocate a string buffer. */
+    str = wv_mallocz(sizeof *str);
+    if (str == NULL) {
+        DBG("wv_malloc IRP_MN_QUERY_DEVICE_TEXT\n");
+        status = STATUS_INSUFFICIENT_RESOURCES;
+        goto alloc_str;
+      }
+    /* Determine the query type. */
+    switch (io_stack_loc->Parameters.QueryDeviceText.DeviceTextType) {
+        case DeviceTextDescription:
+          str_len = swprintf(*str, winvblock__literal_w L" Bus") + 1;
+          irp->IoStatus.Information =
+            (ULONG_PTR) wv_palloc(str_len * sizeof *str);
+          if (irp->IoStatus.Information == 0) {
+              DBG("wv_palloc DeviceTextDescription\n");
+              status = STATUS_INSUFFICIENT_RESOURCES;
+              goto alloc_info;
+            }
+          RtlCopyMemory(
+              (PWCHAR) irp->IoStatus.Information,
+              str,
+              str_len * sizeof (WCHAR)
+            );
+          status = STATUS_SUCCESS;
+          goto alloc_info;
+
+        case DeviceTextLocationInformation:
+          str_len = device__pnp_id(
+              dev,
+              BusQueryInstanceID,
+              str
+            );
+          irp->IoStatus.Information =
+            (ULONG_PTR) wv_palloc(str_len * sizeof *str);
+          if (irp->IoStatus.Information == 0) {
+              DBG("wv_palloc DeviceTextLocationInformation\n");
+              status = STATUS_INSUFFICIENT_RESOURCES;
+              goto alloc_info;
+            }
+          RtlCopyMemory(
+              (PWCHAR) irp->IoStatus.Information,
+              str,
+              str_len * sizeof (WCHAR)
+            );
+          status = STATUS_SUCCESS;
+          goto alloc_info;
+
+        default:
+          irp->IoStatus.Information = 0;
+          status = STATUS_NOT_SUPPORTED;
+      }
+    /* irp->IoStatus.Information not freed. */
+    alloc_info:
+
+    wv_free(str);
+    alloc_str:
+
+    return driver__complete_irp(irp, irp->IoStatus.Information, status);
+  }
+
+DEFINE_GUID(
+    GUID_BUS_TYPE_INTERNAL,
+    0x2530ea73L,
+    0x086b,
+    0x11d1,
+    0xa0,
+    0x9f,
+    0x00,
+    0xc0,
+    0x4f,
+    0xc3,
+    0x40,
+    0xb1
+  );
+
+static NTSTATUS STDCALL bus_pnp__query_bus_info_(
+    IN struct device__type * dev,
+    IN PIRP irp
+  ) {
+    PPNP_BUS_INFORMATION pnp_bus_info;
+    NTSTATUS status;
+
+    pnp_bus_info = wv_palloc(sizeof *pnp_bus_info);
+    if (pnp_bus_info == NULL) {
+        DBG("wv_palloc IRP_MN_QUERY_BUS_INFORMATION\n");
+        status = STATUS_INSUFFICIENT_RESOURCES;
+        goto alloc_pnp_bus_info;
+      }
+    pnp_bus_info->BusTypeGuid = GUID_BUS_TYPE_INTERNAL;
+    pnp_bus_info->LegacyBusType = PNPBus;
+    pnp_bus_info->BusNumber = 0;
+    irp->IoStatus.Information = (ULONG_PTR) pnp_bus_info;
+    status = STATUS_SUCCESS;
+
+    /* irp-IoStatus.Information (pnp_bus_info) not freed. */
+    alloc_pnp_bus_info:
+
+    irp->IoStatus.Status = status;
+    IoCompleteRequest(irp, IO_NO_INCREMENT);
+    return status;
+  }
+
 static NTSTATUS STDCALL bus_pnp__simple_(
     IN struct device__type * dev,
     IN PIRP irp,
@@ -203,45 +352,59 @@ static NTSTATUS STDCALL bus_pnp__simple_(
 
     switch (code) {
         case IRP_MN_QUERY_PNP_DEVICE_STATE:
+          DBG("bus_pnp: IRP_MN_QUERY_PNP_DEVICE_STATE\n");
           irp->IoStatus.Information = 0;
           status = STATUS_SUCCESS;
           break;
 
         case IRP_MN_QUERY_STOP_DEVICE:
+          DBG("bus_pnp: IRP_MN_QUERY_STOP_DEVICE\n");
           dev->old_state = dev->state;
           dev->state = device__state_stop_pending;
           status = STATUS_SUCCESS;
           break;
 
         case IRP_MN_CANCEL_STOP_DEVICE:
+          DBG("bus_pnp: IRP_MN_CANCEL_STOP_DEVICE\n");
           dev->state = dev->old_state;
           status = STATUS_SUCCESS;
           break;
 
         case IRP_MN_STOP_DEVICE:
+          DBG("bus_pnp: IRP_MN_STOP_DEVICE\n");
           dev->old_state = dev->state;
           dev->state = device__state_stopped;
           status = STATUS_SUCCESS;
           break;
 
         case IRP_MN_QUERY_REMOVE_DEVICE:
+          DBG("bus_pnp: IRP_MN_QUERY_REMOVE_DEVICE\n");
           dev->old_state = dev->state;
           dev->state = device__state_remove_pending;
           status = STATUS_SUCCESS;
           break;
 
         case IRP_MN_CANCEL_REMOVE_DEVICE:
+          DBG("bus_pnp: IRP_MN_CANCEL_REMOVE_DEVICE\n");
           dev->state = dev->old_state;
           status = STATUS_SUCCESS;
           break;
 
         case IRP_MN_SURPRISE_REMOVAL:
+          DBG("bus_pnp: IRP_MN_SURPRISE_REMOVAL\n");
           dev->old_state = dev->state;
           dev->state = device__state_surprise_remove_pending;
           status = STATUS_SUCCESS;
           break;
 
+        case IRP_MN_QUERY_RESOURCES:
+        case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
+          DBG("bus_pnp: IRP_MN_QUERY_RESOURCE*\n");
+          IoCompleteRequest(irp, IO_NO_INCREMENT);
+          return STATUS_SUCCESS;
+          
         default:
+          DBG("bus_pnp: Unhandled IRP_MN_*: %d\n", code);
           status = irp->IoStatus.Status;
       }
 
@@ -261,15 +424,31 @@ NTSTATUS STDCALL bus_pnp__dispatch(
   ) {
     switch (code) {
         case IRP_MN_QUERY_ID:
+          DBG("bus_pnp: IRP_MN_QUERY_ID\n");
           return device__pnp_query_id(dev, irp);
 
+        case IRP_MN_QUERY_DEVICE_TEXT:
+          DBG("bus_pnp: IRP_MN_QUERY_DEVICE_TEXT\n");
+          return bus_pnp__query_dev_text_(dev, irp);
+
+        case IRP_MN_QUERY_BUS_INFORMATION:
+          DBG("bus_pnp: IRP_MN_QUERY_BUS_INFORMATION\n");
+          return bus_pnp__query_bus_info_(dev, irp);
+
         case IRP_MN_QUERY_DEVICE_RELATIONS:
+          DBG("bus_pnp: IRP_MJ_QUERY_DEVICE_RELATIONS\n");
           return bus_pnp__query_dev_relations_(dev, irp);
 
+        case IRP_MN_QUERY_CAPABILITIES:
+          DBG("bus_pnp: IRP_MN_QUERY_CAPABILITIES\n");
+          return bus_pnp__query_capabilities_(dev, irp);
+
         case IRP_MN_REMOVE_DEVICE:
+          DBG("bus_pnp: IRP_MN_REMOVE_DEVICE\n");
           return bus_pnp__remove_dev_(dev, irp);
 
         case IRP_MN_START_DEVICE:
+          DBG("bus_pnp: IRP_MN_START_DEVICE\n");
           return bus_pnp__start_dev_(dev, irp);
 
         default:
index f006fe4..713c41b 100644 (file)
@@ -284,6 +284,7 @@ static NTSTATUS STDCALL disk_pnp__simple_(
 
     switch (code) {
         case IRP_MN_DEVICE_USAGE_NOTIFICATION:
+          DBG("disk_pnp: IRP_MN_DEVICE_USAGE_NOTIFICATION\n");
           if (io_stack_loc->Parameters.UsageNotification.InPath) {
               disk->SpecialFileCount++;
             } else {
@@ -294,40 +295,47 @@ static NTSTATUS STDCALL disk_pnp__simple_(
           break;
 
         case IRP_MN_QUERY_PNP_DEVICE_STATE:
+          DBG("disk_pnp: IRP_MN_QUERY_PNP_DEVICE_STATE\n");
           irp->IoStatus.Information = 0;
           status = STATUS_SUCCESS;
           break;
 
         case IRP_MN_START_DEVICE:
+          DBG("disk_pnp: IRP_MN_START_DEVICE\n");
           dev->old_state = dev->state;
           dev->state = device__state_started;
           status = STATUS_SUCCESS;
           break;
 
         case IRP_MN_QUERY_STOP_DEVICE:
+          DBG("disk_pnp: IRP_MN_QUERY_STOP_DEVICE\n");
           dev->old_state = dev->state;
           dev->state = device__state_stop_pending;
           status = STATUS_SUCCESS;
           break;
 
         case IRP_MN_CANCEL_STOP_DEVICE:
+          DBG("disk_pnp: IRP_MN_CANCEL_STOP_DEVICE\n");
           dev->state = dev->old_state;
           status = STATUS_SUCCESS;
           break;
 
         case IRP_MN_STOP_DEVICE:
+          DBG("disk_pnp: IRP_MN_STOP_DEVICE\n");
           dev->old_state = dev->state;
           dev->state = device__state_stopped;
           status = STATUS_SUCCESS;
           break;
 
         case IRP_MN_QUERY_REMOVE_DEVICE:
+          DBG("disk_pnp: IRP_MN_QUERY_REMOVE_DEVICE\n");
           dev->old_state = dev->state;
           dev->state = device__state_remove_pending;
           status = STATUS_SUCCESS;
           break;
 
         case IRP_MN_REMOVE_DEVICE:
+          DBG("disk_pnp: IRP_MN_REMOVE_DEVICE\n");
           dev->old_state = dev->state;
           dev->state = device__state_not_started;
           if (disk->Unmount) {
@@ -341,17 +349,20 @@ static NTSTATUS STDCALL disk_pnp__simple_(
           break;
 
         case IRP_MN_CANCEL_REMOVE_DEVICE:
+          DBG("disk_pnp: IRP_MN_CANCEL_REMOVE_DEVICE\n");
           dev->state = dev->old_state;
           status = STATUS_SUCCESS;
           break;
 
         case IRP_MN_SURPRISE_REMOVAL:
+          DBG("disk_pnp: IRP_MN_SURPRISE_REMOVAL\n");
           dev->old_state = dev->state;
           dev->state = device__state_surprise_remove_pending;
           status = STATUS_SUCCESS;
           break;
 
         default:
+          DBG("disk_pnp: Unhandled IRP_MN_*: %d\n", code);
           status = irp->IoStatus.Status;
       }
 
@@ -368,18 +379,23 @@ NTSTATUS STDCALL disk_pnp__dispatch(
   ) {
     switch (code) {
         case IRP_MN_QUERY_ID:
+          DBG("disk_pnp: IIRP_MN_QUERY_ID\n");
           return device__pnp_query_id(dev, irp);
 
         case IRP_MN_QUERY_DEVICE_TEXT:
+          DBG("disk_pnp: IRP_MN_QUERY_DEVICE_TEXT\n");
           return disk_pnp__query_dev_text_(dev, irp);
 
         case IRP_MN_QUERY_DEVICE_RELATIONS:
+          DBG("disk_pnp: IRP_MN_QUERY_DEVICE_RELATIONS\n");
           return disk_pnp__query_dev_relations_(dev, irp);
 
         case IRP_MN_QUERY_BUS_INFORMATION:
+          DBG("disk_pnp: IRP_MN_QUERY_BUS_INFORMATION\n");
           return disk_pnp__query_bus_info_(dev, irp);
 
         case IRP_MN_QUERY_CAPABILITIES:
+          DBG("disk_pnp: IRP_MN_QUERY_CAPABILITIES\n");
           return disk_pnp__query_capabilities_(dev, irp);
 
         default: