Home | History | Annotate | Line # | Download | only in src
      1 /*
      2  * Copyright 2008 Red Hat, Inc.
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * on the rights to use, copy, modify, merge, publish, distribute, sub
      8  * license, and/or sell copies of the Software, and to permit persons to whom
      9  * the Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice (including the next
     12  * paragraph) shall be included in all copies or substantial portions of the
     13  * Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
     18  * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
     19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     21  */
     22 
     23 /** \file qxl_driver.c
     24  * \author Adam Jackson <ajax (at) redhat.com>
     25  * \author Sren Sandmann <sandmann (at) redhat.com>
     26  *
     27  * This is qxl, a driver for the Qumranet paravirtualized graphics device
     28  * in qemu.
     29  */
     30 
     31 #ifdef HAVE_CONFIG_H
     32 #include "config.h"
     33 #endif
     34 
     35 #include <unistd.h>
     36 #include <string.h>
     37 #include <stdio.h>
     38 #include <errno.h>
     39 #include <time.h>
     40 #include <stdlib.h>
     41 
     42 #include <xf86Crtc.h>
     43 #include <xf86RandR12.h>
     44 
     45 #include "qxl.h"
     46 #include "assert.h"
     47 #include "qxl_option_helpers.h"
     48 #include <spice/protocol.h>
     49 
     50 #ifdef XSPICE
     51 #include "spiceqxl_driver.h"
     52 #include "spiceqxl_main_loop.h"
     53 #include "spiceqxl_display.h"
     54 #include "spiceqxl_inputs.h"
     55 #include "spiceqxl_io_port.h"
     56 #include "spiceqxl_spice_server.h"
     57 #include "spiceqxl_audio.h"
     58 #include "spiceqxl_smartcard.h"
     59 #include "spiceqxl_vdagent.h"
     60 #endif /* XSPICE */
     61 
     62 #include "dfps.h"
     63 
     64 extern void compat_init_scrn (ScrnInfoPtr);
     65 
     66 #define BREAKPOINT()   do { __asm__ __volatile__ ("int $03"); } while (0)
     67 
     68 #ifdef XSPICE
     69 static char filter_str[] = "filter";
     70 static char auto_str[]   = "auto";
     71 static char auto_glz_str[]   = "auto_glz";
     72 static char spice_vdagent_virtio_path_default[] = "/tmp/xspice-virtio";
     73 static char spice_vdagent_uinput_path_default[] = "/tmp/xspice-uinput";
     74 #endif
     75 static char driver_name[] = QXL_DRIVER_NAME;
     76 static const OptionInfoRec DefaultOptions[] =
     77 {
     78     { OPTION_ENABLE_IMAGE_CACHE,
     79       "EnableImageCache",         OPTV_BOOLEAN, { 1 }, FALSE },
     80     { OPTION_ENABLE_FALLBACK_CACHE,
     81       "EnableFallbackCache",      OPTV_BOOLEAN, { 1 }, FALSE },
     82     { OPTION_ENABLE_SURFACES,
     83       "EnableSurfaces",           OPTV_BOOLEAN, { 1 }, FALSE },
     84     { OPTION_DEBUG_RENDER_FALLBACKS,
     85       "DebugRenderFallbacks",     OPTV_BOOLEAN, { 0 }, FALSE },
     86     { OPTION_NUM_HEADS,
     87       "NumHeads",                 OPTV_INTEGER, { 4 }, FALSE },
     88     { OPTION_SPICE_DEFERRED_FPS,
     89       "SpiceDeferredFPS",         OPTV_INTEGER, { 0 }, FALSE},
     90 #ifdef XSPICE
     91     { OPTION_SPICE_PORT,
     92       "SpicePort",                OPTV_INTEGER,   {5900}, FALSE },
     93     { OPTION_SPICE_TLS_PORT,
     94       "SpiceTlsPort",             OPTV_INTEGER,   {0}, FALSE},
     95     { OPTION_SPICE_ADDR,
     96       "SpiceAddr",                OPTV_STRING,    {0}, FALSE},
     97     { OPTION_SPICE_X509_DIR,
     98       "SpiceX509Dir",             OPTV_STRING,    {0}, FALSE},
     99     { OPTION_SPICE_SASL,
    100       "SpiceSasl",                OPTV_BOOLEAN,   {0}, FALSE},
    101     { OPTION_SPICE_AGENT_MOUSE,
    102       "SpiceAgentMouse",          OPTV_BOOLEAN,   {0}, TRUE },
    103     { OPTION_SPICE_DISABLE_TICKETING,
    104       "SpiceDisableTicketing",    OPTV_BOOLEAN,   {0}, FALSE},
    105     { OPTION_SPICE_PASSWORD,
    106       "SpicePassword",            OPTV_STRING,    {0}, FALSE},
    107     { OPTION_SPICE_X509_KEY_FILE,
    108       "SpiceX509KeyFile",         OPTV_STRING,    {0}, FALSE},
    109     { OPTION_SPICE_STREAMING_VIDEO,
    110       "SpiceStreamingVideo",      OPTV_STRING,    {.str = filter_str}, FALSE},
    111     { OPTION_SPICE_PLAYBACK_COMPRESSION,
    112       "SpicePlaybackCompression", OPTV_BOOLEAN,   {1}, FALSE},
    113     { OPTION_SPICE_ZLIB_GLZ_WAN_COMPRESSION,
    114       "SpiceZlibGlzWanCompression", OPTV_STRING,  {.str = auto_str}, FALSE},
    115     { OPTION_SPICE_JPEG_WAN_COMPRESSION,
    116       "SpiceJpegWanCompression",  OPTV_STRING,    {.str = auto_str}, FALSE},
    117     { OPTION_SPICE_IMAGE_COMPRESSION,
    118       "SpiceImageCompression",    OPTV_STRING,    {.str = auto_glz_str}, FALSE},
    119     { OPTION_SPICE_DISABLE_COPY_PASTE,
    120       "SpiceDisableCopyPaste",    OPTV_BOOLEAN,   {0}, FALSE},
    121     { OPTION_SPICE_IPV4_ONLY,
    122       "SpiceIPV4Only",            OPTV_BOOLEAN,   {0}, FALSE},
    123     { OPTION_SPICE_IPV6_ONLY,
    124       "SpiceIPV6Only",            OPTV_BOOLEAN,   {0}, FALSE},
    125     { OPTION_SPICE_X509_CERT_FILE,
    126       "SpiceX509CertFile",        OPTV_STRING,    {0}, FALSE},
    127     { OPTION_SPICE_X509_KEY_PASSWORD,
    128       "SpiceX509KeyPassword",     OPTV_STRING,    {0}, FALSE},
    129     { OPTION_SPICE_TLS_CIPHERS,
    130       "SpiceTlsCiphers",          OPTV_STRING,    {0}, FALSE},
    131     { OPTION_SPICE_CACERT_FILE,
    132       "SpiceCacertFile",          OPTV_STRING,    {0}, FALSE},
    133     { OPTION_SPICE_DH_FILE,
    134       "SpiceDhFile",              OPTV_STRING,    {0}, FALSE},
    135     { OPTION_SPICE_EXIT_ON_DISCONNECT,
    136       "SpiceExitOnDisconnect",    OPTV_BOOLEAN,   {0}, FALSE},
    137     { OPTION_SPICE_PLAYBACK_FIFO_DIR,
    138       "SpicePlaybackFIFODir",     OPTV_STRING,    {0}, FALSE},
    139     { OPTION_SPICE_VDAGENT_ENABLED,
    140       "SpiceVdagentEnabled",      OPTV_BOOLEAN,   {0}, FALSE},
    141     { OPTION_SPICE_VDAGENT_VIRTIO_PATH,
    142       "SpiceVdagentVirtioPath",   OPTV_STRING,    {.str = spice_vdagent_virtio_path_default}, FALSE},
    143     { OPTION_SPICE_VDAGENT_UINPUT_PATH,
    144       "SpiceVdagentUinputPath",   OPTV_STRING,    {.str = spice_vdagent_uinput_path_default}, FALSE},
    145     { OPTION_SPICE_VDAGENT_UID,
    146       "SpiceVdagentUid",          OPTV_INTEGER,    {0}, FALSE},
    147     { OPTION_SPICE_VDAGENT_GID,
    148       "SpiceVdagentGid",          OPTV_INTEGER,    {0}, FALSE},
    149     { OPTION_FRAME_BUFFER_SIZE,
    150       "FrameBufferSize",          OPTV_INTEGER,    {DEFAULT_FRAME_BUFFER_SIZE}, FALSE},
    151     { OPTION_SURFACE_BUFFER_SIZE,
    152       "SurfaceBufferSize",        OPTV_INTEGER,    {DEFAULT_SURFACE_BUFFER_SIZE}, FALSE},
    153     { OPTION_COMMAND_BUFFER_SIZE,
    154       "CommandBufferSize",        OPTV_INTEGER,    {DEFAULT_COMMAND_BUFFER_SIZE}, FALSE},
    155     { OPTION_SPICE_SMARTCARD_FILE,
    156       "SpiceSmartcardFile",       OPTV_STRING,    {0}, FALSE},
    157     { OPTION_SPICE_VIDEO_CODECS,
    158       "SpiceVideoCodecs",         OPTV_STRING,    {0}, FALSE},
    159 #endif
    160 
    161     { -1, NULL, OPTV_NONE, {0}, FALSE }
    162 };
    163 
    164 static const OptionInfoRec *
    165 qxl_available_options (int chipid, int busid)
    166 {
    167     return DefaultOptions;
    168 }
    169 
    170 /* Having a single monitors config struct allocated on the device avoids any
    171  * possible fragmentation. Since X is single threaded there is no danger
    172  * in us changing it between issuing the io and getting the interrupt to signal
    173  * spice-server is done reading it.
    174  */
    175 #define MAX_MONITORS_NUM 16
    176 
    177 void
    178 qxl_allocate_monitors_config (qxl_screen_t *qxl)
    179 {
    180     qxl->monitors_config = (QXLMonitorsConfig *)(void *)
    181 	((unsigned long)qxl->ram + qxl->rom->ram_header_offset - qxl->monitors_config_size);
    182 }
    183 
    184 static Bool
    185 qxl_blank_screen (ScreenPtr pScreen, int mode)
    186 {
    187     return TRUE;
    188 }
    189 
    190 #ifdef XSPICE
    191 static void
    192 unmap_memory_helper (qxl_screen_t *qxl)
    193 {
    194     free (qxl->ram);
    195     free (qxl->vram);
    196     free (qxl->rom);
    197 }
    198 
    199 static void
    200 map_memory_helper (qxl_screen_t *qxl)
    201 {
    202     qxl->ram = calloc (qxl->ram_size, 1);
    203     qxl->ram_physical = qxl->ram;
    204     qxl->vram = calloc (qxl->vram_size, 1);
    205     qxl->vram_physical = qxl->vram;
    206     qxl->rom = calloc (ROM_SIZE, 1);
    207 
    208     init_qxl_rom (qxl, ROM_SIZE);
    209 }
    210 
    211 #else /* Default */
    212 
    213 static void
    214 unmap_memory_helper (qxl_screen_t *qxl)
    215 {
    216 #ifdef XSERVER_LIBPCIACCESS
    217     if (qxl->ram)
    218 	pci_device_unmap_range (qxl->pci, qxl->ram, qxl->pci->regions[0].size);
    219     if (qxl->vram)
    220 	pci_device_unmap_range (qxl->pci, qxl->vram, qxl->pci->regions[1].size);
    221     if (qxl->rom)
    222 	pci_device_unmap_range (qxl->pci, qxl->rom, qxl->pci->regions[2].size);
    223     if (qxl->io)
    224 	pci_device_close_io (qxl->pci, qxl->io);
    225 #else
    226     if (qxl->ram)
    227 	xf86UnMapVidMem (scrnIndex, qxl->ram, (1 << qxl->pci->size[0]));
    228     if (qxl->vram)
    229 	xf86UnMapVidMem (scrnIndex, qxl->vram, (1 << qxl->pci->size[1]));
    230     if (qxl->rom)
    231 	xf86UnMapVidMem (scrnIndex, qxl->rom, (1 << qxl->pci->size[2]));
    232 #endif
    233 }
    234 
    235 static void
    236 map_memory_helper (qxl_screen_t *qxl)
    237 {
    238 #ifdef XSERVER_LIBPCIACCESS
    239     pci_device_map_range (qxl->pci, qxl->pci->regions[0].base_addr,
    240                           qxl->pci->regions[0].size,
    241                           PCI_DEV_MAP_FLAG_WRITABLE | PCI_DEV_MAP_FLAG_WRITE_COMBINE,
    242                           &qxl->ram);
    243     qxl->ram_physical = u64_to_pointer (qxl->pci->regions[0].base_addr);
    244     qxl->ram_size = qxl->pci->regions[0].size;
    245 
    246     pci_device_map_range (qxl->pci, qxl->pci->regions[1].base_addr,
    247                           qxl->pci->regions[1].size,
    248                           PCI_DEV_MAP_FLAG_WRITABLE,
    249                           &qxl->vram);
    250     qxl->vram_physical = u64_to_pointer (qxl->pci->regions[1].base_addr);
    251     qxl->vram_size = qxl->pci->regions[1].size;
    252 
    253     pci_device_map_range (qxl->pci, qxl->pci->regions[2].base_addr,
    254                           qxl->pci->regions[2].size, 0,
    255                           (void **)&qxl->rom);
    256 
    257     qxl->io = pci_device_open_io(qxl->pci,
    258                                 qxl->pci->regions[3].base_addr,
    259                                 qxl->pci->regions[3].size);
    260     qxl->io_base = qxl->pci->regions[3].base_addr;
    261 #else
    262     qxl->ram = xf86MapPciMem (scrnIndex, VIDMEM_FRAMEBUFFER,
    263                               qxl->pci_tag, qxl->pci->memBase[0],
    264                               (1 << qxl->pci->size[0]));
    265     qxl->ram_physical = (void *)qxl->pci->memBase[0];
    266 
    267     qxl->vram = xf86MapPciMem (scrnIndex, VIDMEM_MMIO | VIDMEM_MMIO_32BIT,
    268                                qxl->pci_tag, qxl->pci->memBase[1],
    269                                (1 << qxl->pci->size[1]));
    270     qxl->vram_physical = (void *)qxl->pci->memBase[1];
    271     qxl->vram_size = (1 << qxl->pci->size[1]);
    272 
    273     qxl->rom = xf86MapPciMem (scrnIndex, VIDMEM_MMIO | VIDMEM_MMIO_32BIT,
    274                               qxl->pci_tag, qxl->pci->memBase[2],
    275                               (1 << qxl->pci->size[2]));
    276 
    277     qxl->io_base = qxl->pci->ioBase[3];
    278 #endif
    279 }
    280 
    281 #endif /* XSPICE */
    282 
    283 static void
    284 qxl_unmap_memory (qxl_screen_t *qxl)
    285 {
    286 #ifdef XSPICE
    287     if (qxl->worker)
    288     {
    289         spice_server_vm_stop(qxl->spice_server);
    290 	qxl->worker_running = FALSE;
    291     }
    292 #endif
    293 
    294     if (qxl->mem)
    295     {
    296 	qxl_mem_free_all (qxl->mem);
    297 	free(qxl->mem);
    298 	qxl->mem = NULL;
    299     }
    300 
    301     if (qxl->surf_mem) {
    302 	qxl_mem_free_all (qxl->surf_mem);
    303 	free(qxl->surf_mem);
    304 	qxl->surf_mem = NULL;
    305     }
    306 
    307     unmap_memory_helper (qxl);
    308     qxl->ram = qxl->ram_physical = qxl->vram = qxl->rom = NULL;
    309 
    310     qxl->num_modes = 0;
    311     qxl->modes = NULL;
    312 }
    313 
    314 #ifdef QXLDRV_RESIZABLE_SURFACE0
    315 static void
    316 qxl_dump_ring_stat (qxl_screen_t *qxl)
    317 {
    318     int cmd_prod, cursor_prod, cmd_cons, cursor_cons;
    319     int release_prod, release_cons;
    320 
    321     cmd_prod = qxl_ring_prod (qxl->command_ring);
    322     cursor_prod = qxl_ring_prod (qxl->cursor_ring);
    323     cmd_cons = qxl_ring_cons (qxl->command_ring);
    324     cursor_cons = qxl_ring_cons (qxl->cursor_ring);
    325     release_prod = qxl_ring_prod (qxl->release_ring);
    326     release_cons = qxl_ring_cons (qxl->release_ring);
    327 
    328     ErrorF ("%s: Cmd %d/%d, Cur %d/%d, Rel %d/%d\n",
    329             __func__, cmd_cons, cmd_prod, cursor_cons, cursor_prod,
    330             release_cons, release_prod);
    331 }
    332 
    333 #endif
    334 
    335 /* To resize surface0 we need to ensure qxl->mem is empty. We can do that by:
    336  * - fast:
    337  *   - ooming until command ring is empty.
    338  *   - flushing the release ring (>V10)
    339  * - slow: calling update_area on all surfaces.
    340  * This is done via already known code, so use that by default now.
    341  */
    342 static int
    343 qxl_resize_surface0 (qxl_screen_t *qxl, long surface0_size)
    344 {
    345     long ram_header_size = qxl->ram_size - qxl->rom->ram_header_offset;
    346     long new_mem_size = qxl->ram_size -
    347 	(surface0_size + ram_header_size + qxl->monitors_config_size);
    348 
    349     if (new_mem_size < 0)
    350     {
    351 	ErrorF ("cannot resize surface0 to %ld, does not fit in BAR 0\n",
    352 	        surface0_size);
    353 	return 0;
    354     }
    355 
    356     ErrorF ("resizing surface0 to %ld\n", surface0_size);
    357 
    358     if (qxl->mem)
    359     {
    360 #ifdef QXLDRV_RESIZABLE_SURFACE0
    361 	void *surfaces;
    362 	qxl_dump_ring_stat (qxl);
    363 	qxl_io_flush_surfaces (qxl);
    364 	surfaces = qxl_surface_cache_evacuate_all (qxl->surface_cache);
    365 	qxl_io_destroy_all_surfaces (qxl); // redundant?
    366 	qxl_io_flush_release (qxl);
    367 	qxl_dump_ring_stat (qxl);
    368 	qxl_surface_cache_replace_all (qxl->surface_cache, surfaces);
    369 #else
    370 	ErrorF ("resizing surface0 compiled out\n");
    371 	return 0;
    372 #endif
    373     }
    374 
    375     /* surface0_area is still fixed to start of ram BAR */
    376     qxl->surface0_size = surface0_size;
    377 
    378     qxl->mem_size = new_mem_size;
    379     qxl->mem = qxl_mem_create ((void *)((unsigned long)qxl->surface0_area + qxl->surface0_size),
    380                                qxl->mem_size);
    381     return 1;
    382 }
    383 
    384 static Bool
    385 qxl_map_memory (qxl_screen_t *qxl, int scrnIndex)
    386 {
    387     map_memory_helper (qxl);
    388 
    389     if (!qxl->ram || !qxl->vram || !qxl->rom)
    390 	return FALSE;
    391 
    392     xf86DrvMsg (scrnIndex, X_INFO, "framebuffer at %p (%d KB)\n",
    393                 qxl->ram, qxl->rom->surface0_area_size / 1024);
    394 
    395     xf86DrvMsg (scrnIndex, X_INFO, "command ram at %p (%d KB)\n",
    396                 (void *)((unsigned long)qxl->ram + qxl->rom->surface0_area_size),
    397                 (qxl->rom->num_pages * getpagesize ()) / 1024);
    398 
    399     xf86DrvMsg (scrnIndex, X_INFO, "vram at %p (%ld KB)\n",
    400                 qxl->vram, qxl->vram_size / 1024);
    401 
    402     xf86DrvMsg (scrnIndex, X_INFO, "rom at %p\n", qxl->rom);
    403 
    404     /*
    405      * Keep a hole for MonitorsConfig. This is not part of QXLRam to ensure
    406      * the driver can change it without affecting the driver/device ABI.
    407      */
    408     qxl->monitors_config_size = (sizeof (QXLMonitorsConfig) +
    409                                  sizeof (QXLHead) * MAX_MONITORS_NUM + getpagesize () - 1)
    410 	& ~(getpagesize () - 1);
    411     qxl->num_modes = *(uint32_t *)((uint8_t *)qxl->rom + qxl->rom->modes_offset);
    412     qxl->modes = (struct QXLMode *)(((uint8_t *)qxl->rom) + qxl->rom->modes_offset + 4);
    413     qxl->surface0_area = qxl->ram;
    414     qxl->surface0_size = 0;
    415     qxl->mem = NULL;
    416     if (!qxl_resize_surface0 (qxl, qxl->rom->surface0_area_size))
    417 	return FALSE;
    418     qxl->surf_mem = qxl_mem_create ((void *)((unsigned long)qxl->vram), qxl->vram_size);
    419     qxl_allocate_monitors_config (qxl);
    420 
    421     return TRUE;
    422 }
    423 
    424 #ifdef XSPICE
    425 static void
    426 qxl_save_state (ScrnInfoPtr pScrn)
    427 {
    428 }
    429 
    430 static void
    431 qxl_restore_state (ScrnInfoPtr pScrn)
    432 {
    433 }
    434 
    435 #else /* QXL */
    436 static void
    437 qxl_save_state (ScrnInfoPtr pScrn)
    438 {
    439     qxl_screen_t *qxl = pScrn->driverPrivate;
    440 
    441     if (xf86IsPrimaryPci (qxl->pci))
    442 	vgaHWSaveFonts (pScrn, &qxl->vgaRegs);
    443 }
    444 
    445 static void
    446 qxl_restore_state (ScrnInfoPtr pScrn)
    447 {
    448     qxl_screen_t *qxl = pScrn->driverPrivate;
    449 
    450     if (xf86IsPrimaryPci (qxl->pci))
    451 	vgaHWRestoreFonts (pScrn, &qxl->vgaRegs);
    452 }
    453 
    454 #endif /* XSPICE */
    455 
    456 static Bool
    457 qxl_close_screen (CLOSE_SCREEN_ARGS_DECL)
    458 {
    459     ScrnInfoPtr pScrn = xf86ScreenToScrn (pScreen);
    460     qxl_screen_t *qxl = pScrn->driverPrivate;
    461     Bool result;
    462 
    463     ErrorF ("Disabling FB access for %d\n", pScrn->scrnIndex);
    464 #ifndef XF86_SCRN_INTERFACE
    465     pScrn->EnableDisableFBAccess (scrnIndex, FALSE);
    466 #else
    467     pScrn->EnableDisableFBAccess (pScrn, FALSE);
    468 #endif
    469 
    470     pScreen->CreateScreenResources = qxl->create_screen_resources;
    471     pScreen->CloseScreen = qxl->close_screen;
    472 
    473     result = pScreen->CloseScreen (CLOSE_SCREEN_ARGS);
    474 
    475 #ifndef XSPICE
    476     if (!xf86IsPrimaryPci (qxl->pci) && qxl->primary)
    477 	qxl_reset_and_create_mem_slots (qxl);
    478 #endif
    479 
    480     if (pScrn->vtSema)
    481     {
    482 	qxl_restore_state (pScrn);
    483 	qxl_mark_mem_unverifiable (qxl);
    484 	qxl_unmap_memory (qxl);
    485     }
    486     pScrn->vtSema = FALSE;
    487 
    488     return result;
    489 }
    490 
    491 void
    492 qxl_set_screen_pixmap_header (ScreenPtr pScreen)
    493 {
    494     ScrnInfoPtr pScrn = xf86ScreenToScrn (pScreen);
    495     qxl_screen_t *qxl = pScrn->driverPrivate;
    496     PixmapPtr pPixmap = pScreen->GetScreenPixmap (pScreen);
    497 
    498     // TODO: don't ModifyPixmapHeader too early?
    499 
    500     if (pPixmap)
    501     {
    502 	pScreen->ModifyPixmapHeader (pPixmap,
    503 	                             qxl->primary_mode.x_res, qxl->primary_mode.y_res,
    504 	                             -1, -1,
    505 	                             qxl->primary_mode.x_res * qxl->bytes_per_pixel,
    506 	                             qxl_surface_get_host_bits(qxl->primary));
    507     }
    508     else
    509     {
    510 	ErrorF ("pix: %p;\n", pPixmap);
    511     }
    512 }
    513 
    514 static qxl_surface_t *
    515 qxl_create_primary(qxl_screen_t *qxl)
    516 {
    517     struct QXLMode *pm = &qxl->primary_mode;
    518     pm->id = 0x4242;
    519     pm->x_res = qxl->virtual_x;
    520     pm->y_res = qxl->virtual_y;
    521     pm->bits = qxl->pScrn->bitsPerPixel;
    522     pm->stride = qxl->virtual_x * pm->bits / 8;
    523     pm->x_mili = 0; // TODO
    524     pm->y_mili = 0; // TODO
    525     pm->orientation = 0; // ? supported by us for single head usage? more TODO
    526 
    527     return qxl_surface_cache_create_primary (qxl, &qxl->primary_mode);
    528 }
    529 
    530 Bool
    531 qxl_resize_primary_to_virtual (qxl_screen_t *qxl)
    532 {
    533     long new_surface0_size;
    534 
    535     if ((qxl->primary_mode.x_res == qxl->virtual_x &&
    536          qxl->primary_mode.y_res == qxl->virtual_y) &&
    537         qxl->device_primary == QXL_DEVICE_PRIMARY_CREATED)
    538     {
    539 	return TRUE; /* empty Success */
    540     }
    541 
    542     ErrorF ("resizing primary to %dx%d\n", qxl->virtual_x, qxl->virtual_y);
    543 
    544     if (!qxl->kms_enabled) {
    545 	new_surface0_size =
    546 	    qxl->virtual_x * qxl->pScrn->bitsPerPixel / 8 * qxl->virtual_y;
    547 
    548 	if (new_surface0_size > qxl->surface0_size)
    549 	{
    550 	    if (!qxl_resize_surface0 (qxl, new_surface0_size))
    551 	    {
    552 		ErrorF ("not resizing primary to virtual, leaving old virtual\n");
    553 		return FALSE;
    554 	    }
    555 	}
    556     }
    557 
    558     if (qxl->primary)
    559     {
    560 	qxl_surface_kill (qxl->primary);
    561 	qxl_surface_cache_sanity_check (qxl->surface_cache);
    562 	qxl->bo_funcs->destroy_primary(qxl, qxl->primary_bo);
    563     }
    564 
    565     qxl->primary = qxl_create_primary(qxl);
    566     qxl->bytes_per_pixel = (qxl->pScrn->bitsPerPixel + 7) / 8;
    567 
    568     if (qxl->screen_resources_created)
    569     {
    570         ScreenPtr pScreen = qxl->pScrn->pScreen;
    571 	PixmapPtr root = pScreen->GetScreenPixmap (pScreen);
    572 
    573         if (qxl->deferred_fps <= 0)
    574         {
    575             qxl_surface_t *surf;
    576 
    577             if ((surf = get_surface (root)))
    578                 qxl_surface_kill (surf);
    579 
    580             set_surface (root, qxl->primary);
    581         }
    582 
    583         qxl_set_screen_pixmap_header (pScreen);
    584     }
    585 
    586     ErrorF ("primary is %p\n", qxl->primary);
    587     return TRUE;
    588 }
    589 
    590 Bool
    591 qxl_resize_primary (qxl_screen_t *qxl, uint32_t width, uint32_t height)
    592 {
    593     qxl->virtual_x = width;
    594     qxl->virtual_y = height;
    595 
    596     if (qxl->vt_surfaces)
    597     {
    598 	ErrorF ("%s: ignoring resize due to not being in control of VT\n",
    599 	        __FUNCTION__);
    600 	return FALSE;
    601     }
    602     return qxl_resize_primary_to_virtual (qxl);
    603 }
    604 
    605 static Bool
    606 qxl_switch_mode (SWITCH_MODE_ARGS_DECL)
    607 {
    608     SCRN_INFO_PTR (arg);
    609     qxl_screen_t *qxl = pScrn->driverPrivate;
    610 
    611     ErrorF ("Ignoring display mode, ensuring recreation of primary\n");
    612 
    613     return qxl_resize_primary_to_virtual (qxl);
    614 }
    615 
    616 static Bool
    617 qxl_create_screen_resources (ScreenPtr pScreen)
    618 {
    619     ScrnInfoPtr    pScrn = xf86ScreenToScrn (pScreen);
    620     qxl_screen_t * qxl = pScrn->driverPrivate;
    621     Bool           ret;
    622     PixmapPtr      pPixmap;
    623     qxl_surface_t *surf;
    624 
    625     pScreen->CreateScreenResources = qxl->create_screen_resources;
    626     ret = pScreen->CreateScreenResources (pScreen);
    627     pScreen->CreateScreenResources = qxl_create_screen_resources;
    628 
    629     if (!ret)
    630 	return FALSE;
    631 
    632     pPixmap = pScreen->GetScreenPixmap (pScreen);
    633 
    634     if (qxl->deferred_fps <= 0)
    635     {
    636         qxl_set_screen_pixmap_header (pScreen);
    637 
    638         if ((surf = get_surface (pPixmap)))
    639             qxl_surface_kill (surf);
    640 
    641         set_surface (pPixmap, qxl->primary);
    642     }
    643 
    644     qxl_create_desired_modes (qxl);
    645     qxl_update_edid (qxl);
    646 
    647     qxl->screen_resources_created = TRUE;
    648     return TRUE;
    649 }
    650 
    651 #ifdef XSPICE
    652 
    653 static void
    654 spiceqxl_screen_init (ScrnInfoPtr pScrn, qxl_screen_t *qxl)
    655 {
    656     // Init spice
    657     if (!qxl->spice_server)
    658     {
    659 	qxl->spice_server = xspice_get_spice_server ();
    660 	xspice_set_spice_server_options (qxl->options);
    661 	qxl->core = basic_event_loop_init ();
    662 	if (spice_server_init (qxl->spice_server, qxl->core) < 0) {
    663             ErrorF ("failed to initialize server\n");
    664             abort ();
    665         }
    666 	qxl_add_spice_display_interface (qxl);
    667 	qxl_add_spice_playback_interface (qxl);
    668 	qxl_add_spice_smartcard_interface (qxl);
    669 	spiceqxl_vdagent_init (qxl);
    670     }
    671     else
    672     {
    673         /* Crashes result from invalid xorg_timer pointers in
    674            our watch lists because Xorg clears all timers at server reset.
    675            We would require a fairly substantial revamp of how the
    676            spice server is started and operated to avoid this crash.  */
    677         ErrorF("WARNING: XSPICE requires -noreset; crashes are now likely.\n");
    678     }
    679 
    680     if (! qxl->worker_running)
    681     {
    682         xspice_register_handlers();
    683         spice_server_vm_start(qxl->spice_server);
    684 	qxl->worker_running = TRUE;
    685     }
    686 }
    687 
    688 #endif
    689 
    690 Bool
    691 qxl_fb_init (qxl_screen_t *qxl, ScreenPtr pScreen)
    692 {
    693     ScrnInfoPtr pScrn = qxl->pScrn;
    694 
    695     if (!fbScreenInit (pScreen, qxl_surface_get_host_bits(qxl->primary),
    696                        pScrn->virtualX, pScrn->virtualY,
    697                        pScrn->xDpi, pScrn->yDpi, pScrn->virtualX,
    698                        pScrn->bitsPerPixel))
    699 	return FALSE;
    700 
    701     fbPictureInit (pScreen, NULL, 0);
    702     return TRUE;
    703 }
    704 
    705 static Bool
    706 qxl_screen_init (SCREEN_INIT_ARGS_DECL)
    707 {
    708     ScrnInfoPtr    pScrn = xf86ScreenToScrn (pScreen);
    709     qxl_screen_t * qxl = pScrn->driverPrivate;
    710     struct QXLRam *ram_header;
    711     VisualPtr      visual;
    712 
    713     CHECK_POINT ();
    714 
    715     assert (qxl->pScrn == pScrn);
    716 
    717     if (!qxl_map_memory (qxl, pScrn->scrnIndex))
    718 	return FALSE;
    719 
    720 #ifdef XSPICE
    721     spiceqxl_screen_init (pScrn, qxl);
    722 #endif
    723     ram_header = (void *)((unsigned long)qxl->ram + (unsigned long)qxl->rom->ram_header_offset);
    724 
    725     printf ("ram_header at %d\n", qxl->rom->ram_header_offset);
    726     printf ("surf0 size: %d\n", qxl->rom->surface0_area_size);
    727 
    728     qxl_save_state (pScrn);
    729     qxl_blank_screen (pScreen, SCREEN_SAVER_ON);
    730 
    731     miClearVisualTypes ();
    732     if (!miSetVisualTypes (pScrn->depth, miGetDefaultVisualMask (pScrn->depth),
    733                            pScrn->rgbBits, pScrn->defaultVisual))
    734 	goto out;
    735     if (!miSetPixmapDepths ())
    736 	goto out;
    737 
    738 #if 0
    739     ErrorF ("allocated %d x %d  %p\n", pScrn->virtualX, pScrn->virtualY, qxl->fb);
    740 #endif
    741 
    742     /* Set up resources */
    743     qxl_reset_and_create_mem_slots (qxl);
    744     ErrorF ("done reset\n");
    745 
    746     qxl->surface_cache = qxl_surface_cache_create (qxl);
    747     qxl->primary = qxl_create_primary(qxl);
    748 
    749     if (!qxl_fb_init (qxl, pScreen))
    750 	goto out;
    751 
    752     visual = pScreen->visuals + pScreen->numVisuals;
    753     while (--visual >= pScreen->visuals)
    754     {
    755 	if ((visual->class | DynamicClass) == DirectColor)
    756 	{
    757 	    visual->offsetRed = pScrn->offset.red;
    758 	    visual->offsetGreen = pScrn->offset.green;
    759 	    visual->offsetBlue = pScrn->offset.blue;
    760 	    visual->redMask = pScrn->mask.red;
    761 	    visual->greenMask = pScrn->mask.green;
    762 	    visual->blueMask = pScrn->mask.blue;
    763 	}
    764     }
    765 
    766     qxl->command_ring = qxl_ring_create ((struct qxl_ring_header *)&(ram_header->cmd_ring),
    767                                          sizeof (struct QXLCommand),
    768                                          QXL_COMMAND_RING_SIZE, QXL_IO_NOTIFY_CMD, qxl);
    769     qxl->cursor_ring = qxl_ring_create ((struct qxl_ring_header *)&(ram_header->cursor_ring),
    770                                         sizeof (struct QXLCommand),
    771                                         QXL_CURSOR_RING_SIZE, QXL_IO_NOTIFY_CURSOR, qxl);
    772     qxl->release_ring = qxl_ring_create ((struct qxl_ring_header *)&(ram_header->release_ring),
    773                                          sizeof (uint64_t),
    774                                          QXL_RELEASE_RING_SIZE, 0, qxl);
    775 
    776     /* xf86DPMSInit (pScreen, xf86DPMSSet, 0); */
    777 
    778     pScreen->SaveScreen = qxl_blank_screen;
    779 
    780     qxl_uxa_init (qxl, pScreen);
    781 
    782     uxa_set_fallback_debug (pScreen, qxl->debug_render_fallbacks);
    783 
    784     DamageSetup (pScreen);
    785 
    786     /* We need to set totalPixmapSize after setup_uxa and Damage,
    787        as the privates size is not computed correctly until then
    788      */
    789 #if (XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 12, 99, 901, 0))
    790     pScreen->totalPixmapSize = BitmapBytePad ((sizeof (PixmapRec) + dixPrivatesSize (PRIVATE_PIXMAP) ) * 8);
    791 #else
    792     pScreen->totalPixmapSize = BitmapBytePad((sizeof(PixmapRec) +
    793 			    dixScreenSpecificPrivatesSize(pScreen, PRIVATE_PIXMAP) ) * 8);
    794 #endif
    795 
    796     miDCInitialize (pScreen, xf86GetPointerScreenFuncs());
    797     if (!miCreateDefColormap (pScreen))
    798         goto out;
    799 
    800     qxl->create_screen_resources = pScreen->CreateScreenResources;
    801     pScreen->CreateScreenResources = qxl_create_screen_resources;
    802 
    803     qxl->close_screen = pScreen->CloseScreen;
    804     pScreen->CloseScreen = qxl_close_screen;
    805 
    806     qxl_cursor_init (pScreen);
    807 
    808     CHECK_POINT ();
    809 
    810     pScreen->width = qxl->primary_mode.x_res;
    811     pScreen->height = qxl->primary_mode.y_res;
    812 
    813     if (!xf86CrtcScreenInit (pScreen))
    814 	return FALSE;
    815 
    816     if (!qxl_resize_primary_to_virtual (qxl))
    817 	return FALSE;
    818 
    819     /* Note: this must be done after DamageSetup() because it calls
    820      * _dixInitPrivates. And if that has been called, DamageSetup()
    821      * will assert.
    822      */
    823     if (!uxa_resources_init (pScreen))
    824 	return FALSE;
    825     CHECK_POINT ();
    826 
    827     /* fake transform support, to allow agent to switch crtc mode */
    828     /* without X doing checks, see rrcrtc.c "Check screen size */
    829     /* bounds" */
    830     xf86RandR12SetTransformSupport (pScreen, TRUE);
    831 
    832     if (qxl->deferred_fps)
    833         dfps_start_ticker(qxl);
    834 
    835     return TRUE;
    836 
    837 out:
    838     return FALSE;
    839 }
    840 
    841 static Bool
    842 qxl_enter_vt (VT_FUNC_ARGS_DECL)
    843 {
    844     SCRN_INFO_PTR (arg);
    845     qxl_screen_t *qxl = pScrn->driverPrivate;
    846 
    847     qxl_save_state (pScrn);
    848 
    849     qxl_reset_and_create_mem_slots (qxl);
    850 
    851     if (!qxl_resize_primary_to_virtual (qxl))
    852 	return FALSE;
    853 
    854     if (qxl->mem)
    855     {
    856 	qxl_mem_free_all (qxl->mem);
    857     }
    858 
    859     if (qxl->surf_mem)
    860 	qxl_mem_free_all (qxl->surf_mem);
    861 
    862     if (qxl->vt_surfaces)
    863     {
    864 	qxl_surface_cache_replace_all (qxl->surface_cache, qxl->vt_surfaces);
    865 
    866 	qxl->vt_surfaces = NULL;
    867     }
    868 
    869     qxl_create_desired_modes (qxl);
    870 
    871     pScrn->EnableDisableFBAccess (XF86_SCRN_ARG (pScrn), TRUE);
    872 
    873     return TRUE;
    874 }
    875 
    876 static void
    877 qxl_leave_vt (VT_FUNC_ARGS_DECL)
    878 {
    879     SCRN_INFO_PTR (arg);
    880     qxl_screen_t *qxl = pScrn->driverPrivate;
    881 
    882     xf86_hide_cursors (pScrn);
    883 
    884     pScrn->EnableDisableFBAccess (XF86_SCRN_ARG (pScrn), FALSE);
    885 
    886     if (qxl->deferred_fps <= 0)
    887         qxl->vt_surfaces = qxl_surface_cache_evacuate_all (qxl->surface_cache);
    888 
    889     ioport_write (qxl, QXL_IO_RESET, 0);
    890 
    891     qxl_restore_state (pScrn);
    892     qxl->device_primary = QXL_DEVICE_PRIMARY_NONE;
    893 }
    894 
    895 static Bool
    896 qxl_color_setup (ScrnInfoPtr pScrn)
    897 {
    898     int   scrnIndex = pScrn->scrnIndex;
    899     Gamma gzeros = { 0.0, 0.0, 0.0 };
    900     rgb   rzeros = { 0, 0, 0 };
    901 
    902     if (!xf86SetDepthBpp (pScrn, 0, 0, 0, Support32bppFb))
    903 	return FALSE;
    904 
    905     if (pScrn->depth != 15 && pScrn->depth != 24)
    906     {
    907 	xf86DrvMsg (scrnIndex, X_ERROR, "Depth %d is not supported\n",
    908 	            pScrn->depth);
    909 	return FALSE;
    910     }
    911     xf86PrintDepthBpp (pScrn);
    912 
    913     if (!xf86SetWeight (pScrn, rzeros, rzeros))
    914 	return FALSE;
    915 
    916     if (!xf86SetDefaultVisual (pScrn, -1))
    917 	return FALSE;
    918 
    919     if (!xf86SetGamma (pScrn, gzeros))
    920 	return FALSE;
    921 
    922     return TRUE;
    923 }
    924 
    925 static void
    926 print_modes (qxl_screen_t *qxl, int scrnIndex)
    927 {
    928     int i;
    929 
    930     for (i = 0; i < qxl->num_modes; ++i)
    931     {
    932 	struct QXLMode *m = qxl->modes + i;
    933 
    934 	xf86DrvMsg (scrnIndex, X_INFO,
    935 	            "%d: %dx%d, %d bits, stride %d, %dmm x %dmm, orientation %d\n",
    936 	            m->id, m->x_res, m->y_res, m->bits, m->stride, m->x_mili,
    937 	            m->y_mili, m->orientation);
    938     }
    939 }
    940 
    941 #ifndef XSPICE
    942 static Bool
    943 qxl_check_device (ScrnInfoPtr pScrn, qxl_screen_t *qxl)
    944 {
    945     int            scrnIndex = pScrn->scrnIndex;
    946     struct QXLRom *rom = qxl->rom;
    947     struct QXLRam *ram_header = (void *)((unsigned long)qxl->ram + rom->ram_header_offset);
    948 
    949     CHECK_POINT ();
    950 
    951     if (rom->magic != 0x4f525851)   /* "QXRO" little-endian */
    952     {
    953 	xf86DrvMsg (scrnIndex, X_ERROR, "Bad ROM signature %x\n", rom->magic);
    954 	return FALSE;
    955     }
    956 
    957     xf86DrvMsg (scrnIndex, X_INFO, "Device version %d.%d\n",
    958                 rom->id, rom->update_id);
    959 
    960     xf86DrvMsg (scrnIndex, X_INFO, "Compression level %d, log level %d\n",
    961                 rom->compression_level,
    962                 rom->log_level);
    963 
    964     xf86DrvMsg (scrnIndex, X_INFO, "%d io pages at 0x%lx\n",
    965                 rom->num_pages, (unsigned long)qxl->ram);
    966 
    967     xf86DrvMsg (scrnIndex, X_INFO, "RAM header offset: 0x%x\n", rom->ram_header_offset);
    968 
    969     if (ram_header->magic != 0x41525851)   /* "QXRA" little-endian */
    970     {
    971 	xf86DrvMsg (scrnIndex, X_ERROR, "Bad RAM signature %x at %p\n",
    972 	            ram_header->magic,
    973 	            &ram_header->magic);
    974 	return FALSE;
    975     }
    976 
    977     xf86DrvMsg (scrnIndex, X_INFO, "Correct RAM signature %x\n",
    978                 ram_header->magic);
    979     return TRUE;
    980 }
    981 
    982 #endif /* !XSPICE */
    983 
    984 Bool
    985 qxl_pre_init_common(ScrnInfoPtr pScrn)
    986 {
    987     int           scrnIndex = pScrn->scrnIndex;
    988     qxl_screen_t *qxl = pScrn->driverPrivate;
    989 
    990     if (!qxl_color_setup (pScrn))
    991 	goto out;
    992 
    993     /* option parsing and card differentiation */
    994     xf86CollectOptions (pScrn, NULL);
    995     memcpy (qxl->options, DefaultOptions, sizeof (DefaultOptions));
    996     xf86ProcessOptions (scrnIndex, pScrn->options, qxl->options);
    997 
    998     qxl->enable_image_cache =
    999         get_bool_option (qxl->options, OPTION_ENABLE_IMAGE_CACHE, "QXL_ENABLE_IMAGE_CACHE");
   1000     qxl->enable_fallback_cache =
   1001         get_bool_option (qxl->options, OPTION_ENABLE_FALLBACK_CACHE, "QXL_ENABLE_FALLBACK_CACHE");
   1002     qxl->enable_surfaces =
   1003         get_bool_option (qxl->options, OPTION_ENABLE_SURFACES, "QXL_ENABLE_SURFACES");
   1004     qxl->debug_render_fallbacks =
   1005         get_bool_option (qxl->options, OPTION_DEBUG_RENDER_FALLBACKS, "QXL_DEBUG_RENDER_FALLBACKS");
   1006     qxl->num_heads =
   1007         get_int_option (qxl->options, OPTION_NUM_HEADS, "QXL_NUM_HEADS");
   1008     if (qxl->num_heads == 0) {
   1009         xf86DrvMsg (scrnIndex, X_INFO, "QXL_NUM_HEADS not configured, defaulting to 1\n");
   1010         qxl->num_heads = 1;
   1011     }
   1012 
   1013     qxl->deferred_fps = get_int_option(qxl->options, OPTION_SPICE_DEFERRED_FPS, "XSPICE_DEFERRED_FPS");
   1014     if (qxl->deferred_fps > 0)
   1015         xf86DrvMsg(scrnIndex, X_INFO, "Deferred FPS: %d\n", qxl->deferred_fps);
   1016     else
   1017         xf86DrvMsg(scrnIndex, X_INFO, "Deferred Frames: Disabled\n");
   1018 
   1019     xf86DrvMsg (scrnIndex, X_INFO, "Offscreen Surfaces: %s\n",
   1020                 qxl->enable_surfaces ? "Enabled" : "Disabled");
   1021     xf86DrvMsg (scrnIndex, X_INFO, "Image Cache: %s\n",
   1022                 qxl->enable_image_cache ? "Enabled" : "Disabled");
   1023     xf86DrvMsg (scrnIndex, X_INFO, "Fallback Cache: %s\n",
   1024                 qxl->enable_fallback_cache ? "Enabled" : "Disabled");
   1025 
   1026     return TRUE;
   1027 out:
   1028     return FALSE;
   1029 }
   1030 
   1031 static Bool
   1032 qxl_pre_init (ScrnInfoPtr pScrn, int flags)
   1033 {
   1034     int           scrnIndex = pScrn->scrnIndex;
   1035     qxl_screen_t *qxl = NULL;
   1036     ClockRangePtr clockRanges = NULL;
   1037     //int *linePitches = NULL;
   1038     //DisplayModePtr mode;
   1039     unsigned int max_x, max_y;
   1040 #ifdef XSPICE
   1041     const char *playback_fifo_dir;
   1042     const char *smartcard_file;
   1043 #endif
   1044 
   1045     /* In X server 1.7.5, Xorg -configure will cause this
   1046      * function to get called without a confScreen.
   1047      */
   1048     if (!pScrn->confScreen)
   1049 	return FALSE;
   1050 
   1051     CHECK_POINT ();
   1052 
   1053     qxl_mem_init();
   1054 
   1055     /* zaphod mode is for suckers and i choose not to implement it */
   1056     if (xf86IsEntityShared (pScrn->entityList[0]))
   1057     {
   1058 	xf86DrvMsg (scrnIndex, X_ERROR, "No Zaphod mode for you\n");
   1059 	return FALSE;
   1060     }
   1061 
   1062     if (!pScrn->driverPrivate)
   1063 	pScrn->driverPrivate = xnfcalloc (sizeof (qxl_screen_t), 1);
   1064 
   1065     qxl = pScrn->driverPrivate;
   1066     qxl->device_primary = QXL_DEVICE_PRIMARY_UNDEFINED;
   1067     qxl->pScrn = pScrn;
   1068     qxl->x_modes = NULL;
   1069     qxl->entity = xf86GetEntityInfo (pScrn->entityList[0]);
   1070     qxl->kms_enabled = FALSE;
   1071     xorg_list_init(&qxl->ums_bos);
   1072 
   1073 #ifndef XSPICE
   1074     qxl->pci = xf86GetPciInfoForEntity (qxl->entity->index);
   1075 #ifndef XSERVER_LIBPCIACCESS
   1076     qxl->pci_tag = pciTag (qxl->pci->bus, qxl->pci->device, qxl->pci->func);
   1077 #endif
   1078     if (qxl->pci->revision < 4)
   1079     {
   1080 	ErrorF ("Ignoring monitor config, device revision < 4\n");
   1081     }
   1082 #endif /* XSPICE */
   1083     pScrn->monitor = pScrn->confScreen->monitor;
   1084 
   1085     qxl_ums_setup_funcs(qxl);
   1086 
   1087     if (!qxl_pre_init_common(pScrn))
   1088 	goto out;
   1089 
   1090 #ifdef XSPICE
   1091     playback_fifo_dir = get_str_option(qxl->options, OPTION_SPICE_PLAYBACK_FIFO_DIR,
   1092                "XSPICE_PLAYBACK_FIFO_DIR");
   1093     if (playback_fifo_dir)
   1094         strncpy(qxl->playback_fifo_dir, playback_fifo_dir, sizeof(qxl->playback_fifo_dir));
   1095     else
   1096         qxl->playback_fifo_dir[0] = '\0';
   1097 
   1098     smartcard_file = get_str_option(qxl->options, OPTION_SPICE_SMARTCARD_FILE,
   1099                "XSPICE_SMARTCARD_FILE");
   1100     if (smartcard_file)
   1101         strncpy(qxl->smartcard_file, smartcard_file, sizeof(qxl->smartcard_file));
   1102     else
   1103         qxl->smartcard_file[0] = '\0';
   1104 
   1105     qxl->surface0_size =
   1106         get_int_option (qxl->options, OPTION_FRAME_BUFFER_SIZE, "QXL_FRAME_BUFFER_SIZE") << 20L;
   1107     qxl->vram_size =
   1108         get_int_option (qxl->options, OPTION_SURFACE_BUFFER_SIZE, "QXL_SURFACE_BUFFER_SIZE") << 20L;
   1109     qxl->ram_size =
   1110         get_int_option (qxl->options, OPTION_COMMAND_BUFFER_SIZE, "QXL_COMMAND_BUFFER_SIZE") << 20L;
   1111 #endif
   1112 
   1113     if (!qxl_map_memory (qxl, scrnIndex))
   1114 	goto out;
   1115 
   1116 #ifndef XSPICE
   1117     if (!qxl_check_device (pScrn, qxl))
   1118 	goto out;
   1119 #else
   1120     xspice_init_qxl_ram (qxl); /* initialize the rings */
   1121 #endif
   1122 
   1123 #define DIV_ROUND_UP(n, a) (((n) + (a) - 1) / (a))
   1124 #define BYTES_TO_KB(bytes) DIV_ROUND_UP(bytes, 1024)
   1125 #define PAGES_TO_KB(pages) ((pages) * getpagesize() / 1024)
   1126 
   1127     pScrn->videoRam = PAGES_TO_KB(qxl->rom->num_pages)
   1128                       - BYTES_TO_KB(qxl->monitors_config_size);
   1129     xf86DrvMsg (scrnIndex, X_INFO, "%d KB of video RAM\n", pScrn->videoRam);
   1130     xf86DrvMsg (scrnIndex, X_INFO, "%d surfaces\n", qxl->rom->n_surfaces);
   1131 
   1132     /* ddc stuff here */
   1133 
   1134     clockRanges = xnfcalloc (sizeof (ClockRange), 1);
   1135     clockRanges->next = NULL;
   1136     clockRanges->minClock = 10000;
   1137     clockRanges->maxClock = 400000;
   1138     clockRanges->clockIndex = -1;
   1139     clockRanges->interlaceAllowed = clockRanges->doubleScanAllowed = 0;
   1140     clockRanges->ClockMulFactor = clockRanges->ClockDivFactor = 1;
   1141     pScrn->progClock = TRUE;
   1142 
   1143     /* override QXL monitor stuff */
   1144     if (pScrn->monitor->nHsync <= 0)
   1145     {
   1146 	pScrn->monitor->hsync[0].lo =  29.0;
   1147 	pScrn->monitor->hsync[0].hi = 160.0;
   1148 	pScrn->monitor->nHsync = 1;
   1149     }
   1150     if (pScrn->monitor->nVrefresh <= 0)
   1151     {
   1152 	pScrn->monitor->vrefresh[0].lo = 50;
   1153 	pScrn->monitor->vrefresh[0].hi = 75;
   1154 	pScrn->monitor->nVrefresh = 1;
   1155     }
   1156 
   1157     qxl_initialize_x_modes (qxl, pScrn, &max_x, &max_y);
   1158 
   1159     CHECK_POINT ();
   1160 
   1161     xf86PruneDriverModes (pScrn);
   1162 
   1163     qxl_init_randr (pScrn, qxl);
   1164 
   1165     xf86SetDpi (pScrn, 0, 0);
   1166 
   1167     if (!xf86LoadSubModule (pScrn, "fb")
   1168 #ifndef XSPICE
   1169         || !xf86LoadSubModule (pScrn, "ramdac")
   1170         || !xf86LoadSubModule (pScrn, "vgahw")
   1171 #endif
   1172         )
   1173     {
   1174 	goto out;
   1175     }
   1176 
   1177     print_modes (qxl, scrnIndex);
   1178 
   1179 #ifndef XSPICE
   1180     /* VGA hardware initialisation */
   1181     if (!vgaHWGetHWRec (pScrn))
   1182 	return FALSE;
   1183     vgaHWSetStdFuncs (VGAHWPTR (pScrn));
   1184 #endif
   1185 
   1186     /* hate */
   1187     qxl_unmap_memory (qxl);
   1188 
   1189     CHECK_POINT ();
   1190 
   1191     xf86DrvMsg (scrnIndex, X_INFO, "PreInit complete\n");
   1192 #ifdef GIT_VERSION
   1193     xf86DrvMsg (scrnIndex, X_INFO, "git commit %s\n", GIT_VERSION);
   1194 #endif
   1195     return TRUE;
   1196 
   1197 out:
   1198     if (clockRanges)
   1199 	free (clockRanges);
   1200     if (qxl)
   1201 	free (qxl);
   1202 
   1203     return FALSE;
   1204 }
   1205 
   1206 #ifndef XSPICE
   1207 #ifdef XSERVER_LIBPCIACCESS
   1208 enum qxl_class
   1209 {
   1210     CHIP_QXL_1,
   1211 };
   1212 
   1213 static const struct pci_id_match qxl_device_match[] = {
   1214     {
   1215 	PCI_VENDOR_RED_HAT, PCI_CHIP_QXL_0100, PCI_MATCH_ANY, PCI_MATCH_ANY,
   1216 	0x00000000, 0x00000000, CHIP_QXL_1
   1217     },
   1218     {
   1219 	PCI_VENDOR_RED_HAT, PCI_CHIP_QXL_01FF, PCI_MATCH_ANY, PCI_MATCH_ANY,
   1220 	0x00000000, 0x00000000, CHIP_QXL_1
   1221     },
   1222 
   1223     { 0 },
   1224 };
   1225 #endif
   1226 
   1227 static SymTabRec qxlChips[] = {
   1228     { PCI_CHIP_QXL_0100, "QXL 1", },
   1229     { -1, NULL }
   1230 };
   1231 
   1232 #ifndef XSERVER_LIBPCIACCESS
   1233 static PciChipsets qxlPciChips[] = {
   1234     { PCI_CHIP_QXL_0100, PCI_CHIP_QXL_0100, RES_SHARED_VGA },
   1235     { -1, -1, RES_UNDEFINED }
   1236 };
   1237 #endif
   1238 #endif /* !XSPICE */
   1239 
   1240 static void
   1241 qxl_identify (int flags)
   1242 {
   1243 #ifndef XSPICE
   1244     xf86PrintChipsets ("qxl", "Driver for QXL virtual graphics", qxlChips);
   1245 #endif
   1246 }
   1247 
   1248 static void
   1249 qxl_init_scrn (ScrnInfoPtr pScrn, Bool kms)
   1250 {
   1251     pScrn->driverVersion    = 0;
   1252     pScrn->driverName       = driver_name;
   1253     pScrn->name             = driver_name;
   1254 
   1255     if (kms) {
   1256 #if !defined(XSPICE) && defined(XF86DRM_MODE)
   1257 	pScrn->PreInit          = qxl_pre_init_kms;
   1258 	pScrn->ScreenInit       = qxl_screen_init_kms;
   1259 	pScrn->EnterVT          = qxl_enter_vt_kms;
   1260 	pScrn->LeaveVT          = qxl_leave_vt_kms;
   1261 #endif
   1262     } else {
   1263 	pScrn->PreInit          = qxl_pre_init;
   1264 	pScrn->ScreenInit       = qxl_screen_init;
   1265 	pScrn->EnterVT          = qxl_enter_vt;
   1266 	pScrn->LeaveVT          = qxl_leave_vt;
   1267     }
   1268     pScrn->SwitchMode       = qxl_switch_mode;
   1269     pScrn->ValidMode        = NULL;
   1270 }
   1271 
   1272 #if defined(XF86DRM_MODE) && !defined(XSPICE)
   1273 static char *
   1274 CreatePCIBusID(const struct pci_device *dev)
   1275 {
   1276     char *busID;
   1277 
   1278     if (asprintf(&busID, "pci:%04x:%02x:%02x.%d",
   1279                  dev->domain, dev->bus, dev->dev, dev->func) == -1)
   1280         return NULL;
   1281 
   1282     return busID;
   1283 }
   1284 
   1285 static Bool qxl_kernel_mode_enabled(ScrnInfoPtr pScrn, struct pci_device *pci_dev)
   1286 {
   1287     char *busIdString;
   1288     int ret;
   1289 
   1290     busIdString = CreatePCIBusID(pci_dev);
   1291     ret = drmCheckModesettingSupported(busIdString);
   1292     free(busIdString);
   1293     if (ret) {
   1294       xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0,
   1295 		   "[KMS] drm report modesetting isn't supported.\n");
   1296 	return FALSE;
   1297     }
   1298 
   1299     xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 0,
   1300 		   "[KMS] Kernel modesetting enabled.\n");
   1301     return TRUE;
   1302 }
   1303 #else
   1304 #define qxl_kernel_mode_enabled(x, y) FALSE
   1305 #endif
   1306 
   1307 #ifdef XSPICE
   1308 static Bool
   1309 qxl_probe (struct _DriverRec *drv, int flags)
   1310 {
   1311     ScrnInfoPtr   pScrn;
   1312     int           entityIndex;
   1313     EntityInfoPtr pEnt;
   1314     GDevPtr*      device;
   1315 
   1316     if (flags & PROBE_DETECT)
   1317 	return TRUE;
   1318 
   1319     pScrn = xf86AllocateScreen (drv, flags);
   1320     qxl_init_scrn (pScrn, FALSE);
   1321 
   1322     xf86MatchDevice (driver_name, &device);
   1323     entityIndex = xf86ClaimNoSlot (drv, 0, device[0], TRUE);
   1324     pEnt = xf86GetEntityInfo (entityIndex);
   1325     pEnt->driver = drv;
   1326 
   1327     xf86AddEntityToScreen (pScrn, entityIndex);
   1328 
   1329     return TRUE;
   1330 }
   1331 
   1332 #else /* normal, not XSPICE */
   1333 #ifndef XSERVER_LIBPCIACCESS
   1334 static Bool
   1335 qxl_probe (DriverPtr drv, int flags)
   1336 {
   1337     int      i, numUsed;
   1338     int      numDevSections;
   1339     int *    usedChips;
   1340     GDevPtr *devSections;
   1341 
   1342     if ((numDevSections = xf86MatchDevice (QXL_NAME, &devSections)) <= 0)
   1343 	return FALSE;
   1344 
   1345     if (!xf86GetPciVideoInfo ())
   1346 	return FALSE;
   1347 
   1348     numUsed = xf86MatchPciInstances (QXL_NAME, PCI_VENDOR_RED_HAT,
   1349                                      qxlChips, qxlPciChips,
   1350                                      devSections, numDevSections,
   1351                                      drv, &usedChips);
   1352 
   1353     xfree (devSections);
   1354 
   1355     if (numUsed < 0)
   1356     {
   1357 	xfree (usedChips);
   1358 	return FALSE;
   1359     }
   1360 
   1361     if (flags & PROBE_DETECT)
   1362     {
   1363 	xfree (usedChips);
   1364 	return TRUE;
   1365     }
   1366 
   1367     for (i = 0; i < numUsed; i++)
   1368     {
   1369 	ScrnInfoPtr pScrn = NULL;
   1370 	if ((pScrn = xf86ConfigPciEntity (pScrn, 0, usedChips[i], qxlPciChips,
   1371 	                                  0, 0, 0, 0, 0)))
   1372 	    qxl_init_scrn (pScrn, FALSE);
   1373     }
   1374 
   1375     xfree (usedChips);
   1376     return TRUE;
   1377 }
   1378 
   1379 #else /* pciaccess */
   1380 
   1381 static Bool
   1382 qxl_pci_probe (DriverPtr drv, int entity, struct pci_device *dev, intptr_t match)
   1383 {
   1384     qxl_screen_t *qxl;
   1385     ScrnInfoPtr   pScrn = xf86ConfigPciEntity (NULL, 0, entity, NULL, NULL,
   1386                                                NULL, NULL, NULL, NULL);
   1387     Bool kms = FALSE;
   1388 
   1389     if (!pScrn)
   1390 	return FALSE;
   1391 
   1392     if (dev) {
   1393 	if (qxl_kernel_mode_enabled(pScrn, dev)) {
   1394 	    kms = TRUE;
   1395 	}
   1396     }
   1397 
   1398     if (!pScrn->driverPrivate)
   1399 	pScrn->driverPrivate = xnfcalloc (sizeof (qxl_screen_t), 1);
   1400     qxl = pScrn->driverPrivate;
   1401     qxl->pci = dev;
   1402 
   1403     qxl_init_scrn (pScrn, kms);
   1404 
   1405     return TRUE;
   1406 }
   1407 
   1408 #define qxl_probe NULL
   1409 
   1410 #endif
   1411 
   1412 #ifdef XSERVER_PLATFORM_BUS
   1413 static Bool
   1414 qxl_platform_probe(DriverPtr driver, int entity, int flags,
   1415                    struct xf86_platform_device *dev, intptr_t match_data)
   1416 {
   1417     qxl_screen_t *qxl;
   1418     ScrnInfoPtr pScrn;
   1419     int scrnFlag = 0;
   1420 
   1421     if (!dev->pdev)
   1422         return FALSE;
   1423 
   1424     if (flags & PLATFORM_PROBE_GPU_SCREEN)
   1425         scrnFlag = XF86_ALLOCATE_GPU_SCREEN;
   1426 
   1427     pScrn = xf86AllocateScreen(driver, scrnFlag);
   1428     if (!pScrn)
   1429 	return FALSE;
   1430 
   1431     if (xf86IsEntitySharable(entity))
   1432         xf86SetEntityShared(entity);
   1433 
   1434     xf86AddEntityToScreen(pScrn, entity);
   1435 
   1436     qxl = pScrn->driverPrivate = xnfcalloc (sizeof (qxl_screen_t), 1);
   1437     qxl->pci = dev->pdev;
   1438     qxl->platform_dev = dev;
   1439 
   1440     qxl_init_scrn (pScrn, qxl_kernel_mode_enabled(pScrn, dev->pdev));
   1441 
   1442     return TRUE;
   1443 }
   1444 #endif /* XSERVER_PLATFORM_BUS */
   1445 
   1446 #endif /* XSPICE */
   1447 
   1448 static Bool
   1449 qxl_driver_func(ScrnInfoPtr pScrn, xorgDriverFuncOp op, void *data)
   1450 {
   1451     xorgHWFlags *hw_flags;
   1452 
   1453     switch (op) {
   1454     case GET_REQUIRED_HW_INTERFACES:
   1455         hw_flags = data;
   1456 #ifdef XSPICE
   1457         *hw_flags = HW_SKIP_CONSOLE;
   1458 #else
   1459         *hw_flags = HW_IO | HW_MMIO;
   1460 #endif
   1461         return TRUE;
   1462 #if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,902,0)
   1463     case SUPPORTS_SERVER_FDS:
   1464         return TRUE;
   1465 #endif
   1466     default:
   1467         return FALSE;
   1468     }
   1469 }
   1470 
   1471 static DriverRec qxl_driver = {
   1472     0,
   1473     driver_name,
   1474     qxl_identify,
   1475     qxl_probe,
   1476     qxl_available_options,
   1477     NULL,
   1478     0,
   1479     qxl_driver_func,
   1480 #ifdef XSPICE
   1481     NULL,
   1482     NULL,
   1483     NULL,
   1484 #else
   1485 #ifdef XSERVER_LIBPCIACCESS
   1486     qxl_device_match,
   1487     qxl_pci_probe,
   1488 #else
   1489     NULL,
   1490     NULL,
   1491 #endif
   1492 #ifdef XSERVER_PLATFORM_BUS
   1493     qxl_platform_probe,
   1494 #else
   1495     NULL,
   1496 #endif
   1497 #endif /* XSPICE */
   1498 };
   1499 
   1500 static pointer
   1501 qxl_setup (pointer module, pointer opts, int *errmaj, int *errmin)
   1502 {
   1503     static Bool loaded = FALSE;
   1504 
   1505     if (!loaded)
   1506     {
   1507 	loaded = TRUE;
   1508 	xf86AddDriver (&qxl_driver, module, HaveDriverFuncs);
   1509 #ifdef XSPICE
   1510 	xspice_add_input_drivers (module);
   1511 #endif
   1512 	return (void *)1;
   1513     }
   1514     else
   1515     {
   1516 	if (errmaj)
   1517 	    *errmaj = LDR_ONCEONLY;
   1518 
   1519 	return NULL;
   1520     }
   1521 }
   1522 
   1523 static XF86ModuleVersionInfo qxl_module_info =
   1524 {
   1525     driver_name,
   1526     MODULEVENDORSTRING,
   1527     MODINFOSTRING1,
   1528     MODINFOSTRING2,
   1529     XORG_VERSION_CURRENT,
   1530     PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
   1531     ABI_CLASS_VIDEODRV,
   1532     ABI_VIDEODRV_VERSION,
   1533     MOD_CLASS_VIDEODRV,
   1534     { 0, 0, 0, 0 }
   1535 };
   1536 
   1537 _X_EXPORT XF86ModuleData
   1538 #ifdef XSPICE
   1539 spiceqxlModuleData
   1540 #else
   1541 qxlModuleData
   1542 #endif
   1543 = {
   1544     &qxl_module_info,
   1545     qxl_setup,
   1546     NULL
   1547 };
   1548