Skip to content

Commit

Permalink
usb-redir: Change cancelled packet code into a generic packet-id queue
Browse files Browse the repository at this point in the history
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
  • Loading branch information
jwrdegoede authored and kraxel committed Sep 13, 2012
1 parent ceab6f9 commit 8e60452
Showing 1 changed file with 71 additions and 31 deletions.
102 changes: 71 additions & 31 deletions hw/usb/redirect.c
Expand Up @@ -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) */
Expand All @@ -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 */
Expand All @@ -86,19 +97,14 @@ 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;
struct usbredirfilter_rule *filter_rules;
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);
Expand Down Expand Up @@ -239,37 +245,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,
Expand Down Expand Up @@ -914,7 +958,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);
}
Expand All @@ -933,13 +977,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));
}
Expand Down

0 comments on commit 8e60452

Please sign in to comment.