Subject: Re: kern/35049: viaide.c v1.35 + VT8237 + ST3200822AS != OK
To: None <teemu@rinta-aho.org>
From: Manuel Bouyer <bouyer@antioche.eu.org>
List: netbsd-bugs
Date: 11/14/2006 14:29:30
--LQksG6bCIzRHxTLp
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Mon, Nov 13, 2006 at 09:30:01PM +0000, teemu@rinta-aho.org wrote:
> I have a VIA EPIA PD8000E Mini-ITX motherboard with VT8237 SATA controller and two Seagate 7200.7 SATA discs (ST3200822AS).
> 
> 4.0_BETA kernel (Sep 29 2006) works fine, 4.99.3 (Nov 13 2006) does not. The problem seems to be with the new code added in version 1.35 of viaide.c. When booting up the discs are not recognized correctly. Type is "ST506" instead of "ST3200822AS", access is "chs" instead of "LBA48", size is less than half of what it should be etc... And as it doesn't match MBR, kernel doesn't boot.

Looks like the same issue as kern/35008.
Can you try the attached patch ?

-- 
Manuel Bouyer, LIP6, Universite Paris VI.           Manuel.Bouyer@lip6.fr
     NetBSD: 26 ans d'experience feront toujours la difference
--

--LQksG6bCIzRHxTLp
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=diff

Index: wdc.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/wdc.c,v
retrieving revision 1.240
diff -u -u -r1.240 wdc.c
--- wdc.c	25 Oct 2006 20:14:00 -0000	1.240
+++ wdc.c	12 Nov 2006 23:24:14 -0000
@@ -238,7 +238,13 @@
 	bus_space_write_4(wdr->sata_iot, wdr->sata_control, 0, scontrol);
 
 	tsleep(wdr, PRIBIO, "sataup", mstohz(50));
-	sstatus = bus_space_read_4(wdr->sata_iot, wdr->sata_status, 0);
+	/* wait up to 1s for device to come up */
+	for (i = 0; i < 100; i++) {
+		sstatus = bus_space_read_4(wdr->sata_iot, wdr->sata_status, 0);
+		if ((sstatus & SStatus_DET_mask) == SStatus_DET_DEV)
+			break;
+		tsleep(wdr, PRIBIO, "sataup", mstohz(10));
+	}
 
 	switch (sstatus & SStatus_DET_mask) {
 	case SStatus_DET_NODEV:
@@ -286,6 +292,12 @@
 		aprint_normal("%s: port %d: device present, speed: %s\n",
 		    chp->ch_atac->atac_dev.dv_xname, chp->ch_channel,
 		    sata_speed(sstatus));
+		/*
+		 * issue a reset in case only the interface part of the drive
+		 * is up
+		 */
+		if (wdcreset(chp, RESET_SLEEP) != 0)
+			chp->ch_drive[0].drive_flags = 0;
 		break;
 
 	default:

--LQksG6bCIzRHxTLp--