[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[win-pv-devel] [PATCH 1/2] Use the registry to check for vendor device



Using the XENFILT_PVDEVICE interface to select active device (which entails
checking for the presence of a vendor device) means that XENBUS requires a
reboot on installation before any instance can create PDOs. By using the
registry to check for vendor device presence (by looking if there is a key
under HKLM/System/CurrentControlset/Enum) there is no longer any need for
that reboot.

This patch amends the code as necessary, essentially pulling most of the
implementation of XENFILT_PVDEVICE into src/xenbus/driver.c.

Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
---
 src/xenbus/driver.c | 270 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/xenbus/driver.h |  17 ++++
 src/xenbus/fdo.c    | 131 ++++++++-----------------
 3 files changed, 327 insertions(+), 91 deletions(-)

diff --git a/src/xenbus/driver.c b/src/xenbus/driver.c
index 46712e3..b1a5cb3 100644
--- a/src/xenbus/driver.c
+++ b/src/xenbus/driver.c
@@ -228,6 +228,276 @@ DriverRemoveFunctionDeviceObject(
         FiltersUninstall();
 }
 
+//
+// The canonical location for active device information is the XENFILT
+// Parameters key.
+//
+#define ACTIVE_PATH 
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services\\XENFILT\\Parameters"
+
+NTSTATUS
+DriverGetActive(
+    OUT PCHAR       DeviceID,
+    OUT PCHAR       InstanceID
+    )
+{
+    HANDLE          ActiveKey;
+    PANSI_STRING    Ansi;
+    NTSTATUS        status;
+
+    Trace("====>\n");
+
+    ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+
+    status = RegistryOpenSubKey(NULL,
+                                ACTIVE_PATH,
+                                KEY_READ,
+                                &ActiveKey);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    status = RegistryQuerySzValue(ActiveKey,
+                                  "ActiveDeviceID",
+                                  NULL,
+                                  &Ansi);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    status = RtlStringCbPrintfA(DeviceID,
+                                MAX_DEVICE_ID_LEN,
+                                "%Z",
+                                &Ansi[0]);
+    ASSERT(NT_SUCCESS(status));
+
+    RegistryFreeSzValue(Ansi);
+
+    status = RegistryQuerySzValue(ActiveKey,
+                                  "ActiveInstanceID",
+                                  NULL,
+                                  &Ansi);
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
+    status = RtlStringCbPrintfA(InstanceID,
+                                MAX_DEVICE_ID_LEN,
+                                "%Z",
+                                &Ansi[0]);
+    ASSERT(NT_SUCCESS(status));
+
+    RegistryFreeSzValue(Ansi);
+
+    RegistryCloseKey(ActiveKey);
+
+    Trace("<====\n");
+
+    return STATUS_SUCCESS;
+
+fail3:
+    Error("fail3\n");
+
+fail2:
+    Error("fail2\n");
+
+    RegistryCloseKey(ActiveKey);
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return status;
+}
+
+static const CHAR *DriverLegacyDevicePrefix[] = {
+    "PCI\\VEN_5853&DEV_0001",
+    "PCI\\VEN_5853&DEV_0002"
+};
+
+static FORCEINLINE BOOLEAN
+__DriverIsDeviceLegacy(
+    IN  PCHAR   DeviceID
+    )
+{
+    ULONG       Index;
+
+    for (Index = 0; Index < ARRAYSIZE(DriverLegacyDevicePrefix); Index++) {
+        const CHAR  *Prefix = DriverLegacyDevicePrefix[Index];
+
+        if (_strnicmp(DeviceID, Prefix, strlen(Prefix)) == 0)
+            return TRUE;
+    }
+
+    return FALSE;
+}
+
+static const CHAR *DriverVendorDeviceID =
+#ifdef VENDOR_DEVICE_ID_STR
+    "PCI\\VEN_5853&DEV_" VENDOR_DEVICE_ID_STR "&SUBSYS_C0005853&REV_01";
+#else
+    NULL;
+#endif
+
+#define ENUM_PATH "\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Enum"
+
+static FORCEINLINE BOOLEAN
+__DriverIsVendorDevicePresent(
+    VOID
+    )
+{
+    HANDLE      EnumKey;
+    HANDLE      DeviceKey;
+    BOOLEAN     Found;
+    NTSTATUS    status;
+
+    status = RegistryOpenSubKey(NULL,
+                                ENUM_PATH,
+                                KEY_READ,
+                                &EnumKey);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    Found = FALSE;
+
+    status = RegistryOpenSubKey(EnumKey,
+                                (PCHAR)DriverVendorDeviceID,
+                                KEY_READ,
+                                &DeviceKey);
+    if (!NT_SUCCESS(status))
+        goto done;
+
+    RegistryCloseKey(DeviceKey);
+    Found = TRUE;
+
+done:
+    RegistryCloseKey(EnumKey);
+
+    return Found;
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return FALSE;
+}
+
+NTSTATUS
+DriverSetActive(
+    IN  PCHAR   DeviceID,
+    IN  PCHAR   InstanceID
+    )
+{
+    HANDLE      ActiveKey;
+    ANSI_STRING Ansi[2];
+    NTSTATUS    status;
+
+    Trace("====>\n");
+
+    ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+
+    status = RegistryOpenSubKey(NULL,
+                                ACTIVE_PATH,
+                                KEY_ALL_ACCESS,
+                                &ActiveKey);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    status = STATUS_UNSUCCESSFUL;
+    if (__DriverIsDeviceLegacy(DeviceID) &&
+        __DriverIsVendorDevicePresent())
+        goto fail2;
+
+    RtlZeroMemory(Ansi, sizeof (ANSI_STRING) * 2);
+
+    RtlInitAnsiString(&Ansi[0], DeviceID);
+
+    status = RegistryUpdateSzValue(ActiveKey,
+                                   "ActiveDeviceID",
+                                   REG_SZ,
+                                   Ansi);
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
+    RtlInitAnsiString(&Ansi[0], InstanceID);
+
+    status = RegistryUpdateSzValue(ActiveKey,
+                                   "ActiveInstanceID",
+                                   REG_SZ,
+                                   Ansi);
+    if (!NT_SUCCESS(status))
+        goto fail4;
+
+    Info("%s\\%s\n", DeviceID, InstanceID);
+
+    RegistryCloseKey(ActiveKey);
+
+    Trace("<====\n");
+
+    return STATUS_SUCCESS;
+
+fail4:
+    Error("fail4\n");
+
+fail3:
+    Error("fail3\n");
+
+fail2:
+    Error("fail2\n");
+
+    RegistryCloseKey(ActiveKey);
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return status;
+}
+
+NTSTATUS
+DriverClearActive(
+    VOID
+    )
+{
+    HANDLE      ActiveKey;
+    NTSTATUS    status;
+
+    Trace("====>\n");
+
+    ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+
+    status = RegistryOpenSubKey(NULL,
+                                ACTIVE_PATH,
+                                KEY_ALL_ACCESS,
+                                &ActiveKey);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    status = RegistryDeleteValue(ActiveKey,
+                                 "ActiveDeviceID");
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    status = RegistryDeleteValue(ActiveKey,
+                                 "ActiveInstanceID");
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
+    Info("DONE\n");
+
+    RegistryCloseKey(ActiveKey);
+
+    Trace("<====\n");
+
+    return STATUS_SUCCESS;
+
+fail3:
+    Error("fail3\n");
+
+fail2:
+    Error("fail2\n");
+
+    RegistryCloseKey(ActiveKey);
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return status;
+}
+
 DRIVER_UNLOAD       DriverUnload;
 
 VOID
diff --git a/src/xenbus/driver.h b/src/xenbus/driver.h
index 78b1b25..dd81e4c 100644
--- a/src/xenbus/driver.h
+++ b/src/xenbus/driver.h
@@ -57,6 +57,23 @@ DriverReleaseMutex(
     VOID
      );
 
+extern NTSTATUS
+DriverGetActive(
+    OUT PCHAR   DeviceID,
+    OUT PCHAR   InstanceID
+    );
+
+NTSTATUS
+DriverSetActive(
+    IN  PCHAR   DeviceID,
+    IN  PCHAR   InstanceID
+    );
+
+NTSTATUS
+DriverClearActive(
+    VOID
+    );
+
 typedef struct _XENBUS_FDO      XENBUS_FDO, *PXENBUS_FDO;
 typedef struct _XENBUS_PDO      XENBUS_PDO, *PXENBUS_PDO;
 
diff --git a/src/xenbus/fdo.c b/src/xenbus/fdo.c
index 0c33a57..49ae08d 100644
--- a/src/xenbus/fdo.c
+++ b/src/xenbus/fdo.c
@@ -116,7 +116,6 @@ struct _XENBUS_FDO {
     PCM_PARTIAL_RESOURCE_LIST       RawResourceList;
     PCM_PARTIAL_RESOURCE_LIST       TranslatedResourceList;
 
-    XENFILT_PVDEVICE_INTERFACE      PvdeviceInterface;
     BOOLEAN                         Active;
 
     PXENBUS_SUSPEND_CONTEXT         SuspendContext;
@@ -634,22 +633,14 @@ FdoSetActive(
     if (!NT_SUCCESS(status))
         goto fail2;
 
-    status = XENFILT_PVDEVICE(Acquire, &Fdo->PvdeviceInterface);
-    if (!NT_SUCCESS(status))
-        goto fail3;
-
-    status = XENFILT_PVDEVICE(GetActive,
-                              &Fdo->PvdeviceInterface,
-                              ActiveDeviceID,
-                              ActiveInstanceID);
+    status = DriverGetActive(ActiveDeviceID,
+                             ActiveInstanceID);
     if (NT_SUCCESS(status)) {
         if (_stricmp(DeviceID, ActiveDeviceID) != 0)
             goto done;
     } else {
-        status = XENFILT_PVDEVICE(SetActive,
-                                  &Fdo->PvdeviceInterface,
-                                  DeviceID,
-                                  InstanceID);
+        status = DriverSetActive(DeviceID,
+                                 InstanceID);
         if (!NT_SUCCESS(status))
             goto done;
     }
@@ -657,13 +648,8 @@ FdoSetActive(
     Fdo->Active = TRUE;
 
 done:
-    XENFILT_PVDEVICE(Release, &Fdo->PvdeviceInterface);
-
     return STATUS_SUCCESS;
 
-fail3:
-    Error("fail3\n");
-
 fail2:
     Error("fail2\n");
 
@@ -673,30 +659,14 @@ fail1:
     return status;
 }
 
-static NTSTATUS
+static VOID
 FdoClearActive(
     IN  PXENBUS_FDO Fdo
     )
 {
-    NTSTATUS        status;
-
-    status = XENFILT_PVDEVICE(Acquire, &Fdo->PvdeviceInterface);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    (VOID) XENFILT_PVDEVICE(ClearActive,
-                            &Fdo->PvdeviceInterface);
+    (VOID) DriverClearActive();
 
     Fdo->Active = FALSE;
-
-    XENFILT_PVDEVICE(Release, &Fdo->PvdeviceInterface);
-
-    return STATUS_SUCCESS;
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    return status;
 }
 
 static FORCEINLINE BOOLEAN
@@ -5056,67 +5026,53 @@ FdoCreate(
 
     __FdoSetName(Fdo);
 
-    status = FDO_QUERY_INTERFACE(Fdo,
-                                 XENFILT,
-                                 PVDEVICE,
-                                 (PINTERFACE)&Fdo->PvdeviceInterface,
-                                 sizeof (Fdo->PvdeviceInterface),
-                                 TRUE);
-    if (!NT_SUCCESS(status))
-        goto fail8;
-
-    if (Fdo->PvdeviceInterface.Interface.Context == NULL) {
-        DriverRequestReboot();
-        goto done;
-    }
-
     status = FdoSetActive(Fdo);
     if (!NT_SUCCESS(status))
-        goto fail9;
+        goto fail8;
 
     if (!__FdoIsActive(Fdo))
         goto done;
 
     status = DebugInitialize(Fdo, &Fdo->DebugContext);
     if (!NT_SUCCESS(status))
-        goto fail10;
+        goto fail9;
 
     status = SuspendInitialize(Fdo, &Fdo->SuspendContext);
     if (!NT_SUCCESS(status))
-        goto fail11;
+        goto fail10;
 
     status = SharedInfoInitialize(Fdo, &Fdo->SharedInfoContext);
     if (!NT_SUCCESS(status))
-        goto fail12;
+        goto fail11;
 
     status = EvtchnInitialize(Fdo, &Fdo->EvtchnContext);
     if (!NT_SUCCESS(status))
-        goto fail13;
+        goto fail12;
 
     status = StoreInitialize(Fdo, &Fdo->StoreContext);
     if (!NT_SUCCESS(status))
-        goto fail14;
+        goto fail13;
 
     status = RangeSetInitialize(Fdo, &Fdo->RangeSetContext);
     if (!NT_SUCCESS(status))
-        goto fail15;
+        goto fail14;
 
     status = CacheInitialize(Fdo, &Fdo->CacheContext);
     if (!NT_SUCCESS(status))
-        goto fail16;
+        goto fail15;
 
     status = GnttabInitialize(Fdo, &Fdo->GnttabContext);
     if (!NT_SUCCESS(status))
-        goto fail17;
+        goto fail16;
 
     status = UnplugInitialize(Fdo, &Fdo->UnplugContext);
     if (!NT_SUCCESS(status))
-        goto fail18;
+        goto fail17;
 
     if (FdoIsBalloonEnabled(Fdo)) {
         status = BalloonInitialize(Fdo, &Fdo->BalloonContext);
         if (!NT_SUCCESS(status))
-            goto fail19;
+            goto fail18;
     }
 
     status = DebugGetInterface(__FdoGetDebugContext(Fdo),
@@ -5179,70 +5135,68 @@ done:
 
     return STATUS_SUCCESS;
 
-fail19:
-    Error("fail19\n");
-
-    UnplugTeardown(Fdo->UnplugContext);
-    Fdo->UnplugContext = NULL;
-
 fail18:
     Error("fail18\n");
 
-    GnttabTeardown(Fdo->GnttabContext);
-    Fdo->GnttabContext = NULL;
+    UnplugTeardown(Fdo->UnplugContext);
+    Fdo->UnplugContext = NULL;
 
 fail17:
     Error("fail17\n");
 
-    CacheTeardown(Fdo->CacheContext);
-    Fdo->CacheContext = NULL;
+    GnttabTeardown(Fdo->GnttabContext);
+    Fdo->GnttabContext = NULL;
 
 fail16:
     Error("fail16\n");
 
-    RangeSetTeardown(Fdo->RangeSetContext);
-    Fdo->RangeSetContext = NULL;
+    CacheTeardown(Fdo->CacheContext);
+    Fdo->CacheContext = NULL;
 
 fail15:
     Error("fail15\n");
 
-    StoreTeardown(Fdo->StoreContext);
-    Fdo->StoreContext = NULL;
+    RangeSetTeardown(Fdo->RangeSetContext);
+    Fdo->RangeSetContext = NULL;
 
 fail14:
     Error("fail14\n");
 
-    EvtchnTeardown(Fdo->EvtchnContext);
-    Fdo->EvtchnContext = NULL;
+    StoreTeardown(Fdo->StoreContext);
+    Fdo->StoreContext = NULL;
 
 fail13:
     Error("fail13\n");
 
-    SharedInfoTeardown(Fdo->SharedInfoContext);
-    Fdo->SharedInfoContext = NULL;
+    EvtchnTeardown(Fdo->EvtchnContext);
+    Fdo->EvtchnContext = NULL;
 
 fail12:
     Error("fail12\n");
 
-    SuspendTeardown(Fdo->SuspendContext);
-    Fdo->SuspendContext = NULL;
+    SharedInfoTeardown(Fdo->SharedInfoContext);
+    Fdo->SharedInfoContext = NULL;
 
 fail11:
     Error("fail11\n");
 
-    DebugTeardown(Fdo->DebugContext);
-    Fdo->DebugContext = NULL;
+    SuspendTeardown(Fdo->SuspendContext);
+    Fdo->SuspendContext = NULL;
 
 fail10:
     Error("fail10\n");
 
-    Fdo->Active = FALSE;
+    DebugTeardown(Fdo->DebugContext);
+    Fdo->DebugContext = NULL;
 
 fail9:
     Error("fail9\n");
 
-    RtlZeroMemory(&Fdo->PvdeviceInterface,
-                  sizeof (XENFILT_PVDEVICE_INTERFACE));
+    //
+    // We don't want to call DriverClearActive() so just
+    // clear the FDO flag.
+    //
+    Fdo->Active = FALSE;
 
 fail8:
     Error("fail8\n");
@@ -5371,14 +5325,9 @@ FdoDestroy(
         DebugTeardown(Fdo->DebugContext);
         Fdo->DebugContext = NULL;
 
-        Fdo->Active = FALSE;
-
         FdoClearActive(Fdo);
     }
 
-    RtlZeroMemory(&Fdo->PvdeviceInterface,
-                  sizeof (XENFILT_PVDEVICE_INTERFACE));
-
     RtlZeroMemory(Fdo->VendorName, MAXNAMELEN);
 
     FdoReleaseLowerBusInterface(Fdo);
-- 
2.1.1


_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
http://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.