summary refs log tree commit diff
path: root/drivers/ata/sata_sil.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/sata_sil.c')
-rw-r--r--drivers/ata/sata_sil.c29
1 files changed, 17 insertions, 12 deletions
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c
index 4e6e381279cc..025622b14efb 100644
--- a/drivers/ata/sata_sil.c
+++ b/drivers/ata/sata_sil.c
@@ -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;