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

Re: [win-pv-devel] [PATCH 2/4] xenvkbd: Move input reports to Ring.c



> -----Original Message-----
> From: win-pv-devel [mailto:win-pv-devel-bounces@xxxxxxxxxxxxxxxxxxxx] On
> Behalf Of owen.smith@xxxxxxxxxx
> Sent: 07 June 2017 16:52
> To: win-pv-devel@xxxxxxxxxxxxxxxxxxxx
> Cc: Owen Smith <owen.smith@xxxxxxxxxx>
> Subject: [win-pv-devel] [PATCH 2/4] xenvkbd: Move input reports to Ring.c
> 
> From: Owen Smith <owen.smith@xxxxxxxxxx>
> 
> Has the benefit of not requiring another suspend callback or debug
> callback
> 
> Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx>

Acked-by: Paul Durrant <paul.durrant@xxxxxxxxxx>

> ---
>  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@xxxxxxxxxxxxxxxxxxxx
> https://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel
_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
https://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®.