Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 27 Jan 1995 23:25:06 +0300
From:      vak@cronyx.ru
To:        hackers@FreeBSD.org
Subject:   [patch 2.0R] wd.c: 32-bit mode added
Message-ID:  <GGYQLAlS9K@arch.kiae.su>

next in thread | raw e-mail | index | archive | help
Hi,

Did anybode there ever try a VLBus IDE adapter?
Theu are so cheap ($18), that I decided to buy a one.
I tested it under MSDOS and FreeBSD on 486DX2/66, using 
the disk Caviar WDC AC2420H, and here are the results:

		      IDE VLB         IDE ISA
------------------------------------------------
    DOS: Checkit        1205            847
    DOS: Sysinfo        1556            1089
FreeBSD: Iozone         1675            1143

All numbers are measured in kilobytes per second.
IDE ISA is a standard milti-i/o card.
Under MSDOS for IDE VLB was used the special driver HTIDE,
delivered with the board.
Under FreeBSD was used the wd driver with 32-bit mode patch applied.
Iozone parameters were: filesize = 8 megabytes, blocksize = 4096 bytes
(there were 6 Meg of RAM on the test machine).

It seems that VLB IDE is quite useful: 50% disk speed increase.

This patch adds 32-bit i/o mode to wd driver.

Regards,
Serge

--- wd20.c	Fri Nov 18 14:27:41 1994
+++ wd.c	Fri Jan 27 22:48:50 1995
@@ -218,6 +218,7 @@
 #define	DKFL_BADSECT	0x00020	/* has a bad144 badsector table */
 #define	DKFL_WRITEPROT	0x00040	/* manual unit write protect */
 #define	DKFL_LABELLING	0x00080	/* readdisklabel() in progress */
+#define	DKFL_32BIT	0x00100	/* use 32-bit i/o mode */
 	struct wdparams dk_params; /* ESDI/IDE drive/controller parameters */
 	int	dk_dkunit;	/* number of statistics purposes */
 	struct disklabel dk_dd;	/* device configuration data */
@@ -397,14 +398,17 @@
 		    char buf[sizeof(du->dk_params.wdp_model) + 1];
 		    bcopy(du->dk_params.wdp_model, buf, sizeof(buf)-1);
 		    buf[sizeof(buf)-1] = '\0';
-		    printf("wdc%d: unit %d (wd%d): <%s>\n",
+		    printf("wdc%d: unit %d (wd%d): <%s>",
 			dvp->id_unit, unit, lunit, buf);
+		    if (du->dk_flags & DKFL_32BIT)
+			printf(", 32-bit data path");
+		    printf("\n");
 		    if (du->dk_params.wdp_heads == 0 && 
 			du->dk_dd.d_secperunit > 100)
-			printf("wd%d: size unknown, using BIOS values\n",
+			printf("wd%d: size unknown, using BIOS values: ",
 			    lunit);
 		    else if (du->dk_params.wdp_heads == 0)
-			printf("wd%d: size unknown\n", lunit);
+			printf("wd%d: size unknown: ", lunit);
 		    else
 			printf("wd%d: %luMB (%lu total sec), ",
 				lunit,
@@ -759,9 +763,14 @@
 	}
 
 	/* then send it! */
-	outsw(du->dk_port + wd_data,
-	      (void *)((int)bp->b_un.b_addr + du->dk_skip * DEV_BSIZE),
-	      DEV_BSIZE / sizeof(short));
+	if (du->dk_flags & DKFL_32BIT)
+		outsl(du->dk_port + wd_data,
+		      (void *)((int)bp->b_un.b_addr + du->dk_skip * DEV_BSIZE),
+		      DEV_BSIZE / sizeof(long));
+	else
+		outsw(du->dk_port + wd_data,
+		      (void *)((int)bp->b_un.b_addr + du->dk_skip * DEV_BSIZE),
+		      DEV_BSIZE / sizeof(short));
 	du->dk_bc -= DEV_BSIZE;
 }
 
@@ -844,10 +853,6 @@
 	 */
 	if (((bp->b_flags & (B_READ | B_ERROR)) == B_READ)
 	    && wdtab[unit].b_active) {
-		int	chk, dummy;
-
-		chk = min(DEV_BSIZE / sizeof(short), du->dk_bc / sizeof(short));
-
 		/* ready to receive data? */
 		if ((du->dk_status & (WDCS_READY | WDCS_SEEKCMPLT | WDCS_DRQ))
 		    != (WDCS_READY | WDCS_SEEKCMPLT | WDCS_DRQ))
@@ -858,14 +863,15 @@
 		}
 
 		/* suck in data */
-		insw(du->dk_port + wd_data,
-		     (void *)((int)bp->b_un.b_addr + du->dk_skip * DEV_BSIZE),
-				chk);
-		du->dk_bc -= chk * sizeof(short);
-
-		/* XXX for obsolete fractional sector reads. */
-		while (chk++ < DEV_BSIZE / sizeof(short))
-			insw(du->dk_port + wd_data, &dummy, 1);
+		if (du->dk_flags & DKFL_32BIT)
+			insl(du->dk_port + wd_data,
+				bp->b_un.b_addr + du->dk_skip * DEV_BSIZE,
+				DEV_BSIZE / sizeof(long));
+		else
+			insw(du->dk_port + wd_data,
+				bp->b_un.b_addr + du->dk_skip * DEV_BSIZE,
+				DEV_BSIZE / sizeof(short));
+		du->dk_bc -= DEV_BSIZE;
 	}
 
 	wdxfer[du->dk_lunit]++;
