From: mickey Date: Tue, 15 Apr 1997 06:25:18 +0000 (+0000) Subject: do bounce-buffering to avoid DMA overrun X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=78eb4a0657accaa7a3da18e6eec2e7a7cb248cc5;p=openbsd do bounce-buffering to avoid DMA overrun somebody, test it! --- 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