diff --git a/0216-qxl-Ignore-set_client_capabilities-pre-post-migrate.patch b/0216-qxl-Ignore-set_client_capabilities-pre-post-migrate.patch
new file mode 100644
index 0000000..3391970
--- /dev/null
+++ b/0216-qxl-Ignore-set_client_capabilities-pre-post-migrate.patch
@@ -0,0 +1,41 @@
+From 68d246d6a904e0a851c521a08a18187598e1c696 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Fri, 7 Sep 2012 21:29:22 +0200
+Subject: [PATCH] qxl: Ignore set_client_capabilities pre/post migrate
+
+The recent introduction of set_client_capabilities has broken
+(seamless) migration by trying to call qxl_send_events pre (seamless
+incoming) and post (*) migration, triggering the following assert:
+qxl_send_events: Assertion `qemu_spice_display_is_running(&d->ssd)' failed.
+
+The solution is easy, pre migration the guest will have already received
+the client caps on the migration source side, and post migration there no
+longer is a guest, so we can simply ignore the set_client_capabilities call
+in both those scenarios.
+
+*) Post migration, so not fatal for to the migration itself, but still a crash
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ hw/qxl.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/hw/qxl.c b/hw/qxl.c
+index 045432e..1b400f1 100644
+--- a/hw/qxl.c
++++ b/hw/qxl.c
+@@ -953,6 +953,11 @@ static void interface_set_client_capabilities(QXLInstance *sin,
+ {
+     PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
+ 
++    if (runstate_check(RUN_STATE_INMIGRATE) ||
++        runstate_check(RUN_STATE_POSTMIGRATE)) {
++        return;
++    }
++
+     qxl->shadow_rom.client_present = client_present;
+     memcpy(qxl->shadow_rom.client_capabilities, caps, sizeof(caps));
+     qxl->rom->client_present = client_present;
+-- 
+1.7.12
+
diff --git a/0361-usb-Migrate-over-device-speed-and-speedmask.patch b/0361-usb-Migrate-over-device-speed-and-speedmask.patch
deleted file mode 100644
index d775b9c..0000000
--- a/0361-usb-Migrate-over-device-speed-and-speedmask.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 6ba840c192897029895930a504527d4350b88d26 Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Thu, 6 Sep 2012 15:34:19 +0200
-Subject: [PATCH 361/366] usb: Migrate over device speed and speedmask
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- hw/usb.h     | 4 ++--
- hw/usb/bus.c | 2 ++
- 2 files changed, 4 insertions(+), 2 deletions(-)
-
-diff --git a/hw/usb.h b/hw/usb.h
-index 48c8926..918af99 100644
---- a/hw/usb.h
-+++ b/hw/usb.h
-@@ -204,9 +204,9 @@ struct USBDevice {
-     uint32_t flags;
- 
-     /* Actual connected speed */
--    int speed;
-+    int32_t speed;
-     /* Supported speeds, not in info because it may be variable (hostdevs) */
--    int speedmask;
-+    int32_t speedmask;
-     uint8_t addr;
-     char product_desc[32];
-     int auto_attach;
-diff --git a/hw/usb/bus.c b/hw/usb/bus.c
-index b649360..223c1df 100644
---- a/hw/usb/bus.c
-+++ b/hw/usb/bus.c
-@@ -55,6 +55,8 @@ const VMStateDescription vmstate_usb_device = {
-     .minimum_version_id = 1,
-     .post_load = usb_device_post_load,
-     .fields = (VMStateField []) {
-+        VMSTATE_INT32(speed, USBDevice),
-+        VMSTATE_INT32(speedmask, USBDevice),
-         VMSTATE_UINT8(addr, USBDevice),
-         VMSTATE_INT32(state, USBDevice),
-         VMSTATE_INT32(remote_wakeup, USBDevice),
--- 
-1.7.12
-
diff --git a/0361-usb-redir-Change-cancelled-packet-code-into-a-generi.patch b/0361-usb-redir-Change-cancelled-packet-code-into-a-generi.patch
new file mode 100644
index 0000000..2efd733
--- /dev/null
+++ b/0361-usb-redir-Change-cancelled-packet-code-into-a-generi.patch
@@ -0,0 +1,184 @@
+From efbf5d06a89ec7b329d2aa15d3a6ea023b63c646 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Tue, 4 Sep 2012 14:18:34 +0200
+Subject: [PATCH 361/365] usb-redir: Change cancelled packet code into a
+ generic packet-id queue
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ hw/usb/redirect.c | 102 +++++++++++++++++++++++++++++++++++++-----------------
+ 1 file changed, 71 insertions(+), 31 deletions(-)
+
+diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
+index 9cbcddb..08776d9 100644
+--- a/hw/usb/redirect.c
++++ b/hw/usb/redirect.c
+@@ -43,7 +43,6 @@
+ #define EP2I(ep_address) (((ep_address & 0x80) >> 3) | (ep_address & 0x0f))
+ #define I2EP(i) (((i & 0x10) << 3) | (i & 0x0f))
+ 
+-typedef struct Cancelled Cancelled;
+ typedef struct USBRedirDevice USBRedirDevice;
+ 
+ /* Struct to hold buffered packets (iso or int input packets) */
+@@ -69,6 +68,18 @@ struct endp_data {
+     int bufpq_target_size;
+ };
+ 
++struct PacketIdQueueEntry {
++    uint64_t id;
++    QTAILQ_ENTRY(PacketIdQueueEntry)next;
++};
++
++struct PacketIdQueue {
++    USBRedirDevice *dev;
++    const char *name;
++    QTAILQ_HEAD(, PacketIdQueueEntry) head;
++    int size;
++};
++
+ struct USBRedirDevice {
+     USBDevice dev;
+     /* Properties */
+@@ -86,7 +97,7 @@ struct USBRedirDevice {
+     int64_t next_attach_time;
+     struct usbredirparser *parser;
+     struct endp_data endpoint[MAX_ENDPOINTS];
+-    QTAILQ_HEAD(, Cancelled) cancelled;
++    struct PacketIdQueue cancelled;
+     /* Data for device filtering */
+     struct usb_redir_device_connect_header device_info;
+     struct usb_redir_interface_info_header interface_info;
+@@ -94,11 +105,6 @@ struct USBRedirDevice {
+     int filter_rules_count;
+ };
+ 
+-struct Cancelled {
+-    uint64_t id;
+-    QTAILQ_ENTRY(Cancelled)next;
+-};
+-
+ static void usbredir_hello(void *priv, struct usb_redir_hello_header *h);
+ static void usbredir_device_connect(void *priv,
+     struct usb_redir_device_connect_header *device_connect);
+@@ -249,37 +255,75 @@ static int usbredir_write(void *priv, uint8_t *data, int count)
+  * Cancelled and buffered packets helpers
+  */
+ 
+-static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p)
++static void packet_id_queue_init(struct PacketIdQueue *q,
++    USBRedirDevice *dev, const char *name)
+ {
+-    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
+-    Cancelled *c;
++    q->dev = dev;
++    q->name = name;
++    QTAILQ_INIT(&q->head);
++    q->size = 0;
++}
++
++static void packet_id_queue_add(struct PacketIdQueue *q, uint64_t id)
++{
++    USBRedirDevice *dev = q->dev;
++    struct PacketIdQueueEntry *e;
++
++    DPRINTF("adding packet id %"PRIu64" to %s queue\n", id, q->name);
++
++    e = g_malloc0(sizeof(struct PacketIdQueueEntry));
++    e->id = id;
++    QTAILQ_INSERT_TAIL(&q->head, e, next);
++    q->size++;
++}
++
++static int packet_id_queue_remove(struct PacketIdQueue *q, uint64_t id)
++{
++    USBRedirDevice *dev = q->dev;
++    struct PacketIdQueueEntry *e;
++
++    QTAILQ_FOREACH(e, &q->head, next) {
++        if (e->id == id) {
++            DPRINTF("removing packet id %"PRIu64" from %s queue\n",
++                    id, q->name);
++            QTAILQ_REMOVE(&q->head, e, next);
++            q->size--;
++            g_free(e);
++            return 1;
++        }
++    }
++    return 0;
++}
++
++static void packet_id_queue_empty(struct PacketIdQueue *q)
++{
++    USBRedirDevice *dev = q->dev;
++    struct PacketIdQueueEntry *e, *next_e;
+ 
+-    DPRINTF("cancel packet id %"PRIu64"\n", p->id);
++    DPRINTF("removing %d packet-ids from %s queue\n", q->size, q->name);
+ 
+-    c = g_malloc0(sizeof(Cancelled));
+-    c->id = p->id;
+-    QTAILQ_INSERT_TAIL(&dev->cancelled, c, next);
++    QTAILQ_FOREACH_SAFE(e, &q->head, next, next_e) {
++        QTAILQ_REMOVE(&q->head, e, next);
++        g_free(e);
++    }
++    q->size = 0;
++}
+ 
++static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p)
++{
++    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
++
++    packet_id_queue_add(&dev->cancelled, p->id);
+     usbredirparser_send_cancel_data_packet(dev->parser, p->id);
+     usbredirparser_do_write(dev->parser);
+ }
+ 
+ static int usbredir_is_cancelled(USBRedirDevice *dev, uint64_t id)
+ {
+-    Cancelled *c;
+-
+     if (!dev->dev.attached) {
+         return 1; /* Treat everything as cancelled after a disconnect */
+     }
+-
+-    QTAILQ_FOREACH(c, &dev->cancelled, next) {
+-        if (c->id == id) {
+-            QTAILQ_REMOVE(&dev->cancelled, c, next);
+-            g_free(c);
+-            return 1;
+-        }
+-    }
+-    return 0;
++    return packet_id_queue_remove(&dev->cancelled, id);
+ }
+ 
+ static USBPacket *usbredir_find_packet_by_id(USBRedirDevice *dev,
+@@ -942,7 +986,7 @@ static int usbredir_initfn(USBDevice *udev)
+     dev->chardev_close_bh = qemu_bh_new(usbredir_chardev_close_bh, dev);
+     dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev);
+ 
+-    QTAILQ_INIT(&dev->cancelled);
++    packet_id_queue_init(&dev->cancelled, dev, "cancelled");
+     for (i = 0; i < MAX_ENDPOINTS; i++) {
+         QTAILQ_INIT(&dev->endpoint[i].bufpq);
+     }
+@@ -960,13 +1004,9 @@ static int usbredir_initfn(USBDevice *udev)
+ 
+ static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
+ {
+-    Cancelled *c, *next_c;
+     int i;
+ 
+-    QTAILQ_FOREACH_SAFE(c, &dev->cancelled, next, next_c) {
+-        QTAILQ_REMOVE(&dev->cancelled, c, next);
+-        g_free(c);
+-    }
++    packet_id_queue_empty(&dev->cancelled);
+     for (i = 0; i < MAX_ENDPOINTS; i++) {
+         usbredir_free_bufpq(dev, I2EP(i));
+     }
+-- 
+1.7.12
+
diff --git a/0362-usb-redir-Add-an-already_in_flight-packet-id-queue.patch b/0362-usb-redir-Add-an-already_in_flight-packet-id-queue.patch
new file mode 100644
index 0000000..10c9aa3
--- /dev/null
+++ b/0362-usb-redir-Add-an-already_in_flight-packet-id-queue.patch
@@ -0,0 +1,119 @@
+From b422d151d0861ed346bed7cddb410a6b4c67711b Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Tue, 4 Sep 2012 17:03:54 +0200
+Subject: [PATCH 362/365] usb-redir: Add an already_in_flight packet-id queue
+
+After a live migration, the usb-hcd will re-queue all packets by
+walking over the schedule in the guest memory again, but requests which
+were encountered on the migration source before will already be in flight,
+so these should *not* be re-send to the usbredir-host.
+
+This patch adds an already in flight packet ud queue, which will be filled by
+the source before migration and then moved over to the migration dest, any
+async handled packets are then checked against this queue to avoid sending
+the same packet to the usbredir-host twice.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat,com>
+---
+ hw/usb/redirect.c | 43 +++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 43 insertions(+)
+
+diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
+index 08776d9..1c8edd3 100644
+--- a/hw/usb/redirect.c
++++ b/hw/usb/redirect.c
+@@ -98,6 +98,7 @@ struct USBRedirDevice {
+     struct usbredirparser *parser;
+     struct endp_data endpoint[MAX_ENDPOINTS];
+     struct PacketIdQueue cancelled;
++    struct PacketIdQueue already_in_flight;
+     /* Data for device filtering */
+     struct usb_redir_device_connect_header device_info;
+     struct usb_redir_interface_info_header interface_info;
+@@ -326,6 +327,34 @@ static int usbredir_is_cancelled(USBRedirDevice *dev, uint64_t id)
+     return packet_id_queue_remove(&dev->cancelled, id);
+ }
+ 
++static void usbredir_fill_already_in_flight_from_ep(USBRedirDevice *dev,
++    struct USBEndpoint *ep)
++{
++    static USBPacket *p;
++
++    QTAILQ_FOREACH(p, &ep->queue, queue) {
++        packet_id_queue_add(&dev->already_in_flight, p->id);
++    }
++}
++
++static void usbredir_fill_already_in_flight(USBRedirDevice *dev)
++{
++    int ep;
++    struct USBDevice *udev = &dev->dev;
++
++    usbredir_fill_already_in_flight_from_ep(dev, &udev->ep_ctl);
++
++    for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) {
++        usbredir_fill_already_in_flight_from_ep(dev, &udev->ep_in[ep]);
++        usbredir_fill_already_in_flight_from_ep(dev, &udev->ep_out[ep]);
++    }
++}
++
++static int usbredir_already_in_flight(USBRedirDevice *dev, uint64_t id)
++{
++    return packet_id_queue_remove(&dev->already_in_flight, id);
++}
++
+ static USBPacket *usbredir_find_packet_by_id(USBRedirDevice *dev,
+     uint8_t ep, uint64_t id)
+ {
+@@ -541,6 +570,10 @@ static int usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p,
+ 
+     DPRINTF("bulk-out ep %02X len %zd id %"PRIu64"\n", ep, p->iov.size, p->id);
+ 
++    if (usbredir_already_in_flight(dev, p->id)) {
++        return USB_RET_ASYNC;
++    }
++
+     bulk_packet.endpoint  = ep;
+     bulk_packet.length    = p->iov.size;
+     bulk_packet.stream_id = 0;
+@@ -621,6 +654,10 @@ static int usbredir_handle_interrupt_data(USBRedirDevice *dev,
+         DPRINTF("interrupt-out ep %02X len %zd id %"PRIu64"\n", ep,
+                 p->iov.size, p->id);
+ 
++        if (usbredir_already_in_flight(dev, p->id)) {
++            return USB_RET_ASYNC;
++        }
++
+         interrupt_packet.endpoint  = ep;
+         interrupt_packet.length    = p->iov.size;
+ 
+@@ -763,6 +800,10 @@ static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
+     USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
+     struct usb_redir_control_packet_header control_packet;
+ 
++    if (usbredir_already_in_flight(dev, p->id)) {
++        return USB_RET_ASYNC;
++    }
++
+     /* Special cases for certain standard device requests */
+     switch (request) {
+     case DeviceOutRequest | USB_REQ_SET_ADDRESS:
+@@ -987,6 +1028,7 @@ static int usbredir_initfn(USBDevice *udev)
+     dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev);
+ 
+     packet_id_queue_init(&dev->cancelled, dev, "cancelled");
++    packet_id_queue_init(&dev->already_in_flight, dev, "already-in-flight");
+     for (i = 0; i < MAX_ENDPOINTS; i++) {
+         QTAILQ_INIT(&dev->endpoint[i].bufpq);
+     }
+@@ -1007,6 +1049,7 @@ static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
+     int i;
+ 
+     packet_id_queue_empty(&dev->cancelled);
++    packet_id_queue_empty(&dev->already_in_flight);
+     for (i = 0; i < MAX_ENDPOINTS; i++) {
+         usbredir_free_bufpq(dev, I2EP(i));
+     }
+-- 
+1.7.12
+
diff --git a/0362-usb-redir-Change-cancelled-packet-code-into-a-generi.patch b/0362-usb-redir-Change-cancelled-packet-code-into-a-generi.patch
deleted file mode 100644
index ee0c0f9..0000000
--- a/0362-usb-redir-Change-cancelled-packet-code-into-a-generi.patch
+++ /dev/null
@@ -1,184 +0,0 @@
-From 4d7d1b57fa5d3a950818e5dee459aefa4dc6ae27 Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Tue, 4 Sep 2012 14:18:34 +0200
-Subject: [PATCH 362/366] usb-redir: Change cancelled packet code into a
- generic packet-id queue
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- hw/usb/redirect.c | 102 +++++++++++++++++++++++++++++++++++++-----------------
- 1 file changed, 71 insertions(+), 31 deletions(-)
-
-diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
-index 9cbcddb..08776d9 100644
---- a/hw/usb/redirect.c
-+++ b/hw/usb/redirect.c
-@@ -43,7 +43,6 @@
- #define EP2I(ep_address) (((ep_address & 0x80) >> 3) | (ep_address & 0x0f))
- #define I2EP(i) (((i & 0x10) << 3) | (i & 0x0f))
- 
--typedef struct Cancelled Cancelled;
- typedef struct USBRedirDevice USBRedirDevice;
- 
- /* Struct to hold buffered packets (iso or int input packets) */
-@@ -69,6 +68,18 @@ struct endp_data {
-     int bufpq_target_size;
- };
- 
-+struct PacketIdQueueEntry {
-+    uint64_t id;
-+    QTAILQ_ENTRY(PacketIdQueueEntry)next;
-+};
-+
-+struct PacketIdQueue {
-+    USBRedirDevice *dev;
-+    const char *name;
-+    QTAILQ_HEAD(, PacketIdQueueEntry) head;
-+    int size;
-+};
-+
- struct USBRedirDevice {
-     USBDevice dev;
-     /* Properties */
-@@ -86,7 +97,7 @@ struct USBRedirDevice {
-     int64_t next_attach_time;
-     struct usbredirparser *parser;
-     struct endp_data endpoint[MAX_ENDPOINTS];
--    QTAILQ_HEAD(, Cancelled) cancelled;
-+    struct PacketIdQueue cancelled;
-     /* Data for device filtering */
-     struct usb_redir_device_connect_header device_info;
-     struct usb_redir_interface_info_header interface_info;
-@@ -94,11 +105,6 @@ struct USBRedirDevice {
-     int filter_rules_count;
- };
- 
--struct Cancelled {
--    uint64_t id;
--    QTAILQ_ENTRY(Cancelled)next;
--};
--
- static void usbredir_hello(void *priv, struct usb_redir_hello_header *h);
- static void usbredir_device_connect(void *priv,
-     struct usb_redir_device_connect_header *device_connect);
-@@ -249,37 +255,75 @@ static int usbredir_write(void *priv, uint8_t *data, int count)
-  * Cancelled and buffered packets helpers
-  */
- 
--static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p)
-+static void packet_id_queue_init(struct PacketIdQueue *q,
-+    USBRedirDevice *dev, const char *name)
- {
--    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
--    Cancelled *c;
-+    q->dev = dev;
-+    q->name = name;
-+    QTAILQ_INIT(&q->head);
-+    q->size = 0;
-+}
-+
-+static void packet_id_queue_add(struct PacketIdQueue *q, uint64_t id)
-+{
-+    USBRedirDevice *dev = q->dev;
-+    struct PacketIdQueueEntry *e;
-+
-+    DPRINTF("adding packet id %"PRIu64" to %s queue\n", id, q->name);
-+
-+    e = g_malloc0(sizeof(struct PacketIdQueueEntry));
-+    e->id = id;
-+    QTAILQ_INSERT_TAIL(&q->head, e, next);
-+    q->size++;
-+}
-+
-+static int packet_id_queue_remove(struct PacketIdQueue *q, uint64_t id)
-+{
-+    USBRedirDevice *dev = q->dev;
-+    struct PacketIdQueueEntry *e;
-+
-+    QTAILQ_FOREACH(e, &q->head, next) {
-+        if (e->id == id) {
-+            DPRINTF("removing packet id %"PRIu64" from %s queue\n",
-+                    id, q->name);
-+            QTAILQ_REMOVE(&q->head, e, next);
-+            q->size--;
-+            g_free(e);
-+            return 1;
-+        }
-+    }
-+    return 0;
-+}
-+
-+static void packet_id_queue_empty(struct PacketIdQueue *q)
-+{
-+    USBRedirDevice *dev = q->dev;
-+    struct PacketIdQueueEntry *e, *next_e;
- 
--    DPRINTF("cancel packet id %"PRIu64"\n", p->id);
-+    DPRINTF("removing %d packet-ids from %s queue\n", q->size, q->name);
- 
--    c = g_malloc0(sizeof(Cancelled));
--    c->id = p->id;
--    QTAILQ_INSERT_TAIL(&dev->cancelled, c, next);
-+    QTAILQ_FOREACH_SAFE(e, &q->head, next, next_e) {
-+        QTAILQ_REMOVE(&q->head, e, next);
-+        g_free(e);
-+    }
-+    q->size = 0;
-+}
- 
-+static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p)
-+{
-+    USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
-+
-+    packet_id_queue_add(&dev->cancelled, p->id);
-     usbredirparser_send_cancel_data_packet(dev->parser, p->id);
-     usbredirparser_do_write(dev->parser);
- }
- 
- static int usbredir_is_cancelled(USBRedirDevice *dev, uint64_t id)
- {
--    Cancelled *c;
--
-     if (!dev->dev.attached) {
-         return 1; /* Treat everything as cancelled after a disconnect */
-     }
--
--    QTAILQ_FOREACH(c, &dev->cancelled, next) {
--        if (c->id == id) {
--            QTAILQ_REMOVE(&dev->cancelled, c, next);
--            g_free(c);
--            return 1;
--        }
--    }
--    return 0;
-+    return packet_id_queue_remove(&dev->cancelled, id);
- }
- 
- static USBPacket *usbredir_find_packet_by_id(USBRedirDevice *dev,
-@@ -942,7 +986,7 @@ static int usbredir_initfn(USBDevice *udev)
-     dev->chardev_close_bh = qemu_bh_new(usbredir_chardev_close_bh, dev);
-     dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev);
- 
--    QTAILQ_INIT(&dev->cancelled);
-+    packet_id_queue_init(&dev->cancelled, dev, "cancelled");
-     for (i = 0; i < MAX_ENDPOINTS; i++) {
-         QTAILQ_INIT(&dev->endpoint[i].bufpq);
-     }
-@@ -960,13 +1004,9 @@ static int usbredir_initfn(USBDevice *udev)
- 
- static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
- {
--    Cancelled *c, *next_c;
-     int i;
- 
--    QTAILQ_FOREACH_SAFE(c, &dev->cancelled, next, next_c) {
--        QTAILQ_REMOVE(&dev->cancelled, c, next);
--        g_free(c);
--    }
-+    packet_id_queue_empty(&dev->cancelled);
-     for (i = 0; i < MAX_ENDPOINTS; i++) {
-         usbredir_free_bufpq(dev, I2EP(i));
-     }
--- 
-1.7.12
-
diff --git a/0363-usb-redir-Add-an-already_in_flight-packet-id-queue.patch b/0363-usb-redir-Add-an-already_in_flight-packet-id-queue.patch
deleted file mode 100644
index 9fea679..0000000
--- a/0363-usb-redir-Add-an-already_in_flight-packet-id-queue.patch
+++ /dev/null
@@ -1,119 +0,0 @@
-From 4e0fcd7ef28b0ee06fd6f9d736dbdccefcf0b2bf Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Tue, 4 Sep 2012 17:03:54 +0200
-Subject: [PATCH 363/366] usb-redir: Add an already_in_flight packet-id queue
-
-After a live migration, the usb-hcd will re-queue all packets by
-walking over the schedule in the guest memory again, but requests which
-were encountered on the migration source before will already be in flight,
-so these should *not* be re-send to the usbredir-host.
-
-This patch adds an already in flight packet ud queue, which will be filled by
-the source before migration and then moved over to the migration dest, any
-async handled packets are then checked against this queue to avoid sending
-the same packet to the usbredir-host twice.
-
-Signed-off-by: Hans de Goede <hdegoede@redhat,com>
----
- hw/usb/redirect.c | 43 +++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 43 insertions(+)
-
-diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
-index 08776d9..1c8edd3 100644
---- a/hw/usb/redirect.c
-+++ b/hw/usb/redirect.c
-@@ -98,6 +98,7 @@ struct USBRedirDevice {
-     struct usbredirparser *parser;
-     struct endp_data endpoint[MAX_ENDPOINTS];
-     struct PacketIdQueue cancelled;
-+    struct PacketIdQueue already_in_flight;
-     /* Data for device filtering */
-     struct usb_redir_device_connect_header device_info;
-     struct usb_redir_interface_info_header interface_info;
-@@ -326,6 +327,34 @@ static int usbredir_is_cancelled(USBRedirDevice *dev, uint64_t id)
-     return packet_id_queue_remove(&dev->cancelled, id);
- }
- 
-+static void usbredir_fill_already_in_flight_from_ep(USBRedirDevice *dev,
-+    struct USBEndpoint *ep)
-+{
-+    static USBPacket *p;
-+
-+    QTAILQ_FOREACH(p, &ep->queue, queue) {
-+        packet_id_queue_add(&dev->already_in_flight, p->id);
-+    }
-+}
-+
-+static void usbredir_fill_already_in_flight(USBRedirDevice *dev)
-+{
-+    int ep;
-+    struct USBDevice *udev = &dev->dev;
-+
-+    usbredir_fill_already_in_flight_from_ep(dev, &udev->ep_ctl);
-+
-+    for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) {
-+        usbredir_fill_already_in_flight_from_ep(dev, &udev->ep_in[ep]);
-+        usbredir_fill_already_in_flight_from_ep(dev, &udev->ep_out[ep]);
-+    }
-+}
-+
-+static int usbredir_already_in_flight(USBRedirDevice *dev, uint64_t id)
-+{
-+    return packet_id_queue_remove(&dev->already_in_flight, id);
-+}
-+
- static USBPacket *usbredir_find_packet_by_id(USBRedirDevice *dev,
-     uint8_t ep, uint64_t id)
- {
-@@ -541,6 +570,10 @@ static int usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p,
- 
-     DPRINTF("bulk-out ep %02X len %zd id %"PRIu64"\n", ep, p->iov.size, p->id);
- 
-+    if (usbredir_already_in_flight(dev, p->id)) {
-+        return USB_RET_ASYNC;
-+    }
-+
-     bulk_packet.endpoint  = ep;
-     bulk_packet.length    = p->iov.size;
-     bulk_packet.stream_id = 0;
-@@ -621,6 +654,10 @@ static int usbredir_handle_interrupt_data(USBRedirDevice *dev,
-         DPRINTF("interrupt-out ep %02X len %zd id %"PRIu64"\n", ep,
-                 p->iov.size, p->id);
- 
-+        if (usbredir_already_in_flight(dev, p->id)) {
-+            return USB_RET_ASYNC;
-+        }
-+
-         interrupt_packet.endpoint  = ep;
-         interrupt_packet.length    = p->iov.size;
- 
-@@ -763,6 +800,10 @@ static int usbredir_handle_control(USBDevice *udev, USBPacket *p,
-     USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
-     struct usb_redir_control_packet_header control_packet;
- 
-+    if (usbredir_already_in_flight(dev, p->id)) {
-+        return USB_RET_ASYNC;
-+    }
-+
-     /* Special cases for certain standard device requests */
-     switch (request) {
-     case DeviceOutRequest | USB_REQ_SET_ADDRESS:
-@@ -987,6 +1028,7 @@ static int usbredir_initfn(USBDevice *udev)
-     dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev);
- 
-     packet_id_queue_init(&dev->cancelled, dev, "cancelled");
-+    packet_id_queue_init(&dev->already_in_flight, dev, "already-in-flight");
-     for (i = 0; i < MAX_ENDPOINTS; i++) {
-         QTAILQ_INIT(&dev->endpoint[i].bufpq);
-     }
-@@ -1007,6 +1049,7 @@ static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
-     int i;
- 
-     packet_id_queue_empty(&dev->cancelled);
-+    packet_id_queue_empty(&dev->already_in_flight);
-     for (i = 0; i < MAX_ENDPOINTS; i++) {
-         usbredir_free_bufpq(dev, I2EP(i));
-     }
--- 
-1.7.12
-
diff --git a/0363-usb-redir-Store-max_packet_size-in-endp_data.patch b/0363-usb-redir-Store-max_packet_size-in-endp_data.patch
new file mode 100644
index 0000000..16f05d3
--- /dev/null
+++ b/0363-usb-redir-Store-max_packet_size-in-endp_data.patch
@@ -0,0 +1,38 @@
+From c9917c910cf59e2407bbf51770724c5ec17d9cd1 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Thu, 6 Sep 2012 20:52:36 +0200
+Subject: [PATCH 363/365] usb-redir: Store max_packet_size in endp_data
+
+So that we've a place to migrate it to / from to allow restoring it after
+migration.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ hw/usb/redirect.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
+index 1c8edd3..d8568ae 100644
+--- a/hw/usb/redirect.c
++++ b/hw/usb/redirect.c
+@@ -57,6 +57,7 @@ struct endp_data {
+     uint8_t type;
+     uint8_t interval;
+     uint8_t interface; /* bInterfaceNumber this ep belongs to */
++    uint16_t max_packet_size; /* In bytes, not wMaxPacketSize format !! */
+     uint8_t iso_started;
+     uint8_t iso_error; /* For reporting iso errors to the HC */
+     uint8_t interrupt_started;
+@@ -1305,7 +1306,8 @@ static void usbredir_ep_info(void *priv,
+         usb_ep->ifnum = dev->endpoint[i].interface;
+         if (usbredirparser_peer_has_cap(dev->parser,
+                                      usb_redir_cap_ep_info_max_packet_size)) {
+-            usb_ep->max_packet_size = ep_info->max_packet_size[i];
++            dev->endpoint[i].max_packet_size =
++                usb_ep->max_packet_size = ep_info->max_packet_size[i];
+         }
+         if (ep_info->type[i] == usb_redir_type_bulk) {
+             usb_ep->pipeline = true;
+-- 
+1.7.12
+
diff --git a/0364-usb-redir-Add-support-for-migration.patch b/0364-usb-redir-Add-support-for-migration.patch
new file mode 100644
index 0000000..bcbbaab
--- /dev/null
+++ b/0364-usb-redir-Add-support-for-migration.patch
@@ -0,0 +1,429 @@
+From 0d733a1280bdaba402c6efbfae116408d7c81bb0 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Wed, 5 Sep 2012 09:21:44 +0200
+Subject: [PATCH 364/365] usb-redir: Add support for migration
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ hw/usb/redirect.c | 349 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 346 insertions(+), 3 deletions(-)
+
+diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
+index d8568ae..812096e 100644
+--- a/hw/usb/redirect.c
++++ b/hw/usb/redirect.c
+@@ -65,8 +65,8 @@ struct endp_data {
+     uint8_t bufpq_prefilled;
+     uint8_t bufpq_dropping_packets;
+     QTAILQ_HEAD(, buf_packet) bufpq;
+-    int bufpq_size;
+-    int bufpq_target_size;
++    int32_t bufpq_size;
++    int32_t bufpq_target_size;
+ };
+ 
+ struct PacketIdQueueEntry {
+@@ -241,6 +241,11 @@ static int usbredir_write(void *priv, uint8_t *data, int count)
+         return 0;
+     }
+ 
++    /* Don't send new data to the chardev until our state is fully synced */
++    if (!runstate_check(RUN_STATE_RUNNING)) {
++        return 0;
++    }
++
+     r = qemu_chr_fe_write(dev->cs, data, count);
+ 
+     if (r < 0) {
+@@ -868,6 +873,7 @@ static void usbredir_chardev_open(USBRedirDevice *dev)
+ {
+     uint32_t caps[USB_REDIR_CAPS_SIZE] = { 0, };
+     char version[32];
++    int flags = 0;
+ 
+     /* Make sure any pending closes are handled (no-op if none pending) */
+     usbredir_chardev_close_bh(dev);
+@@ -903,7 +909,12 @@ static void usbredir_chardev_open(USBRedirDevice *dev)
+     usbredirparser_caps_set_cap(caps, usb_redir_cap_filter);
+     usbredirparser_caps_set_cap(caps, usb_redir_cap_ep_info_max_packet_size);
+     usbredirparser_caps_set_cap(caps, usb_redir_cap_64bits_ids);
+-    usbredirparser_init(dev->parser, version, caps, USB_REDIR_CAPS_SIZE, 0);
++
++    if (runstate_check(RUN_STATE_INMIGRATE)) {
++        flags |= usbredirparser_fl_no_hello;
++    }
++    usbredirparser_init(dev->parser, version, caps, USB_REDIR_CAPS_SIZE,
++                        flags);
+     usbredirparser_do_write(dev->parser);
+ }
+ 
+@@ -949,6 +960,11 @@ static int usbredir_chardev_can_read(void *opaque)
+         return 0;
+     }
+ 
++    /* Don't read new data from the chardev until our state is fully synced */
++    if (!runstate_check(RUN_STATE_RUNNING)) {
++        return 0;
++    }
++
+     /* usbredir_parser_do_read will consume *all* data we give it */
+     return 1024 * 1024;
+ }
+@@ -1004,6 +1020,15 @@ static const QemuChrHandlers usbredir_chr_handlers = {
+  * init + destroy
+  */
+ 
++static void usbredir_vm_state_change(void *priv, int running, RunState state)
++{
++    USBRedirDevice *dev = priv;
++
++    if (state == RUN_STATE_RUNNING && dev->parser != NULL) {
++        usbredirparser_do_write(dev->parser); /* Flush any pending writes */
++    }
++}
++
+ static int usbredir_initfn(USBDevice *udev)
+ {
+     USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
+@@ -1041,6 +1066,7 @@ static int usbredir_initfn(USBDevice *udev)
+     qemu_chr_fe_open(dev->cs);
+     qemu_chr_add_handlers(dev->cs, &usbredir_chr_handlers, dev);
+ 
++    qemu_add_vm_change_state_handler(usbredir_vm_state_change, dev);
+     add_boot_device_path(dev->bootindex, &udev->qdev, NULL);
+     return 0;
+ }
+@@ -1530,6 +1556,322 @@ static void usbredir_interrupt_packet(void *priv, uint64_t id,
+     }
+ }
+ 
++/*
++ * Migration code
++ */
++
++static void usbredir_pre_save(void *priv)
++{
++    USBRedirDevice *dev = priv;
++
++    usbredir_fill_already_in_flight(dev);
++}
++
++static int usbredir_post_load(void *priv, int version_id)
++{
++    USBRedirDevice *dev = priv;
++    struct USBEndpoint *usb_ep;
++    int i;
++
++    switch (dev->device_info.speed) {
++    case usb_redir_speed_low:
++        dev->dev.speed = USB_SPEED_LOW;
++        break;
++    case usb_redir_speed_full:
++        dev->dev.speed = USB_SPEED_FULL;
++        break;
++    case usb_redir_speed_high:
++        dev->dev.speed = USB_SPEED_HIGH;
++        break;
++    case usb_redir_speed_super:
++        dev->dev.speed = USB_SPEED_SUPER;
++        break;
++    default:
++        dev->dev.speed = USB_SPEED_FULL;
++    }
++    dev->dev.speedmask = (1 << dev->dev.speed);
++
++    for (i = 0; i < MAX_ENDPOINTS; i++) {
++        usb_ep = usb_ep_get(&dev->dev,
++                            (i & 0x10) ? USB_TOKEN_IN : USB_TOKEN_OUT,
++                            i & 0x0f);
++        usb_ep->type = dev->endpoint[i].type;
++        usb_ep->ifnum = dev->endpoint[i].interface;
++        usb_ep->max_packet_size = dev->endpoint[i].max_packet_size;
++        if (dev->endpoint[i].type == usb_redir_type_bulk) {
++            usb_ep->pipeline = true;
++        }
++    }
++    return 0;
++}
++
++/* For usbredirparser migration */
++static void usbredir_put_parser(QEMUFile *f, void *priv, size_t unused)
++{
++    USBRedirDevice *dev = priv;
++    uint8_t *data;
++    int len;
++
++    if (dev->parser == NULL) {
++        qemu_put_be32(f, 0);
++        return;
++    }
++
++    usbredirparser_serialize(dev->parser, &data, &len);
++    qemu_oom_check(data);
++
++    qemu_put_be32(f, len);
++    qemu_put_buffer(f, data, len);
++
++    free(data);
++}
++
++static int usbredir_get_parser(QEMUFile *f, void *priv, size_t unused)
++{
++    USBRedirDevice *dev = priv;
++    uint8_t *data;
++    int len, ret;
++
++    len = qemu_get_be32(f);
++    if (len == 0) {
++        return 0;
++    }
++
++    /*
++     * Our chardev should be open already at this point, otherwise
++     * the usbredir channel will be broken (ie spice without seamless)
++     */
++    if (dev->parser == NULL) {
++        ERROR("get_parser called with closed chardev, failing migration\n");
++        return -1;
++    }
++
++    data = g_malloc(len);
++    qemu_get_buffer(f, data, len);
++
++    ret = usbredirparser_unserialize(dev->parser, data, len);
++
++    g_free(data);
++
++    return ret;
++}
++
++static const VMStateInfo usbredir_parser_vmstate_info = {
++    .name = "usb-redir-parser",
++    .put  = usbredir_put_parser,
++    .get  = usbredir_get_parser,
++};
++
++
++/* For buffered packets (iso/irq) queue migration */
++static void usbredir_put_bufpq(QEMUFile *f, void *priv, size_t unused)
++{
++    struct endp_data *endp = priv;
++    struct buf_packet *bufp;
++    int remain = endp->bufpq_size;
++
++    qemu_put_be32(f, endp->bufpq_size);
++    QTAILQ_FOREACH(bufp, &endp->bufpq, next) {
++        qemu_put_be32(f, bufp->len);
++        qemu_put_be32(f, bufp->status);
++        qemu_put_buffer(f, bufp->data, bufp->len);
++        remain--;
++    }
++    assert(remain == 0);
++}
++
++static int usbredir_get_bufpq(QEMUFile *f, void *priv, size_t unused)
++{
++    struct endp_data *endp = priv;
++    struct buf_packet *bufp;
++    int i;
++
++    endp->bufpq_size = qemu_get_be32(f);
++    for (i = 0; i < endp->bufpq_size; i++) {
++        bufp = g_malloc(sizeof(struct buf_packet));
++        bufp->len = qemu_get_be32(f);
++        bufp->status = qemu_get_be32(f);
++        bufp->data = qemu_oom_check(malloc(bufp->len)); /* regular malloc! */
++        qemu_get_buffer(f, bufp->data, bufp->len);
++        QTAILQ_INSERT_TAIL(&endp->bufpq, bufp, next);
++    }
++    return 0;
++}
++
++static const VMStateInfo usbredir_ep_bufpq_vmstate_info = {
++    .name = "usb-redir-bufpq",
++    .put  = usbredir_put_bufpq,
++    .get  = usbredir_get_bufpq,
++};
++
++
++/* For endp_data migration */
++static const VMStateDescription usbredir_ep_vmstate = {
++    .name = "usb-redir-ep",
++    .version_id = 1,
++    .minimum_version_id = 1,
++    .fields = (VMStateField []) {
++        VMSTATE_UINT8(type, struct endp_data),
++        VMSTATE_UINT8(interval, struct endp_data),
++        VMSTATE_UINT8(interface, struct endp_data),
++        VMSTATE_UINT16(max_packet_size, struct endp_data),
++        VMSTATE_UINT8(iso_started, struct endp_data),
++        VMSTATE_UINT8(iso_error, struct endp_data),
++        VMSTATE_UINT8(interrupt_started, struct endp_data),
++        VMSTATE_UINT8(interrupt_error, struct endp_data),
++        VMSTATE_UINT8(bufpq_prefilled, struct endp_data),
++        VMSTATE_UINT8(bufpq_dropping_packets, struct endp_data),
++        {
++            .name         = "bufpq",
++            .version_id   = 0,
++            .field_exists = NULL,
++            .size         = 0,
++            .info         = &usbredir_ep_bufpq_vmstate_info,
++            .flags        = VMS_SINGLE,
++            .offset       = 0,
++        },
++        VMSTATE_INT32(bufpq_target_size, struct endp_data),
++        VMSTATE_END_OF_LIST()
++    }
++};
++
++
++/* For PacketIdQueue migration */
++static void usbredir_put_packet_id_q(QEMUFile *f, void *priv, size_t unused)
++{
++    struct PacketIdQueue *q = priv;
++    USBRedirDevice *dev = q->dev;
++    struct PacketIdQueueEntry *e;
++    int remain = q->size;
++
++    DPRINTF("put_packet_id_q %s size %d\n", q->name, q->size);
++    qemu_put_be32(f, q->size);
++    QTAILQ_FOREACH(e, &q->head, next) {
++        qemu_put_be64(f, e->id);
++        remain--;
++    }
++    assert(remain == 0);
++}
++
++static int usbredir_get_packet_id_q(QEMUFile *f, void *priv, size_t unused)
++{
++    struct PacketIdQueue *q = priv;
++    USBRedirDevice *dev = q->dev;
++    int i, size;
++    uint64_t id;
++
++    size = qemu_get_be32(f);
++    DPRINTF("get_packet_id_q %s size %d\n", q->name, size);
++    for (i = 0; i < size; i++) {
++        id = qemu_get_be64(f);
++        packet_id_queue_add(q, id);
++    }
++    assert(q->size == size);
++    return 0;
++}
++
++static const VMStateInfo usbredir_ep_packet_id_q_vmstate_info = {
++    .name = "usb-redir-packet-id-q",
++    .put  = usbredir_put_packet_id_q,
++    .get  = usbredir_get_packet_id_q,
++};
++
++static const VMStateDescription usbredir_ep_packet_id_queue_vmstate = {
++    .name = "usb-redir-packet-id-queue",
++    .version_id = 1,
++    .minimum_version_id = 1,
++    .fields = (VMStateField []) {
++        {
++            .name         = "queue",
++            .version_id   = 0,
++            .field_exists = NULL,
++            .size         = 0,
++            .info         = &usbredir_ep_packet_id_q_vmstate_info,
++            .flags        = VMS_SINGLE,
++            .offset       = 0,
++        },
++        VMSTATE_END_OF_LIST()
++    }
++};
++
++
++/* For usb_redir_device_connect_header migration */
++static const VMStateDescription usbredir_device_info_vmstate = {
++    .name = "usb-redir-device-info",
++    .version_id = 1,
++    .minimum_version_id = 1,
++    .fields = (VMStateField []) {
++        VMSTATE_UINT8(speed, struct usb_redir_device_connect_header),
++        VMSTATE_UINT8(device_class, struct usb_redir_device_connect_header),
++        VMSTATE_UINT8(device_subclass, struct usb_redir_device_connect_header),
++        VMSTATE_UINT8(device_protocol, struct usb_redir_device_connect_header),
++        VMSTATE_UINT16(vendor_id, struct usb_redir_device_connect_header),
++        VMSTATE_UINT16(product_id, struct usb_redir_device_connect_header),
++        VMSTATE_UINT16(device_version_bcd,
++                       struct usb_redir_device_connect_header),
++        VMSTATE_END_OF_LIST()
++    }
++};
++
++
++/* For usb_redir_interface_info_header migration */
++static const VMStateDescription usbredir_interface_info_vmstate = {
++    .name = "usb-redir-interface-info",
++    .version_id = 1,
++    .minimum_version_id = 1,
++    .fields = (VMStateField []) {
++        VMSTATE_UINT32(interface_count,
++                       struct usb_redir_interface_info_header),
++        VMSTATE_UINT8_ARRAY(interface,
++                            struct usb_redir_interface_info_header, 32),
++        VMSTATE_UINT8_ARRAY(interface_class,
++                            struct usb_redir_interface_info_header, 32),
++        VMSTATE_UINT8_ARRAY(interface_subclass,
++                            struct usb_redir_interface_info_header, 32),
++        VMSTATE_UINT8_ARRAY(interface_protocol,
++                            struct usb_redir_interface_info_header, 32),
++        VMSTATE_END_OF_LIST()
++    }
++};
++
++
++/* And finally the USBRedirDevice vmstate itself */
++static const VMStateDescription usbredir_vmstate = {
++    .name = "usb-redir",
++    .version_id = 1,
++    .minimum_version_id = 1,
++    .pre_save = usbredir_pre_save,
++    .post_load = usbredir_post_load,
++    .fields = (VMStateField []) {
++        VMSTATE_USB_DEVICE(dev, USBRedirDevice),
++        VMSTATE_TIMER(attach_timer, USBRedirDevice),
++        {
++            .name         = "parser",
++            .version_id   = 0,
++            .field_exists = NULL,
++            .size         = 0,
++            .info         = &usbredir_parser_vmstate_info,
++            .flags        = VMS_SINGLE,
++            .offset       = 0,
++        },
++        VMSTATE_STRUCT_ARRAY(endpoint, USBRedirDevice, MAX_ENDPOINTS, 1,
++                             usbredir_ep_vmstate, struct endp_data),
++        VMSTATE_STRUCT(cancelled, USBRedirDevice, 1,
++                       usbredir_ep_packet_id_queue_vmstate,
++                       struct PacketIdQueue),
++        VMSTATE_STRUCT(already_in_flight, USBRedirDevice, 1,
++                       usbredir_ep_packet_id_queue_vmstate,
++                       struct PacketIdQueue),
++        VMSTATE_STRUCT(device_info, USBRedirDevice, 1,
++                       usbredir_device_info_vmstate,
++                       struct usb_redir_device_connect_header),
++        VMSTATE_STRUCT(interface_info, USBRedirDevice, 1,
++                       usbredir_interface_info_vmstate,
++                       struct usb_redir_interface_info_header),
++        VMSTATE_END_OF_LIST()
++    }
++};
++
+ static Property usbredir_properties[] = {
+     DEFINE_PROP_CHR("chardev", USBRedirDevice, cs),
+     DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, 0),
+@@ -1550,6 +1892,7 @@ static void usbredir_class_initfn(ObjectClass *klass, void *data)
+     uc->handle_reset   = usbredir_handle_reset;
+     uc->handle_data    = usbredir_handle_data;
+     uc->handle_control = usbredir_handle_control;
++    dc->vmsd           = &usbredir_vmstate;
+     dc->props          = usbredir_properties;
+ }
+ 
+-- 
+1.7.12
+
diff --git a/0364-usb-redir-Store-max_packet_size-in-endp_data.patch b/0364-usb-redir-Store-max_packet_size-in-endp_data.patch
deleted file mode 100644
index 6976b2c..0000000
--- a/0364-usb-redir-Store-max_packet_size-in-endp_data.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 372d6c55bbe5fb092ff9e96c72ff53bfd10fdede Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Thu, 6 Sep 2012 20:52:36 +0200
-Subject: [PATCH 364/366] usb-redir: Store max_packet_size in endp_data
-
-So that we've a place to migrate it to / from to allow restoring it after
-migration.
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- hw/usb/redirect.c | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
-diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
-index 1c8edd3..d8568ae 100644
---- a/hw/usb/redirect.c
-+++ b/hw/usb/redirect.c
-@@ -57,6 +57,7 @@ struct endp_data {
-     uint8_t type;
-     uint8_t interval;
-     uint8_t interface; /* bInterfaceNumber this ep belongs to */
-+    uint16_t max_packet_size; /* In bytes, not wMaxPacketSize format !! */
-     uint8_t iso_started;
-     uint8_t iso_error; /* For reporting iso errors to the HC */
-     uint8_t interrupt_started;
-@@ -1305,7 +1306,8 @@ static void usbredir_ep_info(void *priv,
-         usb_ep->ifnum = dev->endpoint[i].interface;
-         if (usbredirparser_peer_has_cap(dev->parser,
-                                      usb_redir_cap_ep_info_max_packet_size)) {
--            usb_ep->max_packet_size = ep_info->max_packet_size[i];
-+            dev->endpoint[i].max_packet_size =
-+                usb_ep->max_packet_size = ep_info->max_packet_size[i];
-         }
-         if (ep_info->type[i] == usb_redir_type_bulk) {
-             usb_ep->pipeline = true;
--- 
-1.7.12
-
diff --git a/0365-usb-redir-Add-chardev-open-close-debug-logging.patch b/0365-usb-redir-Add-chardev-open-close-debug-logging.patch
new file mode 100644
index 0000000..4e2f75d
--- /dev/null
+++ b/0365-usb-redir-Add-chardev-open-close-debug-logging.patch
@@ -0,0 +1,54 @@
+From 3efd9345ea643cf6f15776425213a92a442dd217 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Wed, 5 Sep 2012 15:56:57 +0200
+Subject: [PATCH 365/365] usb-redir: Add chardev open / close debug logging
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+---
+ hw/usb/redirect.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
+index 812096e..b03c412 100644
+--- a/hw/usb/redirect.c
++++ b/hw/usb/redirect.c
+@@ -864,6 +864,7 @@ static void usbredir_chardev_close_bh(void *opaque)
+     usbredir_device_disconnect(dev);
+ 
+     if (dev->parser) {
++        DPRINTF("destroying usbredirparser\n");
+         usbredirparser_destroy(dev->parser);
+         dev->parser = NULL;
+     }
+@@ -879,6 +880,8 @@ static void usbredir_chardev_open(USBRedirDevice *dev)
+     usbredir_chardev_close_bh(dev);
+     qemu_bh_cancel(dev->chardev_close_bh);
+ 
++    DPRINTF("creating usbredirparser\n");
++
+     strcpy(version, "qemu usb-redir guest ");
+     pstrcat(version, sizeof(version), qemu_get_version());
+ 
+@@ -990,9 +993,11 @@ static void usbredir_chardev_event(void *opaque, int event)
+ 
+     switch (event) {
+     case CHR_EVENT_OPENED:
++        DPRINTF("chardev open\n");
+         usbredir_chardev_open(dev);
+         break;
+     case CHR_EVENT_CLOSED:
++        DPRINTF("chardev close\n");
+         qemu_bh_schedule(dev->chardev_close_bh);
+         break;
+     }
+@@ -1255,6 +1260,7 @@ static void usbredir_device_disconnect(void *priv)
+     qemu_del_timer(dev->attach_timer);
+ 
+     if (dev->dev.attached) {
++        DPRINTF("detaching device\n");
+         usb_device_detach(&dev->dev);
+         /*
+          * Delay next usb device attach to give the guest a chance to see
+-- 
+1.7.12
+
diff --git a/0365-usb-redir-Add-support-for-migration.patch b/0365-usb-redir-Add-support-for-migration.patch
deleted file mode 100644
index 97b8ab2..0000000
--- a/0365-usb-redir-Add-support-for-migration.patch
+++ /dev/null
@@ -1,411 +0,0 @@
-From e6a683c844845c53bcf14f9fb3ea175331eaca0c Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Wed, 5 Sep 2012 09:21:44 +0200
-Subject: [PATCH 365/366] usb-redir: Add support for migration
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- hw/usb/redirect.c | 331 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 328 insertions(+), 3 deletions(-)
-
-diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
-index d8568ae..8dbb722 100644
---- a/hw/usb/redirect.c
-+++ b/hw/usb/redirect.c
-@@ -65,8 +65,8 @@ struct endp_data {
-     uint8_t bufpq_prefilled;
-     uint8_t bufpq_dropping_packets;
-     QTAILQ_HEAD(, buf_packet) bufpq;
--    int bufpq_size;
--    int bufpq_target_size;
-+    int32_t bufpq_size;
-+    int32_t bufpq_target_size;
- };
- 
- struct PacketIdQueueEntry {
-@@ -241,6 +241,11 @@ static int usbredir_write(void *priv, uint8_t *data, int count)
-         return 0;
-     }
- 
-+    /* Don't send new data to the chardev until our state is fully synced */
-+    if (!runstate_check(RUN_STATE_RUNNING)) {
-+        return 0;
-+    }
-+
-     r = qemu_chr_fe_write(dev->cs, data, count);
- 
-     if (r < 0) {
-@@ -868,6 +873,7 @@ static void usbredir_chardev_open(USBRedirDevice *dev)
- {
-     uint32_t caps[USB_REDIR_CAPS_SIZE] = { 0, };
-     char version[32];
-+    int flags = 0;
- 
-     /* Make sure any pending closes are handled (no-op if none pending) */
-     usbredir_chardev_close_bh(dev);
-@@ -903,7 +909,12 @@ static void usbredir_chardev_open(USBRedirDevice *dev)
-     usbredirparser_caps_set_cap(caps, usb_redir_cap_filter);
-     usbredirparser_caps_set_cap(caps, usb_redir_cap_ep_info_max_packet_size);
-     usbredirparser_caps_set_cap(caps, usb_redir_cap_64bits_ids);
--    usbredirparser_init(dev->parser, version, caps, USB_REDIR_CAPS_SIZE, 0);
-+
-+    if (runstate_check(RUN_STATE_INMIGRATE)) {
-+        flags |= usbredirparser_fl_no_hello;
-+    }
-+    usbredirparser_init(dev->parser, version, caps, USB_REDIR_CAPS_SIZE,
-+                        flags);
-     usbredirparser_do_write(dev->parser);
- }
- 
-@@ -949,6 +960,11 @@ static int usbredir_chardev_can_read(void *opaque)
-         return 0;
-     }
- 
-+    /* Don't read new data from the chardev until our state is fully synced */
-+    if (!runstate_check(RUN_STATE_RUNNING)) {
-+        return 0;
-+    }
-+
-     /* usbredir_parser_do_read will consume *all* data we give it */
-     return 1024 * 1024;
- }
-@@ -1004,6 +1020,15 @@ static const QemuChrHandlers usbredir_chr_handlers = {
-  * init + destroy
-  */
- 
-+static void usbredir_vm_state_change(void *priv, int running, RunState state)
-+{
-+    USBRedirDevice *dev = priv;
-+
-+    if (state == RUN_STATE_RUNNING && dev->parser != NULL) {
-+        usbredirparser_do_write(dev->parser); /* Flush any pending writes */
-+    }
-+}
-+
- static int usbredir_initfn(USBDevice *udev)
- {
-     USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
-@@ -1041,6 +1066,7 @@ static int usbredir_initfn(USBDevice *udev)
-     qemu_chr_fe_open(dev->cs);
-     qemu_chr_add_handlers(dev->cs, &usbredir_chr_handlers, dev);
- 
-+    qemu_add_vm_change_state_handler(usbredir_vm_state_change, dev);
-     add_boot_device_path(dev->bootindex, &udev->qdev, NULL);
-     return 0;
- }
-@@ -1530,6 +1556,304 @@ static void usbredir_interrupt_packet(void *priv, uint64_t id,
-     }
- }
- 
-+/*
-+ * Migration code
-+ */
-+
-+static void usbredir_pre_save(void *priv)
-+{
-+    USBRedirDevice *dev = priv;
-+
-+    usbredir_fill_already_in_flight(dev);
-+}
-+
-+static int usbredir_post_load(void *priv, int version_id)
-+{
-+    USBRedirDevice *dev = priv;
-+    struct USBEndpoint *usb_ep;
-+    int i;
-+
-+    for (i = 0; i < MAX_ENDPOINTS; i++) {
-+        usb_ep = usb_ep_get(&dev->dev,
-+                            (i & 0x10) ? USB_TOKEN_IN : USB_TOKEN_OUT,
-+                            i & 0x0f);
-+        usb_ep->type = dev->endpoint[i].type;
-+        usb_ep->ifnum = dev->endpoint[i].interface;
-+        usb_ep->max_packet_size = dev->endpoint[i].max_packet_size;
-+        if (dev->endpoint[i].type == usb_redir_type_bulk) {
-+            usb_ep->pipeline = true;
-+        }
-+    }
-+    return 0;
-+}
-+
-+/* For usbredirparser migration */
-+static void usbredir_put_parser(QEMUFile *f, void *priv, size_t unused)
-+{
-+    USBRedirDevice *dev = priv;
-+    uint8_t *data;
-+    int len;
-+
-+    if (dev->parser == NULL) {
-+        qemu_put_be32(f, 0);
-+        return;
-+    }
-+
-+    usbredirparser_serialize(dev->parser, &data, &len);
-+    qemu_oom_check(data);
-+
-+    qemu_put_be32(f, len);
-+    qemu_put_buffer(f, data, len);
-+
-+    free(data);
-+}
-+
-+static int usbredir_get_parser(QEMUFile *f, void *priv, size_t unused)
-+{
-+    USBRedirDevice *dev = priv;
-+    uint8_t *data;
-+    int len, ret;
-+
-+    len = qemu_get_be32(f);
-+    if (len == 0) {
-+        return 0;
-+    }
-+
-+    /*
-+     * Our chardev should be open already at this point, otherwise
-+     * the usbredir channel will be broken (ie spice without seamless)
-+     */
-+    if (dev->parser == NULL) {
-+        ERROR("get_parser called with closed chardev, failing migration\n");
-+        return -1;
-+    }
-+
-+    data = g_malloc(len);
-+    qemu_get_buffer(f, data, len);
-+
-+    ret = usbredirparser_unserialize(dev->parser, data, len);
-+
-+    g_free(data);
-+
-+    return ret;
-+}
-+
-+static const VMStateInfo usbredir_parser_vmstate_info = {
-+    .name = "usb-redir-parser",
-+    .put  = usbredir_put_parser,
-+    .get  = usbredir_get_parser,
-+};
-+
-+
-+/* For buffered packets (iso/irq) queue migration */
-+static void usbredir_put_bufpq(QEMUFile *f, void *priv, size_t unused)
-+{
-+    struct endp_data *endp = priv;
-+    struct buf_packet *bufp;
-+    int remain = endp->bufpq_size;
-+
-+    qemu_put_be32(f, endp->bufpq_size);
-+    QTAILQ_FOREACH(bufp, &endp->bufpq, next) {
-+        qemu_put_be32(f, bufp->len);
-+        qemu_put_be32(f, bufp->status);
-+        qemu_put_buffer(f, bufp->data, bufp->len);
-+        remain--;
-+    }
-+    assert(remain == 0);
-+}
-+
-+static int usbredir_get_bufpq(QEMUFile *f, void *priv, size_t unused)
-+{
-+    struct endp_data *endp = priv;
-+    struct buf_packet *bufp;
-+    int i;
-+
-+    endp->bufpq_size = qemu_get_be32(f);
-+    for (i = 0; i < endp->bufpq_size; i++) {
-+        bufp = g_malloc(sizeof(struct buf_packet));
-+        bufp->len = qemu_get_be32(f);
-+        bufp->status = qemu_get_be32(f);
-+        bufp->data = qemu_oom_check(malloc(bufp->len)); /* regular malloc! */
-+        qemu_get_buffer(f, bufp->data, bufp->len);
-+        QTAILQ_INSERT_TAIL(&endp->bufpq, bufp, next);
-+    }
-+    return 0;
-+}
-+
-+static const VMStateInfo usbredir_ep_bufpq_vmstate_info = {
-+    .name = "usb-redir-bufpq",
-+    .put  = usbredir_put_bufpq,
-+    .get  = usbredir_get_bufpq,
-+};
-+
-+
-+/* For endp_data migration */
-+static const VMStateDescription usbredir_ep_vmstate = {
-+    .name = "usb-redir-ep",
-+    .version_id = 1,
-+    .minimum_version_id = 1,
-+    .fields = (VMStateField []) {
-+        VMSTATE_UINT8(type, struct endp_data),
-+        VMSTATE_UINT8(interval, struct endp_data),
-+        VMSTATE_UINT8(interface, struct endp_data),
-+        VMSTATE_UINT16(max_packet_size, struct endp_data),
-+        VMSTATE_UINT8(iso_started, struct endp_data),
-+        VMSTATE_UINT8(iso_error, struct endp_data),
-+        VMSTATE_UINT8(interrupt_started, struct endp_data),
-+        VMSTATE_UINT8(interrupt_error, struct endp_data),
-+        VMSTATE_UINT8(bufpq_prefilled, struct endp_data),
-+        VMSTATE_UINT8(bufpq_dropping_packets, struct endp_data),
-+        {
-+            .name         = "bufpq",
-+            .version_id   = 0,
-+            .field_exists = NULL,
-+            .size         = 0,
-+            .info         = &usbredir_ep_bufpq_vmstate_info,
-+            .flags        = VMS_SINGLE,
-+            .offset       = 0,
-+        },
-+        VMSTATE_INT32(bufpq_target_size, struct endp_data),
-+        VMSTATE_END_OF_LIST()
-+    }
-+};
-+
-+
-+/* For PacketIdQueue migration */
-+static void usbredir_put_packet_id_q(QEMUFile *f, void *priv, size_t unused)
-+{
-+    struct PacketIdQueue *q = priv;
-+    USBRedirDevice *dev = q->dev;
-+    struct PacketIdQueueEntry *e;
-+    int remain = q->size;
-+
-+    DPRINTF("put_packet_id_q %s size %d\n", q->name, q->size);
-+    qemu_put_be32(f, q->size);
-+    QTAILQ_FOREACH(e, &q->head, next) {
-+        qemu_put_be64(f, e->id);
-+        remain--;
-+    }
-+    assert(remain == 0);
-+}
-+
-+static int usbredir_get_packet_id_q(QEMUFile *f, void *priv, size_t unused)
-+{
-+    struct PacketIdQueue *q = priv;
-+    USBRedirDevice *dev = q->dev;
-+    int i, size;
-+    uint64_t id;
-+
-+    size = qemu_get_be32(f);
-+    DPRINTF("get_packet_id_q %s size %d\n", q->name, size);
-+    for (i = 0; i < size; i++) {
-+        id = qemu_get_be64(f);
-+        packet_id_queue_add(q, id);
-+    }
-+    assert(q->size == size);
-+    return 0;
-+}
-+
-+static const VMStateInfo usbredir_ep_packet_id_q_vmstate_info = {
-+    .name = "usb-redir-packet-id-q",
-+    .put  = usbredir_put_packet_id_q,
-+    .get  = usbredir_get_packet_id_q,
-+};
-+
-+static const VMStateDescription usbredir_ep_packet_id_queue_vmstate = {
-+    .name = "usb-redir-packet-id-queue",
-+    .version_id = 1,
-+    .minimum_version_id = 1,
-+    .fields = (VMStateField []) {
-+        {
-+            .name         = "queue",
-+            .version_id   = 0,
-+            .field_exists = NULL,
-+            .size         = 0,
-+            .info         = &usbredir_ep_packet_id_q_vmstate_info,
-+            .flags        = VMS_SINGLE,
-+            .offset       = 0,
-+        },
-+        VMSTATE_END_OF_LIST()
-+    }
-+};
-+
-+
-+/* For usb_redir_device_connect_header migration */
-+static const VMStateDescription usbredir_device_info_vmstate = {
-+    .name = "usb-redir-device-info",
-+    .version_id = 1,
-+    .minimum_version_id = 1,
-+    .fields = (VMStateField []) {
-+        VMSTATE_UINT8(speed, struct usb_redir_device_connect_header),
-+        VMSTATE_UINT8(device_class, struct usb_redir_device_connect_header),
-+        VMSTATE_UINT8(device_subclass, struct usb_redir_device_connect_header),
-+        VMSTATE_UINT8(device_protocol, struct usb_redir_device_connect_header),
-+        VMSTATE_UINT16(vendor_id, struct usb_redir_device_connect_header),
-+        VMSTATE_UINT16(product_id, struct usb_redir_device_connect_header),
-+        VMSTATE_UINT16(device_version_bcd,
-+                       struct usb_redir_device_connect_header),
-+        VMSTATE_END_OF_LIST()
-+    }
-+};
-+
-+
-+/* For usb_redir_interface_info_header migration */
-+static const VMStateDescription usbredir_interface_info_vmstate = {
-+    .name = "usb-redir-interface-info",
-+    .version_id = 1,
-+    .minimum_version_id = 1,
-+    .fields = (VMStateField []) {
-+        VMSTATE_UINT32(interface_count,
-+                       struct usb_redir_interface_info_header),
-+        VMSTATE_UINT8_ARRAY(interface,
-+                            struct usb_redir_interface_info_header, 32),
-+        VMSTATE_UINT8_ARRAY(interface_class,
-+                            struct usb_redir_interface_info_header, 32),
-+        VMSTATE_UINT8_ARRAY(interface_subclass,
-+                            struct usb_redir_interface_info_header, 32),
-+        VMSTATE_UINT8_ARRAY(interface_protocol,
-+                            struct usb_redir_interface_info_header, 32),
-+        VMSTATE_END_OF_LIST()
-+    }
-+};
-+
-+
-+/* And finally the USBRedirDevice vmstate itself */
-+static const VMStateDescription usbredir_vmstate = {
-+    .name = "usb-redir",
-+    .version_id = 1,
-+    .minimum_version_id = 1,
-+    .pre_save = usbredir_pre_save,
-+    .post_load = usbredir_post_load,
-+    .fields = (VMStateField []) {
-+        VMSTATE_USB_DEVICE(dev, USBRedirDevice),
-+        VMSTATE_TIMER(attach_timer, USBRedirDevice),
-+        {
-+            .name         = "parser",
-+            .version_id   = 0,
-+            .field_exists = NULL,
-+            .size         = 0,
-+            .info         = &usbredir_parser_vmstate_info,
-+            .flags        = VMS_SINGLE,
-+            .offset       = 0,
-+        },
-+        VMSTATE_STRUCT_ARRAY(endpoint, USBRedirDevice, MAX_ENDPOINTS, 1,
-+                             usbredir_ep_vmstate, struct endp_data),
-+        VMSTATE_STRUCT(cancelled, USBRedirDevice, 1,
-+                       usbredir_ep_packet_id_queue_vmstate,
-+                       struct PacketIdQueue),
-+        VMSTATE_STRUCT(already_in_flight, USBRedirDevice, 1,
-+                       usbredir_ep_packet_id_queue_vmstate,
-+                       struct PacketIdQueue),
-+        VMSTATE_STRUCT(device_info, USBRedirDevice, 1,
-+                       usbredir_device_info_vmstate,
-+                       struct usb_redir_device_connect_header),
-+        VMSTATE_STRUCT(interface_info, USBRedirDevice, 1,
-+                       usbredir_interface_info_vmstate,
-+                       struct usb_redir_interface_info_header),
-+        VMSTATE_END_OF_LIST()
-+    }
-+};
-+
- static Property usbredir_properties[] = {
-     DEFINE_PROP_CHR("chardev", USBRedirDevice, cs),
-     DEFINE_PROP_UINT8("debug", USBRedirDevice, debug, 0),
-@@ -1550,6 +1874,7 @@ static void usbredir_class_initfn(ObjectClass *klass, void *data)
-     uc->handle_reset   = usbredir_handle_reset;
-     uc->handle_data    = usbredir_handle_data;
-     uc->handle_control = usbredir_handle_control;
-+    dc->vmsd           = &usbredir_vmstate;
-     dc->props          = usbredir_properties;
- }
- 
--- 
-1.7.12
-
diff --git a/0366-usb-redir-Add-chardev-open-close-debug-logging.patch b/0366-usb-redir-Add-chardev-open-close-debug-logging.patch
deleted file mode 100644
index 42719c9..0000000
--- a/0366-usb-redir-Add-chardev-open-close-debug-logging.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From 93691f50a5200651f22e698cc29be0b1a020f5c5 Mon Sep 17 00:00:00 2001
-From: Hans de Goede <hdegoede@redhat.com>
-Date: Wed, 5 Sep 2012 15:56:57 +0200
-Subject: [PATCH 366/366] usb-redir: Add chardev open / close debug logging
-
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- hw/usb/redirect.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
-diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
-index 8dbb722..95a2167 100644
---- a/hw/usb/redirect.c
-+++ b/hw/usb/redirect.c
-@@ -864,6 +864,7 @@ static void usbredir_chardev_close_bh(void *opaque)
-     usbredir_device_disconnect(dev);
- 
-     if (dev->parser) {
-+        DPRINTF("destroying usbredirparser\n");
-         usbredirparser_destroy(dev->parser);
-         dev->parser = NULL;
-     }
-@@ -879,6 +880,8 @@ static void usbredir_chardev_open(USBRedirDevice *dev)
-     usbredir_chardev_close_bh(dev);
-     qemu_bh_cancel(dev->chardev_close_bh);
- 
-+    DPRINTF("creating usbredirparser\n");
-+
-     strcpy(version, "qemu usb-redir guest ");
-     pstrcat(version, sizeof(version), qemu_get_version());
- 
-@@ -990,9 +993,11 @@ static void usbredir_chardev_event(void *opaque, int event)
- 
-     switch (event) {
-     case CHR_EVENT_OPENED:
-+        DPRINTF("chardev open\n");
-         usbredir_chardev_open(dev);
-         break;
-     case CHR_EVENT_CLOSED:
-+        DPRINTF("chardev close\n");
-         qemu_bh_schedule(dev->chardev_close_bh);
-         break;
-     }
-@@ -1255,6 +1260,7 @@ static void usbredir_device_disconnect(void *priv)
-     qemu_del_timer(dev->attach_timer);
- 
-     if (dev->dev.attached) {
-+        DPRINTF("detaching device\n");
-         usb_device_detach(&dev->dev);
-         /*
-          * Delay next usb device attach to give the guest a chance to see
--- 
-1.7.12
-
diff --git a/qemu.spec b/qemu.spec
index 452f280..9214282 100644
--- a/qemu.spec
+++ b/qemu.spec
@@ -37,7 +37,7 @@
 Summary: QEMU is a FAST! processor emulator
 Name: qemu
 Version: 1.2.0
-Release: 1%{?dist}
+Release: 2%{?dist}
 # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped
 Epoch: 2
 License: GPLv2+ and LGPLv2+ and BSD
@@ -115,6 +115,7 @@ Patch212: 0212-spice-make-number-of-surfaces-runtime-configurable.patch
 Patch213: 0213-qxl-Add-set_client_capabilities-interface-to-QXLInte.patch
 Patch214: 0214-Remove-ifdef-QXL_COMMAND_FLAG_COMPAT_16BPP.patch
 Patch215: 0215-qxl-dont-update-invalid-area.patch
+Patch216: 0216-qxl-Ignore-set_client_capabilities-pre-post-migrate.patch
 
 # Ugh, ton of USB bugfixes / preparation patches for usb-redir
 # live-migration which did not make 1.2.0 :|
@@ -182,12 +183,11 @@ Patch0357: 0357-usb-host-allow-emulated-non-async-control-requests-w.patch
 Patch0358: 0358-ehci-Don-t-set-seen-to-0-when-removing-unseen-queue-.patch
 Patch0359: 0359-ehci-Walk-async-schedule-before-and-after-migration.patch
 Patch0360: 0360-ehci-Don-t-process-too-much-frames-in-1-timer-tick.patch
-Patch0361: 0361-usb-Migrate-over-device-speed-and-speedmask.patch
-Patch0362: 0362-usb-redir-Change-cancelled-packet-code-into-a-generi.patch
-Patch0363: 0363-usb-redir-Add-an-already_in_flight-packet-id-queue.patch
-Patch0364: 0364-usb-redir-Store-max_packet_size-in-endp_data.patch
-Patch0365: 0365-usb-redir-Add-support-for-migration.patch
-Patch0366: 0366-usb-redir-Add-chardev-open-close-debug-logging.patch
+Patch0361: 0361-usb-redir-Change-cancelled-packet-code-into-a-generi.patch
+Patch0362: 0362-usb-redir-Add-an-already_in_flight-packet-id-queue.patch
+Patch0363: 0363-usb-redir-Store-max_packet_size-in-endp_data.patch
+Patch0364: 0364-usb-redir-Add-support-for-migration.patch
+Patch0365: 0365-usb-redir-Add-chardev-open-close-debug-logging.patch
 
 BuildRequires: SDL-devel
 BuildRequires: zlib-devel
@@ -500,6 +500,7 @@ such as kvm_stat.
 %patch213 -p1
 %patch214 -p1
 %patch215 -p1
+%patch216 -p1
 
 %patch301 -p1
 %patch302 -p1
@@ -566,7 +567,6 @@ such as kvm_stat.
 %patch363 -p1
 %patch364 -p1
 %patch365 -p1
-%patch366 -p1
 
 
 %build
@@ -1046,6 +1046,10 @@ fi
 %{_mandir}/man1/qemu-img.1*
 
 %changelog
+* Sat Sep 10 2012 Hans de Goede <hdegoede@redhat.com> - 2:1.2.0-2
+- Fix crash on (seamless) migration
+- Sync usbredir live migration patches with upstream
+
 * Fri Sep  9 2012 Hans de Goede <hdegoede@redhat.com> - 2:1.2.0-1
 - New upstream release 1.2.0 final
 - Add support for Spice seamless migration