|
|
5544c1 |
From 5b44a6c9c102b69690adcc2c5be886857ea35ebd Mon Sep 17 00:00:00 2001
|
|
Hans de Goede |
c8dfc6 |
From: Hans de Goede <hdegoede@redhat.com>
|
|
Hans de Goede |
c8dfc6 |
Date: Tue, 4 Sep 2012 14:18:34 +0200
|
|
|
5544c1 |
Subject: [PATCH] usb-redir: Change cancelled packet code into a generic
|
|
|
5544c1 |
packet-id queue
|
|
Hans de Goede |
c8dfc6 |
|
|
Hans de Goede |
c8dfc6 |
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
|
Hans de Goede |
c8dfc6 |
---
|
|
Hans de Goede |
c8dfc6 |
hw/usb/redirect.c | 102 +++++++++++++++++++++++++++++++++++++-----------------
|
|
Hans de Goede |
c8dfc6 |
1 file changed, 71 insertions(+), 31 deletions(-)
|
|
Hans de Goede |
c8dfc6 |
|
|
Hans de Goede |
c8dfc6 |
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
|
|
|
5544c1 |
index f183263..e2b8159 100644
|
|
Hans de Goede |
c8dfc6 |
--- a/hw/usb/redirect.c
|
|
Hans de Goede |
c8dfc6 |
+++ b/hw/usb/redirect.c
|
|
Hans de Goede |
c8dfc6 |
@@ -43,7 +43,6 @@
|
|
Hans de Goede |
c8dfc6 |
#define EP2I(ep_address) (((ep_address & 0x80) >> 3) | (ep_address & 0x0f))
|
|
Hans de Goede |
c8dfc6 |
#define I2EP(i) (((i & 0x10) << 3) | (i & 0x0f))
|
|
Hans de Goede |
c8dfc6 |
|
|
Hans de Goede |
c8dfc6 |
-typedef struct Cancelled Cancelled;
|
|
Hans de Goede |
c8dfc6 |
typedef struct USBRedirDevice USBRedirDevice;
|
|
Hans de Goede |
c8dfc6 |
|
|
Hans de Goede |
c8dfc6 |
/* Struct to hold buffered packets (iso or int input packets) */
|
|
Hans de Goede |
c8dfc6 |
@@ -69,6 +68,18 @@ struct endp_data {
|
|
Hans de Goede |
c8dfc6 |
int bufpq_target_size;
|
|
Hans de Goede |
c8dfc6 |
};
|
|
Hans de Goede |
c8dfc6 |
|
|
Hans de Goede |
c8dfc6 |
+struct PacketIdQueueEntry {
|
|
Hans de Goede |
c8dfc6 |
+ uint64_t id;
|
|
Hans de Goede |
c8dfc6 |
+ QTAILQ_ENTRY(PacketIdQueueEntry)next;
|
|
Hans de Goede |
c8dfc6 |
+};
|
|
Hans de Goede |
c8dfc6 |
+
|
|
Hans de Goede |
c8dfc6 |
+struct PacketIdQueue {
|
|
Hans de Goede |
c8dfc6 |
+ USBRedirDevice *dev;
|
|
Hans de Goede |
c8dfc6 |
+ const char *name;
|
|
Hans de Goede |
c8dfc6 |
+ QTAILQ_HEAD(, PacketIdQueueEntry) head;
|
|
Hans de Goede |
c8dfc6 |
+ int size;
|
|
Hans de Goede |
c8dfc6 |
+};
|
|
Hans de Goede |
c8dfc6 |
+
|
|
Hans de Goede |
c8dfc6 |
struct USBRedirDevice {
|
|
Hans de Goede |
c8dfc6 |
USBDevice dev;
|
|
Hans de Goede |
c8dfc6 |
/* Properties */
|
|
Hans de Goede |
c8dfc6 |
@@ -86,7 +97,7 @@ struct USBRedirDevice {
|
|
Hans de Goede |
c8dfc6 |
int64_t next_attach_time;
|
|
Hans de Goede |
c8dfc6 |
struct usbredirparser *parser;
|
|
Hans de Goede |
c8dfc6 |
struct endp_data endpoint[MAX_ENDPOINTS];
|
|
Hans de Goede |
c8dfc6 |
- QTAILQ_HEAD(, Cancelled) cancelled;
|
|
Hans de Goede |
c8dfc6 |
+ struct PacketIdQueue cancelled;
|
|
Hans de Goede |
c8dfc6 |
/* Data for device filtering */
|
|
Hans de Goede |
c8dfc6 |
struct usb_redir_device_connect_header device_info;
|
|
Hans de Goede |
c8dfc6 |
struct usb_redir_interface_info_header interface_info;
|
|
Hans de Goede |
c8dfc6 |
@@ -94,11 +105,6 @@ struct USBRedirDevice {
|
|
Hans de Goede |
c8dfc6 |
int filter_rules_count;
|
|
Hans de Goede |
c8dfc6 |
};
|
|
Hans de Goede |
c8dfc6 |
|
|
Hans de Goede |
c8dfc6 |
-struct Cancelled {
|
|
Hans de Goede |
c8dfc6 |
- uint64_t id;
|
|
Hans de Goede |
c8dfc6 |
- QTAILQ_ENTRY(Cancelled)next;
|
|
Hans de Goede |
c8dfc6 |
-};
|
|
Hans de Goede |
c8dfc6 |
-
|
|
Hans de Goede |
c8dfc6 |
static void usbredir_hello(void *priv, struct usb_redir_hello_header *h);
|
|
Hans de Goede |
c8dfc6 |
static void usbredir_device_connect(void *priv,
|
|
Hans de Goede |
c8dfc6 |
struct usb_redir_device_connect_header *device_connect);
|
|
|
5544c1 |
@@ -251,37 +257,75 @@ static int usbredir_write(void *priv, uint8_t *data, int count)
|
|
Hans de Goede |
c8dfc6 |
* Cancelled and buffered packets helpers
|
|
Hans de Goede |
c8dfc6 |
*/
|
|
Hans de Goede |
c8dfc6 |
|
|
Hans de Goede |
c8dfc6 |
-static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p)
|
|
Hans de Goede |
c8dfc6 |
+static void packet_id_queue_init(struct PacketIdQueue *q,
|
|
Hans de Goede |
c8dfc6 |
+ USBRedirDevice *dev, const char *name)
|
|
Hans de Goede |
c8dfc6 |
{
|
|
Hans de Goede |
c8dfc6 |
- USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
|
|
Hans de Goede |
c8dfc6 |
- Cancelled *c;
|
|
Hans de Goede |
c8dfc6 |
+ q->dev = dev;
|
|
Hans de Goede |
c8dfc6 |
+ q->name = name;
|
|
Hans de Goede |
c8dfc6 |
+ QTAILQ_INIT(&q->head);
|
|
Hans de Goede |
c8dfc6 |
+ q->size = 0;
|
|
Hans de Goede |
c8dfc6 |
+}
|
|
Hans de Goede |
c8dfc6 |
+
|
|
Hans de Goede |
c8dfc6 |
+static void packet_id_queue_add(struct PacketIdQueue *q, uint64_t id)
|
|
Hans de Goede |
c8dfc6 |
+{
|
|
Hans de Goede |
c8dfc6 |
+ USBRedirDevice *dev = q->dev;
|
|
Hans de Goede |
c8dfc6 |
+ struct PacketIdQueueEntry *e;
|
|
Hans de Goede |
c8dfc6 |
+
|
|
Hans de Goede |
c8dfc6 |
+ DPRINTF("adding packet id %"PRIu64" to %s queue\n", id, q->name);
|
|
Hans de Goede |
c8dfc6 |
+
|
|
Hans de Goede |
c8dfc6 |
+ e = g_malloc0(sizeof(struct PacketIdQueueEntry));
|
|
Hans de Goede |
c8dfc6 |
+ e->id = id;
|
|
Hans de Goede |
c8dfc6 |
+ QTAILQ_INSERT_TAIL(&q->head, e, next);
|
|
Hans de Goede |
c8dfc6 |
+ q->size++;
|
|
Hans de Goede |
c8dfc6 |
+}
|
|
Hans de Goede |
c8dfc6 |
+
|
|
Hans de Goede |
c8dfc6 |
+static int packet_id_queue_remove(struct PacketIdQueue *q, uint64_t id)
|
|
Hans de Goede |
c8dfc6 |
+{
|
|
Hans de Goede |
c8dfc6 |
+ USBRedirDevice *dev = q->dev;
|
|
Hans de Goede |
c8dfc6 |
+ struct PacketIdQueueEntry *e;
|
|
Hans de Goede |
c8dfc6 |
+
|
|
Hans de Goede |
c8dfc6 |
+ QTAILQ_FOREACH(e, &q->head, next) {
|
|
Hans de Goede |
c8dfc6 |
+ if (e->id == id) {
|
|
Hans de Goede |
c8dfc6 |
+ DPRINTF("removing packet id %"PRIu64" from %s queue\n",
|
|
Hans de Goede |
c8dfc6 |
+ id, q->name);
|
|
Hans de Goede |
c8dfc6 |
+ QTAILQ_REMOVE(&q->head, e, next);
|
|
Hans de Goede |
c8dfc6 |
+ q->size--;
|
|
Hans de Goede |
c8dfc6 |
+ g_free(e);
|
|
Hans de Goede |
c8dfc6 |
+ return 1;
|
|
Hans de Goede |
c8dfc6 |
+ }
|
|
Hans de Goede |
c8dfc6 |
+ }
|
|
Hans de Goede |
c8dfc6 |
+ return 0;
|
|
Hans de Goede |
c8dfc6 |
+}
|
|
Hans de Goede |
c8dfc6 |
+
|
|
Hans de Goede |
c8dfc6 |
+static void packet_id_queue_empty(struct PacketIdQueue *q)
|
|
Hans de Goede |
c8dfc6 |
+{
|
|
Hans de Goede |
c8dfc6 |
+ USBRedirDevice *dev = q->dev;
|
|
Hans de Goede |
c8dfc6 |
+ struct PacketIdQueueEntry *e, *next_e;
|
|
Hans de Goede |
c8dfc6 |
|
|
Hans de Goede |
c8dfc6 |
- DPRINTF("cancel packet id %"PRIu64"\n", p->id);
|
|
Hans de Goede |
c8dfc6 |
+ DPRINTF("removing %d packet-ids from %s queue\n", q->size, q->name);
|
|
Hans de Goede |
c8dfc6 |
|
|
Hans de Goede |
c8dfc6 |
- c = g_malloc0(sizeof(Cancelled));
|
|
Hans de Goede |
c8dfc6 |
- c->id = p->id;
|
|
Hans de Goede |
c8dfc6 |
- QTAILQ_INSERT_TAIL(&dev->cancelled, c, next);
|
|
Hans de Goede |
c8dfc6 |
+ QTAILQ_FOREACH_SAFE(e, &q->head, next, next_e) {
|
|
Hans de Goede |
c8dfc6 |
+ QTAILQ_REMOVE(&q->head, e, next);
|
|
Hans de Goede |
c8dfc6 |
+ g_free(e);
|
|
Hans de Goede |
c8dfc6 |
+ }
|
|
Hans de Goede |
c8dfc6 |
+ q->size = 0;
|
|
Hans de Goede |
c8dfc6 |
+}
|
|
Hans de Goede |
c8dfc6 |
|
|
Hans de Goede |
c8dfc6 |
+static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p)
|
|
Hans de Goede |
c8dfc6 |
+{
|
|
Hans de Goede |
c8dfc6 |
+ USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
|
|
Hans de Goede |
c8dfc6 |
+
|
|
Hans de Goede |
c8dfc6 |
+ packet_id_queue_add(&dev->cancelled, p->id);
|
|
Hans de Goede |
c8dfc6 |
usbredirparser_send_cancel_data_packet(dev->parser, p->id);
|
|
Hans de Goede |
c8dfc6 |
usbredirparser_do_write(dev->parser);
|
|
Hans de Goede |
c8dfc6 |
}
|
|
Hans de Goede |
c8dfc6 |
|
|
Hans de Goede |
c8dfc6 |
static int usbredir_is_cancelled(USBRedirDevice *dev, uint64_t id)
|
|
Hans de Goede |
c8dfc6 |
{
|
|
Hans de Goede |
c8dfc6 |
- Cancelled *c;
|
|
Hans de Goede |
c8dfc6 |
-
|
|
Hans de Goede |
c8dfc6 |
if (!dev->dev.attached) {
|
|
Hans de Goede |
c8dfc6 |
return 1; /* Treat everything as cancelled after a disconnect */
|
|
Hans de Goede |
c8dfc6 |
}
|
|
Hans de Goede |
c8dfc6 |
-
|
|
Hans de Goede |
c8dfc6 |
- QTAILQ_FOREACH(c, &dev->cancelled, next) {
|
|
Hans de Goede |
c8dfc6 |
- if (c->id == id) {
|
|
Hans de Goede |
c8dfc6 |
- QTAILQ_REMOVE(&dev->cancelled, c, next);
|
|
Hans de Goede |
c8dfc6 |
- g_free(c);
|
|
Hans de Goede |
c8dfc6 |
- return 1;
|
|
Hans de Goede |
c8dfc6 |
- }
|
|
Hans de Goede |
c8dfc6 |
- }
|
|
Hans de Goede |
c8dfc6 |
- return 0;
|
|
Hans de Goede |
c8dfc6 |
+ return packet_id_queue_remove(&dev->cancelled, id);
|
|
Hans de Goede |
c8dfc6 |
}
|
|
Hans de Goede |
c8dfc6 |
|
|
Hans de Goede |
c8dfc6 |
static USBPacket *usbredir_find_packet_by_id(USBRedirDevice *dev,
|
|
|
5544c1 |
@@ -937,7 +981,7 @@ static int usbredir_initfn(USBDevice *udev)
|
|
Hans de Goede |
c8dfc6 |
dev->chardev_close_bh = qemu_bh_new(usbredir_chardev_close_bh, dev);
|
|
Hans de Goede |
c8dfc6 |
dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev);
|
|
Hans de Goede |
c8dfc6 |
|
|
Hans de Goede |
c8dfc6 |
- QTAILQ_INIT(&dev->cancelled);
|
|
Hans de Goede |
c8dfc6 |
+ packet_id_queue_init(&dev->cancelled, dev, "cancelled");
|
|
Hans de Goede |
c8dfc6 |
for (i = 0; i < MAX_ENDPOINTS; i++) {
|
|
Hans de Goede |
c8dfc6 |
QTAILQ_INIT(&dev->endpoint[i].bufpq);
|
|
Hans de Goede |
c8dfc6 |
}
|
|
|
5544c1 |
@@ -955,13 +999,9 @@ static int usbredir_initfn(USBDevice *udev)
|
|
Hans de Goede |
c8dfc6 |
|
|
Hans de Goede |
c8dfc6 |
static void usbredir_cleanup_device_queues(USBRedirDevice *dev)
|
|
Hans de Goede |
c8dfc6 |
{
|
|
Hans de Goede |
c8dfc6 |
- Cancelled *c, *next_c;
|
|
Hans de Goede |
c8dfc6 |
int i;
|
|
Hans de Goede |
c8dfc6 |
|
|
Hans de Goede |
c8dfc6 |
- QTAILQ_FOREACH_SAFE(c, &dev->cancelled, next, next_c) {
|
|
Hans de Goede |
c8dfc6 |
- QTAILQ_REMOVE(&dev->cancelled, c, next);
|
|
Hans de Goede |
c8dfc6 |
- g_free(c);
|
|
Hans de Goede |
c8dfc6 |
- }
|
|
Hans de Goede |
c8dfc6 |
+ packet_id_queue_empty(&dev->cancelled);
|
|
Hans de Goede |
c8dfc6 |
for (i = 0; i < MAX_ENDPOINTS; i++) {
|
|
Hans de Goede |
c8dfc6 |
usbredir_free_bufpq(dev, I2EP(i));
|
|
Hans de Goede |
c8dfc6 |
}
|
|
Hans de Goede |
c8dfc6 |
--
|
|
|
5544c1 |
1.7.12.1
|
|
Hans de Goede |
c8dfc6 |
|