NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/54289: wd1 fails to be identified properly



Hello,
could you try the attached patch ?
Re-reading the AHCI specs, I noticed we didn't clear the Fis Receive bits
on channel stop, as specified for a reset.

-- 
Manuel Bouyer <bouyer%antioche.eu.org@localhost>
     NetBSD: 26 ans d'experience feront toujours la difference
--
Index: ahcisata_core.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/ahcisata_core.c,v
retrieving revision 1.57
diff -u -p -u -r1.57 ahcisata_core.c
--- ahcisata_core.c	3 Jun 2016 10:34:03 -0000	1.57
+++ ahcisata_core.c	23 Jun 2019 19:07:44 -0000
@@ -664,8 +664,8 @@ ahci_exec_fis(struct ata_channel *chp, i
 				 */
 				return ERROR;
 			}
-			aprint_debug("%s channel %d: error 0x%x sending FIS\n",
-			    AHCINAME(sc), chp->ch_channel, is);
+			aprint_debug("%s channel %d: error 0x%x sending FIS, t %d\n",
+			    AHCINAME(sc), chp->ch_channel, is, timeout);
 			return ERR_DF;
 		}
 		if (flags & AT_WAIT)
@@ -1385,9 +1385,27 @@ ahci_channel_stop(struct ahci_softc *sc,
 		/* XXX controller reset ? */
 		return;
 	}
-
 	if (sc->sc_channel_stop)
 		sc->sc_channel_stop(sc, chp);
+	if ((AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)) & AHCI_P_CMD_FRE) == 0)
+		return;
+
+	AHCI_WRITE(sc, AHCI_P_CMD(chp->ch_channel),
+	    AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)) & ~AHCI_P_CMD_FRE);
+	/* wait 1s for FIS receive to stop */
+	for (i = 0; i <100; i++) {
+		if ((AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)) & AHCI_P_CMD_FR)
+		    == 0)
+			break;
+		if (flags & AT_WAIT)
+			tsleep(&sc, PRIBIO, "ahcistop", mstohz(10));
+		else
+			delay(10000);
+	}
+	if (AHCI_READ(sc, AHCI_P_CMD(chp->ch_channel)) & AHCI_P_CMD_FR) {
+		printf("%s: channel FIS receive wouldn't stop\n", AHCINAME(sc));
+		/* XXX controller reset ? */
+	}
 }
 
 static void


Home | Main Index | Thread Index | Old Index