Subject: kern/25366: wdc does not know about flushcache_ext
To: None <gnats-bugs@gnats.NetBSD.org>
From: None <christos@zoulas.com>
List: netbsd-bugs
Date: 04/28/2004 10:40:07
>Number:         25366
>Category:       kern
>Synopsis:       wdc does not know about flushcache_ext
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    kern-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Wed Apr 28 14:41:00 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator:     Christos Zoulas
>Release:        NetBSD 2.0E
>Organization:
	Galvanized Software, Inc.
>Environment:
NetBSD mx-temp.twosigma.com 2.0E NetBSD 2.0E (TWOSIGMA.MP) #3: Wed Apr 28 10:13:43 EDT 2004  christos@mx-temp.twosigma.com:/usr/src/sys/arch/i386/compile/TWOSIGMA.MP i386
Architecture: i386
Machine: i386
>Description:
	I have the following wdc:

piixide0 at pci0 dev 31 function 1
piixide0: Intel 82801CA IDE Controller (ICH3) (rev. 0x02)
piixide0: bus-master DMA support present
piixide0: primary channel wired to compatibility mode
piixide0: primary channel interrupting at ioapic0 pin 14 (irq 14)
atabus0 at piixide0 channel 0
piixide0: secondary channel wired to compatibility mode
piixide0: secondary channel interrupting at ioapic0 pin 15 (irq 15)
atabus1 at piixide0 channel 1

	And the following wd's:
wd0 at atabus0 drive 0: <WDC WD400BB-00DKA0>
wd0: drive supports 16-sector PIO transfers, LBA48 addressing
wd0: 38166 MB, 77545 cyl, 16 head, 63 sec, 512 bytes/sect x 78165360 sectors
wd0: 32-bit data port
wd0: drive supports PIO mode 4, DMA mode 2, Ultra-DMA mode 5 (Ultra/100)
wd0(piixide0:0:0): using PIO mode 4, Ultra-DMA mode 5 (Ultra/100) (using DMA data transfers)
atapibus0 at atabus1: 2 targets
wd1 at atabus1 drive 0: <WDC WD400BB-00FRA0>
wd1: drive supports 16-sector PIO transfers, LBA48 addressing
wd1: 38166 MB, 77545 cyl, 16 head, 63 sec, 512 bytes/sect x 78165360 sectors
wd1: 32-bit data port
wd1: drive supports PIO mode 4, DMA mode 2, Ultra-DMA mode 5 (Ultra/100)
wd1(piixide0:1:0): using PIO mode 4, Ultra-DMA mode 5 (Ultra/100) (using DMA data transfers)

When I reboot I get:
UP kernel: flush cache command didn't complete
MP kernel: panics with polled command aborted or something.

According to ATA application notes, if the controller/drive combination
support flushcache_ext and lba48, then flushcache_ext should be used instead
of flushcache in all cases.

>How-To-Repeat:
	setup raidframe on the above disks, and reboot while parity is
	rebuilding
>Fix:

Index: atareg.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ata/atareg.h,v
retrieving revision 1.17
diff -u -u -r1.17 atareg.h
--- atareg.h	14 Mar 2004 20:11:24 -0000	1.17
+++ atareg.h	28 Apr 2004 14:27:43 -0000
@@ -120,6 +120,7 @@
 #define	WDCC_UNLOCK		0xdf	/* unlock drawer */
 
 #define	WDCC_FLUSHCACHE		0xe7	/* Flush cache */
+#define	WDCC_FLUSHCACHE_EXT	0xea	/* Flush cache ext */
 #define	WDCC_IDENTIFY		0xec	/* read parameters from controller */
 #define	SET_FEATURES		0xef	/* set features */
 
Index: wd.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ata/wd.c,v
retrieving revision 1.274
diff -u -u -r1.274 wd.c
--- wd.c	28 Feb 2004 06:28:47 -0000	1.274
+++ wd.c	28 Apr 2004 14:27:44 -0000
@@ -327,8 +327,11 @@
 	    wd->sc_dev.dv_xname, wd->sc_multi);
 
 	/* 48-bit LBA addressing */
-	if ((wd->sc_params.atap_cmd2_en & ATA_CMD2_LBA48) != 0)
+	if ((wd->sc_params.atap_cmd2_en & ATA_CMD2_LBA48) != 0) {
 		wd->sc_flags |= WDF_LBA48;
+		if ((wd->sc_params.atap_cmd2_en & ATA_CMD2_FCE) != 0)
+			wd->sc_flags |= WDF_FCE;
+	}
 
 	/* Prior to ATA-4, LBA was optional. */
 	if ((wd->sc_params.atap_capabilities1 & WDC_CAP_LBA) != 0)
@@ -1651,7 +1654,8 @@
 	if (wd->drvp->ata_vers < 4) /* WDCC_FLUSHCACHE is here since ATA-4 */
 		return;
 	memset(&wdc_c, 0, sizeof(struct wdc_command));
-	wdc_c.r_command = WDCC_FLUSHCACHE;
+	wdc_c.r_command = (wd->sc_flags & WDF_FCE) ?
+	    WDCC_FLUSHCACHE_EXT : WDCC_FLUSHCACHE;
 	wdc_c.r_st_bmask = WDCS_DRDY;
 	wdc_c.r_st_pmask = WDCS_DRDY;
 	wdc_c.flags = flags;
Index: wdvar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ata/wdvar.h,v
retrieving revision 1.26
diff -u -u -r1.26 wdvar.h
--- wdvar.h	14 Dec 2003 05:38:20 -0000	1.26
+++ wdvar.h	28 Apr 2004 14:27:44 -0000
@@ -59,6 +59,7 @@
 #define WDF_LBA		0x040 /* using LBA mode */
 #define WDF_KLABEL	0x080 /* retain label after 'full' close */
 #define WDF_LBA48	0x100 /* using 48-bit LBA mode */
+#define WDF_FCE		0x200 /* using flush cache ext */
 	u_int64_t sc_capacity;
 	int cyl; /* actual drive parameters */
 	int heads;
>Release-Note:
>Audit-Trail:
>Unformatted: