From patchwork Thu Oct 11 11:40:22 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerd Hoffmann X-Patchwork-Id: 190875 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id E2B9C2C008E for ; Thu, 11 Oct 2012 22:41:06 +1100 (EST) Received: from localhost ([::1]:56222 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TMH8T-0003sT-5B for incoming@patchwork.ozlabs.org; Thu, 11 Oct 2012 07:41:05 -0400 Received: from eggs.gnu.org ([208.118.235.92]:44103) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TMH7w-0002je-Uj for qemu-devel@nongnu.org; Thu, 11 Oct 2012 07:40:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TMH7q-0008Om-06 for qemu-devel@nongnu.org; Thu, 11 Oct 2012 07:40:32 -0400 Received: from mx1.redhat.com ([209.132.183.28]:16731) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TMH7p-0008Nk-N3 for qemu-devel@nongnu.org; Thu, 11 Oct 2012 07:40:25 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q9BBeO5X014147 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 11 Oct 2012 07:40:24 -0400 Received: from rincewind.home.kraxel.org (ovpn-116-28.ams2.redhat.com [10.36.116.28]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q9BBeNJF032701; Thu, 11 Oct 2012 07:40:24 -0400 Received: by rincewind.home.kraxel.org (Postfix, from userid 500) id E8A5241655; Thu, 11 Oct 2012 13:40:22 +0200 (CEST) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Thu, 11 Oct 2012 13:40:22 +0200 Message-Id: <1349955622-15183-4-git-send-email-kraxel@redhat.com> In-Reply-To: <1349955622-15183-1-git-send-email-kraxel@redhat.com> References: <1349955622-15183-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: Hans de Goede , Gerd Hoffmann Subject: [Qemu-devel] [PATCH 3/3] uhci: Raise interrupt when requested even for non active tds X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Hans de Goede According to the spec we must raise an interrupt when one is requested even for non active tds. Linux depends on this, for bulk transfers it runs an inactivity timer to work around a bug in early uhci revisions, when we take longer then 200 ms to process a packet, this timer goes of, and as part of the handling Linux then unlinks the qh, and relinks it after the frindex has increased by atleast 1, the problem is Linux only checks for the frindex increases on an interrupt, and we don't send that, causing the qh to go inactive for more then 32 frames, at which point we consider the packet cancelled. Signed-off-by: Hans de Goede Signed-off-by: Gerd Hoffmann --- hw/usb/hcd-uhci.c | 10 +++++++++- 1 files changed, 9 insertions(+), 1 deletions(-) diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c index cdc8bc3..c2f08e3 100644 --- a/hw/usb/hcd-uhci.c +++ b/hw/usb/hcd-uhci.c @@ -826,8 +826,16 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, USBEndpoint *ep; /* Is active ? */ - if (!(td->ctrl & TD_CTRL_ACTIVE)) + if (!(td->ctrl & TD_CTRL_ACTIVE)) { + /* + * ehci11d spec page 22: "Even if the Active bit in the TD is already + * cleared when the TD is fetched ... an IOC interrupt is generated" + */ + if (td->ctrl & TD_CTRL_IOC) { + *int_mask |= 0x01; + } return TD_RESULT_NEXT_QH; + } async = uhci_async_find_td(s, addr, td); if (async) {