From owner-svn-src-all@FreeBSD.ORG Mon Jan 26 17:49:58 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 8DD6E1065811; Mon, 26 Jan 2009 17:49:58 +0000 (UTC) (envelope-from thompsa@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 6F8848FC27; Mon, 26 Jan 2009 17:49:58 +0000 (UTC) (envelope-from thompsa@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n0QHnwNt057792; Mon, 26 Jan 2009 17:49:58 GMT (envelope-from thompsa@svn.freebsd.org) Received: (from thompsa@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n0QHnwZm057789; Mon, 26 Jan 2009 17:49:58 GMT (envelope-from thompsa@svn.freebsd.org) Message-Id: <200901261749.n0QHnwZm057789@svn.freebsd.org> From: Andrew Thompson Date: Mon, 26 Jan 2009 17:49:58 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r187730 - in head/sys/dev/usb2: controller core X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 26 Jan 2009 17:50:01 -0000 Author: thompsa Date: Mon Jan 26 17:49:58 2009 New Revision: 187730 URL: http://svn.freebsd.org/changeset/base/187730 Log: MFp4 //depot/projects/usb/ @156522,156530 UHCI SOF Quirk. Makes some broken USB devices work again. Reported by several people. Patch made by me. Submitted by: Hans Petter Selasky Modified: head/sys/dev/usb2/controller/uhci2.c head/sys/dev/usb2/controller/usb2_controller.h head/sys/dev/usb2/core/usb2_hub.c Modified: head/sys/dev/usb2/controller/uhci2.c ============================================================================== --- head/sys/dev/usb2/controller/uhci2.c Mon Jan 26 17:49:48 2009 (r187729) +++ head/sys/dev/usb2/controller/uhci2.c Mon Jan 26 17:49:58 2009 (r187730) @@ -2396,6 +2396,24 @@ uhci_portreset(uhci_softc_t *sc, uint16_ else return (USB_ERR_IOERROR); + /* + * Before we do anything, turn on SOF messages on the USB + * BUS. Some USB devices do not cope without them! + */ + if (!(UREAD2(sc, UHCI_CMD) & UHCI_CMD_RS)) { + + DPRINTF("Activating SOFs!\n"); + + UHCICMD(sc, (UHCI_CMD_MAXP | UHCI_CMD_RS)); + + /* wait a little bit */ + if (use_polling) { + DELAY(10000); + } else { + usb2_pause_mtx(&sc->sc_bus.bus_mtx, 10); + } + } + x = URWMASK(UREAD2(sc, port)); UWRITE2(sc, port, x | UHCI_PORTSC_PR); @@ -3320,7 +3338,13 @@ uhci_set_hw_power(struct usb2_bus *bus) flags = bus->hw_power_state; + /* + * WARNING: Some FULL speed USB devices require periodic SOF + * messages! If any USB devices are connected through the + * UHCI, power save will be disabled! + */ if (flags & (USB_HW_POWER_CONTROL | + USB_HW_POWER_NON_ROOT_HUB | USB_HW_POWER_BULK | USB_HW_POWER_INTERRUPT | USB_HW_POWER_ISOC)) { Modified: head/sys/dev/usb2/controller/usb2_controller.h ============================================================================== --- head/sys/dev/usb2/controller/usb2_controller.h Mon Jan 26 17:49:48 2009 (r187729) +++ head/sys/dev/usb2/controller/usb2_controller.h Mon Jan 26 17:49:58 2009 (r187730) @@ -84,6 +84,11 @@ struct usb2_bus_methods { * are active: */ #define USB_HW_POWER_ISOC 0x08 + /* + * The following flag is set if one or more non-root-HUB devices + * are present on the given USB bus: + */ +#define USB_HW_POWER_NON_ROOT_HUB 0x10 /* USB Device mode only - Mandatory */ Modified: head/sys/dev/usb2/core/usb2_hub.c ============================================================================== --- head/sys/dev/usb2/core/usb2_hub.c Mon Jan 26 17:49:48 2009 (r187729) +++ head/sys/dev/usb2/core/usb2_hub.c Mon Jan 26 17:49:58 2009 (r187730) @@ -1503,7 +1503,7 @@ usb2_bus_powerd(struct usb2_bus *bus) unsigned int temp; unsigned int limit; unsigned int mintime; - uint32_t type_refs[4]; + uint32_t type_refs[5]; uint8_t x; uint8_t rem_wakeup; @@ -1564,6 +1564,7 @@ usb2_bus_powerd(struct usb2_bus *bus) type_refs[1] = 0; type_refs[2] = 0; type_refs[3] = 0; + type_refs[4] = 0; /* Re-loop all the devices to get the actual state */ @@ -1574,6 +1575,9 @@ usb2_bus_powerd(struct usb2_bus *bus) if (udev == NULL) continue; + /* we found a non-Root-Hub USB device */ + type_refs[4] += 1; + /* "last_xfer_time" can be updated by a resume */ temp = ticks - udev->pwr_save.last_xfer_time; @@ -1604,6 +1608,8 @@ usb2_bus_powerd(struct usb2_bus *bus) bus->hw_power_state |= USB_HW_POWER_INTERRUPT; if (type_refs[UE_ISOCHRONOUS] != 0) bus->hw_power_state |= USB_HW_POWER_ISOC; + if (type_refs[4] != 0) + bus->hw_power_state |= USB_HW_POWER_NON_ROOT_HUB; } USB_BUS_UNLOCK(bus);