summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb2/controller
diff options
context:
space:
mode:
authorthompsa <thompsa@FreeBSD.org>2009-01-26 17:49:58 +0000
committerthompsa <thompsa@FreeBSD.org>2009-01-26 17:49:58 +0000
commit23e475fdba781a77a74d3cdb7aad20b8287324fc (patch)
treef4b8963855c9ba9a83965141342937ed6e10ef14 /sys/dev/usb2/controller
parent2c5a7eae690f4f18d5619f226a414d5aba9fe074 (diff)
downloadFreeBSD-src-23e475fdba781a77a74d3cdb7aad20b8287324fc.zip
FreeBSD-src-23e475fdba781a77a74d3cdb7aad20b8287324fc.tar.gz
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
Diffstat (limited to 'sys/dev/usb2/controller')
-rw-r--r--sys/dev/usb2/controller/uhci2.c24
-rw-r--r--sys/dev/usb2/controller/usb2_controller.h5
2 files changed, 29 insertions, 0 deletions
diff --git a/sys/dev/usb2/controller/uhci2.c b/sys/dev/usb2/controller/uhci2.c
index e393218..e967a9e 100644
--- a/sys/dev/usb2/controller/uhci2.c
+++ b/sys/dev/usb2/controller/uhci2.c
@@ -2396,6 +2396,24 @@ uhci_portreset(uhci_softc_t *sc, uint16_t index, uint8_t use_polling)
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)) {
diff --git a/sys/dev/usb2/controller/usb2_controller.h b/sys/dev/usb2/controller/usb2_controller.h
index 646b49a..80633d9 100644
--- a/sys/dev/usb2/controller/usb2_controller.h
+++ b/sys/dev/usb2/controller/usb2_controller.h
@@ -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 */
OpenPOWER on IntegriCloud