On Sunday 27 February 2005 10:58 am, Chris Clayton wrote: > On Thursday 24 Feb 2005 22:15, David Brownell wrote: > > > > If you can find some approach that works reliably, I think the right way > > to package it would be by defining a new quirk flag and kicking in the > > logic that's needed on your chip. Then set that flag when the PCI probe > > detects this particular PCI vendor/product and this revision (or older). > > > > That way if someone sticks a "modern" CardBus controller into that laptop, > > this workaround would only apply to the built-in controller. > > > > OK, here's what I've come up with. ohci-pci.c::ohci_pci_start() is the only > place I can find where I can get access to both the pci_dev, to get at its > vendor and device fields, and the usb_device, to get the chipset revision > from ->descriptor.bcdDevice. Furthermore, ohci_run must have completed > before ->descriptor.bcdDevice has been loaded with the chipset revision.
Ignore the bcdDevice, it's not related to the hardware. For hardware specifics, you'd use the pci revision ... which I see in 'lspci', but not obviously in the kernel pci_dev. Hmm ... probably doesn't matter much, I don't think many people have boards with "Compaq" OHCI; we asked a few years back and nobody fessed up to having seen any at all! > I've tried it out on my laptop and I see the "enabled...quirk" message when > it boots or I bounce the usb drivers, but not when I insert the cardbus USB2 > adapter (which also has ohci). The usb system on the laptop appears still to > be fully functional, but I'll give it a bit of stress testing this evening. That's as it should be: only for that one PCI device. > Comments, advice, corrections etc welcome. For the extremely unlikely case > that it's OK as it stands: Not quite yet ... see below. :) - Dave > Signed-off-by: Chris Clayton <[EMAIL PROTECTED]> > > diff -ur linux-2.6.11-rc4.orig/drivers/usb/host/ohci-pci.c > linux-2.6.11-rc4/drivers/usb/host/ohci-pci.c > --- linux-2.6.11-rc4.orig/drivers/usb/host/ohci-pci.c 2005-02-13 > 03:07:01.000000000 +0000 > +++ linux-2.6.11-rc4/drivers/usb/host/ohci-pci.c 2005-02-27 > 16:29:30.000000000 +0000 > @@ -44,9 +44,10 @@ > { > struct ohci_hcd *ohci = hcd_to_ohci (hcd); > int ret; > + struct usb_device *udev; > + struct pci_dev *pdev = to_pci_dev(hcd->self.controller); > > if(hcd->self.controller && hcd->self.controller->bus == &pci_bus_type) { > - struct pci_dev *pdev = to_pci_dev(hcd->self.controller); Dont change this; just stick another case in this existing switch statement. > > /* AMD 756, for most chips (early revs), corrupts register > * values on read ... so enable the vendor workaround. > @@ -97,6 +98,19 @@ > ohci_stop (hcd); > return ret; > } > + > + /* Check for Compaq's ZFMicro chipset, which needs some short > + * delays when urbs are unlinked in ochi-q.c::finish_unlinks() > + */ > +#define ZFMICRO_MAX_REV 0x0206 That's as in "Linux 2.6 kernel" by the way ... so this code would break when 2.7 starts! Not desirable. > + udev = hcd->self.root_hub; > + if (pdev->vendor == PCI_VENDOR_ID_COMPAQ > + && pdev->device == 0xa0f8 > + && udev->descriptor.bcdDevice <= ZFMICRO_MAX_REV) { > + ohci->flags |= OHCI_QUIRK_ZFMICRO; > + ohci_info (ohci, "enabled Compaq ZFMicro chipset quirk\n"); This is the right way to do this, but it should go in the existing switch statement and that should probably be ohci_dbg() since it's not exactly a critical bit of info. (If other quirks are ohci_info level, it's worth changing them too ... no point in bloating the kernel with this class of useless strings.) > + } > + > return 0; > } > > diff -ur linux-2.6.11-rc4.orig/drivers/usb/host/ohci-q.c > linux-2.6.11-rc4/drivers/usb/host/ohci-q.c > --- linux-2.6.11-rc4.orig/drivers/usb/host/ohci-q.c 2005-02-13 > 03:07:40.000000000 +0000 > +++ linux-2.6.11-rc4/drivers/usb/host/ohci-q.c 2005-02-26 > 12:46:01.000000000 +0000 > @@ -1018,6 +1018,8 @@ > > if (ohci->ed_controltail) { > command |= OHCI_CLF; > + if (ohci->flags & OHCI_QUIRK_ZFMICRO) > + mdelay(1); > if (!(ohci->hc_control & OHCI_CTRL_CLE)) { > control |= OHCI_CTRL_CLE; > ohci_writel (ohci, 0, > @@ -1026,6 +1028,8 @@ > } > if (ohci->ed_bulktail) { > command |= OHCI_BLF; > + if (ohci->flags & OHCI_QUIRK_ZFMICRO) > + mdelay(1); > if (!(ohci->hc_control & OHCI_CTRL_BLE)) { > control |= OHCI_CTRL_BLE; > ohci_writel (ohci, 0, > @@ -1036,12 +1040,17 @@ > /* CLE/BLE to enable, CLF/BLF to (maybe) kickstart */ > if (control) { > ohci->hc_control |= control; > + if (ohci->flags & OHCI_QUIRK_ZFMICRO) > + mdelay(1); > ohci_writel (ohci, ohci->hc_control, > &ohci->regs->control); > } > - if (command) > + if (command) { > + if (ohci->flags & OHCI_QUIRK_ZFMICRO) > + mdelay(1); > ohci_writel (ohci, command, &ohci->regs->cmdstatus); > - } > + } > + } > } > > > diff -ur linux-2.6.11-rc4.orig/drivers/usb/host/ohci.h > linux-2.6.11-rc4/drivers/usb/host/ohci.h > --- linux-2.6.11-rc4.orig/drivers/usb/host/ohci.h 2005-02-13 > 03:07:50.000000000 +0000 > +++ linux-2.6.11-rc4/drivers/usb/host/ohci.h 2005-02-26 12:46:01.000000000 > +0000 > @@ -396,6 +396,7 @@ > #define OHCI_QUIRK_SUPERIO 0x02 /* natsemi */ > #define OHCI_QUIRK_INITRESET 0x04 /* SiS, OPTi, > ... */ > #define OHCI_BIG_ENDIAN 0x08 /* big endian > HC */ > +#define OHCI_QUIRK_ZFMICRO 0x10 /* Compaq > ZFMicro chipset*/ > // there are also chip quirks/bugs in init logic > > }; > ------------------------------------------------------- SF email is sponsored by - The IT Product Guide Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now. http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click _______________________________________________ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel