[Spice-devel] [RfC xf86-video-qxl PATCH] Use async I/O commands.

Gerd Hoffmann kraxel at redhat.com
Wed Jun 22 01:46:24 PDT 2011


Use the non-blocking versions of the I/O commands when available.
---
 src/qxl.h         |    8 +++++++
 src/qxl_driver.c  |   61 ++++++++++++++++++++++++++++++++++++++++++++++++----
 src/qxl_surface.c |    4 +-
 3 files changed, 66 insertions(+), 7 deletions(-)

diff --git a/src/qxl.h b/src/qxl.h
index a2daa8b..ac7786c 100644
--- a/src/qxl.h
+++ b/src/qxl.h
@@ -335,4 +335,12 @@ void *            qxl_allocnf          (qxl_screen_t           *qxl,
 					unsigned long           size);
 int		   qxl_garbage_collect (qxl_screen_t *qxl);
 
+/*
+ * I/O port commands
+ */
+void qxl_update_area(qxl_screen_t *qxl);
+void qxl_memslot_add(qxl_screen_t *qxl, uint8_t id);
+void qxl_create_primary(qxl_screen_t *qxl);
+void qxl_notify_oom(qxl_screen_t *qxl);
+
 #endif // QXL_H
diff --git a/src/qxl_driver.c b/src/qxl_driver.c
index 08bf2d8..e29bb00 100644
--- a/src/qxl_driver.c
+++ b/src/qxl_driver.c
@@ -42,6 +42,57 @@
 #endif
 #define CHECK_POINT()
 
+static void qxl_wait_for_io_command(qxl_screen_t *qxl)
+{
+    struct QXLRam *ram_header = (void *)(
+        (unsigned long)qxl->ram + qxl->rom->ram_header_offset);
+
+    while (!(ram_header->int_pending & QXL_INTERRUPT_IO_CMD)) {
+        usleep(1);
+    }
+    ram_header->int_pending &= ~QXL_INTERRUPT_IO_CMD;
+}
+
+void qxl_update_area(qxl_screen_t *qxl)
+{
+    if (qxl->pci->revision >= 3) {
+        outb (qxl->io_base + QXL_IO_UPDATE_AREA_ASYNC, 0);
+        qxl_wait_for_io_command(qxl);
+    } else {
+        outb (qxl->io_base + QXL_IO_UPDATE_AREA, 0);
+    }
+}
+
+void qxl_memslot_add(qxl_screen_t *qxl, uint8_t id)
+{
+    if (qxl->pci->revision >= 3) {
+        outb (qxl->io_base + QXL_IO_MEMSLOT_ADD_ASYNC, id);
+        qxl_wait_for_io_command(qxl);
+    } else {
+        outb (qxl->io_base + QXL_IO_MEMSLOT_ADD, id);
+    }
+}
+
+void qxl_create_primary(qxl_screen_t *qxl)
+{
+    if (qxl->pci->revision >= 3) {
+        outb (qxl->io_base + QXL_IO_CREATE_PRIMARY_ASYNC, 0);
+        qxl_wait_for_io_command(qxl);
+    } else {
+        outb (qxl->io_base + QXL_IO_CREATE_PRIMARY, 0);
+    }
+}
+
+void qxl_notify_oom(qxl_screen_t *qxl)
+{
+    if (qxl->pci->revision >= 3) {
+        outb (qxl->io_base + QXL_IO_NOTIFY_OOM_ASYNC, 0);
+        qxl_wait_for_io_command(qxl);
+    } else {
+        outb (qxl->io_base + QXL_IO_NOTIFY_OOM, 0);
+    }
+}
+
 int
 qxl_garbage_collect (qxl_screen_t *qxl)
 {
@@ -130,7 +181,7 @@ qxl_usleep (int useconds)
 int
 qxl_handle_oom (qxl_screen_t *qxl)
 {
-    outb (qxl->io_base + QXL_IO_NOTIFY_OOM, 0);
+    qxl_notify_oom(qxl);
     
 #if 0
     ErrorF (".");
@@ -168,7 +219,7 @@ qxl_allocnf (qxl_screen_t *qxl, unsigned long size)
 	ram_header->update_area.right = qxl->virtual_x;
 	ram_header->update_surface = 0;		/* Only primary for now */
 	
-	outb (qxl->io_base + QXL_IO_UPDATE_AREA, 0);
+        qxl_update_area(qxl);
 	
 #if 0
  	ErrorF ("eliminated memory (%d)\n", nth_oom++);
@@ -369,8 +420,8 @@ qxl_reset (qxl_screen_t *qxl)
     
     ram_header->mem_slot.mem_start = slot->start_phys_addr;
     ram_header->mem_slot.mem_end = slot->end_phys_addr;
-    
-    outb (qxl->io_base + QXL_IO_MEMSLOT_ADD, qxl->main_mem_slot);
+
+    qxl_memslot_add(qxl, qxl->main_mem_slot);
 
     slot->generation = qxl->rom->slot_generation;
     
@@ -390,7 +441,7 @@ qxl_reset (qxl_screen_t *qxl)
     ram_header->mem_slot.mem_start = slot->start_phys_addr;
     ram_header->mem_slot.mem_end = slot->end_phys_addr;
 
-    outb (qxl->io_base + QXL_IO_MEMSLOT_ADD, qxl->vram_mem_slot);
+    qxl_memslot_add(qxl, qxl->vram_mem_slot);
 
     slot->generation = qxl->rom->slot_generation;
     
diff --git a/src/qxl_surface.c b/src/qxl_surface.c
index bf91483..2e69bbf 100644
--- a/src/qxl_surface.c
+++ b/src/qxl_surface.c
@@ -378,7 +378,7 @@ qxl_surface_cache_create_primary (surface_cache_t	*cache,
     create->type = QXL_SURF_TYPE_PRIMARY;
     create->mem = physical_address (cache->qxl, cache->qxl->ram, cache->qxl->main_mem_slot);
 
-    outb (qxl->io_base + QXL_IO_CREATE_PRIMARY, 0);
+    qxl_create_primary(qxl);
 
     dev_addr = (uint8_t *)qxl->ram + mode->stride * (mode->y_res - 1);
 
@@ -920,7 +920,7 @@ download_box (qxl_surface_t *surface, int x1, int y1, int x2, int y2)
     ErrorF ("Issuing update command for %d\n", surface->id);
 #endif
 
-    outb (surface->cache->qxl->io_base + QXL_IO_UPDATE_AREA, 0);
+    qxl_update_area(surface->cache->qxl);
 
     pixman_image_composite (PIXMAN_OP_SRC,
      			    surface->dev_image,
-- 
1.7.1



More information about the Spice-devel mailing list