Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

USB: OHCI: fix endless polling behavior

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>
Cc: stable <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Alan Stern and committed by
Greg Kroah-Hartman
71b7497c 8b6346ec

+32 -19
+32 -19
drivers/usb/host/ohci-hub.c
··· 359 359 360 360 /* Carry out polling-, autostop-, and autoresume-related state changes */ 361 361 static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed, 362 - int any_connected) 362 + int any_connected, int rhsc_status) 363 363 { 364 364 int poll_rh = 1; 365 - int rhsc_status, rhsc_enable; 365 + int rhsc_enable; 366 366 367 367 /* Some broken controllers never turn off RHCS in the interrupt 368 368 * status register. For their sake we won't re-enable RHSC 369 369 * interrupts if the interrupt bit is already active. 370 370 */ 371 - rhsc_status = ohci_readl(ohci, &ohci->regs->intrstatus) & 372 - OHCI_INTR_RHSC; 373 371 rhsc_enable = ohci_readl(ohci, &ohci->regs->intrenable) & 374 372 OHCI_INTR_RHSC; 375 373 ··· 419 421 ohci_rh_resume(ohci); 420 422 else 421 423 usb_hcd_resume_root_hub(ohci_to_hcd(ohci)); 424 + 425 + /* If remote wakeup is disabled, stop polling */ 426 + } else if (!ohci->autostop && 427 + !ohci_to_hcd(ohci)->self.root_hub-> 428 + do_remote_wakeup) { 429 + poll_rh = 0; 430 + 422 431 } else { 423 - if (!rhsc_enable && !rhsc_status && (ohci->autostop || 424 - ohci_to_hcd(ohci)->self.root_hub-> 425 - do_remote_wakeup)) { 432 + /* If no status changes are pending, 433 + * enable RHSC interrupts 434 + */ 435 + if (!rhsc_enable && !rhsc_status) { 426 436 rhsc_enable = OHCI_INTR_RHSC; 427 437 ohci_writel(ohci, rhsc_enable, 428 438 &ohci->regs->intrenable); 429 439 } 440 + /* Keep polling until RHSC is enabled */ 430 441 if (rhsc_enable) 431 442 poll_rh = 0; 432 443 } ··· 455 448 * autostop isn't used when CONFIG_PM is turned off. 456 449 */ 457 450 static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed, 458 - int any_connected) 451 + int any_connected, int rhsc_status) 459 452 { 460 - int rhsc_status; 461 - 462 453 /* If RHSC is enabled, don't poll */ 463 454 if (ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC) 464 455 return 0; 465 456 466 - /* If no status changes are pending, enable RHSC interrupts */ 467 - rhsc_status = ohci_readl(ohci, &ohci->regs->intrstatus) & 468 - OHCI_INTR_RHSC; 469 - if (!changed && !rhsc_status) { 470 - ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable); 471 - return 0; 472 - } 473 - return 1; 457 + /* If status changes are pending, continue polling. 458 + * Conversely, if no status changes are pending but the RHSC 459 + * status bit was set, then RHSC may be broken so continue polling. 460 + */ 461 + if (changed || rhsc_status) 462 + return 1; 463 + 464 + /* It's safe to re-enable RHSC interrupts */ 465 + ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable); 466 + return 0; 474 467 } 475 468 476 469 #endif /* CONFIG_PM */ ··· 485 478 struct ohci_hcd *ohci = hcd_to_ohci (hcd); 486 479 int i, changed = 0, length = 1; 487 480 int any_connected = 0; 481 + int rhsc_status; 488 482 unsigned long flags; 489 483 490 484 spin_lock_irqsave (&ohci->lock, flags); ··· 511 503 length++; 512 504 } 513 505 506 + /* Clear the RHSC status flag before reading the port statuses */ 507 + ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrstatus); 508 + rhsc_status = ohci_readl(ohci, &ohci->regs->intrstatus) & 509 + OHCI_INTR_RHSC; 510 + 514 511 /* look at each port */ 515 512 for (i = 0; i < ohci->num_ports; i++) { 516 513 u32 status = roothub_portstatus (ohci, i); ··· 534 521 } 535 522 536 523 hcd->poll_rh = ohci_root_hub_state_changes(ohci, changed, 537 - any_connected); 524 + any_connected, rhsc_status); 538 525 539 526 done: 540 527 spin_unlock_irqrestore (&ohci->lock, flags);