Please CC me on replies, as I'm not on the list.
My system is an AR9132 mips SoC, kernel 3.6.11 with OpenWrt patches.
The audio device is a C-Media usb audio adapter, IDs 0d8c/000e. It is a
full speed device, and is connected directly to the only USB port. I'm
using only the output, but it does have a mic input as well. (There are
also various controls, e.g. mute, suggested by the USB descriptors, but
those aren't present on my device.)
The device was working fine with OpenWrt-patched kernel 3.3.8.
With the new kernel, I have the following problems:
* audio output is choppy (underruns). the usb audio driver
intermittently prints:
ALSA sound/usb/pcm.c:1187 delay: estimated 624, actual 288
(I realize the message is not directly indicative of an underrun, but
I believe the underruns and the message are correlated)
This tends to get worse as playback progresses, and sometimes there
are "cannot submit urb" messages with error -27, and sometimes
playback hangs.
* audio programs almost always hang in "D" state when closing the audio
device.
I investigated the second problem first in hopes I could eliminate the
reboot after each experiment, but in the end, both problems went away
simultaneously.
I tracked the hang to the sleep in ehci_endpoint_disable that waits for
active iso transactions to finish (indicated by stream->td_list being
empty).
My theory is that the changes in
f42890782241a60d107f23d08089a4a12b507a11 ("USB: EHCI: simplify
isochronous scanning") result in leakage of sitds when still-active
sitds in the previous frame are skipped by scan_isoc. I don't know why
this results in the underruns, but it is a low-memory embedded system,
so possibly it's just leaking enough descriptors to run out of
dma-eligible memory.
The patch below restores the behavior before commit f428 of stopping the
scan immediately once a still-active descriptor is found (and leaving
next_frame at the previous frame rather than the current frame if
appropriate). This patch resolves the problems I've been seeing, but I
don't know if it's the best fix.
I have various ftrace captures, which I can post somewhere if there's
interest. Some of them have the iso stream refcounting restored, and
clearly show that there aren't as many puts as gets. The detail of
scan_isoc behavior isn't visible in the traces, though.
(An aside: I noticed there is an rmb() before the itd status check, but
not before the sitd status check.)
--- a/drivers/usb/host/ehci-sched.c 2013-01-26 19:37:21.000000000 -0800
+++ b/drivers/usb/host/ehci-sched.c 2013-01-26 19:39:25.000000000 -0800
@@ -2296,7 +2296,7 @@
type = Q_NEXT_TYPE(ehci,
q.sitd->hw_next);
q = *q_p;
- break;
+ goto end_scan;
}
/* Take finished SITDs out of the schedule
@@ -2336,5 +2336,6 @@
break;
frame = (frame + 1) & fmask;
}
- ehci->next_frame = now_frame;
+end_scan:
+ ehci->next_frame = frame;
}
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html