mirror of
https://git.proxmox.com/git/qemu
synced 2025-08-07 12:58:20 +00:00
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_urb_idx;
|
||||||
int iso_buffer_used;
|
int iso_buffer_used;
|
||||||
int max_packet_size;
|
int max_packet_size;
|
||||||
|
int inflight;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct USBAutoFilter {
|
struct USBAutoFilter {
|
||||||
@ -184,7 +185,19 @@ static void clear_iso_started(USBHostDevice *s, int ep)
|
|||||||
|
|
||||||
static void set_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)
|
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;
|
USBHostDevice *s = opaque;
|
||||||
AsyncURB *aurb;
|
AsyncURB *aurb;
|
||||||
|
int urbs = 0;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
USBPacket *p;
|
USBPacket *p;
|
||||||
@ -289,6 +303,9 @@ static void async_complete(void *opaque)
|
|||||||
int r = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &aurb);
|
int r = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &aurb);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
if (errno == EAGAIN) {
|
if (errno == EAGAIN) {
|
||||||
|
if (urbs > 2) {
|
||||||
|
fprintf(stderr, "husb: %d iso urbs finished at once\n", urbs);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (errno == ENODEV && !s->closing) {
|
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
|
/* 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) */
|
anything else (it is handled further in usb_host_handle_iso_data) */
|
||||||
if (aurb->iso_frame_idx == -1) {
|
if (aurb->iso_frame_idx == -1) {
|
||||||
|
int inflight;
|
||||||
if (aurb->urb.status == -EPIPE) {
|
if (aurb->urb.status == -EPIPE) {
|
||||||
set_halt(s, aurb->urb.endpoint & 0xf);
|
set_halt(s, aurb->urb.endpoint & 0xf);
|
||||||
}
|
}
|
||||||
aurb->iso_frame_idx = 0;
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -670,6 +693,7 @@ static int usb_host_handle_iso_data(USBHostDevice *s, USBPacket *p, int in)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
aurb[i].iso_frame_idx = -1;
|
aurb[i].iso_frame_idx = -1;
|
||||||
|
change_iso_inflight(s, p->devep, +1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user