diff options
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/sata_sil.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c index a7e99a1def2..bc9f918a7f2 100644 --- a/drivers/scsi/sata_sil.c +++ b/drivers/scsi/sata_sil.c @@ -344,7 +344,25 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2) u8 status; if (unlikely(bmdma2 & SIL_DMA_SATA_IRQ)) { - ata_ehi_hotplugged(&ap->eh_info); + u32 serror; + + /* SIEN doesn't mask SATA IRQs on some 3112s. Those + * controllers continue to assert IRQ as long as + * SError bits are pending. Clear SError immediately. + */ + serror = sil_scr_read(ap, SCR_ERROR); + 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. + */ + if (!(ap->flags & ATA_FLAG_FROZEN)) { + ata_ehi_hotplugged(&ap->eh_info); + ap->eh_info.serror |= serror; + } + goto freeze; } |