[Spice-commits] 7 commits - build.bat display/driver.c display/qxldd.h display/res.c display/text.c miniport/qxl.c

Alon Levy alon at kemper.freedesktop.org
Thu Oct 6 05:00:57 PDT 2011


 build.bat        |   42 ++++++++++++++++++++++++++++++++++++++++++
 display/driver.c |    1 +
 display/qxldd.h  |   42 ++++++++++++++++++++++++++++++++++++++++--
 display/res.c    |    4 ++--
 display/text.c   |    2 ++
 miniport/qxl.c   |    2 +-
 6 files changed, 88 insertions(+), 5 deletions(-)

New commits:
commit ff93ec988c6dffe0287c12b736326d160308fd3e
Author: Alon Levy <alevy at redhat.com>
Date:   Wed Oct 5 18:03:47 2011 +0200

    qxldd: push INTERRUPT_NOT_PRESENT_TIMEOUT to 60 seconds, less likely to happen out of WHQL

diff --git a/display/qxldd.h b/display/qxldd.h
index f02a71e..d0166b5 100644
--- a/display/qxldd.h
+++ b/display/qxldd.h
@@ -458,7 +458,7 @@ static _inline ULONG64 eng_time_diff_ms(ENG_TIME_FIELDS *b, ENG_TIME_FIELDS *a)
     return ret;
 }
 
