]> git.baikalelectronics.ru Git - kernel.git/commit
libata-sff: fix spurious IRQ handling
authorTejun Heo <tj@kernel.org>
Tue, 23 Mar 2010 03:24:08 +0000 (12:24 +0900)
committerJeff Garzik <jgarzik@redhat.com>
Tue, 23 Mar 2010 13:39:08 +0000 (09:39 -0400)
commit3703391db79f6a527cc5673e56be8abe676741d1
treefae900efeabe1b0d9ebc170d14170d31f3b8cbf4
parent5c4c527b91557e2ee21220f77dff0851d9d554e1
libata-sff: fix spurious IRQ handling

Commit fb25155bff987153405a4f2d59f4ef62ea338b9e 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=15537

Signed-off-by: Tejun 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: Jeff Garzik <jgarzik@redhat.com>
drivers/ata/libata-sff.c