summaryrefslogtreecommitdiff
path: root/sys/arch/i386/stand/libsa/biosdev.c
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>1997-04-15 06:25:19 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>1997-04-15 06:25:19 +0000
commiteb2063a11dd96d611a925e45d8e1c06eb1b8e290 (patch)
tree81d4fc45ad1dd6f0f4cc8a4ee04469b14f60e5ca /sys/arch/i386/stand/libsa/biosdev.c
parent5424050ea1a8211aec2f6e8859e71771545371c5 (diff)
do bounce-buffering to avoid DMA overrun
somebody, test it!
Diffstat (limited to 'sys/arch/i386/stand/libsa/biosdev.c')
-rw-r--r--sys/arch/i386/stand/libsa/biosdev.c51
1 files changed, 37 insertions, 14 deletions
diff --git a/sys/arch/i386/stand/libsa/biosdev.c b/sys/arch/i386/stand/libsa/biosdev.c
index 3c40b8ef344..a73ffd9ead4 100644
--- a/sys/arch/i386/stand/libsa/biosdev.c
+++ b/sys/arch/i386/stand/libsa/biosdev.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: biosdev.c,v 1.5 1997/04/09 08:39:15 mickey Exp $ */
+/* $OpenBSD: biosdev.c,v 1.6 1997/04/15 06:25:18 mickey Exp $ */
/*
* Copyright (c) 1996 Michael Shalayeff
@@ -279,7 +279,8 @@ biosstrategy(void *devdata, int rw,
for (i = 0; error == 0 && i < nsect;
i += n, blk += n, buf += n * DEV_BSIZE) {
- register int cyl, hd, sect;
+ register int cyl, hd, sect, j;
+ void *bb;
btochs(blk, cyl, hd, sect,
BIOSNHEADS(bd->dinfo), BIOSNSECTS(bd->dinfo));
@@ -287,28 +288,50 @@ biosstrategy(void *devdata, int rw,
n = BIOSNSECTS(bd->dinfo) - sect;
else
n = nsect - i;
+
+ /* use a bounce buffer to not to cross 64k DMA boundary */
+ if ((((u_int32_t)buf) & ~0xffff) !=
+ (((u_int32_t)buf + n * DEV_BSIZE) & ~0xffff)) {
+ bb = alloc(n * DEV_BSIZE);
+ if (rw != F_READ)
+ bcopy (buf, bb, n * DEV_BSIZE);
+ } else
+ bb = buf;
#ifdef BIOS_DEBUG
if (debug)
- printf(" (%d,%d,%d,%d)@%p", cyl, hd, sect, n, buf);
+ printf(" (%d,%d,%d,%d)@%p", cyl, hd, sect, n, bb);
#endif
- if (rw == F_READ)
- error = biosread (bd->biosdev, cyl, hd, sect, n, buf);
- else
- error = bioswrite(bd->biosdev, cyl, hd, sect, n, buf);
-
- if (error != 0) {
- for (p = bd_errors; p < &bd_errors[bd_nents] &&
- p->bd_id != error; p++);
-
- if (error == 0x11) /* ECC corrected */
+ for (error = 1, j = 5; error && j--;) {
+ error = (rw == F_READ)?
+ biosread (bd->biosdev, cyl, hd, sect, n, bb)
+ : bioswrite(bd->biosdev, cyl, hd, sect, n, bb);
+
+ switch (error) {
+ case 0x06: /* disk changed */
+ printf ("disk changed\n");
+ default:
+ continue;
+
+ case 0x11: /* ECC corrected */
error = 0;
+ break;
+ }
+ }
+
+ if (bb != buf) {
+ if (rw == F_READ)
+ bcopy (bb, buf, n * DEV_BSIZE);
+ free (bb, n * DEV_BSIZE);
}
}
#ifdef BIOS_DEBUG
if (debug) {
- if (error != 0)
+ if (error != 0) {
+ for (p = bd_errors; p < &bd_errors[bd_nents] &&
+ p->bd_id != error; p++);
printf("=%x(%s)", p->bd_id, p->msg);
+ }
putchar('\n');
}
#endif