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>
