On Sunday 27 October 2002 15:32, David Brownell wrote:
> > The problem is all over the place. I've been going over some scsi
> > drivers and realised the scale of the mess, thats why I noticed it in
> > your patch 8)
>
> When I fixed that issue for EHCI, I recall Linus commenting that
> there were no good models to copy/paste ... which is how so many
> drivers get written!  (That, and many drivers just don't ever need
> to cope with Cardbus versions of their hardware.  I'm not sure that
> anyone's ever sold a Cardbus UHCI, for one example.)
>
> So ehci now has an internal handshake() routine that might be helpful,
> at least for drivers using memory cycles (vs i/o cycles) to spin.

This is a fine routine, and quite general (I've included the code at the end
of this message, for reference).  Why don't you move it out of ehci-hcd.c
and make it available to all of the usb subsystem - or all of the kernel for
that matter?

Limitations:
(1) registers are assumed to be 32 bits wide.
(2) failure is assumed to mean all ones.  Is that a general rule in the PCI world?
(3) assumes memory access.  It would be easy to write a version (io_handshake,
original routine -> mem_handshake?) using I/O access, though you would have to
keep track of time differently, since the read can take some time.

Ciao, Duncan.

/*
 * handshake - spin reading hc until handshake completes or fails
 * @ptr: address of hc register to be read
 * @mask: bits to look at in result of read
 * @done: value of those bits when handshake succeeds
 * @usec: timeout in microseconds
 *
 * Returns negative errno, or zero on success
 *
 * Success happens when the "mask" bits have the specified value (hardware
 * handshake done).  There are two failure modes:  "usec" have passed (major
 * hardware flakeout), or the register reads as all-ones (hardware removed).
 *
 * That last failure should_only happen in cases like physical cardbus eject
 * before driver shutdown. But it also seems to be caused by bugs in cardbus
 * bridge shutdown:  shutting down the bridge before the devices using it.
 */
static int handshake (u32 *ptr, u32 mask, u32 done, int usec)
{
        u32     result;

        do {
                result = readl (ptr);
                if (result == ~(u32)0)          /* card removed */
                        return -ENODEV;
                result &= mask;
                if (result == done)
                        return 0;
                udelay (1);
                usec--;
        } while (usec > 0);
        return -ETIMEDOUT;
}


-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to