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
This commit is contained in:
parent
4d64302ef7
commit
2b9a58fd23
@ -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)) {
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user