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?
As you noticed, it's a general model but the implementation has a few
limitations that make me want anyone adopting it to look and think.
Plus, at a few dozen bytes (?) the size doesn't make me worry.

Of USB drivers, only ohci might directly use this code ... and that's
currently got different fixes for the most pressing "cardbus eject"
problems.  (And less need for a spin/handshake too.)


Limitations:
(1) registers are assumed to be 32 bits wide.
Commonly but not universally true.

(2) failure is assumed to mean all ones.  Is that a general rule in the PCI world?
Seems to be so in Cardbus, as Linus observed.  Maybe Greg or Alan can
comment about the various other hotpluggable busses.

(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.
See -- to use this with UHCI, you're doing the adapt+think step!  :)

Glad it was helpful.

- Dave


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