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>