• Tejun Heo's avatar
    libata-sff: fix spurious IRQ handling · 332ac7ff
    Tejun Heo authored
    Commit 27943620 introduced spurious
    IRQ handling but it has a race condition where valid completion can be
    lost while trying to clear spurious IRQ leading to occassional command
    timeouts.
    
    This patch improves SFF interrupt handler such that
    
    1. Once BMDMA HSM is stopped, the condition is never considered
       spurious.  As there's no way to resume stopped BMDMA HSM, if device
       status doesn't agree with BMDMA status, the only way out is
       aborting the command (otherwise, it will just end up timing out).
    
    2. ap->ops->sff_check_status() can be safely called to clear spurious
       device IRQ as it atomically returns completion status but BMDMA IRQ
       status can't be cleared in safe way if command is in flight.  After
       a spurious IRQ, call ap->ops->sff_irq_clear() only if the
       respective device is idle and retry completion if
       sff_check_status() indicates command completion.
    
    Please note that ata_piix uses bmdma_status for sff_irq_check() and #2
    won't weaken spurious IRQ handling even with in-flight command because
    if bmdma_status indicates IRQ pending but device status is not on
    spurious check, the next IRQ handler invocation will abort the command
    due to #1.
    
    This fixes bko#15537.
    
       https://bugzilla.kernel.org/show_bug.cgi?id=15537Signed-off-by: default avatarTejun Heo <tj@kernel.org>
    Cc: Andrew Benton <b3nton@gmail.com>
    Cc: Petr Uzel <petr.uzel@centrum.cz>
    Cc: Rafael J. Wysocki <rjw@sisk.pl>
    Signed-off-by: default avatarJeff Garzik <jgarzik@redhat.com>
    332ac7ff
libata-sff.c 79.3 KB