Author: kevans
Date: Sun Apr 21 03:27:12 2019
New Revision: 346474
URL: https://svnweb.freebsd.org/changeset/base/346474

Log:
  MFC i386 stand cleanup: r337353-r337354, r337356, r337872, r337878, r337881,
  r337890-r337891, r338188
  
  r337353:
  loader: cstyle cleanup for biosdisk.c
  
  Also switch u_int to uint32_t. Also replace "write" by "dowrite".
  No functional changes intended.
  
  r337354:
  loader: 337353 did miss to rename 2 write instances
  
  2 write instances got somehow missed.
  
  r337356:
  loader: bd_open() should cleanup from disk_open() error
  
  Since bd_open() does early increment for reference counter and bcache
  allocation, it also should undo those in case of the error.
  
  Also remove unused variables rdev, g_err.
  
  r337872:
  libi386: remove BD_SUPPORT_FRAGS
  
  BD_SUPPORT_FRAGS is preprocessor knob to allow partial reads in 
bioscd/biosdisk
  level. However, we already have support for partial reads in bcache, and there
  is no need to have duplication via preprocessor controls.
  
  Note that bioscd/biosdisk interface is assumed to perform IO in 512B blocks,
  so the only translation we have to do is 512 <-> native block size.
  
  r337878:
  libi386: remove bd_read() and bd_write() wrappers
  
  Those wroappers are nice, but do not really add much value.
  
  r337881:
  libi386: use BD_RD and BR_WR constants
  
  Use BD_RD and BD_WR instead of 0 and 1.
  
  r337890:
  libi386: small style updates in biosdisk
  
  Use break instead of return in for loop, as done earlier. Insert and remove
  some blank lines. No functional changes intended.
  
  r337891:
  libi386: bd_io_workaround() is to be called for reads only
  
  bd_io() can perform either reads or writes, we only need bd_io_workaround()
  for reads.
  
  r338188:
  loader: bios loader should allow to chain load a file
  
  The current chain command does accept only device, allow also a file to be 
used,
  such as /boot/pmbr or /boot/mbr (or stored third party MBR/VBR block).
  
  Also fix file descriptor leak.

Modified:
  stable/11/stand/i386/libi386/bioscd.c
  stable/11/stand/i386/libi386/biosdisk.c
  stable/11/stand/i386/loader/chain.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/stand/i386/libi386/bioscd.c
==============================================================================
--- stable/11/stand/i386/libi386/bioscd.c       Sun Apr 21 03:22:57 2019        
(r346473)
+++ stable/11/stand/i386/libi386/bioscd.c       Sun Apr 21 03:27:12 2019        
(r346474)
@@ -258,15 +258,9 @@ bc_realstrategy(void *devdata, int rw, daddr_t dblk, s
        struct i386_devdesc *dev;
        int unit;
        int blks;
-#ifdef BD_SUPPORT_FRAGS
-       char fragbuf[BIOSCD_SECSIZE];
-       size_t fragsize;
 
-       fragsize = size % BIOSCD_SECSIZE;
-#else
        if (size % BIOSCD_SECSIZE)
                return (EINVAL);
-#endif
 
        if ((rw & F_MASK) != F_READ)
                return(EROFS);
@@ -290,20 +284,6 @@ bc_realstrategy(void *devdata, int rw, daddr_t dblk, s
                        return (0);
                }
        }
-#ifdef BD_SUPPORT_FRAGS
-       DEBUG("frag read %d from %lld+%d to %p", 
-           fragsize, dblk, blks, buf + (blks * BIOSCD_SECSIZE));
-       if (fragsize && bc_read(unit, dblk + blks, 1, fragbuf) != 1) {
-               if (blks) {
-                       if (rsize)
-                               *rsize = blks * BIOSCD_SECSIZE;
-                       return (0);
-               }
-               DEBUG("frag read error");
-               return(EIO);
-       }
-       bcopy(fragbuf, buf + (blks * BIOSCD_SECSIZE), fragsize);
-#endif 
        if (rsize)
                *rsize = size;
        return (0);

