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

Reply via email to