Patch "firewire: ohci: mask bus reset interrupts between ISR and bottom half" has been added to the 5.4-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    firewire: ohci: mask bus reset interrupts between ISR and bottom half

to the 5.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     firewire-ohci-mask-bus-reset-interrupts-between-isr-.patch
and it can be found in the queue-5.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 76f0dd9bf79af92647068f8e5caa28a1085af55c
Author: Adam Goldman <adamg@xxxxxxxxx>
Date:   Mon Mar 25 07:38:41 2024 +0900

    firewire: ohci: mask bus reset interrupts between ISR and bottom half
    
    [ Upstream commit 752e3c53de0fa3b7d817a83050b6699b8e9c6ec9 ]
    
    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
    a007bb857e0b26f5d8b73c2ff90782d9c0972620: 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: Adam Goldman <adamg@xxxxxxxxx>
    Signed-off-by: Takashi Sakamoto <o-takashi@xxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 6603f13f5de9b..2db5448c4293a 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -2053,6 +2053,8 @@ static void bus_reset_work(struct work_struct *work)
 
 	ohci->generation = generation;
 	reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset);
+	if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS)
+		reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_busReset);
 
 	if (ohci->quirks & QUIRK_RESET_PACKET)
 		ohci->request_generation = generation;
@@ -2119,12 +2121,14 @@ static irqreturn_t irq_handler(int irq, void *data)
 		return IRQ_NONE;
 
 	/*
-	 * busReset and postedWriteErr must not be cleared yet
+	 * busReset and postedWriteErr events must not be cleared yet
 	 * (OHCI 1.1 clauses 7.2.3.2 and 13.2.8.1)
 	 */
 	reg_write(ohci, OHCI1394_IntEventClear,
 		  event & ~(OHCI1394_busReset | OHCI1394_postedWriteErr));
 	log_irqs(ohci, event);
+	if (event & OHCI1394_busReset)
+		reg_write(ohci, OHCI1394_IntMaskClear, OHCI1394_busReset);
 
 	if (event & OHCI1394_selfIDComplete)
 		queue_work(selfid_workqueue, &ohci->bus_reset_work);




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux