Alan Stern wrote:
On Mon, 12 Aug 2013, Takashi Iwai wrote:
So... Clemens, Daniel, Eldad, could you guys review the latest version of Alan's patch? I'd love to sort this out for 3.12.
Here's a revised version of the patch (still untested).
- maxsize = ((ep->freqmax + 0xffff) * (frame_bits >> 3))
>> (16 - ep->datainterval);
- maxsize = ((ep->freqmax + 0xffff) >> (16 - ep->datainterval))
* (frame_bits >> 3);
What do you assume prevents firmware writers from splitting frames across packages? The specification? Sanity? :) (see txfr_quirk)
The difference is that this version tries always to keep a period's worth of bytes in the USB hardware queue.
Having truncated URBs is possible only when URBs are shorter than one period, so I think that a queue length of at least two periods, together with a minimum period size, should ensure the isochrounous scheduling threshold.
This isn't tested either.
Regards, Clemens
sound/usb/endpoint.c | 3 ++- sound/usb/pcm.c | 16 ++++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-)
--- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c @@ -638,7 +638,8 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep, if (sync_ep) minsize -= minsize >> 3; minsize = max(minsize, 1u); - total_packs = (period_bytes + minsize - 1) / minsize; + /* try to make the queue length the same as two periods */ + total_packs = (2 * period_bytes + minsize - 1) / minsize; /* we need at least two URBs for queueing */ if (total_packs < 2) { total_packs = 2; --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -1131,10 +1131,22 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre return err;
param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME; - if (subs->speed == USB_SPEED_FULL) + switch (subs->speed) { + case USB_SPEED_FULL: /* full speed devices have fixed data packet interval */ ptmin = 1000; - if (ptmin == 1000) + break; + case USB_SPEED_HIGH: + /* + * Assume we have an EHCI controller with an Isochronous + * Scheduling Threshold of one frame (8 microframes), and + * add 2 microframes for boundary cases. Increase by 4% + * to have a margin for clock inaccuracies. + */ + ptmin = max(ptmin, (8 + 2) * 130u); + break; + } + if (ptmin >= 1000) /* if period time doesn't go below 1 ms, no rules needed */ param_period_time_if_needed = -1; snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME,