On Wed, Jun 22, 2011 at 10:46:06AM +0200, Gerd Hoffmann wrote: > Signed-off-by: Gerd Hoffmann <kra...@redhat.com> > --- > hw/qxl.c | 134 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- > hw/qxl.h | 3 + > 2 files changed, 133 insertions(+), 4 deletions(-) > > diff --git a/hw/qxl.c b/hw/qxl.c > index 03c871a..60caff9 100644 > --- a/hw/qxl.c > +++ b/hw/qxl.c > @@ -28,6 +28,18 @@ > > #include "qxl.h" > > +/* old spice-protocol */ > +#ifndef QXL_INTERRUPT_IO_CMD > +#define QXL_INTERRUPT_IO_CMD (1 << 2) > +#define QXL_IO_UPDATE_AREA_ASYNC (QXL_IO_DESTROY_ALL_SURFACES +1) > +#define QXL_IO_NOTIFY_OOM_ASYNC (QXL_IO_DESTROY_ALL_SURFACES +2) > +#define QXL_IO_MEMSLOT_ADD_ASYNC (QXL_IO_DESTROY_ALL_SURFACES +3) > +#define QXL_IO_CREATE_PRIMARY_ASYNC (QXL_IO_DESTROY_ALL_SURFACES +4) > +#define QXL_IO_DESTROY_PRIMARY_ASYNC (QXL_IO_DESTROY_ALL_SURFACES +5) > +#define QXL_IO_DESTROY_SURFACE_ASYNC (QXL_IO_DESTROY_ALL_SURFACES +6) > +#define QXL_IO_DESTROY_ALL_SURFACES_ASYNC (QXL_IO_DESTROY_ALL_SURFACES +7) > +#endif > +
Can you drop this? I think it's better to just not support the io if spice-protocol is too old, or better yet just require a newer spice-protocol for building (and bump spice-protocol version). > #undef SPICE_RING_PROD_ITEM > #define SPICE_RING_PROD_ITEM(r, ret) { \ > typeof(r) start = r; \ > @@ -910,22 +922,90 @@ static void qxl_set_mode(PCIQXLDevice *d, int modenr, > int loadvm) > qxl_rom_set_dirty(d); > } > > +struct qxl_io_async { > + QXLDevMemSlot memslot; > + QXLDevSurfaceCreate surface; > + QXLRect update_area; > + uint32_t update_surface; > + uint32_t port; > + uint32_t val; > +}; > + > +static void *ioport_write_async(void *arg) > +{ > + PCIQXLDevice *d = arg; > + struct qxl_io_async *io; > + uint32_t io_port; > + uint32_t val; > + int ret; > + > + while (true) { > + ret = read(d->aio_pipe[0], &io, sizeof(io)); > + if (ret != sizeof(io)) { > + break; > + } > + io_port = io->port; > + val = io->val; > + > + fprintf(stderr, "%s: 0x%x\n", __FUNCTION__, io_port); > + switch (io_port) { > + case QXL_IO_UPDATE_AREA_ASYNC: > + qemu_spice_update_area(&d->ssd, io->update_surface, > + &io->update_area, NULL, 0, 0); > + break; > + case QXL_IO_NOTIFY_OOM_ASYNC: > + d->oom_running = 1; > + qemu_spice_oom(&d->ssd); > + d->oom_running = 0; > + break; > + case QXL_IO_MEMSLOT_ADD_ASYNC: > + qemu_spice_add_memslot(&d->ssd, &io->memslot); > + break; > + case QXL_IO_CREATE_PRIMARY_ASYNC: > + qemu_spice_create_primary_surface(&d->ssd, 0, &io->surface); > + break; > + case QXL_IO_DESTROY_PRIMARY_ASYNC: > + qemu_spice_destroy_primary_surface(&d->ssd, 0); > + break; > + case QXL_IO_DESTROY_SURFACE_ASYNC: > + qemu_spice_destroy_surface_wait(&d->ssd, val); > + break; > + case QXL_IO_DESTROY_ALL_SURFACES_ASYNC: > + qemu_spice_destroy_surfaces(&d->ssd); > + break; > + } > + qxl_send_events(d, QXL_INTERRUPT_IO_CMD); > + qemu_free(io); > + } > + qemu_thread_exit(NULL); > + return NULL; > +} > + > static void ioport_write(void *opaque, uint32_t addr, uint32_t val) > { > PCIQXLDevice *d = opaque; > uint32_t io_port = addr - d->io_base; > + struct qxl_io_async *async; > + int ret; > > switch (io_port) { > case QXL_IO_RESET: > case QXL_IO_SET_MODE: > case QXL_IO_MEMSLOT_ADD: > + case QXL_IO_MEMSLOT_ADD_ASYNC: > case QXL_IO_MEMSLOT_DEL: > case QXL_IO_CREATE_PRIMARY: > + case QXL_IO_CREATE_PRIMARY_ASYNC: missing for windows driver, which does QXL_IO_MEMSLOT_ADD before CREATE_PRIMARY, and with async this turns to QXL_IO_MEMSLOT_ADD_ASYNC followed by QXL_IO_UPDATE_IRQ + case QXL_IO_UPDATE_IRQ: > break; > default: > if (d->mode == QXL_MODE_NATIVE || d->mode == QXL_MODE_COMPAT) > break; > dprint(d, 1, "%s: unexpected port 0x%x in vga mode\n", __FUNCTION__, > io_port); > + /* be nice to buggy guest drivers */ > + if (io_port >= QXL_IO_UPDATE_AREA_ASYNC && > + io_port <= QXL_IO_DESTROY_ALL_SURFACES_ASYNC) { > + qxl_send_events(d, QXL_INTERRUPT_IO_CMD); > + } > return; > } > > @@ -1010,6 +1090,46 @@ static void ioport_write(void *opaque, uint32_t addr, > uint32_t val) > case QXL_IO_DESTROY_ALL_SURFACES: > qemu_spice_destroy_surfaces(&d->ssd); > break; > + case QXL_IO_MEMSLOT_ADD_ASYNC: > + PANIC_ON(val >= NUM_MEMSLOTS); > + PANIC_ON(d->guest_slots[val].active); > + d->guest_slots[val].slot = d->ram->mem_slot; > + async = qemu_mallocz(sizeof(*async)); > + qxl_add_memslot(d, val, 0, &async->memslot); > + goto async_common; > + case QXL_IO_CREATE_PRIMARY_ASYNC: > + PANIC_ON(val != 0); > + dprint(d, 1, "QXL_IO_CREATE_PRIMARY_ASYNC\n"); > + d->guest_primary.surface = d->ram->create_surface; > + async = qemu_mallocz(sizeof(*async)); > + qxl_create_guest_primary(d, 0, &async->surface); > + goto async_common; > + case QXL_IO_DESTROY_PRIMARY_ASYNC: > + PANIC_ON(val != 0); > + dprint(d, 1, "QXL_IO_DESTROY_PRIMARY_ASYNC\n"); > + if (d->mode != QXL_MODE_UNDEFINED) { > + d->mode = QXL_MODE_UNDEFINED; > + async = qemu_mallocz(sizeof(*async)); > + goto async_common; > + } else { > + qxl_send_events(d, QXL_INTERRUPT_IO_CMD); > + break; > + } > + case QXL_IO_UPDATE_AREA_ASYNC: > + async = qemu_mallocz(sizeof(*async)); > + async->update_area = d->ram->update_area; > + async->update_surface = d->ram->update_surface; > + goto async_common; > + case QXL_IO_NOTIFY_OOM_ASYNC: > + case QXL_IO_DESTROY_SURFACE_ASYNC: > + case QXL_IO_DESTROY_ALL_SURFACES_ASYNC: > + async = qemu_mallocz(sizeof(*async)); > + async_common: > + async->port = io_port; > + async->val = val; > + ret = write(d->aio_pipe[1], &async, sizeof(async)); > + assert(ret == sizeof(async)); > + break; > default: > fprintf(stderr, "%s: ioport=0x%x, abort()\n", __FUNCTION__, io_port); > abort(); > @@ -1095,7 +1215,8 @@ static void qxl_send_events(PCIQXLDevice *d, uint32_t > events) > > static void init_pipe_signaling(PCIQXLDevice *d) > { > - if (pipe(d->pipe) < 0) { > + if (pipe(d->pipe) < 0 || > + pipe(d->aio_pipe) < 0 ) { > dprint(d, 1, "%s: pipe creation failed\n", __FUNCTION__); > return; > } > @@ -1233,6 +1354,10 @@ static int qxl_init_common(PCIQXLDevice *qxl) > pci_device_id = QXL_DEVICE_ID_STABLE; > pci_device_rev = QXL_REVISION_STABLE_V06; > break; > + case 3: /* qxl-3 */ > + pci_device_id = QXL_DEVICE_ID_STABLE; > + pci_device_rev = 3; > + break; > default: /* experimental */ > pci_device_id = QXL_DEVICE_ID_DEVEL; > pci_device_rev = 1; > @@ -1258,7 +1383,7 @@ static int qxl_init_common(PCIQXLDevice *qxl) > qxl->vram_size = msb_mask(qxl->vram_size * 2 - 1); > qxl->vram_offset = qemu_ram_alloc(&qxl->pci.qdev, "qxl.vram", > qxl->vram_size); > > - io_size = msb_mask(QXL_IO_RANGE_SIZE * 2 - 1); > + io_size = msb_mask((QXL_IO_RANGE_SIZE+7) * 2 - 1); > if (qxl->revision == 1) { > io_size = 8; > } > @@ -1282,6 +1407,7 @@ static int qxl_init_common(PCIQXLDevice *qxl) > qemu_spice_add_interface(&qxl->ssd.qxl.base); > qemu_add_vm_change_state_handler(qxl_vm_change_state_handler, qxl); > > + qemu_thread_create(&qxl->aio_thread, ioport_write_async, qxl); > init_pipe_signaling(qxl); > qxl_reset_state(qxl); > > @@ -1504,7 +1630,7 @@ static PCIDeviceInfo qxl_info_primary = { > .qdev.props = (Property[]) { > DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size, 64 * > 1024 * 1024), > DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram_size, 64 * 1024 * > 1024), > - DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision, 2), > + DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision, 3), > DEFINE_PROP_UINT32("debug", PCIQXLDevice, debug, 0), > DEFINE_PROP_UINT32("guestdebug", PCIQXLDevice, guestdebug, 0), > DEFINE_PROP_UINT32("cmdlog", PCIQXLDevice, cmdlog, 0), > @@ -1522,7 +1648,7 @@ static PCIDeviceInfo qxl_info_secondary = { > .qdev.props = (Property[]) { > DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size, 64 * > 1024 * 1024), > DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram_size, 64 * 1024 * > 1024), > - DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision, 2), > + DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision, 3), > DEFINE_PROP_UINT32("debug", PCIQXLDevice, debug, 0), > DEFINE_PROP_UINT32("guestdebug", PCIQXLDevice, guestdebug, 0), > DEFINE_PROP_UINT32("cmdlog", PCIQXLDevice, cmdlog, 0), > diff --git a/hw/qxl.h b/hw/qxl.h > index f6c450d..6dd38e6 100644 > --- a/hw/qxl.h > +++ b/hw/qxl.h > @@ -30,6 +30,9 @@ typedef struct PCIQXLDevice { > int32_t num_memslots; > int32_t num_surfaces; > > + QemuThread aio_thread; > + int aio_pipe[2]; > + > struct guest_slots { > QXLMemSlot slot; > void *ptr; > -- > 1.7.1 > > _______________________________________________ > Spice-devel mailing list > Spice-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/spice-devel _______________________________________________ Spice-devel mailing list Spice-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/spice-devel