- Check if a disk has wedges, and use the wedge device corresponding to the
root partition, instead of punting. This makes booting work with traditional disklabel disks and wedge autoconfiguration. - factor out disk opening code.
This commit is contained in:
parent
adddcaa6ee
commit
cf1ddb6596
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: x86_autoconf.c,v 1.17 2006/08/12 19:55:42 christos Exp $ */
|
||||
/* $NetBSD: x86_autoconf.c,v 1.18 2006/08/12 21:45:22 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
@ -65,6 +65,109 @@ __KERNEL_RCSID(0, "$NetBSD");
|
||||
struct disklist *x86_alldisks;
|
||||
int x86_ndisks;
|
||||
|
||||
static struct vnode *
|
||||
opendisk(struct device *dv)
|
||||
{
|
||||
int bmajor;
|
||||
struct vnode *tmpvn;
|
||||
int error;
|
||||
|
||||
/*
|
||||
* Lookup major number for disk block device.
|
||||
*/
|
||||
bmajor = devsw_name2blk(dv->dv_xname, NULL, 0);
|
||||
if (bmajor == -1)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Fake a temporary vnode for the disk, open it, and read
|
||||
* and hash the sectors.
|
||||
*/
|
||||
if (bdevvp(MAKEDISKDEV(bmajor, device_unit(dv), RAW_PART), &tmpvn))
|
||||
panic("%s: can't alloc vnode for %s", __func__, dv->dv_xname);
|
||||
error = VOP_OPEN(tmpvn, FREAD, NOCRED, 0);
|
||||
if (error) {
|
||||
#ifndef DEBUG
|
||||
/*
|
||||
* Ignore errors caused by missing device, partition,
|
||||
* or medium.
|
||||
*/
|
||||
if (error != ENXIO && error != ENODEV)
|
||||
#endif
|
||||
printf("%s: can't open dev %s (%d)\n",
|
||||
__func__, dv->dv_xname, error);
|
||||
vput(tmpvn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return tmpvn;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_wedges(struct device *dv, int par)
|
||||
{
|
||||
struct dkwedge_list wl;
|
||||
struct dkwedge_info *wi;
|
||||
struct vnode *vn;
|
||||
char diskname[16];
|
||||
int i, error;
|
||||
|
||||
if ((vn = opendisk(dv)) == NULL)
|
||||
goto out;
|
||||
|
||||
wl.dkwl_bufsize = sizeof(*wi) * 16;
|
||||
wl.dkwl_buf = wi = malloc(wl.dkwl_bufsize, M_TEMP, M_WAITOK);
|
||||
|
||||
error = VOP_IOCTL(vn, DIOCLWEDGES, &wl, FREAD, NOCRED, 0);
|
||||
vput(vn);
|
||||
if (error) {
|
||||
#ifdef DEBUG_WEDGE
|
||||
printf("%s: List wedges returned %d\n", dv->dv_xname, error);
|
||||
#endif
|
||||
free(wi, M_TEMP);
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_WEDGE
|
||||
printf("%s: Returned %u(%u) wedges\n", dv->dv_xname,
|
||||
wl.dkwl_nwedges, wl.dkwl_ncopied);
|
||||
#endif
|
||||
snprintf(diskname, sizeof(diskname), "%s%c", dv->dv_xname,
|
||||
par + 'a');
|
||||
|
||||
for (i = 0; i < wl.dkwl_ncopied; i++) {
|
||||
#ifdef DEBUG_WEDGE
|
||||
printf("%s: Looking for %s in %s\n",
|
||||
dv->dv_xname, diskname, wi[i].dkw_wname);
|
||||
#endif
|
||||
if (strcmp(wi[i].dkw_wname, diskname) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == wl.dkwl_ncopied) {
|
||||
#ifdef DEBUG_WEDGE
|
||||
printf("%s: Cannot find wedge with parent %s\n",
|
||||
dv->dv_xname, diskname);
|
||||
#endif
|
||||
free(wi, M_TEMP);
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_WEDGE
|
||||
printf("%s: Setting boot wedge %s (%s) at %llu %llu\n",
|
||||
dv->dv_xname, wi[i].dkw_devname, wi[i].dkw_wname,
|
||||
(unsigned long long)wi[i].dkw_offset,
|
||||
(unsigned long long)wi[i].dkw_size);
|
||||
#endif
|
||||
dkwedge_set_bootwedge(dv, wi[i].dkw_offset, wi[i].dkw_size);
|
||||
free(wi, M_TEMP);
|
||||
return;
|
||||
out:
|
||||
booted_device = dv;
|
||||
booted_partition = par;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
is_valid_disk(struct device *dv)
|
||||
{
|
||||
@ -93,7 +196,7 @@ matchbiosdisks(void)
|
||||
struct vnode *tv;
|
||||
char mbr[DEV_BSIZE];
|
||||
int dklist_size;
|
||||
int bmajor, numbig;
|
||||
int numbig;
|
||||
|
||||
big = lookup_bootinfo(BTINFO_BIOSGEOM);
|
||||
|
||||
@ -149,19 +252,9 @@ matchbiosdisks(void)
|
||||
sizeof(x86_alldisks->dl_nativedisks[n].ni_devname),
|
||||
"%s", dv->dv_xname);
|
||||
|
||||
bmajor = devsw_name2blk(dv->dv_xname, NULL, 0);
|
||||
if (bmajor == -1)
|
||||
return;
|
||||
|
||||
if (bdevvp(MAKEDISKDEV(bmajor, device_unit(dv),
|
||||
RAW_PART), &tv))
|
||||
panic("matchbiosdisks: can't alloc vnode");
|
||||
|
||||
error = VOP_OPEN(tv, FREAD, NOCRED, 0);
|
||||
if (error) {
|
||||
vput(tv);
|
||||
if ((tv = opendisk(dv)) == NULL)
|
||||
continue;
|
||||
}
|
||||
|
||||
error = vn_rdwr(UIO_READ, tv, mbr, DEV_BSIZE, 0,
|
||||
UIO_SYSSPACE, 0, NOCRED, NULL, NULL);
|
||||
VOP_CLOSE(tv, FREAD, NOCRED, 0);
|
||||
@ -215,7 +308,6 @@ match_bootwedge(struct device *dv, struct btinfo_bootwedge *biw)
|
||||
uint8_t bf[DEV_BSIZE];
|
||||
uint8_t hash[16];
|
||||
int found = 0;
|
||||
int bmajor;
|
||||
daddr_t blk;
|
||||
uint64_t nblks;
|
||||
|
||||
@ -224,34 +316,6 @@ match_bootwedge(struct device *dv, struct btinfo_bootwedge *biw)
|
||||
*/
|
||||
if (biw->matchblk == -1)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Lookup major number for disk block device.
|
||||
*/
|
||||
bmajor = devsw_name2blk(dv->dv_xname, NULL, 0);
|
||||
if (bmajor == -1)
|
||||
return (0); /* XXX panic ??? */
|
||||
|
||||
/*
|
||||
* Fake a temporary vnode for the disk, open it, and read
|
||||
* and hash the sectors.
|
||||
*/
|
||||
if (bdevvp(MAKEDISKDEV(bmajor, device_unit(dv), RAW_PART), &tmpvn))
|
||||
panic("findroot: can't alloc vnode");
|
||||
error = VOP_OPEN(tmpvn, FREAD, NOCRED, 0);
|
||||
if (error) {
|
||||
#ifndef DEBUG
|
||||
/*
|
||||
* Ignore errors caused by missing device, partition,
|
||||
* or medium.
|
||||
*/
|
||||
if (error != ENXIO && error != ENODEV)
|
||||
#endif
|
||||
printf("findroot: can't open dev %s (%d)\n",
|
||||
dv->dv_xname, error);
|
||||
vput(tmpvn);
|
||||
return (0);
|
||||
}
|
||||
|
||||
MD5Init(&ctx);
|
||||
for (blk = biw->matchblk, nblks = biw->matchnblks;
|
||||
@ -288,7 +352,9 @@ match_bootdisk(struct device *dv, struct btinfo_bootdisk *bid)
|
||||
int error;
|
||||
struct disklabel label;
|
||||
int found = 0;
|
||||
int bmajor;
|
||||
|
||||
if (device_is_a(dv, "dk"))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* A disklabel is required here. The boot loader doesn't refuse
|
||||
@ -298,33 +364,9 @@ match_bootdisk(struct device *dv, struct btinfo_bootdisk *bid)
|
||||
if (bid->labelsector == -1)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Lookup major number for disk block device.
|
||||
*/
|
||||
bmajor = devsw_name2blk(dv->dv_xname, NULL, 0);
|
||||
if (bmajor == -1)
|
||||
return (0); /* XXX panic ??? */
|
||||
if ((tmpvn = opendisk(dv)) == NULL)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Fake a temporary vnode for the disk, open it, and read
|
||||
* the disklabel for comparison.
|
||||
*/
|
||||
if (bdevvp(MAKEDISKDEV(bmajor, device_unit(dv), RAW_PART), &tmpvn))
|
||||
panic("findroot: can't alloc vnode");
|
||||
error = VOP_OPEN(tmpvn, FREAD, NOCRED, 0);
|
||||
if (error) {
|
||||
#ifndef DEBUG
|
||||
/*
|
||||
* Ignore errors caused by missing device, partition,
|
||||
* or medium.
|
||||
*/
|
||||
if (error != ENXIO && error != ENODEV)
|
||||
#endif
|
||||
printf("findroot: can't open dev %s (%d)\n",
|
||||
dv->dv_xname, error);
|
||||
vput(tmpvn);
|
||||
return (0);
|
||||
}
|
||||
error = VOP_IOCTL(tmpvn, DIOCGDINFO, &label, FREAD, NOCRED, 0);
|
||||
if (error) {
|
||||
/*
|
||||
@ -340,7 +382,7 @@ match_bootdisk(struct device *dv, struct btinfo_bootdisk *bid)
|
||||
if (label.d_type == bid->label.type &&
|
||||
label.d_checksum == bid->label.checksum &&
|
||||
strncmp(label.d_packname, bid->label.packname, 16) == 0)
|
||||
found = 1;
|
||||
found = 1;
|
||||
|
||||
closeout:
|
||||
VOP_CLOSE(tmpvn, FREAD, NOCRED, 0);
|
||||
@ -403,8 +445,7 @@ findroot(void)
|
||||
|
||||
if (strncmp(cd->cf_name, biv->devname, len) == 0 &&
|
||||
biv->devname[len] - '0' == cd->cf_unit) {
|
||||
booted_device = dv;
|
||||
booted_partition = biv->devname[len + 1] - 'a';
|
||||
handle_wedges(dv, biv->devname[len + 1] - 'a');
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -497,8 +538,7 @@ findroot(void)
|
||||
booted_device->dv_xname, dv->dv_xname);
|
||||
continue;
|
||||
}
|
||||
booted_device = dv;
|
||||
booted_partition = bid->partition;
|
||||
handle_wedges(dv, bid->partition);
|
||||
}
|
||||
|
||||
if (booted_device)
|
||||
|
Loading…
Reference in New Issue
Block a user