From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757628Ab1LGQv1 (ORCPT ); Wed, 7 Dec 2011 11:51:27 -0500 Received: from cantor2.suse.de ([195.135.220.15]:33561 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757587Ab1LGQUB (ORCPT ); Wed, 7 Dec 2011 11:20:01 -0500 X-Mailbox-Line: From gregkh@clark.kroah.org Wed Dec 7 08:08:27 2011 Message-Id: <20111207160827.106077244@clark.kroah.org> User-Agent: quilt/0.50-23.1 Date: Wed, 07 Dec 2011 08:07:15 -0800 From: Greg KH To: , Cc: , , , Matthieu Castet , Thomas Poussevin , Alan Stern Subject: [55/80] USB: EHCI: fix HUB TT scheduling issue with iso transfer In-Reply-To: <20111207161256.GA7736@kroah.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.0-stable review patch. If anyone has any objections, please let me know. ------------------ From: Thomas Poussevin commit 811c926c538f7e8d3c08b630dd5844efd7e000f6 upstream. The current TT scheduling doesn't allow to play and then record on a full-speed device connected to a high speed hub. The IN iso stream can only start on the first uframe (0-2 for a 165 us) because of CSPLIT transactions. For the OUT iso stream there no such restriction. uframe 0-5 are possible. The idea of this patch is that the first uframe are precious (for IN TT iso stream) and we should allocate the last uframes first if possible. For that we reverse the order of uframe allocation (last uframe first). Here an example : hid interrupt stream ---------------------------------------------------------------------- uframe | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | ---------------------------------------------------------------------- max_tt_usecs | 125 | 125 | 125 | 125 | 125 | 125 | 30 | 0 | ---------------------------------------------------------------------- used usecs on a frame | 13 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ---------------------------------------------------------------------- iso OUT stream ---------------------------------------------------------------------- uframe | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | ---------------------------------------------------------------------- max_tt_usecs | 125 | 125 | 125 | 125 | 125 | 125 | 30 | 0 | ---------------------------------------------------------------------- used usecs on a frame | 13 | 125 | 39 | 0 | 0 | 0 | 0 | 0 | ---------------------------------------------------------------------- There no place for iso IN stream (uframe 0-2 are used) and we got "cannot submit datapipe for urb 0, error -28: not enough bandwidth" error. With the patch this become. iso OUT stream ---------------------------------------------------------------------- uframe | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | ---------------------------------------------------------------------- max_tt_usecs | 125 | 125 | 125 | 125 | 125 | 125 | 30 | 0 | ---------------------------------------------------------------------- used usecs on a frame | 13 | 0 | 0 | 0 | 125 | 39 | 0 | 0 | ---------------------------------------------------------------------- iso IN stream ---------------------------------------------------------------------- uframe | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | ---------------------------------------------------------------------- max_tt_usecs | 125 | 125 | 125 | 125 | 125 | 125 | 30 | 0 | ---------------------------------------------------------------------- used usecs on a frame | 13 | 0 | 125 | 40 | 125 | 39 | 0 | 0 | ---------------------------------------------------------------------- Signed-off-by: Matthieu Castet Signed-off-by: Thomas Poussevin Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-sched.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1483,10 +1483,15 @@ iso_stream_schedule ( /* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */ - /* find a uframe slot with enough bandwidth */ - next = start + period; - for (; start < next; start++) { - + /* find a uframe slot with enough bandwidth. + * Early uframes are more precious because full-speed + * iso IN transfers can't use late uframes, + * and therefore they should be allocated last. + */ + next = start; + start += period; + do { + start--; /* check schedule: enough space? */ if (stream->highspeed) { if (itd_slot_ok(ehci, mod, start, @@ -1499,7 +1504,7 @@ iso_stream_schedule ( start, sched, period)) break; } - } + } while (start > next); /* no room in the schedule */ if (start == next) {