From 9cded85d1adf9aa6a74cf7363217afe5a309ee63 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Thu, 21 Jul 2011 16:43:40 -0300 Subject: [RHEL6 qemu-kvm PATCH 02/65] usb-linux: track inflight iso urb count RH-Author: Gerd Hoffmann Message-id: <1311266648-1179-3-git-send-email-kraxel@redhat.com> Patchwork-id: 30124 O-Subject: [RHEL-6.2 kvm PATCH 02/30] usb-linux: track inflight iso urb count Bugzilla: 723858 723863 RH-Acked-by: Hans de Goede RH-Acked-by: Jes Sorensen RH-Acked-by: Alex Williamson Track the number of iso urbs which are currently in flight. Log a message in case the count goes down to zero. Also warn in case many urbs are returned at the same time. Signed-off-by: Gerd Hoffmann (cherry picked from commit 82887262569d9222befadb6a98bf364beae30a7e) Conflicts: usb-linux.c --- usb-linux.c | 30 +++++++++++++++++++++++++++--- 1 files changed, 27 insertions(+), 3 deletions(-) Signed-off-by: Eduardo Habkost --- usb-linux.c | 30 +++++++++++++++++++++++++++--- 1 files changed, 27 insertions(+), 3 deletions(-) diff --git a/usb-linux.c b/usb-linux.c index 372a722..2f8353e 100644 --- a/usb-linux.c +++ b/usb-linux.c @@ -101,6 +101,7 @@ struct endp_data { int iso_urb_idx; int iso_buffer_used; int max_packet_size; + int inflight; }; struct USBAutoFilter { @@ -180,7 +181,19 @@ static void clear_iso_started(USBHostDevice *s, int ep) static void set_iso_started(USBHostDevice *s, int ep) { - s->endp_table[ep - 1].iso_started = 1; + struct endp_data *e = &s->endp_table[ep - 1]; + if (!e->iso_started) { + e->iso_started = 1; + e->inflight = 0; + } +} + +static int change_iso_inflight(USBHostDevice *s, int ep, int value) +{ + struct endp_data *e = &s->endp_table[ep - 1]; + + e->inflight += value; + return e->inflight; } static void set_iso_urb(USBHostDevice *s, int ep, AsyncURB *iso_urb) @@ -280,16 +293,20 @@ static void async_complete(void *opaque) { USBHostDevice *s = opaque; AsyncURB *aurb; + int urbs = 0; while (1) { USBPacket *p; int r = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &aurb); if (r < 0) { - if (errno == EAGAIN) + if (errno == EAGAIN) { + if (urbs > 2) { + fprintf(stderr, "husb: %d iso urbs finished at once\n", urbs); + } return; - if (errno == ENODEV && !s->closing) { + } if (errno == ENODEV && !s->closing) { do_disconnect(s); return; } @@ -304,10 +321,16 @@ static void async_complete(void *opaque) /* If this is a buffered iso urb mark it as complete and don't do anything else (it is handled further in usb_host_handle_iso_data) */ if (aurb->iso_frame_idx == -1) { + int inflight; if (aurb->urb.status == -EPIPE) { set_halt(s, aurb->urb.endpoint & 0xf); } aurb->iso_frame_idx = 0; + urbs++; + inflight = change_iso_inflight(s, aurb->urb.endpoint & 0xf, -1); + if (inflight == 0 && is_iso_started(s, aurb->urb.endpoint & 0xf)) { + fprintf(stderr, "husb: out of buffers for iso stream\n"); + } continue; } @@ -667,6 +690,7 @@ static int usb_host_handle_iso_data(USBHostDevice *s, USBPacket *p, int in) break; } aurb[i].iso_frame_idx = -1; + change_iso_inflight(s, p->devep, +1); } } } -- 1.7.3.2