From owner-svn-src-stable-9@FreeBSD.ORG Sun Feb 23 13:08:19 2014 Return-Path: Delivered-To: svn-src-stable-9@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 6CC71EB7; Sun, 23 Feb 2014 13:08:19 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 48C151AEC; Sun, 23 Feb 2014 13:08:19 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s1ND8JoV034200; Sun, 23 Feb 2014 13:08:19 GMT (envelope-from hselasky@svn.freebsd.org) Received: (from hselasky@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s1ND8Jqv034199; Sun, 23 Feb 2014 13:08:19 GMT (envelope-from hselasky@svn.freebsd.org) Message-Id: <201402231308.s1ND8Jqv034199@svn.freebsd.org> From: Hans Petter Selasky Date: Sun, 23 Feb 2014 13:08:19 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r262359 - stable/9/sys/dev/usb/controller X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-9@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: SVN commit messages for only the 9-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 23 Feb 2014 13:08:19 -0000 Author: hselasky Date: Sun Feb 23 13:08:18 2014 New Revision: 262359 URL: http://svnweb.freebsd.org/changeset/base/262359 Log: MFC r261795: Issue doorbell twice before finally freeing the DMA descriptors. This should fix DMA descriptor caching issues seen with the EHCI controller found in Google Chromebook C720 during removal and insertion of USB devices. Modified: stable/9/sys/dev/usb/controller/ehci.c Directory Properties: stable/9/sys/ (props changed) stable/9/sys/dev/ (props changed) Modified: stable/9/sys/dev/usb/controller/ehci.c ============================================================================== --- stable/9/sys/dev/usb/controller/ehci.c Sun Feb 23 09:44:30 2014 (r262358) +++ stable/9/sys/dev/usb/controller/ehci.c Sun Feb 23 13:08:18 2014 (r262359) @@ -2258,10 +2258,26 @@ ehci_device_bulk_enter(struct usb_xfer * } static void +ehci_doorbell_async(struct ehci_softc *sc) +{ + uint32_t temp; + + /* + * XXX Performance quirk: Some Host Controllers have a too low + * interrupt rate. Issue an IAAD to stimulate the Host + * Controller after queueing the BULK transfer. + * + * XXX Force the host controller to refresh any QH caches. + */ + temp = EOREAD4(sc, EHCI_USBCMD); + if (!(temp & EHCI_CMD_IAAD)) + EOWRITE4(sc, EHCI_USBCMD, temp | EHCI_CMD_IAAD); +} + +static void ehci_device_bulk_start(struct usb_xfer *xfer) { ehci_softc_t *sc = EHCI_BUS2SC(xfer->xroot->bus); - uint32_t temp; /* setup TD's and QH */ ehci_setup_standard_chain(xfer, &sc->sc_async_p_last); @@ -2276,13 +2292,7 @@ ehci_device_bulk_start(struct usb_xfer * if (sc->sc_flags & EHCI_SCFLG_IAADBUG) return; - /* XXX Performance quirk: Some Host Controllers have a too low - * interrupt rate. Issue an IAAD to stimulate the Host - * Controller after queueing the BULK transfer. - */ - temp = EOREAD4(sc, EHCI_USBCMD); - if (!(temp & EHCI_CMD_IAAD)) - EOWRITE4(sc, EHCI_USBCMD, temp | EHCI_CMD_IAAD); + ehci_doorbell_async(sc); } struct usb_pipe_methods ehci_device_bulk_methods = @@ -3899,6 +3909,41 @@ ehci_set_hw_power(struct usb_bus *bus) return; } +static void +ehci_start_dma_delay_second(struct usb_xfer *xfer) +{ + struct ehci_softc *sc = EHCI_BUS2SC(xfer->xroot->bus); + + DPRINTF("\n"); + + /* trigger doorbell */ + ehci_doorbell_async(sc); + + /* give the doorbell 4ms */ + usbd_transfer_timeout_ms(xfer, + (void (*)(void *))&usb_dma_delay_done_cb, 4); +} + +/* + * Ring the doorbell twice before freeing any DMA descriptors. Some host + * controllers apparently cache the QH descriptors and need a message + * that the cache needs to be discarded. + */ +static void +ehci_start_dma_delay(struct usb_xfer *xfer) +{ + struct ehci_softc *sc = EHCI_BUS2SC(xfer->xroot->bus); + + DPRINTF("\n"); + + /* trigger doorbell */ + ehci_doorbell_async(sc); + + /* give the doorbell 4ms */ + usbd_transfer_timeout_ms(xfer, + (void (*)(void *))&ehci_start_dma_delay_second, 4); +} + struct usb_bus_methods ehci_bus_methods = { .endpoint_init = ehci_ep_init, @@ -3911,4 +3956,5 @@ struct usb_bus_methods ehci_bus_methods .set_hw_power_sleep = ehci_set_hw_power_sleep, .roothub_exec = ehci_roothub_exec, .xfer_poll = ehci_do_poll, + .start_dma_delay = ehci_start_dma_delay, };