]> git.kernelconcepts.de Git - karo-tx-linux.git/commit
USB: OHCI: fix endless polling behavior
authorAlan Stern <stern@rowland.harvard.edu>
Fri, 17 Oct 2008 23:10:03 +0000 (23:10 +0000)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 22 Oct 2008 21:21:19 +0000 (14:21 -0700)
commit48e12d72efd753818139a1870ee840ceb1a776e3
tree6d19aac73bb0d5f9a1e0b2d02e2778851469a196
parent5bad3352aa6262a0e4515315060d93d691913399
USB: OHCI: fix endless polling behavior

commit 71b7497c078a97e2afb774ad7c1f8ff5bdda8a60 upstream

This patch (as1149) fixes an obscure problem in OHCI polling.  In the
current code, if the RHSC interrupt status flag turns on at a time
when RHSC interrupts are disabled, it will remain on forever:

The interrupt handler is the only place where RHSC status
gets turned back off;

The interrupt handler won't turn RHSC status off because it
doesn't turn off status flags if the corresponding interrupt
isn't enabled;

RHSC interrupts will never get enabled because
ohci_root_hub_state_changes() doesn't reenable RHSC if RHSC
status is on!

As a result we will continue polling indefinitely instead of reverting
to interrupt-driven operation, and the root hub will not autosuspend.
This particular sequence of events is not at all unusual; in fact
plugging a USB device into an OHCI controller will usually cause it to
occur.

Of course, this is a bug.  The proper thing to do is to turn off RHSC
status just before reading the actual port status values.  That way
either a port status change will be detected (if it occurs before the
status read) or it will turn RHSC back on.  Possibly both, but that
won't hurt anything.

We can still check for systems in which RHSC is totally broken, by
re-reading RHSC after clearing it and before reading the port
statuses.  (This re-read has to be done anyway, to post the earlier
write.)  If RHSC is on but no port-change statuses are set, then we
know that RHSC is broken and we can avoid re-enabling it.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/host/ohci-hub.c