summaryrefslogtreecommitdiff
path: root/sys/arch/amd64
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2004-08-11 18:51:05 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2004-08-11 18:51:05 +0000
commitfec58ae8c4bc4002d602ce897ee4f88767e23679 (patch)
treee53b89ab6350db64b6d90a958cbbf40685d7d5c2 /sys/arch/amd64
parent59be772d42b86c228dc34c00c6c7be3a6b9bc0a9 (diff)
In dkcsumattach() avoid modifying bootdev until we are done matching.
Also deal with mixed scsi/ide/whatever setups. Based on a diff from Fred de Jong. OK deraadt@ and tested by several people.
Diffstat (limited to 'sys/arch/amd64')
-rw-r--r--sys/arch/amd64/amd64/dkcsum.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/sys/arch/amd64/amd64/dkcsum.c b/sys/arch/amd64/amd64/dkcsum.c
index e1c4e285863..8757875fb45 100644
--- a/sys/arch/amd64/amd64/dkcsum.c
+++ b/sys/arch/amd64/amd64/dkcsum.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dkcsum.c,v 1.1 2004/02/25 00:16:04 deraadt Exp $ */
+/* $OpenBSD: dkcsum.c,v 1.2 2004/08/11 18:51:04 millert Exp $ */
/*-
* Copyright (c) 1997 Niklas Hallqvist. All rights reserved.
@@ -58,7 +58,7 @@ dkcsumattach(void)
struct device *dv;
struct buf *bp;
struct bdevsw *bdsw;
- dev_t dev;
+ dev_t dev, pribootdev, altbootdev;
int error;
u_int32_t csum;
bios_diskinfo_t *bdi, *hit;
@@ -67,6 +67,8 @@ dkcsumattach(void)
if (bios_diskinfo == NULL || bios_cksumlen * DEV_BSIZE > MAXBSIZE)
return;
+ pribootdev = altbootdev = 0;
+
/*
* XXX Whatif DEV_BSIZE is changed to something else than the BIOS
* blocksize? Today, /boot doesn't cover that case so neither need
@@ -164,22 +166,37 @@ dkcsumattach(void)
continue;
}
- /* Fixup bootdev if units match. This means that all of
+ /*
+ * Fixup bootdev if units match. This means that all of
* hd*, sd*, wd*, will be interpreted the same. Not 100%
* backwards compatible, but sd* and wd* should be phased-
* out in the bootblocks.
*/
+
+ /* B_TYPE dependent hd unit counting bootblocks */
+ if ((B_TYPE(bootdev) == B_TYPE(hit->bsd_dev)) &&
+ (B_UNIT(bootdev) == B_UNIT(hit->bsd_dev))) {
+ int type, ctrl, adap, part, unit;
+
+ type = major(bp->b_dev);
+ adap = B_ADAPTOR(bootdev);
+ ctrl = B_CONTROLLER(bootdev);
+ unit = DISKUNIT(bp->b_dev);
+ part = B_PARTITION(bootdev);
+
+ pribootdev = MAKEBOOTDEV(type, ctrl, adap, unit, part);
+ }
+ /* B_TYPE independent hd unit counting bootblocks */
if (B_UNIT(bootdev) == (hit->bios_number & 0x7F)) {
int type, ctrl, adap, part, unit;
- /* Translate to MAKEBOOTDEV() style */
type = major(bp->b_dev);
adap = B_ADAPTOR(bootdev);
ctrl = B_CONTROLLER(bootdev);
unit = DISKUNIT(bp->b_dev);
part = B_PARTITION(bootdev);
- bootdev = MAKEBOOTDEV(type, ctrl, adap, unit, part);
+ altbootdev = MAKEBOOTDEV(type, ctrl, adap, unit, part);
}
/* This will overwrite /boot's guess, just so you remember */
@@ -187,6 +204,8 @@ dkcsumattach(void)
DISKUNIT(bp->b_dev), RAW_PART);
hit->flags |= BDI_PICKED;
}
+ bootdev = pribootdev ? pribootdev : altbootdev ? altbootdev : bootdev;
+
bp->b_flags |= B_INVAL;
brelse(bp);
}