[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |