summaryrefslogtreecommitdiff
path: root/sys/arch/i386/stand/libsa/biosdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/i386/stand/libsa/biosdev.c')
-rw-r--r--sys/arch/i386/stand/libsa/biosdev.c37
1 files changed, 30 insertions, 7 deletions
diff --git a/sys/arch/i386/stand/libsa/biosdev.c b/sys/arch/i386/stand/libsa/biosdev.c
index 4ad9aaa1f15..84a0387e1d4 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.68 2004/03/09 19:12:12 tom Exp $ */
+/* $OpenBSD: biosdev.c,v 1.69 2004/06/23 00:21:49 tom Exp $ */
/*
* Copyright (c) 1996 Michael Shalayeff
@@ -34,6 +34,7 @@
#include <machine/tss.h>
#include <machine/biosvar.h>
#include <lib/libsa/saerrno.h>
+#include <isofs/cd9660/iso.h>
#include "disk.h"
#include "debug.h"
#include "libsa.h"
@@ -47,6 +48,7 @@ static int EDD_rw (int, int, u_int64_t, u_int32_t, void *);
extern int debug;
int bios_bootdev;
+int bios_cddev = -1; /* Set by srt0 if coming from CD */
#if 0
struct biosdisk {
@@ -241,17 +243,35 @@ biosd_io(int rw, bios_diskinfo_t *bd, daddr_t off, int nsect, void *buf)
int dev = bd->bios_number;
int j, error;
void *bb;
+ int bbsize = nsect * DEV_BSIZE;
+
+ if (bd->flags & BDI_EL_TORITO) { /* It's a CD device */
+ dev &= 0xff; /* Mask out this flag bit */
- /* use a bounce buffer to not cross 64k DMA boundary */
- if ((((u_int32_t)buf) & ~0xffff) !=
- (((u_int32_t)buf + nsect * DEV_BSIZE) & ~0xffff)) {
+ /*
+ * sys/lib/libsa/cd9600.c converts 2,048-byte CD sectors
+ * to DEV_BSIZE blocks before calling the device strategy
+ * routine. However, the El Torito spec says that the
+ * BIOS will work in 2,048-byte sectors. So shift back.
+ */
+ off >>= (ISO_DEFAULT_BLOCK_SHIFT - DEV_BSHIFT);
+ nsect >>= (ISO_DEFAULT_BLOCK_SHIFT - DEV_BSHIFT);
+ }
+
+ /*
+ * Use a bounce buffer to not cross 64k DMA boundary, and to
+ * not access above 1 MB.
+ */
+ if (((((u_int32_t)buf) & ~0xffff) !=
+ (((u_int32_t)buf + bbsize) & ~0xffff)) ||
+ (((u_int32_t)buf) > 0x100000)) {
/*
* XXX we believe that all the io is buffered
* by fs routines, so no big reads anyway
*/
- bb = alloca(nsect * DEV_BSIZE);
+ bb = alloca(bbsize);
if (rw != F_READ)
- bcopy(buf, bb, nsect * DEV_BSIZE);
+ bcopy(buf, bb, bbsize);
} else
bb = buf;
@@ -302,7 +322,7 @@ biosd_io(int rw, bios_diskinfo_t *bd, daddr_t off, int nsect, void *buf)
}
if (bb != buf && rw == F_READ)
- bcopy(bb, buf, nsect * DEV_BSIZE);
+ bcopy(bb, buf, bbsize);
#ifdef BIOS_DEBUG
if (debug) {
@@ -442,6 +462,9 @@ biosopen(struct open_file *f, ...)
break;
case 2: /* fd */
break;
+ case 6: /* cd */
+ biosdev = bios_bootdev & 0xff;
+ break;
default:
return ENXIO;
}