usb-linux: track inflight iso urb count
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 <kraxel@redhat.com>
This commit is contained in:
parent
b81bcd8aa0
commit
8288726256
26
usb-linux.c
26
usb-linux.c
@ -100,6 +100,7 @@ struct endp_data {
|
||||
int iso_urb_idx;
|
||||
int iso_buffer_used;
|
||||
int max_packet_size;
|
||||
int inflight;
|
||||
};
|
||||
|
||||
struct USBAutoFilter {
|
||||
@ -184,7 +185,19 @@ static void clear_iso_started(USBHostDevice *s, int ep)
|
||||
|
||||
static void set_iso_started(USBHostDevice *s, int ep)
|
||||
{
|
||||
get_endp(s, ep)->iso_started = 1;
|
||||
struct endp_data *e = get_endp(s, ep);
|
||||
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 = get_endp(s, ep);
|
||||
|
||||
e->inflight += value;
|
||||
return e->inflight;
|
||||
}
|
||||
|
||||
static void set_iso_urb(USBHostDevice *s, int ep, AsyncURB *iso_urb)
|
||||
@ -282,6 +295,7 @@ static void async_complete(void *opaque)
|
||||
{
|
||||
USBHostDevice *s = opaque;
|
||||
AsyncURB *aurb;
|
||||
int urbs = 0;
|
||||
|
||||
while (1) {
|
||||
USBPacket *p;
|
||||
@ -289,6 +303,9 @@ static void async_complete(void *opaque)
|
||||
int r = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &aurb);
|
||||
if (r < 0) {
|
||||
if (errno == EAGAIN) {
|
||||
if (urbs > 2) {
|
||||
fprintf(stderr, "husb: %d iso urbs finished at once\n", urbs);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (errno == ENODEV && !s->closing) {
|
||||
@ -306,10 +323,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;
|
||||
}
|
||||
|
||||
@ -670,6 +693,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user