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

[win-pv-devel] [PATCH] Publish distribution information to xenstore



My recent patch series to Xen added a documented path and format for
publishing information about PV driver distributions to xenstore.

This patch adds code to populate the documented path (should it exist)
with information about the XENIFACE driver package.

Suggested-by: Owen Smith <owen.smith@xxxxxxxxxx>
Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
---
 src/xeniface/fdo.c | 445 ++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 405 insertions(+), 40 deletions(-)

diff --git a/src/xeniface/fdo.c b/src/xeniface/fdo.c
index c1467b7..d30a08b 100644
--- a/src/xeniface/fdo.c
+++ b/src/xeniface/fdo.c
@@ -40,7 +40,7 @@
 #include <evtchn_interface.h>
 #include <gnttab_interface.h>
 #include <suspend_interface.h>
-
+#include <version.h>
 
 #include "driver.h"
 #include "registry.h"
@@ -570,16 +570,359 @@ FdoParseResources(
     }
 }
 
+static FORCEINLINE PANSI_STRING
+__FdoMultiSzToUpcaseAnsi(
+    IN  PCHAR       Buffer
+    )
+{
+    PANSI_STRING    Ansi;
+    LONG            Index;
+    LONG            Count;
+    NTSTATUS        status;
+
+    Index = 0;
+    Count = 0;
+    for (;;) {
+        if (Buffer[Index] == '\0') {
+            Count++;
+            Index++;
+
+            // Check for double NUL
+            if (Buffer[Index] == '\0')
+                break;
+        } else {
+            Buffer[Index] = (CHAR)toupper(Buffer[Index]);
+            Index++;
+        }
+    }
+
+    Ansi = __FdoAllocate(sizeof (ANSI_STRING) * (Count + 1));
+
+    status = STATUS_NO_MEMORY;
+    if (Ansi == NULL)
+        goto fail1;
+
+    for (Index = 0; Index < Count; Index++) {
+        ULONG   Length;
+
+        Length = (ULONG)strlen(Buffer);
+        Ansi[Index].MaximumLength = (USHORT)(Length + 1);
+        Ansi[Index].Buffer = __FdoAllocate(Ansi[Index].MaximumLength);
+
+        status = STATUS_NO_MEMORY;
+        if (Ansi[Index].Buffer == NULL)
+            goto fail2;
+
+        RtlCopyMemory(Ansi[Index].Buffer, Buffer, Length);
+        Ansi[Index].Length = (USHORT)Length;
+
+        Buffer += Length + 1;
+    }
+
+    return Ansi;
+
+fail2:
+    Error("fail2\n");
+
+    while (--Index >= 0)
+        __FdoFree(Ansi[Index].Buffer);
+
+    __FdoFree(Ansi);
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return NULL;
+}
+
+static FORCEINLINE VOID
+__FdoFreeAnsi(
+    IN  PANSI_STRING    Ansi
+    )
+{
+    ULONG               Index;
+
+    for (Index = 0; Ansi[Index].Buffer != NULL; Index++)
+        __FdoFree(Ansi[Index].Buffer);
+        
+    __FdoFree(Ansi);
+}
+
+static FORCEINLINE BOOLEAN
+__FdoMatchDistribution(
+    IN  PXENIFACE_FDO   Fdo,
+    IN  PCHAR           Buffer
+    )
+{
+    PCHAR               Vendor;
+    PCHAR               Product;
+    PCHAR               Context;
+    const CHAR          *Text;
+    BOOLEAN             Match;
+    ULONG               Index;
+    NTSTATUS            status;
+
+    UNREFERENCED_PARAMETER(Fdo);
+
+    status = STATUS_INVALID_PARAMETER;
+
+    Vendor = __strtok_r(Buffer, " ", &Context);
+    if (Vendor == NULL)
+        goto fail1;
+
+    Product = __strtok_r(NULL, " ", &Context);
+    if (Product == NULL)
+        goto fail2;
+
+    Match = TRUE;
+
+    Text = VENDOR_NAME_STR;
+
+    for (Index = 0; Text[Index] != 0; Index++) {
+        if (!isalnum((UCHAR)Text[Index])) {
+            if (Vendor[Index] != '_') {
+                Match = FALSE;
+                break;
+            }
+        } else {
+            if (Vendor[Index] != Text[Index]) {
+                Match = FALSE;
+                break;
+            }
+        }
+    }
+
+    Text = "XENIFACE";
+
+    if (_stricmp(Product, Text) != 0)
+        Match = FALSE;
+
+    return Match;
+
+fail2:
+    Error("fail2\n");
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return FALSE;
+}
+
+static VOID
+FdoClearDistribution(
+    IN  PXENIFACE_FDO   Fdo
+    )
+{
+    PCHAR               Buffer;
+    PANSI_STRING        Distributions;
+    ULONG               Index;
+    NTSTATUS            status;
+
+    Trace("====>\n");
+
+    status = XENBUS_STORE(Directory,
+                          &Fdo->StoreInterface,
+                          NULL,
+                          NULL,
+                          "drivers",
+                          &Buffer);
+    if (NT_SUCCESS(status)) {
+        Distributions = __FdoMultiSzToUpcaseAnsi(Buffer);
+
+        XENBUS_STORE(Free,
+                     &Fdo->StoreInterface,
+                     Buffer);
+    } else {
+        Distributions = NULL;
+    }
+
+    if (Distributions == NULL)
+        goto done;
+
+    for (Index = 0; Distributions[Index].Buffer != NULL; Index++) {
+        PANSI_STRING    Distribution = &Distributions[Index];
+
+        status = XENBUS_STORE(Read,
+                              &Fdo->StoreInterface,
+                              NULL,
+                              "drivers",
+                              Distribution->Buffer,
+                              &Buffer);
+        if (!NT_SUCCESS(status))
+            continue;
+
+        if (__FdoMatchDistribution(Fdo, Buffer))
+            (VOID) XENBUS_STORE(Remove,
+                                &Fdo->StoreInterface,
+                                NULL,
+                                "drivers",
+                                Distribution->Buffer);
+
+        XENBUS_STORE(Free,
+                     &Fdo->StoreInterface,
+                     Buffer);
+    }
+
+    __FdoFreeAnsi(Distributions);
+
+done:
+    Trace("<====\n");
+}
+
+#define MAXIMUM_INDEX   255
+
+static NTSTATUS
+FdoSetDistribution(
+    IN  PXENIFACE_FDO   Fdo
+    )
+{
+    ULONG               Index;
+    CHAR                Distribution[MAXNAMELEN];
+    CHAR                Vendor[MAXNAMELEN];
+    const CHAR          *Product;
+    NTSTATUS            status;
+
+    Trace("====>\n");
+
+    Index = 0;
+    while (Index <= MAXIMUM_INDEX) {
+        PCHAR   Buffer;
+
+        status = RtlStringCbPrintfA(Distribution,
+                                    MAXNAMELEN,
+                                    "%u",
+                                    Index);
+        ASSERT(NT_SUCCESS(status));
+
+        status = XENBUS_STORE(Read,
+                              &Fdo->StoreInterface,
+                              NULL,
+                              "drivers",
+                              Distribution,
+                              &Buffer);
+        if (!NT_SUCCESS(status)) {
+            if (status == STATUS_OBJECT_NAME_NOT_FOUND)
+                goto update;
+
+            goto fail1;
+        }
+
+        XENBUS_STORE(Free,
+                     &Fdo->StoreInterface,
+                     Buffer);
+
+        Index++;
+    }
+
+    status = STATUS_UNSUCCESSFUL;
+    goto fail2;
+
+update:
+    status = RtlStringCbPrintfA(Vendor,
+                                MAXNAMELEN,
+                                "%s",
+                                VENDOR_NAME_STR);
+    ASSERT(NT_SUCCESS(status));
+
+    for (Index  = 0; Vendor[Index] != '\0'; Index++)
+        if (!isalnum((UCHAR)Vendor[Index]))
+            Vendor[Index] = '_';
+
+    Product = "XENIFACE";
+
+#if DBG
+#define ATTRIBUTES   "(DEBUG)"
+#else
+#define ATTRIBUTES   ""
+#endif
+
+    (VOID) XENBUS_STORE(Printf,
+                        &Fdo->StoreInterface,
+                        NULL,
+                        "drivers",
+                        Distribution,
+                        "%s %s %u.%u.%u %s",
+                        Vendor,
+                        Product,
+                        MAJOR_VERSION,
+                        MINOR_VERSION,
+                        MICRO_VERSION,
+                        ATTRIBUTES
+                        );
+
+#undef  ATTRIBUTES
+
+    Trace("<====\n");
+    return STATUS_SUCCESS;
+
+fail2:
+    Error("fail2\n");
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return status;
+}
+
+static FORCEINLINE NTSTATUS
+__FdoD3ToD0(
+    IN  PXENIFACE_FDO   Fdo
+    )
+{
+    Trace("====>\n");
+
+    ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
+
+    (VOID) FdoSetDistribution(Fdo);
+
+    Trace("<====\n");
+
+    return STATUS_SUCCESS;
+}
+
+static FORCEINLINE VOID
+__FdoD0ToD3(
+    IN  PXENIFACE_FDO   Fdo
+    )
+{
+    Trace("====>\n");
+
+    ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
+
+    FdoClearDistribution(Fdo);
+
+    Trace("<====\n");
+}
+
+static DECLSPEC_NOINLINE VOID
+FdoSuspendCallbackLate(
+    IN  PVOID       Argument
+    )
+{
+    PXENIFACE_FDO   Fdo = Argument;
+    NTSTATUS        status;
+
+    __FdoD0ToD3(Fdo);
+
+    status = __FdoD3ToD0(Fdo);
+    ASSERT(NT_SUCCESS(status));
+
+    WmiFireSuspendEvent(Fdo);
+}
+
 static DECLSPEC_NOINLINE NTSTATUS
 FdoD3ToD0(
-    IN  PXENIFACE_FDO Fdo
+    IN  PXENIFACE_FDO   Fdo
     )
 {
-    KIRQL           Irql;
-    NTSTATUS        status;
-    POWER_STATE     PowerState;
+    KIRQL               Irql;
+    NTSTATUS            status;
+    POWER_STATE         PowerState;
 
     ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+    ASSERT3U(__FdoGetDevicePowerState(Fdo), ==, PowerDeviceD3);
+
+    Trace("====>\n");
 
     KeRaiseIrql(DISPATCH_LEVEL, &Irql);
 
@@ -597,34 +940,42 @@ FdoD3ToD0(
     if (!NT_SUCCESS(status))
         goto fail3;
 
-    status = XENBUS_GNTTAB(CreateCache,
-                           &Fdo->GnttabInterface,
-                           "xeniface-gnttab",
-                           0,
-                           GnttabAcquireLock,
-                           GnttabReleaseLock,
-                           Fdo,
-                           &Fdo->GnttabCache);
+    status = XENBUS_SUSPEND(Acquire, &Fdo->SuspendInterface);
     if (!NT_SUCCESS(status))
         goto fail4;
 
-    status = XENBUS_SUSPEND(Acquire, &Fdo->SuspendInterface);
+    status = XENBUS_SHARED_INFO(Acquire, &Fdo->SharedInfoInterface);
     if (!NT_SUCCESS(status))
         goto fail5;
 
-    status = XENBUS_SHARED_INFO(Acquire, &Fdo->SharedInfoInterface);
+    Fdo->InterfacesAcquired = TRUE;
+
+    status = __FdoD3ToD0(Fdo);
     if (!NT_SUCCESS(status))
         goto fail6;
 
     status = XENBUS_SUSPEND(Register,
                             &Fdo->SuspendInterface,
                             SUSPEND_CALLBACK_LATE,
-                            WmiFireSuspendEvent,
+                            FdoSuspendCallbackLate,
                             Fdo,
                             &Fdo->SuspendCallbackLate);
     if (!NT_SUCCESS(status))
         goto fail7;
 
+    status = XENBUS_GNTTAB(CreateCache,
+                           &Fdo->GnttabInterface,
+                           "xeniface-gnttab",
+                           0,
+                           GnttabAcquireLock,
+                           GnttabReleaseLock,
+                           Fdo,
+                           &Fdo->GnttabCache);
+    if (!NT_SUCCESS(status))
+        goto fail8;
+
+    KeLowerIrql(Irql);
+
     __FdoSetDevicePowerState(Fdo, PowerDeviceD0);
 
     PowerState.DeviceState = PowerDeviceD0;
@@ -632,30 +983,34 @@ FdoD3ToD0(
                     DevicePowerState,
                     PowerState);
 
-    Fdo->InterfacesAcquired = TRUE;
-    KeLowerIrql(Irql);
-
     WmiSessionsResumeAll(Fdo);
 
+    Trace("<====\n");
+
     return STATUS_SUCCESS;
 
+fail8:
+    Error("fail8\n");
+
+    XENBUS_SUSPEND(Deregister,
+                   &Fdo->SuspendInterface,
+                   Fdo->SuspendCallbackLate);
+    Fdo->SuspendCallbackLate = NULL;
+
 fail7:
     Error("fail7\n");
 
-    XENBUS_SHARED_INFO(Release, &Fdo->SharedInfoInterface);
+    __FdoD0ToD3(Fdo);
 
 fail6:
     Error("fail6\n");
 
-    XENBUS_SUSPEND(Release, &Fdo->SuspendInterface);
+    XENBUS_SHARED_INFO(Release, &Fdo->SharedInfoInterface);
 
 fail5:
     Error("fail5\n");
 
-    XENBUS_GNTTAB(DestroyCache,
-                  &Fdo->GnttabInterface,
-                  Fdo->GnttabCache);
-    Fdo->GnttabCache = NULL;
+    XENBUS_SUSPEND(Release, &Fdo->SuspendInterface);
 
 fail4:
     Error("fail4\n");
@@ -682,45 +1037,55 @@ fail1:
 
 static DECLSPEC_NOINLINE VOID
 FdoD0ToD3(
-    IN  PXENIFACE_FDO Fdo
+    IN  PXENIFACE_FDO   Fdo
     )
 {
-    KIRQL           Irql;
-    POWER_STATE     PowerState;
+    KIRQL               Irql;
+    POWER_STATE         PowerState;
 
     ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+    ASSERT3U(__FdoGetDevicePowerState(Fdo), ==, PowerDeviceD0);
+
+    Trace("====>\n");
 
     WmiSessionsSuspendAll(Fdo);
 
+    PowerState.DeviceState = PowerDeviceD3;
+    PoSetPowerState(Fdo->Dx->DeviceObject,
+                    DevicePowerState,
+                    PowerState);
+
+    __FdoSetDevicePowerState(Fdo, PowerDeviceD3);
+
     KeRaiseIrql(DISPATCH_LEVEL, &Irql);
 
     Fdo->InterfacesAcquired = FALSE;
 
+    XENBUS_GNTTAB(DestroyCache,
+                  &Fdo->GnttabInterface,
+                  Fdo->GnttabCache);
+    Fdo->GnttabCache = NULL;
+
     XENBUS_SUSPEND(Deregister,
                    &Fdo->SuspendInterface,
                    Fdo->SuspendCallbackLate);
     Fdo->SuspendCallbackLate = NULL;
 
+    __FdoD0ToD3(Fdo);
+
     XENBUS_SHARED_INFO(Release, &Fdo->SharedInfoInterface);
-    XENBUS_SUSPEND(Release, &Fdo->SuspendInterface);
 
-    XENBUS_GNTTAB(DestroyCache,
-                  &Fdo->GnttabInterface,
-                  Fdo->GnttabCache);
-    Fdo->GnttabCache = NULL;
+    XENBUS_SUSPEND(Release, &Fdo->SuspendInterface);
 
     XENBUS_GNTTAB(Release, &Fdo->GnttabInterface);
-    XENBUS_EVTCHN(Release, &Fdo->EvtchnInterface);
-    XENBUS_STORE(Release, &Fdo->StoreInterface);
 
-    PowerState.DeviceState = PowerDeviceD3;
-    PoSetPowerState(Fdo->Dx->DeviceObject,
-                    DevicePowerState,
-                    PowerState);
+    XENBUS_EVTCHN(Release, &Fdo->EvtchnInterface);
 
-    __FdoSetDevicePowerState(Fdo, PowerDeviceD3);
+    XENBUS_STORE(Release, &Fdo->StoreInterface);
 
     KeLowerIrql(Irql);
+
+    Trace("<====\n");
 }
 
 static DECLSPEC_NOINLINE VOID
-- 
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®.