summaryrefslogtreecommitdiff
path: root/sys/arch/i386/stand/libsa/diskprobe.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/i386/stand/libsa/diskprobe.c')
-rw-r--r--sys/arch/i386/stand/libsa/diskprobe.c193
1 files changed, 148 insertions, 45 deletions
diff --git a/sys/arch/i386/stand/libsa/diskprobe.c b/sys/arch/i386/stand/libsa/diskprobe.c
index efa39d9aeb1..83b8e901ce1 100644
--- a/sys/arch/i386/stand/libsa/diskprobe.c
+++ b/sys/arch/i386/stand/libsa/diskprobe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: diskprobe.c,v 1.11 1997/10/29 23:12:46 niklas Exp $ */
+/* $OpenBSD: diskprobe.c,v 1.12 1997/11/30 21:51:42 mickey Exp $ */
/*
* Copyright (c) 1997 Tobias Weingartner
@@ -32,12 +32,17 @@
*
*/
+/* We want the disk type names from disklabel.h */
+#define DKTYPENAMES
+
#include <sys/param.h>
+#include <sys/queue.h>
#include <sys/reboot.h>
#include <sys/disklabel.h>
#include <stand/boot/bootarg.h>
#include <machine/biosvar.h>
#include <lib/libz/zlib.h>
+#include "disk.h"
#include "biosdev.h"
#include "libsa.h"
@@ -46,110 +51,202 @@
/* Local Prototypes */
static int disksum __P((int));
-/* These get passed to kernel */
-bios_diskinfo_t bios_diskinfo[16];
-u_int32_t bios_cksumlen;
+/* List of disk devices we found/probed */
+static struct disklist_lh disklist;
-/* Probe for all BIOS disks */
-void
-diskprobe()
-{
- struct disklabel label;
- register u_int i;
- register bios_diskinfo_t *pdi;
- u_int type;
- u_int scsi = 0, ide = 0, bsdunit;
+/* Pointer to boot device */
+struct diskinfo *bootdev_dip;
- printf("Probing disks:");
- pdi = bios_diskinfo;
+
+/* Probe for all BIOS floppies */
+static void
+floppyprobe()
+{
+ struct diskinfo *dip;
+ int i;
/* Floppies */
- for(i = 0; i < 4; i++, pdi++) {
- if(bios_getinfo(i, pdi)) {
+ for(i = 0; i < 4; i++) {
+ dip = alloc(sizeof(struct diskinfo));
+ bzero(dip, sizeof(*dip));
+
+ if(bios_getdiskinfo(i, &dip->bios_info)) {
#ifdef BIOS_DEBUG
printf(" <!fd%u>", i);
#endif
+ free(dip, 0);
break;
- } else
- printf(" fd%u", i);
+ }
+
+ printf(" fd%u", i);
/* Fill out best we can - (fd?) */
- pdi->bsd_dev = MAKEBOOTDEV(2, 0, 0, i, RAW_PART);
+ dip->bios_info.bsd_dev = MAKEBOOTDEV(2, 0, 0, i, RAW_PART);
+ if((bios_getdisklabel(&dip->bios_info, &dip->disklabel)) != 0)
+ dip->bios_info.flags |= BDI_BADLABEL;
+ else
+ dip->bios_info.flags |= BDI_GOODLABEL;
+
+ /* Add to queue of disks */
+ TAILQ_INSERT_TAIL(&disklist, dip, list);
}
+}
-#ifdef BIOS_DEBUG
- printf(";");
-#endif
+
+/* Probe for all BIOS floppies */
+static void
+hardprobe()
+{
+ struct diskinfo *dip;
+ int i;
+ u_int bsdunit, type;
+ u_int scsi = 0, ide = 0;
/* Hard disks */
- for(i = 0; i < 8; i++, pdi++) {
+ for(i = 0x80; i < 0x88; i++) {
+ dip = alloc(sizeof(struct diskinfo));
- if(bios_getinfo(i | 0x80, pdi)) {
+ if(bios_getdiskinfo(i, &dip->bios_info)) {
#ifdef BIOS_DEBUG
printf(" <!hd%u>", i);
#endif
+ free(dip, 0);
break;
}
- printf(" hd%u%s", i, (pdi->bios_edd > 0?"+":""));
+ printf(" hd%u%s", i&0x7f, (dip->bios_info.bios_edd > 0?"+":""));
/* Try to find the label, to figure out device type */
- if((bios_getdisklabel(i | 0x80, &label)) ) {
+ if((bios_getdisklabel(&dip->bios_info, &dip->disklabel)) ) {
printf("*");
bsdunit = ide++;
type = 0; /* XXX let it be IDE */
} else {
/* Best guess */
- switch (label.d_type) {
+ switch (dip->disklabel.d_type) {
case DTYPE_SCSI:
type = 4;
bsdunit = scsi++;
- pdi->flags |= BDI_GOODLABEL;
+ dip->bios_info.flags |= BDI_GOODLABEL;
break;
case DTYPE_ESDI:
case DTYPE_ST506:
type = 0;
bsdunit = ide++;
- pdi->flags |= BDI_GOODLABEL;
+ dip->bios_info.flags |= BDI_GOODLABEL;
break;
default:
- pdi->flags |= BDI_BADLABEL;
+ dip->bios_info.flags |= BDI_BADLABEL;
type = 0; /* XXX Suggest IDE */
bsdunit = ide++;
}
}
- pdi->checksum = 0; /* just in case */
+ dip->bios_info.checksum = 0; /* just in case */
/* Fill out best we can */
- pdi->bsd_dev = MAKEBOOTDEV(type, 0, 0, bsdunit, RAW_PART);
+ dip->bios_info.bsd_dev = MAKEBOOTDEV(type, 0, 0, bsdunit, RAW_PART);
+
+ /* Add to queue of disks */
+ TAILQ_INSERT_TAIL(&disklist, dip, list);
}
+}
+
+
+/* Probe for all BIOS supported disks */
+void
+diskprobe()
+{
+ struct diskinfo *dip;
+ int i;
+
+ /* These get passed to kernel */
+ bios_diskinfo_t *bios_diskinfo;
+ static u_int32_t bios_cksumlen;
+
+ /* Init stuff */
+ printf("disk:");
+ TAILQ_INIT(&disklist);
+
+ /* Do probes */
+ floppyprobe();
+#ifdef BIOS_DEBUG
+ printf(";");
+#endif
+ hardprobe();
+
- /* End of list */
- pdi->bios_number = -1;
/* Checksumming of hard disks */
for (i = 0; disksum(i++) && i < MAX_CKSUMLEN; )
;
bios_cksumlen = i;
- addbootarg(BOOTARG_CKSUMLEN, sizeof(u_int32_t), &bios_cksumlen);
- addbootarg(BOOTARG_DISKINFO, (pdi - bios_diskinfo + 1) *
- sizeof(bios_diskinfo[0]), bios_diskinfo);
+ /* Get space for passing bios_diskinfo stuff to kernel */
+ for(i = 0, dip = TAILQ_FIRST(&disklist); dip; dip = TAILQ_NEXT(dip, list))
+ i++;
+ bios_diskinfo = alloc(++i * sizeof(bios_diskinfo_t));
+
+ /* Copy out the bios_diskinfo stuff */
+ for(i = 0, dip = TAILQ_FIRST(&disklist); dip; dip = TAILQ_NEXT(dip, list))
+ bios_diskinfo[i++] = dip->bios_info;
+
+ bios_diskinfo[i++].bios_number = -1;
+ /* Register for kernel use */
+ addbootarg(BOOTARG_CKSUMLEN, sizeof(u_int32_t), &bios_cksumlen);
+ addbootarg(BOOTARG_DISKINFO, i * sizeof(bios_diskinfo_t), bios_diskinfo);
printf("\n");
}
+
/* Find info on given BIOS disk */
+struct diskinfo *
+dklookup(dev)
+ int dev;
+{
+ struct diskinfo *dip;
+
+ for(dip = TAILQ_FIRST(&disklist); dip; dip = TAILQ_NEXT(dip, list))
+ if(dip->bios_info.bios_number == dev)
+ return(dip);
+
+ return(NULL);
+}
+
+void
+dump_diskinfo()
+{
+ struct diskinfo *dip;
+
+ (void)fstypenames, (void)fstypesnames;
+
+ printf("Disk\tBIOS#\tType\tCyls\tHeads\tSecs\tFlags\tChecksum\n");
+ for(dip = TAILQ_FIRST(&disklist); dip; dip = TAILQ_NEXT(dip, list)){
+ bios_diskinfo_t *bdi = &dip->bios_info;
+ int d = bdi->bios_number;
+
+ printf("%cd%d\t0x%x\t%s\t%d\t%d\t%d\t0x%x\t0x%x\n",
+ (d & 0x80)?'h':'f', d & 0x7F, d,
+ (bdi->flags & BDI_BADLABEL)?"*none*":
+ dktypenames[B_TYPE(dip->disklabel.d_type)],
+ bdi->bios_cylinders, bdi->bios_heads, bdi->bios_sectors,
+ bdi->flags, bdi->checksum);
+ }
+}
+
+/* Find BIOS protion on given BIOS disk
+ * XXX - Use dklookup() instead.
+ */
bios_diskinfo_t *
bios_dklookup(dev)
register int dev;
{
- register int i;
+ struct diskinfo *dip;
- for(i = 0; bios_diskinfo[i].bios_number != -1; i++)
- if(bios_diskinfo[i].bios_number == dev)
- return(&bios_diskinfo[i]);
+ dip = dklookup(dev);
+ if(dip)
+ return(&dip->bios_info);
return(NULL);
}
@@ -164,14 +261,16 @@ static int
disksum(blk)
int blk;
{
- bios_diskinfo_t *bdi, *bd;
+ struct diskinfo *dip, *dip2;
int st, reprobe = 0;
int hpc, spt, dev;
char *buf;
int cyl, head, sect;
buf = alloca(DEV_BSIZE);
- for (bdi = bios_diskinfo; bdi->bios_number != -1; bdi++) {
+ for(dip = TAILQ_FIRST(&disklist); dip; dip = TAILQ_NEXT(dip, list)){
+ bios_diskinfo_t *bdi = &dip->bios_info;
+
/* Skip this disk if it is not a HD or has had an I/O error */
if (!(bdi->bios_number & 0x80) || bdi->flags & BDI_INVALID)
continue;
@@ -189,12 +288,16 @@ disksum(blk)
}
bdi->checksum = adler32(bdi->checksum, buf, DEV_BSIZE);
- for (bd = bios_diskinfo; bd != bdi; bd++)
+ for(dip2 = TAILQ_FIRST(&disklist); dip2 != dip;
+ dip2 = TAILQ_NEXT(dip2, list)){
+ bios_diskinfo_t *bd = &dip2->bios_info;
if ((bd->bios_number & 0x80) &&
!(bd->flags & BDI_INVALID) &&
bdi->checksum == bd->checksum)
reprobe = 1;
+ }
}
return (reprobe);
}
+