Modified: stable/11/stand/i386/libi386/biosdisk.c
==============================================================================
--- stable/11/stand/i386/libi386/biosdisk.c     Sun Apr 21 03:22:57 2019        
(r346473)
+++ stable/11/stand/i386/libi386/biosdisk.c     Sun Apr 21 03:27:12 2019        
(r346474)
@@ -30,7 +30,7 @@ __FBSDID("$FreeBSD$");
 
 /*
  * BIOS disk device handling.
- * 
+ *
  * Ideas and algorithms from:
  *
  * - NetBSD libi386/biosdisk.c
@@ -50,20 +50,20 @@ __FBSDID("$FreeBSD$");
 #include "disk.h"
 #include "libi386.h"
 
-#define BIOS_NUMDRIVES         0x475
-#define BIOSDISK_SECSIZE       512
-#define BUFSIZE                        (1 * BIOSDISK_SECSIZE)
+#define        BIOS_NUMDRIVES          0x475
+#define        BIOSDISK_SECSIZE        512
+#define        BUFSIZE                 (1 * BIOSDISK_SECSIZE)
 
-#define DT_ATAPI               0x10            /* disk type for ATAPI floppies 
*/
-#define WDMAJOR                        0               /* major numbers for 
devices we frontend for */
-#define WFDMAJOR               1
-#define FDMAJOR                        2
-#define DAMAJOR                        4
+#define        DT_ATAPI        0x10    /* disk type for ATAPI floppies */
+#define        WDMAJOR         0       /* major numbers for devices we 
frontend for */
+#define        WFDMAJOR        1
+#define        FDMAJOR         2
+#define        DAMAJOR         4
 
 #ifdef DISK_DEBUG
-# define DEBUG(fmt, args...)   printf("%s: " fmt "\n" , __func__ , ## args)
+#define        DEBUG(fmt, args...)     printf("%s: " fmt "\n", __func__, ## 
args)
 #else
-# define DEBUG(fmt, args...)
+#define        DEBUG(fmt, args...)
 #endif
 
 /*
@@ -91,13 +91,12 @@ static struct bdinfo
 static int nbdinfo = 0;
 
 #define        BD(dev)         (bdinfo[(dev)->dd.d_unit])
+#define        BD_RD           0
+#define        BD_WR           1
 
 static void bd_io_workaround(struct disk_devdesc *dev);
 
-static int bd_read(struct disk_devdesc *dev, daddr_t dblk, int blks,
-    caddr_t dest);
-static int bd_write(struct disk_devdesc *dev, daddr_t dblk, int blks,
-    caddr_t dest);
+static int bd_io(struct disk_devdesc *, daddr_t, int, caddr_t, int);
 static int bd_int13probe(struct bdinfo *bd);
 
 static int bd_init(void);
@@ -164,7 +163,7 @@ bd_init(void)
                         * Check the BIOS equipment list for number
                         * of fixed disks.
                         */
-                       if(base == 0x80 &&
+                       if (base == 0x80 &&
                            (nfd >= *(unsigned char *)PTOV(BIOS_NUMDRIVES)))
                                break;
 #endif
@@ -184,7 +183,7 @@ bd_init(void)
                }
        }
        bcache_add_dev(nbdinfo);
-       return(0);
+       return (0);
 }
 
 /*
@@ -207,7 +206,7 @@ bd_int13probe(struct bdinfo *bd)
            (v86.edx & 0xff) <= (unsigned)(bd->bd_unit & 0x7f)) /* unit # bad */
                return (0);     /* skip device */
 
-       if ((v86.ecx & 0x3f) == 0) /* absurd sector number */
+       if ((v86.ecx & 0x3f) == 0)      /* absurd sector number */
                ret = 0;        /* set error */
 
        /* Convert max cyl # -> # of cylinders */
@@ -307,6 +306,7 @@ bd_print(int verbose)
                    bdinfo[i].bd_sectorsize);
                if ((ret = pager_output(line)) != 0)
                        break;
+
                dev.dd.d_dev = &biosdisk;
                dev.dd.d_unit = i;
                dev.d_slice = -1;
@@ -318,7 +318,7 @@ bd_print(int verbose)
                        ret = disk_print(&dev, line, verbose);
                        disk_close(&dev);
                        if (ret != 0)
-                           return (ret);
+                               break;
                }
        }
        return (ret);
