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