-#define INTERRUPT_NOT_PRESENT_TIMEOUT_MS 2000L
+#define INTERRUPT_NOT_PRESENT_TIMEOUT_MS 60000L
 #define INTERRUPT_NOT_PRESENT_TIMEOUT_100NS (INTERRUPT_NOT_PRESENT_TIMEOUT_MS * 10000L)
 
 /* Write to an ioport. For some operations we support a new port that returns
commit 3653056819a3a55e792c2657dfb9a60189c9d2ee
Author: Alon Levy <alevy at redhat.com>
Date:   Sat Oct 1 00:08:05 2011 +0300

    display/text: add missing punting to DrvTextOut

diff --git a/display/text.c b/display/text.c
index e3b9580..b0a516a 100644
--- a/display/text.c
+++ b/display/text.c
@@ -43,6 +43,8 @@ BOOL APIENTRY DrvTextOut(SURFOBJ *surf, STROBJ *str, FONTOBJ *font, CLIPOBJ *cli
         return FALSE;
     }
 
+    PUNT_IF_DISABLED(pdev);
+
     surface_id = GetSurfaceId(surf);
 
     CountCall(pdev, CALL_COUNTER_TEXT_OUT);
commit ac69ec9abe81a7453b64df998bbf70c8dad2330b
Author: Alon Levy <alevy at redhat.com>
Date:   Wed Sep 21 19:14:06 2011 +0300

    miniport/qxl: more verbose debug on StartIO

diff --git a/miniport/qxl.c b/miniport/qxl.c
index 7006adf..aefd780 100644
--- a/miniport/qxl.c
+++ b/miniport/qxl.c
@@ -918,7 +918,7 @@ BOOLEAN StartIO(PVOID dev_extension, PVIDEO_REQUEST_PACKET packet)
     VP_STATUS error;
 
     PAGED_CODE();
-    DEBUG_PRINT((dev_ext, 0, "%s\n", __FUNCTION__));
+    DEBUG_PRINT((dev_ext, 0, "%s %d\n", __FUNCTION__, packet->IoControlCode));
 
     switch (packet->IoControlCode) {
     case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES:
commit 96b19230c6780a7c877ec53bde525b5f032de0cd
Author: Alon Levy <alevy at redhat.com>
Date:   Wed Sep 21 15:51:36 2011 +0300

    display: handle interrupt handler disappearance (rhbz 721118)
    
    This patch handles the surprise removal whql test. The surprise
    removal test sends a surprise removal IRP via a filter driver to
    qxl.sys. The handling of that IRP is actually done in videoprt.sys,
    and there is no API to get notified. The side effect of the handler
    in videoprt.sys is disabling our interrupt handler. This patch takes
    care of continuing to work after our interrupt is disabled. This is
    in effect the opposite of what the MSDN states that a device should do
    after a surprise removal, since the MSDN requires every IO to fail after
    the surprise removal IRP has been successfully handled. On the other
    hand, this workaround is sufficient to pass the test.
    
    The workaround is to turn the EngWaitForSingleEvent on the io_cmd_event
    event into a timed wait.
    
    If it fails, we revert to synchronouse IO, which doesn't require that
    event at all.

diff --git a/display/qxldd.h b/display/qxldd.h
index c1a509f..f02a71e 100644
--- a/display/qxldd.h
+++ b/display/qxldd.h
@@ -442,6 +442,25 @@ static _inline RingItem *RingGetTail(PDev *pdev, Ring *ring)
 #define WAIT_FOR_EVENT(pdev, event, timeout) EngWaitForSingleObject(event, timeout)
 #endif
 
+/* Helpers for dealing with ENG_TIME_FIELDS */
+static _inline ULONG64 eng_time_diff_ms(ENG_TIME_FIELDS *b, ENG_TIME_FIELDS *a)
+{
+    ULONG64 ret = 0;
+
+    ret += b->usMilliseconds - a->usMilliseconds;
+    ret += 1000 * (b->usSecond - a->usSecond);
+    ret += 60000 * (b->usMinute - a->usMinute);
+    ret += 3600000L * (b->usHour - a->usHour);
+    // don't get into gregorian calendar, just ignore more then a single day difference
+    if (b->usDay != a->usDay) {
+        ret += (3600L * 24L * 1000L);
+    }
+    return ret;
+}
+
+#define INTERRUPT_NOT_PRESENT_TIMEOUT_MS 2000L
+#define INTERRUPT_NOT_PRESENT_TIMEOUT_100NS (INTERRUPT_NOT_PRESENT_TIMEOUT_MS * 10000L)
+
 /* Write to an ioport. For some operations we support a new port that returns
  * immediatly, and completion is signaled by an interrupt that sets io_cmd_event.
  * If the pci_revision is >= QXL_REVISION_STABLE_V10, we support it, else do
@@ -449,10 +468,28 @@ static _inline RingItem *RingGetTail(PDev *pdev, Ring *ring)
  */
 static _inline void async_io(PDev *pdev, asyncable_t op, UCHAR val)
 {
+    ENG_TIME_FIELDS start, finish;
+    LARGE_INTEGER timeout;                      // 1 => 100 nanoseconds
+    ULONG64 millis;
+
     if (pdev->use_async) {
         EngAcquireSemaphore(pdev->io_sem);
         WRITE_PORT_UCHAR(pdev->asyncable[op][ASYNC], val);
-        WAIT_FOR_EVENT(pdev, pdev->io_cmd_event, NULL);
+        /* Our Interrupt may be taken from us unexpectedly, by a surprise removal.
+         * in which case this event will never be set. This happens only during WHQL
+         * tests (pnpdtest /surprise). So instead: Wait on a timer, if we fail, stop waiting, until
+         * we get reset. We use EngQueryLocalTime because there is no way to differentiate a return on
+         * timeout from a return on event set otherwise. */
+        timeout.QuadPart = -INTERRUPT_NOT_PRESENT_TIMEOUT_100NS; // negative  => relative
+        DEBUG_PRINT((pdev, 15, "WAIT_FOR_EVENT %d\n", (int)op));
+        EngQueryLocalTime(&start);
+        WAIT_FOR_EVENT(pdev, pdev->io_cmd_event, &timeout);
+        EngQueryLocalTime(&finish);
+        millis = eng_time_diff_ms(&finish, &start);
+        if (millis >= INTERRUPT_NOT_PRESENT_TIMEOUT_MS) {
+            pdev->use_async = 0;
+            DEBUG_PRINT((pdev, 0, "%s: timeout reached, disabling async io!\n", __FUNCTION__));
+        }
         EngReleaseSemaphore(pdev->io_sem);
         DEBUG_PRINT((pdev, 3, "finished async %d\n", (int)op));
     } else {
commit 0ba9e87062d68bae763130d027370bd3803a72c0
Author: Alon Levy <alevy at redhat.com>
Date:   Wed Sep 21 14:54:34 2011 +0300

    display: add pdev->use_async

diff --git a/display/driver.c b/display/driver.c
index de1f714..5c4578c 100644
--- a/display/driver.c
+++ b/display/driver.c
@@ -719,6 +719,7 @@ static BOOL PrepareHardware(PDev *pdev)
     }
 
     pdev->pci_revision = dev_info.pci_revision;
+    pdev->use_async = (pdev->pci_revision >= QXL_REVISION_STABLE_V10);
     pdev->cmd_ring = dev_info.cmd_ring;
     pdev->cursor_ring = dev_info.cursor_ring;
     pdev->release_ring = dev_info.release_ring;
diff --git a/display/qxldd.h b/display/qxldd.h
index 6482e8a..c1a509f 100644
--- a/display/qxldd.h
+++ b/display/qxldd.h
@@ -287,6 +287,7 @@ typedef struct PDev {
     HSEMAPHORE io_sem;
     PUCHAR memslot_del_port;
     PUCHAR flush_release_port;
+    UINT32 use_async;
 
     UINT8* primary_memory_start;
     UINT32 primary_memory_size;
@@ -448,7 +449,7 @@ static _inline RingItem *RingGetTail(PDev *pdev, Ring *ring)
  */
 static _inline void async_io(PDev *pdev, asyncable_t op, UCHAR val)
 {
-    if (pdev->pci_revision >= QXL_REVISION_STABLE_V10) {
+    if (pdev->use_async) {
         EngAcquireSemaphore(pdev->io_sem);
         WRITE_PORT_UCHAR(pdev->asyncable[op][ASYNC], val);
         WAIT_FOR_EVENT(pdev, pdev->io_cmd_event, NULL);
commit 90e361409112a5e3b739abf027bc9e46e0a4846a
Author: Alon Levy <alevy at redhat.com>
Date:   Wed Sep 21 14:53:11 2011 +0300

    build.bat copy to a dest dir if given

diff --git a/build.bat b/build.bat
index 6e579b1..bd94cea 100755
--- a/build.bat
+++ b/build.bat
@@ -2,21 +2,41 @@
 
 Rem
 Rem Build and copy to target based on environment variables set by WinDDK\bin\setenv.
+Rem if an argument is supplied the build products are copied there too under a subdirectory.
 Rem
 
 Rem Just use %BUILD_ALT_DIR%, it is equivalent
 Rem set TARGET=%DDK_TARGET_OS%_%_BUILDARCH%_%BUILD_TYPE%
+
+if not DEFINED BUILD_ALT_DIR (
+ echo BUILD_ALT_DIR not defined. Please run in a WinDDK Build Environment.
+ goto exit
+)
+
 set TARGET=install_%BUILD_ALT_DIR%
 echo TARGET=%TARGET%
 if not exist %TARGET% mkdir %TARGET%
 
+if not x%1 == x set DEST=%1
+
+:build
 cd miniport
 build -cZg
 cd ../display
 build -cZg
 cd ../
+
+:copy_local
 copy display\obj%BUILD_ALT_DIR%\i386\qxldd.dll %TARGET%
 copy miniport\obj%BUILD_ALT_DIR%\i386\qxl.sys %TARGET%
 copy miniport\qxl.inf %TARGET%
 copy display\obj%BUILD_ALT_DIR%\i386\qxldd.pdb %TARGET%
 copy miniport\obj%BUILD_ALT_DIR%\i386\qxl.pdb %TARGET%
+if not defined DEST goto exit
+if exist %DEST% (
+ echo copying to %DEST%
+ if not exist %DEST%\%TARGET% ( mkdir "%DEST%\%TARGET%" )
+ xcopy /s /y %TARGET% %DEST%\%TARGET%
+)
+
+:exit
\ No newline at end of file
commit ff75c1233e3acf48dadd976170ceb8dc820d3ef6
Author: Alon Levy <alevy at redhat.com>
Date:   Sun Sep 18 19:44:52 2011 +0300

    display: UpdateArea: improve debug messages

diff --git a/build.bat b/build.bat
new file mode 100755
index 0000000..6e579b1
--- /dev/null
+++ b/build.bat
@@ -0,0 +1,22 @@
+ at echo off
+
+Rem
+Rem Build and copy to target based on environment variables set by WinDDK\bin\setenv.
+Rem
+
+Rem Just use %BUILD_ALT_DIR%, it is equivalent
+Rem set TARGET=%DDK_TARGET_OS%_%_BUILDARCH%_%BUILD_TYPE%
+set TARGET=install_%BUILD_ALT_DIR%
+echo TARGET=%TARGET%
+if not exist %TARGET% mkdir %TARGET%
+
+cd miniport
+build -cZg
+cd ../display
+build -cZg
+cd ../
+copy display\obj%BUILD_ALT_DIR%\i386\qxldd.dll %TARGET%
+copy miniport\obj%BUILD_ALT_DIR%\i386\qxl.sys %TARGET%
+copy miniport\qxl.inf %TARGET%
+copy display\obj%BUILD_ALT_DIR%\i386\qxldd.pdb %TARGET%
+copy miniport\obj%BUILD_ALT_DIR%\i386\qxl.pdb %TARGET%
diff --git a/display/res.c b/display/res.c
index f7c0a58..e9c301e 100644
--- a/display/res.c
+++ b/display/res.c
@@ -2534,7 +2534,7 @@ void UpdateArea(PDev *pdev, RECTL *area, UINT32 surface_id)
     QXLOutput *output;
     QXLUpdateCmd *updat_cmd;
 
-    DEBUG_PRINT((pdev, 12, "%s\n", __FUNCTION__));
+    DEBUG_PRINT((pdev, 12, "%s UPDATE_CMD\n", __FUNCTION__));
 
     output = (QXLOutput *)AllocMem(pdev, sizeof(QXLOutput) + sizeof(QXLUpdateCmd));
     RESOURCE_TYPE(output, RESOURCE_TYPE_UPDATE);
@@ -2575,7 +2575,7 @@ void UpdateArea(PDev *pdev, RECTL *area, UINT32 surface_id)
 
 void UpdateArea(PDev *pdev, RECTL *area, UINT32 surface_id)
 {
-    DEBUG_PRINT((pdev, 12, "%s\n", __FUNCTION__));
+    DEBUG_PRINT((pdev, 12, "%s IO\n", __FUNCTION__));
     CopyRect(pdev->update_area, area);
     *pdev->update_surface = surface_id;
     async_io(pdev, ASYNCABLE_UPDATE_AREA, 0);


More information about the Spice-commits mailing list