Deleted Added
full compact
biosdisk.c (39473) biosdisk.c (39662)
1/*-
2 * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
1/*-
2 * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $Id: biosdisk.c,v 1.4 1998/09/18 02:02:33 msmith Exp $
26 * $Id: biosdisk.c,v 1.5 1998/09/19 01:33:29 msmith Exp $
27 */
28
29/*
30 * BIOS disk device handling.
31 *
32 * Ideas and algorithms from:
33 *
34 * - NetBSD libi386/biosdisk.c

--- 357 unchanged lines hidden (view full) ---

392 }
393 bcopy(fragbuf, buf + (blks * BIOSDISK_SECSIZE), fragsize);
394#endif
395 if (rsize)
396 *rsize = size;
397 return (0);
398}
399
27 */
28
29/*
30 * BIOS disk device handling.
31 *
32 * Ideas and algorithms from:
33 *
34 * - NetBSD libi386/biosdisk.c

--- 357 unchanged lines hidden (view full) ---

392 }
393 bcopy(fragbuf, buf + (blks * BIOSDISK_SECSIZE), fragsize);
394#endif
395 if (rsize)
396 *rsize = size;
397 return (0);
398}
399
400/* Max number of sectors to bounce-buffer if the request crosses a 64k boundary */
401#define FLOPPY_BOUNCEBUF 18
402
400static int
401bd_read(struct open_disk *od, daddr_t dblk, int blks, caddr_t dest)
402{
403static int
404bd_read(struct open_disk *od, daddr_t dblk, int blks, caddr_t dest)
405{
403 int x, bpc, cyl, hd, sec, result, resid, cnt;
404 caddr_t p;
406 int x, bpc, cyl, hd, sec, result, resid, cnt, retry, maxfer;
407 caddr_t p, xp, bbuf, breg;
405
406 bpc = (od->od_sec * od->od_hds); /* blocks per cylinder */
407 resid = blks;
408 p = dest;
409
408
409 bpc = (od->od_sec * od->od_hds); /* blocks per cylinder */
410 resid = blks;
411 p = dest;
412
413 /* Decide whether we have to bounce */
414 if ((od->od_unit < 0x80) &&
415 ((VTOP(dest) >> 16) != (VTOP(dest + blks * BIOSDISK_SECSIZE) >> 16))) {
416
417 /*
418 * There is a 64k physical boundary somewhere in the destination buffer, so we have
419 * to arrange a suitable bounce buffer. Allocate a buffer twice as large as we
420 * need to. Use the bottom half unless there is a break there, in which case we
421 * use the top half.
422 */
423 x = min(FLOPPY_BOUNCEBUF, blks);
424 bbuf = malloc(x * 2 * BIOSDISK_SECSIZE);
425 if (((u_int32_t)VTOP(bbuf) & 0xffff0000) == ((u_int32_t)VTOP(dest + x * BIOSDISK_SECSIZE) & 0xffff0000)) {
426 breg = bbuf;
427 } else {
428 breg = bbuf + x * BIOSDISK_SECSIZE;
429 }
430 maxfer = x; /* limit transfers to bounce region size */
431 } else {
432 bbuf = NULL;
433 maxfer = 0;
434 }
435
410 while (resid > 0) {
411 x = dblk;
412 cyl = x / bpc; /* block # / blocks per cylinder */
413 x %= bpc; /* block offset into cylinder */
414 hd = x / od->od_sec; /* offset / blocks per track */
415 sec = x % od->od_sec; /* offset into track */
416
436 while (resid > 0) {
437 x = dblk;
438 cyl = x / bpc; /* block # / blocks per cylinder */
439 x %= bpc; /* block offset into cylinder */
440 hd = x / od->od_sec; /* offset / blocks per track */
441 sec = x % od->od_sec; /* offset into track */
442
417 /* play it safe and don't cross track boundaries */
418 x = min (od->od_sec - sec, resid);
443 /* play it safe and don't cross track boundaries (XXX this is probably unnecessary) */
444 x = min(od->od_sec - sec, resid);
445 if (maxfer > 0)
446 x = min(x, maxfer); /* fit bounce buffer */
419
447
448 /* where do we transfer to? */
449 xp = bbuf == NULL ? p : breg;
450
420 /* correct sector number for 1-based BIOS numbering */
421 sec++;
422
451 /* correct sector number for 1-based BIOS numbering */
452 sec++;
453
423 /* build request XXX support EDD requests too */
424 v86.ctl = V86_FLAGS;
425 v86.addr = 0x13;
426 v86.eax = 0x200 | x;
427 v86.ecx = ((cyl & 0xff) << 8) | ((cyl & 0x300) >> 2) | sec;
428 v86.edx = (hd << 8) | od->od_unit;
429 v86.es = VTOPSEG(p);
430 v86.ebx = VTOPOFF(p);
431 v86int();
432 result = (v86.efl & 0x1);
433 DEBUG("%d sectors from %d/%d/%d %s", x, cyl, hd, sec - 1, result ? "failed" : "ok");
434 if (result)
435 return(-1);
454 /* Loop retrying the operation a couple of times. The BIOS may also retry. */
455 for (retry = 0; retry < 3; retry++) {
456 /* if retrying, reset the drive */
457 if (retry > 0) {
458 v86.ctl = V86_FLAGS;
459 v86.addr = 0x13;
460 v86.eax = 0;
461 v86.edx = od->od_unit;
462 v86int();
463 }
464
465 /* build request XXX support EDD requests too */
466 v86.ctl = V86_FLAGS;
467 v86.addr = 0x13;
468 v86.eax = 0x200 | x;
469 v86.ecx = ((cyl & 0xff) << 8) | ((cyl & 0x300) >> 2) | sec;
470 v86.edx = (hd << 8) | od->od_unit;
471 v86.es = VTOPSEG(xp);
472 v86.ebx = VTOPOFF(xp);
473 v86int();
474 result = (v86.efl & 0x1);
475 if (result == 0)
476 break;
477 }
436
478
479 DEBUG("%d sectors from %d/%d/%d to %p (0x%x) %s", x, cyl, hd, sec - 1, p, VTOP(p), result ? "failed" : "ok");
480 DEBUG("ax = 0x%04x cx = 0x%04x dx = 0x%04x status 0x%x\n",
481 0x200 | x, ((cyl & 0xff) << 8) | ((cyl & 0x300) >> 2) | sec, (hd << 8) | od->od_unit, (v86.eax >> 8) & 0xff);
482 if (result) {
483 if (bbuf != NULL)
484 free(bbuf);
485 return(-1);
486 }
487 if (bbuf != NULL)
488 bcopy(breg, p, x * BIOSDISK_SECSIZE);
437 p += (x * BIOSDISK_SECSIZE);
438 dblk += x;
439 resid -= x;
440 }
441
442/* hexdump(dest, (blks * BIOSDISK_SECSIZE)); */
489 p += (x * BIOSDISK_SECSIZE);
490 dblk += x;
491 resid -= x;
492 }
493
494/* hexdump(dest, (blks * BIOSDISK_SECSIZE)); */
495 if (bbuf != NULL)
496 free(bbuf);
443 return(0);
444}
445
446static int
447bd_getgeom(struct open_disk *od)
448{
449
450 v86.ctl = V86_FLAGS;

--- 19 unchanged lines hidden ---
497 return(0);
498}
499
500static int
501bd_getgeom(struct open_disk *od)
502{
503
504 v86.ctl = V86_FLAGS;

--- 19 unchanged lines hidden ---