Found in the Asus GPL sources. This is very noticable with a Seagate FreeAgent drive. Without the patch, long writes give a "reset high speed usb" error and hang until the drive is disconnnected. The patch solves that problem.
Steve
This patch significantly improves the reliability of high speed usb writes on the bcm5354. It implements a work around for version 2 of the usb20 core that was cribbed from the GPL sources for the Asus wl500gpv2 and verified against the wl520gu sources. The FIX ME warning is not needed as the ohci driver initializes the core only once on behalf of both the ohci and ehci devices. Reference: GPL/WL-520gu-NewUI/src/linux/linux/arch/mips/brcm-boards/bcm947xx/pcibios.c GPL/WL-500gPV2-NewUI/src/linux/linux/arch/mips/brcm-boards/bcm947xx/pcibios.c Signed-off-by: Steve Brown <[email protected]> --- --- a/drivers/usb/host/ohci-ssb.c.orig 2009-07-30 12:03:26.522299510 -0400 +++ b/drivers/usb/host/ohci-ssb.c 2009-07-30 13:28:53.672423682 -0400 @@ -150,28 +150,36 @@ */ else if (dev->id.coreid == SSB_DEV_USB20_HOST) { -#warning FIX ME need test for core being up & exit ssb_device_enable(dev, 0); ssb_write32(dev, 0x200, 0x7ff); + + /* Change Flush control reg */ + tmp = ssb_read32(dev, 0x400); + tmp &= ~8; + ssb_write32(dev, 0x400, tmp); + tmp = ssb_read32(dev, 0x400); + + /* Change Shim control reg */ + tmp = ssb_read32(dev, 0x304); + tmp &= ~0x100; + ssb_write32(dev, 0x304, tmp); + tmp = ssb_read32(dev, 0x304); + udelay(1); - if (dev->id.revision == 1) { // bug in rev 1 - /* Change Flush control reg */ - tmp = ssb_read32(dev, 0x400); - tmp &= ~8; - ssb_write32(dev, 0x400, tmp); - tmp = ssb_read32(dev, 0x400); - printk("USB20H fcr: 0x%0x\n", tmp); - - /* Change Shim control reg */ - tmp = ssb_read32(dev, 0x304); - tmp &= ~0x100; - ssb_write32(dev, 0x304, tmp); - tmp = ssb_read32(dev, 0x304); - printk("USB20H shim: 0x%0x\n", tmp); + /* Work around for 5354 failures */ + if ((dev->id.revision == 2) && (dev->bus->chip_id == 0x5354)) { + + /* Change syn01 reg */ + tmp = 0x00fe00fe; + ssb_write32(dev, 0x894, tmp); + + /* Change syn03 reg */ + tmp = ssb_read32(dev, 0x89c); + tmp |= 0x1; + ssb_write32(dev, 0x89c, tmp); } - } - else + } else ssb_device_enable(dev, 0); /*
_______________________________________________ openwrt-devel mailing list [email protected] https://lists.openwrt.org/mailman/listinfo/openwrt-devel
