• Adam Goldman's avatar
    firewire: ohci: mask bus reset interrupts between ISR and bottom half · 752e3c53
    Adam Goldman authored
    In the FireWire OHCI interrupt handler, if a bus reset interrupt has
    occurred, mask bus reset interrupts until bus_reset_work has serviced and
    cleared the interrupt.
    
    Normally, we always leave bus reset interrupts masked. We infer the bus
    reset from the self-ID interrupt that happens shortly thereafter. A
    scenario where we unmask bus reset interrupts was introduced in 2008 in
    a007bb85: If
    OHCI_PARAM_DEBUG_BUSRESETS (8) is set in the debug parameter bitmask, we
    will unmask bus reset interrupts so we can log them.
    
    irq_handler logs the bus reset interrupt. However, we can't clear the bus
    reset event flag in irq_handler, because we won't service the event until
    later. irq_handler exits with the event flag still set. If the
    corresponding interrupt is still unmasked, the first bus reset will
    usually freeze the system due to irq_handler being called again each
    time it exits. This freeze can be reproduced by loading firewire_ohci
    with "modprobe firewire_ohci debug=-1" (to enable all debugging output).
    Apparently there are also some cases where bus_reset_work will get called
    soon enough to clear the event, and operation will continue normally.
    
    This freeze was first reported a few months after a007bb85 was committed,
    but until now it was never fixed. The debug level could safely be set
    to -1 through sysfs after the module was loaded, but this would be
    ineffectual in logging bus reset interrupts since they were only
    unmasked during initialization.
    
    irq_handler will now leave the event flag set but mask bus reset
    interrupts, so irq_handler won't be called again and there will be no
    freeze. If OHCI_PARAM_DEBUG_BUSRESETS is enabled, bus_reset_work will
    unmask the interrupt after servicing the event, so future interrupts
    will be caught as desired.
    
    As a side effect to this change, OHCI_PARAM_DEBUG_BUSRESETS can now be
    enabled through sysfs in addition to during initial module loading.
    However, when enabled through sysfs, logging of bus reset interrupts will
    be effective only starting with the second bus reset, after
    bus_reset_work has executed.
    Signed-off-by: default avatarAdam Goldman <adamg@pobox.com>
    Signed-off-by: default avatarTakashi Sakamoto <o-takashi@sakamocchi.jp>
    752e3c53
ohci.c 106 KB