@@ -1247,9 +1253,9 @@
 wdgetctlr(struct disk *du)
 {
 	int	i;
-	char	tb[DEV_BSIZE];
+	char    tb[DEV_BSIZE], tb2[DEV_BSIZE];
 	struct wdparams *wp;
-
+again:
 	if (wdcommand(du, 0, 0, 0, 0, WDCC_READP) != 0
 	    || wdwait(du, WDCS_READY | WDCS_SEEKCMPLT | WDCS_DRQ, TIMEOUT) != 0) {
 		/* XXX need to check error status after final transfer. */
@@ -1328,7 +1334,25 @@
 
 	/* obtain parameters */
 	wp = &du->dk_params;
-	insw(du->dk_port + wd_data, tb, sizeof(tb) / sizeof(short));
+	if (du->dk_flags & DKFL_32BIT)
+		insl(du->dk_port + wd_data, tb, sizeof(tb) / sizeof(long));
+	else
+		insw(du->dk_port + wd_data, tb, sizeof(tb) / sizeof(short));
+
+	/* try 32-bit data path (VLB IDE controller) */
+	if (! (du->dk_flags & DKFL_32BIT)) {
+		bcopy(tb, tb2, sizeof(struct wdparams));
+		du->dk_flags |= DKFL_32BIT;
+		goto again;
+	}
+
+	/* check that we really have 32-bit controller */
+	if (bcmp (tb, tb2, sizeof(struct wdparams)) != 0) {
+		/* test failed, use 16-bit i/o mode */
+		bcopy(tb2, tb, sizeof(struct wdparams));
+		du->dk_flags &= ~DKFL_32BIT;
+	}
+
 	bcopy(tb, wp, sizeof(struct wdparams));
 
 	/* shuffle string byte order */
@@ -1745,9 +1769,14 @@
 					"wddump: timeout waiting for DRQ");
 				return (EIO);
 			}
-			outsw(du->dk_port + wd_data,
-			      CADDR1 + ((int)addr & (NBPG - 1)),
-			      DEV_BSIZE / sizeof(short));
+			if (du->dk_flags & DKFL_32BIT)
+				outsl(du->dk_port + wd_data,
+				      CADDR1 + ((int)addr & (NBPG - 1)),
+				      DEV_BSIZE / sizeof(long));
+			else
+				outsw(du->dk_port + wd_data,
+				      CADDR1 + ((int)addr & (NBPG - 1)),
+				      DEV_BSIZE / sizeof(short));
 			addr += DEV_BSIZE;
 			if ((unsigned)addr % (1024 * 1024) == 0)
 				printf("%ld ", num / (1024 * 1024 / DEV_BSIZE));



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?GGYQLAlS9K>