@@ -337,11 +337,11 @@ bd_print(int verbose)
 static int
 bd_open(struct open_file *f, ...)
 {
-       struct disk_devdesc *dev, rdev;
+       struct disk_devdesc *dev;
        struct disk_devdesc disk;
-       int err, g_err;
        va_list ap;
        uint64_t size;
+       int rc;
 
        va_start(ap, f);
        dev = va_arg(ap, struct disk_devdesc *);
@@ -365,6 +365,7 @@ bd_open(struct open_file *f, ...)
        disk.d_slice = -1;
        disk.d_partition = -1;
        disk.d_offset = 0;
+
        if (disk_open(&disk, BD(dev).bd_sectors * BD(dev).bd_sectorsize,
            BD(dev).bd_sectorsize) == 0) {
 
@@ -376,10 +377,16 @@ bd_open(struct open_file *f, ...)
                disk_close(&disk);
        }
 
-       err = disk_open(dev, BD(dev).bd_sectors * BD(dev).bd_sectorsize,
+       rc = disk_open(dev, BD(dev).bd_sectors * BD(dev).bd_sectorsize,
            BD(dev).bd_sectorsize);
-
-       return (err);
+       if (rc != 0) {
+               BD(dev).bd_open--;
+               if (BD(dev).bd_open == 0) {
+                       bcache_free(BD(dev).bd_bcache);
+                       BD(dev).bd_bcache = NULL;
+               }
+       }
+       return (rc);
 }
 
 static int
@@ -410,7 +417,7 @@ bd_ioctl(struct open_file *f, u_long cmd, void *data)
 
        switch (cmd) {
        case DIOCGSECTORSIZE:
-               *(u_int *)data = BD(dev).bd_sectorsize;
+               *(uint32_t *)data = BD(dev).bd_sectorsize;
                break;
        case DIOCGMEDIASIZE:
                *(uint64_t *)data = BD(dev).bd_sectors * BD(dev).bd_sectorsize;
@@ -432,176 +439,161 @@ bd_strategy(void *devdata, int rw, daddr_t dblk, size_
        bcd.dv_strategy = bd_realstrategy;
        bcd.dv_devdata = devdata;
        bcd.dv_cache = BD(dev).bd_bcache;
-       return (bcache_strategy(&bcd, rw, dblk + dev->d_offset,
-           size, buf, rsize));
+       return (bcache_strategy(&bcd, rw, dblk + dev->d_offset, size,
+           buf, rsize));
 }
 
 static int
 bd_realstrategy(void *devdata, int rw, daddr_t dblk, size_t size,
     char *buf, size_t *rsize)
 {
-    struct disk_devdesc *dev = (struct disk_devdesc *)devdata;
-    uint64_t           disk_blocks;
-    int                        blks, rc;
-#ifdef BD_SUPPORT_FRAGS /* XXX: sector size */
-    char               fragbuf[BIOSDISK_SECSIZE];
-    size_t             fragsize;
+       struct disk_devdesc *dev = (struct disk_devdesc *)devdata;
+       uint64_t                disk_blocks;
+       int                     blks, rc;
 
-    fragsize = size % BIOSDISK_SECSIZE;
-#else
-    if (size % BD(dev).bd_sectorsize)
-       panic("bd_strategy: %d bytes I/O not multiple of block size", size);
-#endif
+       if (size % BD(dev).bd_sectorsize) {
+               panic("bd_strategy: %d bytes I/O not multiple of block size",
+                   size);
+       }
 
-    DEBUG("open_disk %p", dev);
+       DEBUG("open_disk %p", dev);
 
-    /*
-     * Check the value of the size argument. We do have quite small
-     * heap (64MB), but we do not know good upper limit, so we check against
-     * INT_MAX here. This will also protect us against possible overflows
-     * while translating block count to bytes.
-     */
-    if (size > INT_MAX) {
-       DEBUG("too large read: %zu bytes", size);
-       return (EIO);
-    }
+       /*
+        * Check the value of the size argument. We do have quite small
+        * heap (64MB), but we do not know good upper limit, so we check against
+        * INT_MAX here. This will also protect us against possible overflows
+        * while translating block count to bytes.
+        */
+       if (size > INT_MAX) {
+               DEBUG("too large read: %zu bytes", size);
+               return (EIO);
+       }
 
-    blks = size / BD(dev).bd_sectorsize;
-    if (dblk > dblk + blks)
-       return (EIO);
+       blks = size / BD(dev).bd_sectorsize;
+       if (dblk > dblk + blks)
+               return (EIO);
 
-    if (rsize)
-       *rsize = 0;
+       if (rsize)
+               *rsize = 0;
 
-    /* Get disk blocks, this value is either for whole disk or for partition */
-    if (disk_ioctl(dev, DIOCGMEDIASIZE, &disk_blocks) == 0) {
-       /* DIOCGMEDIASIZE returns bytes. */
-        disk_blocks /= BD(dev).bd_sectorsize;
-    } else {
-       /* We should not get here. Just try to survive. */
-       disk_blocks = BD(dev).bd_sectors - dev->d_offset;
-    }
+       /*
+        * Get disk blocks, this value is either for whole disk or for
+        * partition.
+        */
+       if (disk_ioctl(dev, DIOCGMEDIASIZE, &disk_blocks) == 0) {
+               /* DIOCGMEDIASIZE returns bytes. */
+               disk_blocks /= BD(dev).bd_sectorsize;
+       } else {
+               /* We should not get here. Just try to survive. */
+               disk_blocks = BD(dev).bd_sectors - dev->d_offset;
+       }
 
-    /* Validate source block address. */
-    if (dblk < dev->d_offset || dblk >= dev->d_offset + disk_blocks)
-       return (EIO);
+       /* Validate source block address. */
+       if (dblk < dev->d_offset || dblk >= dev->d_offset + disk_blocks)
+               return (EIO);
 
-    /*
-     * Truncate if we are crossing disk or partition end.
-     */
-    if (dblk + blks >= dev->d_offset + disk_blocks) {
-       blks = dev->d_offset + disk_blocks - dblk;
-       size = blks * BD(dev).bd_sectorsize;
-       DEBUG("short read %d", blks);
-    }
+       /*
+        * Truncate if we are crossing disk or partition end.
+        */
+       if (dblk + blks >= dev->d_offset + disk_blocks) {
+               blks = dev->d_offset + disk_blocks - dblk;
+               size = blks * BD(dev).bd_sectorsize;
+               DEBUG("short read %d", blks);
+       }
 
-    switch (rw & F_MASK) {
-    case F_READ:
-       DEBUG("read %d from %lld to %p", blks, dblk, buf);
+       switch (rw & F_MASK) {
+       case F_READ:
+               DEBUG("read %d from %lld to %p", blks, dblk, buf);
 
-       if (blks && (rc = bd_read(dev, dblk, blks, buf))) {
-           /* Filter out floppy controller errors */
-           if (BD(dev).bd_flags != BD_FLOPPY || rc != 0x20) {
-               printf("read %d from %lld to %p, error: 0x%x\n", blks, dblk,
-                   buf, rc);
-           }
-           return (EIO);
-       }
-#ifdef BD_SUPPORT_FRAGS /* XXX: sector size */
-       DEBUG("bd_strategy: frag read %d from %d+%d to %p",
-           fragsize, dblk, blks, buf + (blks * BIOSDISK_SECSIZE));
-       if (fragsize && bd_read(od, dblk + blks, 1, fragsize)) {
-           DEBUG("frag read error");
-           return(EIO);
-       }
-       bcopy(fragbuf, buf + (blks * BIOSDISK_SECSIZE), fragsize);
-#endif
-       break;
-    case F_WRITE :
-       DEBUG("write %d from %lld to %p", blks, dblk, buf);
+               if (blks && (rc = bd_io(dev, dblk, blks, buf, BD_RD))) {
+                       /* Filter out floppy controller errors */
+                       if (BD(dev).bd_flags != BD_FLOPPY || rc != 0x20) {
+                               printf("read %d from %lld to %p, error: 0x%x\n",
+                                   blks, dblk, buf, rc);
+                       }
+                       return (EIO);
+               }
+               break;
+       case F_WRITE :
+               DEBUG("write %d from %lld to %p", blks, dblk, buf);
 
-       if (blks && bd_write(dev, dblk, blks, buf)) {
-           DEBUG("write error");
-           return (EIO);
+               if (blks && bd_io(dev, dblk, blks, buf, BD_WR)) {
+                       DEBUG("write error");
+                       return (EIO);
+               }
+               break;
+       default:
+               /* DO NOTHING */
+               return (EROFS);
        }
-#ifdef BD_SUPPORT_FRAGS
-       if(fragsize) {
-           DEBUG("Attempted to write a frag");
-           return (EIO);
-       }
-#endif
-       break;
-    default:
-       /* DO NOTHING */
-       return (EROFS);
-    }
 
-    if (rsize)
-       *rsize = size;
-    return (0);
+       if (rsize)
+               *rsize = size;
+       return (0);
 }
 
 static int
 bd_edd_io(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest,
-    int write)
+    int dowrite)
 {
-    static struct edd_packet packet;
+       static struct edd_packet packet;
 
-    packet.len = sizeof(struct edd_packet);
-    packet.count = blks;
-    packet.off = VTOPOFF(dest);
-    packet.seg = VTOPSEG(dest);
-    packet.lba = dblk;
-    v86.ctl = V86_FLAGS;
-    v86.addr = 0x13;
-    if (write)
+       packet.len = sizeof(struct edd_packet);
+       packet.count = blks;
+       packet.off = VTOPOFF(dest);
+       packet.seg = VTOPSEG(dest);
+       packet.lba = dblk;
+       v86.ctl = V86_FLAGS;
+       v86.addr = 0x13;
        /* Should we Write with verify ?? 0x4302 ? */
-       v86.eax = 0x4300;
-    else
-       v86.eax = 0x4200;
-    v86.edx = BD(dev).bd_unit;
-    v86.ds = VTOPSEG(&packet);
-    v86.esi = VTOPOFF(&packet);
-    v86int();
-    if (V86_CY(v86.efl))
-       return (v86.eax >> 8);
-    return (0);
+       if (dowrite == BD_WR)
+               v86.eax = 0x4300;
+       else
+               v86.eax = 0x4200;
+       v86.edx = BD(dev).bd_unit;
+       v86.ds = VTOPSEG(&packet);
+       v86.esi = VTOPOFF(&packet);
+       v86int();
+       if (V86_CY(v86.efl))
+               return (v86.eax >> 8);
+       return (0);
 }
 
 static int
 bd_chs_io(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest,
-    int write)
+    int dowrite)
 {
-    u_int      x, bpc, cyl, hd, sec;
+       uint32_t x, bpc, cyl, hd, sec;
 
-    bpc = BD(dev).bd_sec * BD(dev).bd_hds;     /* blocks per cylinder */
-    x = dblk;
-    cyl = x / bpc;                     /* block # / blocks per cylinder */
-    x %= bpc;                          /* block offset into cylinder */
-    hd = x / BD(dev).bd_sec;           /* offset / blocks per track */
-    sec = x % BD(dev).bd_sec;          /* offset into track */
+       bpc = BD(dev).bd_sec * BD(dev).bd_hds;  /* blocks per cylinder */
+       x = dblk;
+       cyl = x / bpc;                  /* block # / blocks per cylinder */
+       x %= bpc;                               /* block offset into cylinder */
+       hd = x / BD(dev).bd_sec;                /* offset / blocks per track */
+       sec = x % BD(dev).bd_sec;               /* offset into track */
 
-    /* correct sector number for 1-based BIOS numbering */
-    sec++;
+       /* correct sector number for 1-based BIOS numbering */
+       sec++;
 
-    if (cyl > 1023)
-       /* CHS doesn't support cylinders > 1023. */
-       return (1);
+       if (cyl > 1023) {
+               /* CHS doesn't support cylinders > 1023. */
+               return (1);
+       }
 
-    v86.ctl = V86_FLAGS;
-    v86.addr = 0x13;
-    if (write)
-       v86.eax = 0x300 | blks;
-    else
-       v86.eax = 0x200 | blks;
-    v86.ecx = ((cyl & 0xff) << 8) | ((cyl & 0x300) >> 2) | sec;
-    v86.edx = (hd << 8) | BD(dev).bd_unit;
-    v86.es = VTOPSEG(dest);
-    v86.ebx = VTOPOFF(dest);
-    v86int();
-    if (V86_CY(v86.efl))
-       return (v86.eax >> 8);
-    return (0);
+       v86.ctl = V86_FLAGS;
+       v86.addr = 0x13;
+       if (dowrite == BD_WR)
+               v86.eax = 0x300 | blks;
+       else
+               v86.eax = 0x200 | blks;
+       v86.ecx = ((cyl & 0xff) << 8) | ((cyl & 0x300) >> 2) | sec;
+       v86.edx = (hd << 8) | BD(dev).bd_unit;
+       v86.es = VTOPSEG(dest);
+       v86.ebx = VTOPOFF(dest);
+       v86int();
+       if (V86_CY(v86.efl))
+               return (v86.eax >> 8);
+       return (0);
 }
 
 static void
@@ -609,130 +601,117 @@ bd_io_workaround(struct disk_devdesc *dev)
 {
        uint8_t buf[8 * 1024];
 
-       bd_edd_io(dev, 0xffffffff, 1, (caddr_t)buf, 0);
+       bd_edd_io(dev, 0xffffffff, 1, (caddr_t)buf, BD_RD);
 }
 
 
 static int
-bd_io(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest, int 
write)
+bd_io(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest,
+    int dowrite)
 {
-    u_int      x, sec, result, resid, retry, maxfer;
-    caddr_t    p, xp, bbuf;
+       u_int   x, sec, result, resid, retry, maxfer;
+       caddr_t p, xp, bbuf;
     
-    /* Just in case some idiot actually tries to read/write -1 blocks... */
-    if (blks < 0)
-       return (-1);
+       /* Just in case some idiot actually tries to read/write -1 blocks... */
+       if (blks < 0)
+               return (-1);
 
-    resid = blks;
-    p = dest;
+       resid = blks;
+       p = dest;
 
-    /*
-     * Workaround for a problem with some HP ProLiant BIOS failing to work out
-     * the boot disk after installation. hrs and kuriyama discovered this
-     * problem with an HP ProLiant DL320e Gen 8 with a 3TB HDD, and discovered
-     * that an int13h call seems to cause a buffer overrun in the bios. The
-     * problem is alleviated by doing an extra read before the buggy read. It
-     * is not immediately known whether other models are similarly affected.
-     */
-    if (dblk >= 0x100000000)
-       bd_io_workaround(dev);
-
-    /* Decide whether we have to bounce */
-    if (VTOP(dest) >> 20 != 0 || (BD(dev).bd_unit < 0x80 &&
-       (VTOP(dest) >> 16) != (VTOP(dest +
-       blks * BD(dev).bd_sectorsize) >> 16))) {
-
-       /* 
-        * There is a 64k physical boundary somewhere in the
-        * destination buffer, or the destination buffer is above
-        * first 1MB of physical memory so we have to arrange a
-        * suitable bounce buffer.  Allocate a buffer twice as large
-        * as we need to.  Use the bottom half unless there is a break
-        * there, in which case we use the top half.
-        */
-       x = V86_IO_BUFFER_SIZE / BD(dev).bd_sectorsize;
-       x = min(x, (unsigned)blks);
-       bbuf = PTOV(V86_IO_BUFFER);
-       maxfer = x;             /* limit transfers to bounce region size */
-    } else {
-       bbuf = NULL;
-       maxfer = 0;
-    }
-    
-    while (resid > 0) {
        /*
-        * Play it safe and don't cross track boundaries.
-        * (XXX this is probably unnecessary)
+        * Workaround for a problem with some HP ProLiant BIOS failing to work
+        * out the boot disk after installation. hrs and kuriyama discovered
+        * this problem with an HP ProLiant DL320e Gen 8 with a 3TB HDD, and
+        * discovered that an int13h call seems to cause a buffer overrun in
+        * the bios. The problem is alleviated by doing an extra read before
+        * the buggy read. It is not immediately known whether other models
+        * are similarly affected.
         */
-       sec = dblk % BD(dev).bd_sec;    /* offset into track */
-       x = min(BD(dev).bd_sec - sec, resid);
-       if (maxfer > 0)
-           x = min(x, maxfer);         /* fit bounce buffer */
+       if (dowrite == BD_RD && dblk >= 0x100000000)
+               bd_io_workaround(dev);
 
-       /* where do we transfer to? */
-       xp = bbuf == NULL ? p : bbuf;
+       /* Decide whether we have to bounce */
+       if (VTOP(dest) >> 20 != 0 || (BD(dev).bd_unit < 0x80 &&
+           (VTOP(dest) >> 16) !=
+           (VTOP(dest + blks * BD(dev).bd_sectorsize) >> 16))) {
 
-       /*
-        * Put your Data In, Put your Data out,
-        * Put your Data In, and shake it all about 
-        */
-       if (write && bbuf != NULL)
-           bcopy(p, bbuf, x * BD(dev).bd_sectorsize);
-
-       /*
-        * Loop retrying the operation a couple of times.  The BIOS
-        * may also retry.
-        */
-       for (retry = 0; retry < 3; retry++) {
-           /* if retrying, reset the drive */
-           if (retry > 0) {
-               v86.ctl = V86_FLAGS;
-               v86.addr = 0x13;
-               v86.eax = 0;
-               v86.edx = BD(dev).bd_unit;
-               v86int();
-           }
-
-           if (BD(dev).bd_flags & BD_MODEEDD1)
-               result = bd_edd_io(dev, dblk, x, xp, write);
-           else
-               result = bd_chs_io(dev, dblk, x, xp, write);
-           if (result == 0)
-               break;
+               /* 
+                * There is a 64k physical boundary somewhere in the
+                * destination buffer, or the destination buffer is above
+                * first 1MB of physical memory so we have to arrange a
+                * suitable bounce buffer.  Allocate a buffer twice as large
+                * as we need to.  Use the bottom half unless there is a break
+                * there, in which case we use the top half.
+                */
+               x = V86_IO_BUFFER_SIZE / BD(dev).bd_sectorsize;
+               x = min(x, (unsigned)blks);
+               bbuf = PTOV(V86_IO_BUFFER);
+               maxfer = x;     /* limit transfers to bounce region size */
+       } else {
+               bbuf = NULL;
+               maxfer = 0;
        }
+    
+       while (resid > 0) {
+               /*
+                * Play it safe and don't cross track boundaries.
+                * (XXX this is probably unnecessary)
+                */
+               sec = dblk % BD(dev).bd_sec;    /* offset into track */
+               x = min(BD(dev).bd_sec - sec, resid);
+               if (maxfer > 0)
+                       x = min(x, maxfer);             /* fit bounce buffer */
 
-       if (write)
-           DEBUG("Write %d sector(s) from %p (0x%x) to %lld %s", x,
-               p, VTOP(p), dblk, result ? "failed" : "ok");
-       else
-           DEBUG("Read %d sector(s) from %lld to %p (0x%x) %s", x,
-               dblk, p, VTOP(p), result ? "failed" : "ok");
-       if (result) {
-           return (result);
-       }
-       if (!write && bbuf != NULL)
-           bcopy(bbuf, p, x * BD(dev).bd_sectorsize);
-       p += (x * BD(dev).bd_sectorsize);
-       dblk += x;
-       resid -= x;
-    }
+               /* where do we transfer to? */
+               xp = bbuf == NULL ? p : bbuf;
 
-/*    hexdump(dest, (blks * BD(dev).bd_sectorsize)); */
-    return(0);
-}
+               /*
+                * Put your Data In, Put your Data out,
+                * Put your Data In, and shake it all about 
+                */
+               if (dowrite == BD_WR && bbuf != NULL)
+                       bcopy(p, bbuf, x * BD(dev).bd_sectorsize);
 
-static int
-bd_read(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest)
-{
+               /*
+                * Loop retrying the operation a couple of times.  The BIOS
+                * may also retry.
+                */
+               for (retry = 0; retry < 3; retry++) {
+                       /* if retrying, reset the drive */
+                       if (retry > 0) {
+                               v86.ctl = V86_FLAGS;
+                               v86.addr = 0x13;
+                               v86.eax = 0;
+                               v86.edx = BD(dev).bd_unit;
+                               v86int();
+                       }
 
-       return (bd_io(dev, dblk, blks, dest, 0));
-}
+                       if (BD(dev).bd_flags & BD_MODEEDD1)
+                               result = bd_edd_io(dev, dblk, x, xp, dowrite);
+                       else
+                               result = bd_chs_io(dev, dblk, x, xp, dowrite);
+                       if (result == 0)
+                               break;
+               }
 
-static int
-bd_write(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest)
-{
+               if (dowrite == BD_WR)
+                       DEBUG("Write %d sector(s) from %p (0x%x) to %lld %s", x,
+                           p, VTOP(p), dblk, result ? "failed" : "ok");
+               else
+                       DEBUG("Read %d sector(s) from %lld to %p (0x%x) %s", x,
+                           dblk, p, VTOP(p), result ? "failed" : "ok");
+               if (result) {
+                       return (result);
+               }
+               if (dowrite == BD_RD && bbuf != NULL)
+                       bcopy(bbuf, p, x * BD(dev).bd_sectorsize);
+               p += (x * BD(dev).bd_sectorsize);
+               dblk += x;
+               resid -= x;
+       }
 
-       return (bd_io(dev, dblk, blks, dest, 1));
+       return (0);
 }
 
 /*
@@ -753,15 +732,15 @@ uint32_t
 bd_getbigeom(int bunit)
 {
 
-    v86.ctl = V86_FLAGS;
-    v86.addr = 0x13;
-    v86.eax = 0x800;
-    v86.edx = 0x80 + bunit;
-    v86int();
-    if (V86_CY(v86.efl))
-       return 0x4f010f;
-    return ((v86.ecx & 0xc0) << 18) | ((v86.ecx & 0xff00) << 8) |
-          (v86.edx & 0xff00) | (v86.ecx & 0x3f);
+       v86.ctl = V86_FLAGS;
+       v86.addr = 0x13;
+       v86.eax = 0x800;
+       v86.edx = 0x80 + bunit;
+       v86int();
+       if (V86_CY(v86.efl))
+               return (0x4f010f);
+       return (((v86.ecx & 0xc0) << 18) | ((v86.ecx & 0xff00) << 8) |
+           (v86.edx & 0xff00) | (v86.ecx & 0x3f));
 }
 
 /*
@@ -773,49 +752,49 @@ bd_getbigeom(int bunit)
 int
 bd_getdev(struct i386_devdesc *d)
 {
-    struct disk_devdesc                *dev;
-    int                                biosdev;
-    int                        major;
-    int                                rootdev;
-    char                       *nip, *cp;
-    int                                i, unit;
+       struct disk_devdesc *dev;
+       int     biosdev;
+       int     major;
+       int     rootdev;
+       char    *nip, *cp;
+       int     i, unit;
 
-    dev = (struct disk_devdesc *)d;
-    biosdev = bd_unit2bios(dev->dd.d_unit);
-    DEBUG("unit %d BIOS device %d", dev->dd.d_unit, biosdev);
-    if (biosdev == -1)                         /* not a BIOS device */
-       return(-1);
-    if (disk_open(dev, BD(dev).bd_sectors * BD(dev).bd_sectorsize,
-       BD(dev).bd_sectorsize) != 0)            /* oops, not a viable device */
-           return (-1);
-    else
-       disk_close(dev);
+       dev = (struct disk_devdesc *)d;
+       biosdev = bd_unit2bios(dev->dd.d_unit);
+       DEBUG("unit %d BIOS device %d", dev->dd.d_unit, biosdev);
+       if (biosdev == -1)                      /* not a BIOS device */
+               return (-1);
+       if (disk_open(dev, BD(dev).bd_sectors * BD(dev).bd_sectorsize,
+           BD(dev).bd_sectorsize) != 0)        /* oops, not a viable device */
+               return (-1);
+       else
+               disk_close(dev);
 
-    if (biosdev < 0x80) {
-       /* floppy (or emulated floppy) or ATAPI device */
-       if (bdinfo[dev->dd.d_unit].bd_type == DT_ATAPI) {
-           /* is an ATAPI disk */
-           major = WFDMAJOR;
+       if (biosdev < 0x80) {
+               /* floppy (or emulated floppy) or ATAPI device */
+               if (bdinfo[dev->dd.d_unit].bd_type == DT_ATAPI) {
+                       /* is an ATAPI disk */
+                       major = WFDMAJOR;
+               } else {
+                       /* is a floppy disk */
+                       major = FDMAJOR;
+               }
        } else {
-           /* is a floppy disk */
-           major = FDMAJOR;
+               /* assume an IDE disk */
+               major = WDMAJOR;
        }
-    } else {
-           /* assume an IDE disk */
-           major = WDMAJOR;
-    }
-    /* default root disk unit number */
-    unit = biosdev & 0x7f;
+       /* default root disk unit number */
+       unit = biosdev & 0x7f;
 
-    /* XXX a better kludge to set the root disk unit number */
-    if ((nip = getenv("root_disk_unit")) != NULL) {
-       i = strtol(nip, &cp, 0);
-       /* check for parse error */
-       if ((cp != nip) && (*cp == 0))
-           unit = i;
-    }
+       /* XXX a better kludge to set the root disk unit number */
+       if ((nip = getenv("root_disk_unit")) != NULL) {
+               i = strtol(nip, &cp, 0);
+               /* check for parse error */
+               if ((cp != nip) && (*cp == 0))
+                       unit = i;
+       }
 
-    rootdev = MAKEBOOTDEV(major, dev->d_slice + 1, unit, dev->d_partition);
-    DEBUG("dev is 0x%x\n", rootdev);
-    return(rootdev);
+       rootdev = MAKEBOOTDEV(major, dev->d_slice + 1, unit, dev->d_partition);
+       DEBUG("dev is 0x%x\n", rootdev);
+       return (rootdev);
 }

Modified: stable/11/stand/i386/loader/chain.c
==============================================================================
--- stable/11/stand/i386/loader/chain.c Sun Apr 21 03:22:57 2019        
(r346473)
+++ stable/11/stand/i386/loader/chain.c Sun Apr 21 03:27:12 2019        
(r346474)
@@ -92,24 +92,26 @@ command_chain(int argc, char *argv[])
        i386_getdev((void **)(&rootdev), argv[1], NULL);
        if (rootdev == NULL) {
                command_errmsg = "can't determine root device";
+               close(fd);
                return (CMD_ERROR);
        }
 
-       if (archsw.arch_readin(fd, mem, SECTOR_SIZE) != SECTOR_SIZE) {
+       if (archsw.arch_readin(fd, mem, size) != size) {
                command_errmsg = "failed to read disk";
                close(fd);
                return (CMD_ERROR);
        }
        close(fd);
 
-       if (*((uint16_t *)PTOV(mem + DOSMAGICOFFSET)) != DOSMAGIC) {
+       if (argv[1][len-1] == ':' &&
+           *((uint16_t *)PTOV(mem + DOSMAGICOFFSET)) != DOSMAGIC) {
                command_errmsg = "wrong magic";
                return (CMD_ERROR);
        }
 
        relocater_data[0].src = mem;
        relocater_data[0].dest = 0x7C00;
-       relocater_data[0].size = SECTOR_SIZE;
+       relocater_data[0].size = size;
 
        relocator_edx = bd_unit2bios(rootdev->dd.d_unit);
        relocator_esi = relocater_size;


_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to