mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 04:18:39 +08:00
sata_sil: fix spurious IRQ handling
Interestingly, sata_sil raises spurious interrupts if it's coupled with Sil SATA_PATA bridge. Currently, sata_sil interrupt handler is strict about spurious interrupts and freezes the port when it occurs. This patch makes it more forgiving. * On SATA PHY event interrupt, serror value is checked to see whether it really is PHYRDY CHG event. If not, SATA PHY event interrupt is ignored. * If ATA interrupt occurs while no command is in progress, it's cleared and ignored. This fixes bugzilla bug 9505. http://bugzilla.kernel.org/show_bug.cgi?id=9505 Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
parent
2cc3a8f6ac
commit
8cf32ac657
@ -390,23 +390,28 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
|
||||
sil_scr_read(ap, SCR_ERROR, &serror);
|
||||
sil_scr_write(ap, SCR_ERROR, serror);
|
||||
|
||||
/* Trigger hotplug and accumulate SError only if the
|
||||
* port isn't already frozen. Otherwise, PHY events
|
||||
* during hardreset makes controllers with broken SIEN
|
||||
* repeat probing needlessly.
|
||||
/* Sometimes spurious interrupts occur, double check
|
||||
* it's PHYRDY CHG.
|
||||
*/
|
||||
if (!(ap->pflags & ATA_PFLAG_FROZEN)) {
|
||||
ata_ehi_hotplugged(&ap->link.eh_info);
|
||||
ap->link.eh_info.serror |= serror;
|
||||
if (serror & SERR_PHYRDY_CHG) {
|
||||
/* Trigger hotplug and accumulate SError only
|
||||
* if the port isn't already frozen.
|
||||
* Otherwise, PHY events during hardreset
|
||||
* makes controllers with broken SIEN repeat
|
||||
* probing needlessly.
|
||||
*/
|
||||
if (!(ap->pflags & ATA_PFLAG_FROZEN)) {
|
||||
ata_ehi_hotplugged(&ap->link.eh_info);
|
||||
ap->link.eh_info.serror |= serror;
|
||||
}
|
||||
goto freeze;
|
||||
}
|
||||
|
||||
goto freeze;
|
||||
if (!(bmdma2 & SIL_DMA_COMPLETE))
|
||||
return;
|
||||
}
|
||||
|
||||
if (unlikely(!qc))
|
||||
goto freeze;
|
||||
|
||||
if (unlikely(qc->tf.flags & ATA_TFLAG_POLLING)) {
|
||||
if (unlikely(!qc || (qc->tf.flags & ATA_TFLAG_POLLING))) {
|
||||
/* this sometimes happens, just clear IRQ */
|
||||
ata_chk_status(ap);
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user