From owner-cvs-all@FreeBSD.ORG Sun Nov 27 09:05:42 2005 Return-Path: X-Original-To: cvs-all@FreeBSD.org Delivered-To: cvs-all@FreeBSD.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id A16DE16A41F; Sun, 27 Nov 2005 09:05:42 +0000 (GMT) (envelope-from iedowse@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 3758243D53; Sun, 27 Nov 2005 09:05:41 +0000 (GMT) (envelope-from iedowse@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id jAR95ehl066628; Sun, 27 Nov 2005 09:05:41 GMT (envelope-from iedowse@repoman.freebsd.org) Received: (from iedowse@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id jAR95dbo066626; Sun, 27 Nov 2005 09:05:40 GMT (envelope-from iedowse) Message-Id: <200511270905.jAR95dbo066626@repoman.freebsd.org> From: Ian Dowse Date: Sun, 27 Nov 2005 09:05:37 +0000 (UTC) To: src-committers@FreeBSD.org, cvs-src@FreeBSD.org, cvs-all@FreeBSD.org X-FreeBSD-CVS-Branch: HEAD Cc: Subject: cvs commit: src/sys/dev/usb ohci.c ohcivar.h X-BeenThere: cvs-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: CVS commit messages for the entire tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 27 Nov 2005 09:05:42 -0000 iedowse 2005-11-27 09:05:37 UTC FreeBSD src repository Modified files: sys/dev/usb ohci.c ohcivar.h Log: The ohci driver's processing of completed transfer descriptors (TDs) appeared to rely on all kinds of non-guaranteed behaviours: the transfer abort code assumed that TDs with no interrupt timeout configured would end up on the done queue within 20ms, the done queue processing assumed that all TDs from a transfer would appear at the same time, and there were access-after-free bugs triggered on failed transfers. Attempt to fix these problems by the following changes: - Use a maximum (6-frame) interrupt delay instead of no interrupt delay to ensure that the 20ms wait in ohci_abort_xfer() is enough for the TDs to have been taken off the hardware done queue. - Defer cancellation of timeouts and freeing of TDs until we either hit an error or reach the final TD. - Remove TDs from the done queue before freeing them so that it is safe to continue traversing the done queue. This appears to fix a hang that was reproducable with revision 1.67 or 1.68 of ulpt.c (earlier revisions had a different transfer pattern). With certain HP printers, the command "true > /dev/ulpt0" would cause ohci_add_done() to spin because the done queue had a loop. The list corruption was caused by a 3-TD transfer where the first TD completed but remained on the internal host controller done queue because it had no interrupt timeout. When the transfer timed out, the TD got freed and reused, so it caused a loop in the done queue when it was inserted a second time from a different transfer. Reported by: Alex Pivovarov MFC after: 1 week Revision Changes Path 1.155 +38 -30 src/sys/dev/usb/ohci.c 1.41 +0 -1 src/sys/dev/usb/ohcivar.h