[prev in list] [next in list] [prev in thread] [next in thread]
List: win-pv-devel
Subject: Re: [win-pv-devel] [PATCH 2/4] xenvkbd: Move input reports to Ring.c
From: Paul Durrant <Paul.Durrant () citrix ! com>
Date: 2017-06-12 9:00:50
Message-ID: 20a343b5b913474998eec56dbf0d54b4 () AMSPEX02CL03 ! citrite ! net
[Download RAW message or body]
> -----Original Message-----
> From: win-pv-devel [mailto:win-pv-devel-bounces@lists.xenproject.org] On
> Behalf Of owen.smith@citrix.com
> Sent: 07 June 2017 16:52
> To: win-pv-devel@lists.xenproject.org
> Cc: Owen Smith <owen.smith@citrix.com>
> Subject: [win-pv-devel] [PATCH 2/4] xenvkbd: Move input reports to Ring.c
>
> From: Owen Smith <owen.smith@citrix.com>
>
> Has the benefit of not requiring another suspend callback or debug
> callback
>
> Signed-off-by: Owen Smith <owen.smith@citrix.com>
Acked-by: Paul Durrant <paul.durrant@citrix.com>
> ---
> src/xenvkbd/hid.c | 406 ++++++++---------------------------------------------
> src/xenvkbd/hid.h | 24 +---
> src/xenvkbd/pdo.h | 35 -----
> src/xenvkbd/ring.c | 271 +++++++++++++++++++++++++++++++++--
> src/xenvkbd/ring.h | 14 ++
> 5 files changed, 337 insertions(+), 413 deletions(-)
>
> diff --git a/src/xenvkbd/hid.c b/src/xenvkbd/hid.c
> index 6db6613..03fc1a2 100644
> --- a/src/xenvkbd/hid.c
> +++ b/src/xenvkbd/hid.c
> @@ -40,6 +40,7 @@
>
> #include "pdo.h"
> #include "hid.h"
> +#include "ring.h"
> #include "mrsw.h"
> #include "thread.h"
> #include "vkbd.h"
> @@ -51,20 +52,12 @@ struct _XENVKBD_HID_CONTEXT {
> PXENVKBD_PDO Pdo;
> XENVKBD_MRSW_LOCK Lock;
> LONG References;
> + PXENVKBD_RING Ring;
> PXENVKBD_FRONTEND Frontend;
> BOOLEAN Enabled;
> ULONG Version;
> XENHID_HID_CALLBACK Callback;
> PVOID Argument;
> - XENBUS_DEBUG_INTERFACE DebugInterface;
> - XENBUS_SUSPEND_INTERFACE SuspendInterface;
> - PXENBUS_DEBUG_CALLBACK DebugCallback;
> - PXENBUS_SUSPEND_CALLBACK SuspendCallbackLate;
> -
> - XENVKBD_HID_KEYBOARD KeyboardReport;
> - XENVKBD_HID_ABSMOUSE AbsMouseReport;
> - BOOLEAN KeyboardPending;
> - BOOLEAN AbsMousePending;
> };
>
> #define XENVKBD_VKBD_TAG 'FIV'
> @@ -107,68 +100,6 @@ __HidFree(
> __FreePoolWithTag(Buffer, XENVKBD_VKBD_TAG);
> }
>
> -static DECLSPEC_NOINLINE VOID
> -HidSuspendCallbackLate(
> - IN PVOID Argument
> - )
> -{
> - PXENVKBD_HID_CONTEXT Context = Argument;
> - NTSTATUS status;
> -
> - RtlZeroMemory(&Context->KeyboardReport,
> sizeof(XENVKBD_HID_KEYBOARD));
> - RtlZeroMemory(&Context->AbsMouseReport,
> sizeof(XENVKBD_HID_ABSMOUSE));
> - Context->KeyboardReport.ReportId = 1;
> - Context->AbsMouseReport.ReportId = 2;
> -
> - if (!Context->Enabled)
> - return;
> -
> - status = FrontendSetState(Context->Frontend, FRONTEND_ENABLED);
> - ASSERT(NT_SUCCESS(status));
> -}
> -
> -static DECLSPEC_NOINLINE VOID
> -HidDebugCallback(
> - IN PVOID Argument,
> - IN BOOLEAN Crashing
> - )
> -{
> - PXENVKBD_HID_CONTEXT Context = Argument;
> -
> - UNREFERENCED_PARAMETER(Crashing);
> -
> - XENBUS_DEBUG(Printf,
> - &Context->DebugInterface,
> - "%u 0x%p(0x%p)%s\n",
> - Context->Version,
> - Context->Callback,
> - Context->Argument,
> - Context->Enabled ? " ENABLED" : "");
> -
> - XENBUS_DEBUG(Printf,
> - &Context->DebugInterface,
> - "KBD: %02x %02x %02x %02x %02x %02x %02x %02x%s\n",
> - Context->KeyboardReport.ReportId,
> - Context->KeyboardReport.Modifiers,
> - Context->KeyboardReport.Keys[0],
> - Context->KeyboardReport.Keys[1],
> - Context->KeyboardReport.Keys[2],
> - Context->KeyboardReport.Keys[3],
> - Context->KeyboardReport.Keys[4],
> - Context->KeyboardReport.Keys[5],
> - Context->KeyboardPending ? " PENDING" : "");
> -
> - XENBUS_DEBUG(Printf,
> - &Context->DebugInterface,
> - "MOU: %02x %02x %04x %04x %02x%s\n",
> - Context->AbsMouseReport.ReportId,
> - Context->AbsMouseReport.Buttons,
> - Context->AbsMouseReport.X,
> - Context->AbsMouseReport.Y,
> - Context->AbsMouseReport.dZ,
> - Context->AbsMousePending ? " PENDING" : "");
> -}
> -
> static NTSTATUS
> HidEnable(
> IN PINTERFACE Interface,
> @@ -196,35 +127,9 @@ HidEnable(
>
> KeMemoryBarrier();
>
> - status = XENBUS_SUSPEND(Acquire, &Context->SuspendInterface);
> - if (!NT_SUCCESS(status))
> - goto fail1;
> -
> status = FrontendSetState(Context->Frontend, FRONTEND_ENABLED);
> if (!NT_SUCCESS(status))
> - goto fail2;
> -
> - status = XENBUS_SUSPEND(Register,
> - &Context->SuspendInterface,
> - SUSPEND_CALLBACK_LATE,
> - HidSuspendCallbackLate,
> - Context,
> - &Context->SuspendCallbackLate);
> - if (!NT_SUCCESS(status))
> - goto fail3;
> -
> - status = XENBUS_DEBUG(Acquire, &Context->DebugInterface);
> - if (!NT_SUCCESS(status))
> - goto fail4;
> -
> - status = XENBUS_DEBUG(Register,
> - &Context->DebugInterface,
> - __MODULE__"|DEBUG",
> - HidDebugCallback,
> - Context,
> - &Context->DebugCallback);
> - if (!NT_SUCCESS(status))
> - goto fail5;
> + goto fail1;
>
> done:
> ASSERT(Exclusive);
> @@ -234,32 +139,6 @@ done:
>
> return STATUS_SUCCESS;
>
> -fail5:
> - Error("fail5\n");
> -
> - XENBUS_DEBUG(Release, &Context->DebugInterface);
> -
> -fail4:
> - Error("fail4\n");
> -
> - XENBUS_SUSPEND(Deregister,
> - &Context->SuspendInterface,
> - Context->SuspendCallbackLate);
> - Context->SuspendCallbackLate = NULL;
> -
> -fail3:
> - Error("fail3\n");
> -
> - (VOID) FrontendSetState(Context->Frontend, FRONTEND_CONNECTED);
> -
> - ReleaseMrswLockExclusive(&Context->Lock, Irql, TRUE);
> - Exclusive = FALSE;
> -
> -fail2:
> - Error("fail2\n");
> -
> - XENBUS_SUSPEND(Release, &Context->SuspendInterface);
> -
> fail1:
> Error("fail1 (%08x)\n", status);
>
> @@ -299,24 +178,10 @@ HidDisable(
>
> KeMemoryBarrier();
>
> - XENBUS_DEBUG(Deregister,
> - &Context->DebugInterface,
> - Context->DebugCallback);
> - Context->DebugCallback = NULL;
> -
> - XENBUS_DEBUG(Release, &Context->DebugInterface);
> -
> - XENBUS_SUSPEND(Deregister,
> - &Context->SuspendInterface,
> - Context->SuspendCallbackLate);
> - Context->SuspendCallbackLate = NULL;
> -
> (VOID) FrontendSetState(Context->Frontend, FRONTEND_CONNECTED);
>
> ReleaseMrswLockExclusive(&Context->Lock, Irql, TRUE);
>
> - XENBUS_SUSPEND(Release, &Context->SuspendInterface);
> -
> Context->Argument = NULL;
> Context->Callback = NULL;
>
> @@ -467,8 +332,13 @@ HidGetIndexedString(
> Trace("=====>\n");
> AcquireMrswLockShared(&Context->Lock);
>
> + status = STATUS_DEVICE_NOT_READY;
> + if (!Context->Enabled)
> + goto done;
> +
> status = STATUS_NOT_SUPPORTED;
> -
> +
> +done:
> ReleaseMrswLockShared(&Context->Lock);
> Trace("<=====\n");
>
> @@ -494,8 +364,13 @@ HidGetFeature(
> Trace("=====>\n");
> AcquireMrswLockShared(&Context->Lock);
>
> + status = STATUS_DEVICE_NOT_READY;
> + if (!Context->Enabled)
> + goto done;
> +
> status = STATUS_NOT_SUPPORTED;
> -
> +
> +done:
> ReleaseMrswLockShared(&Context->Lock);
> Trace("<=====\n");
>
> @@ -520,8 +395,13 @@ HidSetFeature(
> Trace("=====>\n");
> AcquireMrswLockShared(&Context->Lock);
>
> + status = STATUS_DEVICE_NOT_READY;
> + if (!Context->Enabled)
> + goto done;
> +
> status = STATUS_NOT_SUPPORTED;
> -
> +
> +done:
> ReleaseMrswLockShared(&Context->Lock);
> Trace("<=====\n");
>
> @@ -546,32 +426,20 @@ HidGetInputReport(
> Trace("=====>\n");
> AcquireMrswLockShared(&Context->Lock);
>
> - switch (ReportId) {
> - case 1:
> - status = HidCopyBuffer(Buffer,
> - Length,
> - &Context->KeyboardReport,
> - sizeof(XENVKBD_HID_KEYBOARD),
> - Returned);
> - break;
> - case 2:
> - status = HidCopyBuffer(Buffer,
> - Length,
> - &Context->AbsMouseReport,
> - sizeof(XENVKBD_HID_ABSMOUSE),
> - Returned);
> - break;
> - default:
> - status = STATUS_NOT_SUPPORTED;
> - break;
> - }
> -
> + status = STATUS_DEVICE_NOT_READY;
> + if (!Context->Enabled)
> + goto done;
> +
> + status = RingGetInputReport(Context->Ring,
> + ReportId,
> + Buffer,
> + Length,
> + Returned);
> +
> +done:
> ReleaseMrswLockShared(&Context->Lock);
> Trace("<=====\n");
>
> - UNREFERENCED_PARAMETER(ReportId);
> - UNREFERENCED_PARAMETER(Buffer);
> - UNREFERENCED_PARAMETER(Length);
> return status;
> }
>
> @@ -589,8 +457,13 @@ HidSetOutputReport(
> Trace("=====>\n");
> AcquireMrswLockShared(&Context->Lock);
>
> + status = STATUS_DEVICE_NOT_READY;
> + if (!Context->Enabled)
> + goto done;
> +
> status = STATUS_NOT_SUPPORTED;
> -
> +
> +done:
> ReleaseMrswLockShared(&Context->Lock);
> Trace("<=====\n");
>
> @@ -600,23 +473,6 @@ HidSetOutputReport(
> return status;
> }
>
> -static BOOLEAN
> -HidSendReadReport(
> - IN PXENVKBD_HID_CONTEXT Context,
> - IN PVOID Buffer,
> - IN ULONG Length
> - )
> -{
> - if (!Context->Enabled)
> - return TRUE; // flag as pending
> -
> - // Callback returns TRUE on success, FALSE when Irp could not be
> completed
> - // Invert the result to indicate Pending state
> - return !Context->Callback(Context->Argument,
> - Buffer,
> - Length);
> -}
> -
> static VOID
> HidReadReport(
> IN PINTERFACE Interface
> @@ -626,15 +482,8 @@ HidReadReport(
>
> AcquireMrswLockShared(&Context->Lock);
>
> - // Check for pending reports, push 1 pending report to subscriber
> - if (Context->KeyboardPending)
> - Context->KeyboardPending = HidSendReadReport(Context,
> - &Context->KeyboardReport,
> - sizeof(XENVKBD_HID_KEYBOARD));
> - else if (Context->AbsMousePending)
> - Context->AbsMousePending = HidSendReadReport(Context,
> - &Context->AbsMouseReport,
> - sizeof(XENVKBD_HID_ABSMOUSE));
> + if (Context->Enabled)
> + RingReadReport(Context->Ring);
>
> ReleaseMrswLockShared(&Context->Lock);
> }
> @@ -653,8 +502,13 @@ HidWriteReport(
> Trace("=====>\n");
> AcquireMrswLockShared(&Context->Lock);
>
> + status = STATUS_DEVICE_NOT_READY;
> + if (!Context->Enabled)
> + goto done;
> +
> status = STATUS_NOT_SUPPORTED;
> -
> +
> +done:
> ReleaseMrswLockShared(&Context->Lock);
> Trace("<=====\n");
>
> @@ -680,6 +534,7 @@ HidAcquire(
> Trace("====>\n");
>
> Context->Frontend = PdoGetFrontend(Context->Pdo);
> + Context->Ring = FrontendGetRing(Context->Frontend);
> Context->Version = Interface->Version;
>
> Trace("<====\n");
> @@ -709,6 +564,7 @@ HidRelease(
>
> Context->Version = 0;
> Context->Frontend = NULL;
> + Context->Ring = NULL;
>
> Trace("<====\n");
>
> @@ -753,12 +609,7 @@ HidInitialize(
>
> InitializeMrswLock(&(*Context)->Lock);
>
> - FdoGetDebugInterface(PdoGetFdo(Pdo),&(*Context)->DebugInterface);
> - FdoGetSuspendInterface(PdoGetFdo(Pdo),&(*Context)-
> >SuspendInterface);
> -
> (*Context)->Pdo = Pdo;
> - (*Context)->KeyboardReport.ReportId = 1;
> - (*Context)->AbsMouseReport.ReportId = 2;
>
> Trace("<====\n");
>
> @@ -813,19 +664,9 @@ HidTeardown(
> {
> Trace("====>\n");
>
> - RtlZeroMemory(&Context->KeyboardReport,
> sizeof(XENVKBD_HID_KEYBOARD));
> - RtlZeroMemory(&Context->AbsMouseReport,
> sizeof(XENVKBD_HID_ABSMOUSE));
> - Context->KeyboardPending = FALSE;
> - Context->AbsMousePending = FALSE;
> -
> Context->Pdo = NULL;
> Context->Version = 0;
>
> - RtlZeroMemory(&Context->SuspendInterface,
> - sizeof (XENBUS_SUSPEND_INTERFACE));
> - RtlZeroMemory(&Context->DebugInterface,
> - sizeof (XENBUS_DEBUG_INTERFACE));
> -
> RtlZeroMemory(&Context->Lock, sizeof (XENVKBD_MRSW_LOCK));
>
> ASSERT(IsZeroMemory(Context, sizeof (XENVKBD_HID_CONTEXT)));
> @@ -834,148 +675,19 @@ HidTeardown(
> Trace("<====\n");
> }
>
> -static FORCEINLINE LONG
> -Constrain(
> - IN LONG Value,
> - IN LONG Min,
> - IN LONG Max
> - )
> -{
> - if (Value < Min)
> - return Min;
> - if (Value > Max)
> - return Max;
> - return Value;
> -}
> -
> -static FORCEINLINE UCHAR
> -SetBit(
> - IN UCHAR Value,
> - IN UCHAR BitIdx,
> - IN BOOLEAN Pressed
> - )
> -{
> - if (Pressed) {
> - return Value | (1 << BitIdx);
> - } else {
> - return Value & ~(1 << BitIdx);
> - }
> -}
> -
> -static FORCEINLINE VOID
> -SetArray(
> - IN PUCHAR Array,
> - IN ULONG Size,
> - IN UCHAR Value,
> - IN BOOLEAN Pressed
> - )
> -{
> - ULONG Idx;
> - if (Pressed) {
> - for (Idx = 0; Idx < Size; ++Idx) {
> - if (Array[Idx] == Value)
> - break;
> - if (Array[Idx] != 0)
> - continue;
> - Array[Idx] = Value;
> - break;
> - }
> - } else {
> - for (Idx = 0; Idx < Size; ++Idx) {
> - if (Array[Idx] == 0)
> - break;
> - if (Array[Idx] != Value)
> - continue;
> - for (; Idx < Size - 1; ++Idx)
> - Array[Idx] = Array[Idx + 1];
> - Array[Size - 1] = 0;
> - break;
> - }
> - }
> -}
> -
> -static FORCEINLINE USHORT
> -KeyCodeToUsage(
> - IN ULONG KeyCode
> - )
> -{
> - if (KeyCode <
> sizeof(VkbdKeyCodeToUsage)/sizeof(VkbdKeyCodeToUsage[0]))
> - return VkbdKeyCodeToUsage[KeyCode];
> - return 0;
> -}
> -
> -VOID
> -HidEventMotion(
> - IN PXENVKBD_HID_CONTEXT Context,
> - IN LONG dX,
> - IN LONG dY,
> - IN LONG dZ
> - )
> -{
> - Context->AbsMouseReport.X = (USHORT)Constrain(Context-
> >AbsMouseReport.X + dX, 0, 32767);
> - Context->AbsMouseReport.Y = (USHORT)Constrain(Context-
> >AbsMouseReport.Y + dY, 0, 32767);
> - Context->AbsMouseReport.dZ = -(CHAR)Constrain(dZ, -127, 127);
> -
> - Context->AbsMousePending = HidSendReadReport(Context,
> - &Context->AbsMouseReport,
> - sizeof(XENVKBD_HID_ABSMOUSE));
> -}
> -
> -VOID
> -HidEventKeypress(
> - IN PXENVKBD_HID_CONTEXT Context,
> - IN ULONG KeyCode,
> - IN BOOLEAN Pressed
> - )
> -{
> - if (KeyCode >= 0x110 && KeyCode <= 0x114) {
> - // Mouse Buttons
> - Context->AbsMouseReport.Buttons = SetBit(Context-
> >AbsMouseReport.Buttons,
> - (UCHAR)(KeyCode - 0x110),
> - Pressed);
> -
> - Context->AbsMousePending = HidSendReadReport(Context,
> - &Context->AbsMouseReport,
> - sizeof(XENVKBD_HID_ABSMOUSE));
> -
> - } else {
> - // map KeyCode to Usage
> - USHORT Usage = KeyCodeToUsage(KeyCode);
> - if (Usage == 0)
> - return; // non-standard key
> -
> - if (Usage >= 0xE0 && Usage <= 0xE7) {
> - // Modifier
> - Context->KeyboardReport.Modifiers = SetBit(Context-
> >KeyboardReport.Modifiers,
> - (UCHAR)(Usage - 0xE0),
> - Pressed);
> - } else {
> - // Standard Key
> - SetArray(Context->KeyboardReport.Keys,
> - 6,
> - (UCHAR)Usage,
> - Pressed);
> - }
> - Context->KeyboardPending = HidSendReadReport(Context,
> - &Context->KeyboardReport,
> - sizeof(XENVKBD_HID_KEYBOARD));
> -
> - }
> -}
> -
> -VOID
> -HidEventPosition(
> +BOOLEAN
> +HidSendReadReport(
> IN PXENVKBD_HID_CONTEXT Context,
> - IN ULONG X,
> - IN ULONG Y,
> - IN LONG dZ
> + IN PVOID Buffer,
> + IN ULONG Length
> )
> {
> - Context->AbsMouseReport.X = (USHORT)Constrain(X, 0, 32767);
> - Context->AbsMouseReport.Y = (USHORT)Constrain(Y, 0, 32767);
> - Context->AbsMouseReport.dZ = -(CHAR)Constrain(dZ, -127, 127);
> + if (!Context->Enabled)
> + return TRUE; // flag as pending
>
> - Context->AbsMousePending = HidSendReadReport(Context,
> - &Context->AbsMouseReport,
> - sizeof(XENVKBD_HID_ABSMOUSE));
> + // Callback returns TRUE on success, FALSE when Irp could not be
> completed
> + // Invert the result to indicate Pending state
> + return !Context->Callback(Context->Argument,
> + Buffer,
> + Length);
> }
> diff --git a/src/xenvkbd/hid.h b/src/xenvkbd/hid.h
> index ec38e28..116f749 100644
> --- a/src/xenvkbd/hid.h
> +++ b/src/xenvkbd/hid.h
> @@ -62,27 +62,11 @@ HidTeardown(
>
> // CALLBACKS
>
> -extern VOID
> -HidEventMotion(
> - IN PXENVKBD_HID_CONTEXT Context,
> - IN LONG dX,
> - IN LONG dY,
> - IN LONG dZ
> - );
> -
> -extern VOID
> -HidEventKeypress(
> - IN PXENVKBD_HID_CONTEXT Context,
> - IN ULONG KeyCode,
> - IN BOOLEAN Pressed
> - );
> -
> -extern VOID
> -HidEventPosition(
> +extern BOOLEAN
> +HidSendReadReport(
> IN PXENVKBD_HID_CONTEXT Context,
> - IN ULONG X,
> - IN ULONG Y,
> - IN LONG dZ
> + IN PVOID Buffer,
> + IN ULONG Length
> );
>
> #endif // _XENVKBD_VKBD_H
> diff --git a/src/xenvkbd/pdo.h b/src/xenvkbd/pdo.h
> index a23811e..5e68a86 100644
> --- a/src/xenvkbd/pdo.h
> +++ b/src/xenvkbd/pdo.h
> @@ -147,36 +147,6 @@ PdoGetFrontend(
> IN PXENVKBD_PDO Pdo
> );
>
> -extern PXENBUS_EVTCHN_INTERFACE
> -PdoGetEvtchnInterface(
> - IN PXENVKBD_PDO Pdo
> - );
> -
> -extern PXENBUS_DEBUG_INTERFACE
> -PdoGetDebugInterface(
> - IN PXENVKBD_PDO Pdo
> - );
> -
> -extern PXENBUS_STORE_INTERFACE
> -PdoGetStoreInterface(
> - IN PXENVKBD_PDO Pdo
> - );
> -
> -extern PXENBUS_CACHE_INTERFACE
> -PdoGetCacheInterface(
> - IN PXENVKBD_PDO Pdo
> - );
> -
> -extern PXENBUS_GNTTAB_INTERFACE
> -PdoGetGnttabInterface(
> - IN PXENVKBD_PDO Pdo
> - );
> -
> -extern PXENBUS_SUSPEND_INTERFACE
> -PdoGetSuspendInterface(
> - IN PXENVKBD_PDO Pdo
> - );
> -
> #include "hid.h"
>
> extern PXENVKBD_HID_CONTEXT
> @@ -184,11 +154,6 @@ PdoGetHidContext(
> IN PXENVKBD_PDO Pdo
> );
>
> -extern PXENHID_HID_INTERFACE
> -PdoGetHidInterface(
> - IN PXENVKBD_PDO Pdo
> - );
> -
> extern NTSTATUS
> PdoDispatch(
> IN PXENVKBD_PDO Pdo,
> diff --git a/src/xenvkbd/ring.c b/src/xenvkbd/ring.c
> index dd15807..da1bd17 100644
> --- a/src/xenvkbd/ring.c
> +++ b/src/xenvkbd/ring.c
> @@ -46,6 +46,7 @@
> #include "frontend.h"
> #include "ring.h"
> #include "hid.h"
> +#include "vkbd.h"
> #include "thread.h"
> #include "registry.h"
> #include "dbg_print.h"
> @@ -77,6 +78,11 @@ struct _XENVKBD_RING {
> BOOLEAN Connected;
> BOOLEAN Enabled;
> BOOLEAN AbsPointer;
> +
> + XENVKBD_HID_KEYBOARD KeyboardReport;
> + XENVKBD_HID_ABSMOUSE AbsMouseReport;
> + BOOLEAN KeyboardPending;
> + BOOLEAN AbsMousePending;
> };
>
> #define XENVKBD_RING_TAG 'gniR'
> @@ -97,6 +103,174 @@ __RingFree(
> __FreePoolWithTag(Buffer, XENVKBD_RING_TAG);
> }
>
> +static FORCEINLINE NTSTATUS
> +__RingCopyBuffer(
> + IN PVOID Buffer,
> + IN ULONG Length,
> + IN const VOID *Source,
> + IN ULONG SourceLength,
> + OUT PULONG Returned
> + )
> +{
> + if (Buffer == NULL)
> + return STATUS_INVALID_PARAMETER;
> + if (Length < SourceLength)
> + return STATUS_NO_MEMORY;
> +
> + RtlCopyMemory(Buffer,
> + Source,
> + SourceLength);
> + if (Returned)
> + *Returned = SourceLength;
> + return STATUS_SUCCESS;
> +}
> +
> +static FORCEINLINE LONG
> +Constrain(
> + IN LONG Value,
> + IN LONG Min,
> + IN LONG Max
> + )
> +{
> + if (Value < Min)
> + return Min;
> + if (Value > Max)
> + return Max;
> + return Value;
> +}
> +
> +static FORCEINLINE UCHAR
> +SetBit(
> + IN UCHAR Value,
> + IN UCHAR BitIdx,
> + IN BOOLEAN Pressed
> + )
> +{
> + if (Pressed) {
> + return Value | (1 << BitIdx);
> + } else {
> + return Value & ~(1 << BitIdx);
> + }
> +}
> +
> +static FORCEINLINE VOID
> +SetArray(
> + IN PUCHAR Array,
> + IN ULONG Size,
> + IN UCHAR Value,
> + IN BOOLEAN Pressed
> + )
> +{
> + ULONG Idx;
> + if (Pressed) {
> + for (Idx = 0; Idx < Size; ++Idx) {
> + if (Array[Idx] == Value)
> + break;
> + if (Array[Idx] != 0)
> + continue;
> + Array[Idx] = Value;
> + break;
> + }
> + } else {
> + for (Idx = 0; Idx < Size; ++Idx) {
> + if (Array[Idx] == 0)
> + break;
> + if (Array[Idx] != Value)
> + continue;
> + for (; Idx < Size - 1; ++Idx)
> + Array[Idx] = Array[Idx + 1];
> + Array[Size - 1] = 0;
> + break;
> + }
> + }
> +}
> +
> +static FORCEINLINE USHORT
> +KeyCodeToUsage(
> + IN ULONG KeyCode
> + )
> +{
> + if (KeyCode <
> sizeof(VkbdKeyCodeToUsage)/sizeof(VkbdKeyCodeToUsage[0]))
> + return VkbdKeyCodeToUsage[KeyCode];
> + return 0;
> +}
> +
> +static FORCEINLINE VOID
> +__RingEventMotion(
> + IN PXENVKBD_RING Ring,
> + IN LONG dX,
> + IN LONG dY,
> + IN LONG dZ
> + )
> +{
> + Ring->AbsMouseReport.X = (USHORT)Constrain(Ring-
> >AbsMouseReport.X + dX, 0, 32767);
> + Ring->AbsMouseReport.Y = (USHORT)Constrain(Ring-
> >AbsMouseReport.Y + dY, 0, 32767);
> + Ring->AbsMouseReport.dZ = -(CHAR)Constrain(dZ, -127, 127);
> +
> + Ring->AbsMousePending = HidSendReadReport(Ring->Hid,
> + &Ring->AbsMouseReport,
> + sizeof(XENVKBD_HID_ABSMOUSE));
> +}
> +
> +static FORCEINLINE VOID
> +__RingEventKeypress(
> + IN PXENVKBD_RING Ring,
> + IN ULONG KeyCode,
> + IN BOOLEAN Pressed
> + )
> +{
> + if (KeyCode >= 0x110 && KeyCode <= 0x114) {
> + // Mouse Buttons
> + Ring->AbsMouseReport.Buttons = SetBit(Ring-
> >AbsMouseReport.Buttons,
> + (UCHAR)(KeyCode - 0x110),
> + Pressed);
> +
> + Ring->AbsMousePending = HidSendReadReport(Ring->Hid,
> + &Ring->AbsMouseReport,
> + sizeof(XENVKBD_HID_ABSMOUSE));
> +
> + } else {
> + // map KeyCode to Usage
> + USHORT Usage = KeyCodeToUsage(KeyCode);
> + if (Usage == 0)
> + return; // non-standard key
> +
> + if (Usage >= 0xE0 && Usage <= 0xE7) {
> + // Modifier
> + Ring->KeyboardReport.Modifiers = SetBit(Ring-
> >KeyboardReport.Modifiers,
> + (UCHAR)(Usage - 0xE0),
> + Pressed);
> + } else {
> + // Standard Key
> + SetArray(Ring->KeyboardReport.Keys,
> + 6,
> + (UCHAR)Usage,
> + Pressed);
> + }
> + Ring->KeyboardPending = HidSendReadReport(Ring->Hid,
> + &Ring->KeyboardReport,
> + sizeof(XENVKBD_HID_KEYBOARD));
> +
> + }
> +}
> +
> +static FORCEINLINE VOID
> +__RingEventPosition(
> + IN PXENVKBD_RING Ring,
> + IN ULONG X,
> + IN ULONG Y,
> + IN LONG dZ
> + )
> +{
> + Ring->AbsMouseReport.X = (USHORT)Constrain(X, 0, 32767);
> + Ring->AbsMouseReport.Y = (USHORT)Constrain(Y, 0, 32767);
> + Ring->AbsMouseReport.dZ = -(CHAR)Constrain(dZ, -127, 127);
> +
> + Ring->AbsMousePending = HidSendReadReport(Ring->Hid,
> + &Ring->AbsMouseReport,
> + sizeof(XENVKBD_HID_ABSMOUSE));
> +}
> +
> __drv_functionClass(KDEFERRED_ROUTINE)
> __drv_maxIRQL(DISPATCH_LEVEL)
> __drv_minIRQL(DISPATCH_LEVEL)
> @@ -140,21 +314,21 @@ RingDpc(
>
> switch (in_evt->type) {
> case XENKBD_TYPE_MOTION:
> - HidEventMotion(Ring->Hid,
> - in_evt->motion.rel_x,
> - in_evt->motion.rel_y,
> - in_evt->motion.rel_z);
> + __RingEventMotion(Ring,
> + in_evt->motion.rel_x,
> + in_evt->motion.rel_y,
> + in_evt->motion.rel_z);
> break;
> case XENKBD_TYPE_KEY:
> - HidEventKeypress(Ring->Hid,
> - in_evt->key.keycode,
> - in_evt->key.pressed);
> + __RingEventKeypress(Ring,
> + in_evt->key.keycode,
> + in_evt->key.pressed);
> break;
> case XENKBD_TYPE_POS:
> - HidEventPosition(Ring->Hid,
> - in_evt->pos.abs_x,
> - in_evt->pos.abs_y,
> - in_evt->pos.rel_z);
> + __RingEventPosition(Ring,
> + in_evt->pos.abs_x,
> + in_evt->pos.abs_y,
> + in_evt->pos.rel_z);
> break;
> case XENKBD_TYPE_MTOUCH:
> Trace("MTOUCH: %u %u %u %u\n",
> @@ -237,6 +411,29 @@ RingDebugCallback(
> "0x%p [%s]\n",
> Ring,
> (Ring->Enabled) ? "ENABLED" : "DISABLED");
> +
> + XENBUS_DEBUG(Printf,
> + &Ring->DebugInterface,
> + "KBD: %02x %02x %02x %02x %02x %02x %02x %02x%s\n",
> + Ring->KeyboardReport.ReportId,
> + Ring->KeyboardReport.Modifiers,
> + Ring->KeyboardReport.Keys[0],
> + Ring->KeyboardReport.Keys[1],
> + Ring->KeyboardReport.Keys[2],
> + Ring->KeyboardReport.Keys[3],
> + Ring->KeyboardReport.Keys[4],
> + Ring->KeyboardReport.Keys[5],
> + Ring->KeyboardPending ? " PENDING" : "");
> +
> + XENBUS_DEBUG(Printf,
> + &Ring->DebugInterface,
> + "MOU: %02x %02x %04x %04x %02x%s\n",
> + Ring->AbsMouseReport.ReportId,
> + Ring->AbsMouseReport.Buttons,
> + Ring->AbsMouseReport.X,
> + Ring->AbsMouseReport.Y,
> + Ring->AbsMouseReport.dZ,
> + Ring->AbsMousePending ? " PENDING" : "");
> }
>
> NTSTATUS
> @@ -341,6 +538,8 @@ RingConnect(
> if (!NT_SUCCESS(status))
> goto fail5;
>
> + Ring->KeyboardReport.ReportId = 1;
> + Ring->AbsMouseReport.ReportId = 2;
> RingReadFeatures(Ring);
>
> Ring->Mdl = __AllocatePage();
> @@ -589,6 +788,13 @@ RingDisconnect(
> __FreePage(Ring->Mdl);
> Ring->Mdl = NULL;
>
> + RtlZeroMemory(&Ring->KeyboardReport,
> + sizeof(XENVKBD_HID_KEYBOARD));
> + RtlZeroMemory(&Ring->AbsMouseReport,
> + sizeof(XENVKBD_HID_ABSMOUSE));
> + Ring->KeyboardPending = FALSE;
> + Ring->AbsMousePending = FALSE;
> +
> XENBUS_GNTTAB(DestroyCache,
> &Ring->GnttabInterface,
> Ring->GnttabCache);
> @@ -645,3 +851,46 @@ RingNotify(
> if (KeInsertQueueDpc(&Ring->Dpc, NULL, NULL))
> Ring->Dpcs++;
> }
> +
> +NTSTATUS
> +RingGetInputReport(
> + IN PXENVKBD_RING Ring,
> + IN ULONG ReportId,
> + IN PVOID Buffer,
> + IN ULONG Length,
> + OUT PULONG Returned
> + )
> +{
> + switch (ReportId) {
> + case 1:
> + return __RingCopyBuffer(Buffer,
> + Length,
> + &Ring->KeyboardReport,
> + sizeof(XENVKBD_HID_KEYBOARD),
> + Returned);
> + case 2:
> + return __RingCopyBuffer(Buffer,
> + Length,
> + &Ring->AbsMouseReport,
> + sizeof(XENVKBD_HID_ABSMOUSE),
> + Returned);
> + default:
> + return STATUS_NOT_SUPPORTED;
> + }
> +}
> +
> +VOID
> +RingReadReport(
> + IN PXENVKBD_RING Ring
> + )
> +{
> + // Check for pending reports, push 1 pending report to subscriber
> + if (Ring->KeyboardPending)
> + Ring->KeyboardPending = HidSendReadReport(Ring->Hid,
> + &Ring->KeyboardReport,
> + sizeof(XENVKBD_HID_KEYBOARD));
> + else if (Ring->AbsMousePending)
> + Ring->AbsMousePending = HidSendReadReport(Ring->Hid,
> + &Ring->AbsMouseReport,
> + sizeof(XENVKBD_HID_ABSMOUSE));
> +}
> diff --git a/src/xenvkbd/ring.h b/src/xenvkbd/ring.h
> index 09d1f8e..bfc6c4f 100644
> --- a/src/xenvkbd/ring.h
> +++ b/src/xenvkbd/ring.h
> @@ -82,4 +82,18 @@ RingNotify(
> IN PXENVKBD_RING Ring
> );
>
> +extern NTSTATUS
> +RingGetInputReport(
> + IN PXENVKBD_RING Ring,
> + IN ULONG ReportId,
> + IN PVOID Buffer,
> + IN ULONG Length,
> + OUT PULONG Returned
> + );
> +
> +extern VOID
> +RingReadReport(
> + IN PXENVKBD_RING Ring
> + );
> +
> #endif // _XENVKBD_RING_H
> --
> 2.8.3
>
>
> _______________________________________________
> win-pv-devel mailing list
> win-pv-devel@lists.xenproject.org
> https://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel
_______________________________________________
win-pv-devel mailing list
win-pv-devel@lists.xenproject.org
https://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic