diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-03-26 11:20:23 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-03-26 11:20:23 -0700 |
commit | 0384e2959127a56d0640505d004d8dd92f9c29f5 (patch) | |
tree | fa2a8d6829ed61fa561deab03a259e25b7b49865 /drivers/ata/libata-eh.c | |
parent | 61a091827e273650b39eb87c799a6d260913fa0b (diff) | |
parent | c96f1732e25362d10ee7bcac1df8412a2e6b7d23 (diff) | |
download | kernel_samsung_smdk4412-0384e2959127a56d0640505d004d8dd92f9c29f5.zip kernel_samsung_smdk4412-0384e2959127a56d0640505d004d8dd92f9c29f5.tar.gz kernel_samsung_smdk4412-0384e2959127a56d0640505d004d8dd92f9c29f5.tar.bz2 |
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev: (35 commits)
[libata] Improve timeout handling
[libata] Drain data on errors
pata_sc1200: Activate secondary channel
pata_artop: Serializing support
[libata] ahci: correct enclosure LED state save
[libata] More robust parsing for IDENTIFY DEVICE multi_count field
sata_mv: fix LED blinking for SoC+NCQ
sata_mv: optimize IRQ coalescing for 8-port chips
sata_mv: implement IRQ coalescing (v2)
sata_mv: cosmetic preparations for IRQ coalescing
pata-rb532-cf: platform_get_irq() fix ignored failure
pata_efar: fix *dma_mask
pata_radisys: fix mwdma_mask to exclude mwdma0
[libata] convert drivers to use ata.h mode mask defines
include/linux/ata.h: add some more transfer masks
ahci: Blacklist HP Compaq 6720s that spins off disks during ACPI power off
[libata] sata_mv: Implement direct FIS transmission via mv_qc_issue_fis().
[libata] Export ata_pio_queue_task() so that it can be used from sata_mv.
[libata] sata_mv: Add a new mv_sff_check_status() function to sata_mv.
[libata] sata_mv: Tighten up interrupt masking in mv_qc_issue()
...
Diffstat (limited to 'drivers/ata/libata-eh.c')
-rw-r--r-- | drivers/ata/libata-eh.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index ea89091..0183131 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -547,7 +547,7 @@ void ata_scsi_error(struct Scsi_Host *host) /* For new EH, all qcs are finished in one of three ways - * normal completion, error completion, and SCSI timeout. - * Both cmpletions can race against SCSI timeout. When normal + * Both completions can race against SCSI timeout. When normal * completion wins, the qc never reaches EH. When error * completion wins, the qc has ATA_QCFLAG_FAILED set. * @@ -562,7 +562,19 @@ void ata_scsi_error(struct Scsi_Host *host) int nr_timedout = 0; spin_lock_irqsave(ap->lock, flags); - + + /* This must occur under the ap->lock as we don't want + a polled recovery to race the real interrupt handler + + The lost_interrupt handler checks for any completed but + non-notified command and completes much like an IRQ handler. + + We then fall into the error recovery code which will treat + this as if normal completion won the race */ + + if (ap->ops->lost_interrupt) + ap->ops->lost_interrupt(ap); + list_for_each_entry_safe(scmd, tmp, &host->eh_cmd_q, eh_entry) { struct ata_queued_cmd *qc; @@ -606,6 +618,9 @@ void ata_scsi_error(struct Scsi_Host *host) ap->eh_tries = ATA_EH_MAX_TRIES; } else spin_unlock_wait(ap->lock); + + /* If we timed raced normal completion and there is nothing to + recover nr_timedout == 0 why exactly are we doing error recovery ? */ repeat: /* invoke error handler */ |