diff --git a/sys/arch/ofppc/stand/ofwboot/ofdev.c b/sys/arch/ofppc/stand/ofwboot/ofdev.c index 077ad9489d65..d643a8669f34 100644 --- a/sys/arch/ofppc/stand/ofwboot/ofdev.c +++ b/sys/arch/ofppc/stand/ofwboot/ofdev.c @@ -1,4 +1,4 @@ -/* $NetBSD: ofdev.c,v 1.7 2002/06/18 00:37:25 itojun Exp $ */ +/* $NetBSD: ofdev.c,v 1.8 2002/09/18 01:45:25 chs Exp $ */ /* * Copyright (C) 1995, 1996 Wolfgang Solfrank. @@ -52,9 +52,9 @@ extern char bootdev[]; #ifdef DEBUG # define DPRINTF printf -#else +#else # define DPRINTF while (0) printf -#endif +#endif static char * filename(str, ppart) @@ -65,35 +65,53 @@ filename(str, ppart) char savec; int dhandle; char devtype[16]; - + lp = str; devtype[0] = 0; *ppart = 0; for (cp = str; *cp; lp = cp) { + /* For each component of the path name... */ - while (*++cp && *cp != '/'); + while (*++cp && *cp != '/') + ; savec = *cp; *cp = 0; + /* ...look whether there is a device with this name */ dhandle = OF_finddevice(str); *cp = savec; if (dhandle == -1) { - /* if not, lp is the delimiter between device and path */ - /* if the last component was a block device... */ + + /* + * if not, lp is the delimiter between device and path + * if the last component was a block device. + */ + if (!strcmp(devtype, "block")) { + /* search for arguments */ for (cp = lp; - --cp >= str && *cp != '/' && *cp != ':';); + --cp >= str && *cp != '/' && *cp != ':';) + ; if (cp >= str && *cp == ':') { - /* found arguments, make firmware ignore them */ + + /* + * found some arguments, + * make OFW ignore them. + */ + *cp = 0; - for (cp = lp; *--cp && *cp != ',';); - if (*++cp >= 'a' && *cp <= 'a' + MAXPARTITIONS) + for (cp = lp; *--cp && *cp != ',';) + ; + if (*++cp >= 'a' && + *cp < 'a' + MAXPARTITIONS) *ppart = *cp; } } return lp; - } else if (OF_getprop(dhandle, "device_type", devtype, sizeof devtype) < 0) + } + if (OF_getprop(dhandle, "device_type", devtype, + sizeof devtype) < 0) devtype[0] = 0; } return 0; @@ -109,16 +127,16 @@ strategy(devdata, rw, blk, size, buf, rsize) size_t *rsize; { struct of_dev *dev = devdata; - u_quad_t pos; + uint64_t pos; int n; - + if (rw != F_READ) return EPERM; if (dev->type != OFDEV_DISK) panic("strategy"); - - pos = (u_quad_t)(blk + dev->partoff) * dev->bsize; - + + pos = (uint64_t)(blk + dev->partoff) * dev->bsize; + for (;;) { if (OF_seek(dev->handle, pos) < 0) break; @@ -138,7 +156,7 @@ devclose(of) struct open_file *of; { struct of_dev *op = of->f_devdata; - + if (op->type == OFDEV_NET) net_close(op); OF_close(op->handle); @@ -184,7 +202,7 @@ get_long(p) const void *p; { const unsigned char *cp = p; - + return cp[0] | (cp[1] << 8) | (cp[2] << 16) | (cp[3] << 24); } @@ -204,18 +222,18 @@ search_label(devp, off, buf, lp, off0) int i; u_long poff; static int recursion; - + if (strategy(devp, F_READ, off, DEV_BSIZE, buf, &read) || read != DEV_BSIZE) return ERDLAB; - + if (*(u_int16_t *)&buf[MBR_MAGICOFF] != sa_htole16(MBR_MAGIC)) return ERDLAB; if (recursion++ <= 1) off0 += off; - for (p = (struct mbr_partition *)(buf + MBR_PARTOFF), i = 4; - --i >= 0; p++) { + for (p = (struct mbr_partition *)(buf + MBR_PARTOFF), i = 0; + i < NMBRPART; i++, p++) { if (p->mbrp_typ == MBR_PTYPE_NETBSD #ifdef COMPAT_386BSD_MBRPART || (p->mbrp_typ == MBR_PTYPE_386BSD && @@ -250,6 +268,7 @@ search_label(devp, off, buf, lp, off0) } } } + recursion--; return ERDLAB; } @@ -296,6 +315,9 @@ devopen(of, name, file) strcat(opened_name, "/"); strcat(opened_name, buf); *file = opened_name + strlen(fname) + 1; + if (partition) { + *file += 2; + } if ((handle = OF_finddevice(fname)) == -1) { DPRINTF("OF_finddevice(\"%s\") failed\n", fname); return ENOENT; @@ -305,9 +327,15 @@ devopen(of, name, file) floppyboot = !strcmp(buf, "floppy"); if (OF_getprop(handle, "device_type", buf, sizeof buf) < 0) return ENXIO; - if (!strcmp(buf, "block")) - /* For block devices, indicate raw partition (:0 in OpenFirmware) */ + if (!strcmp(buf, "block")) { + + /* + * For block devices, indicate raw partition + * (:0 in OpenFirmware) + */ + strcat(fname, ":0"); + } if ((handle = OF_open(fname)) == -1) return ENXIO; memset(&ofdev, 0, sizeof ofdev); @@ -315,11 +343,13 @@ devopen(of, name, file) if (!strcmp(buf, "block")) { ofdev.type = OFDEV_DISK; ofdev.bsize = DEV_BSIZE; + /* First try to find a disklabel without MBR partitions */ if (strategy(&ofdev, F_READ, LABELSECTOR, DEV_BSIZE, buf, &read) != 0 || read != DEV_BSIZE || getdisklabel(buf, &label)) { + /* Else try MBR partitions */ error = search_label(&ofdev, 0, buf, &label, 0); if (error && error != ERDLAB) @@ -327,22 +357,29 @@ devopen(of, name, file) } if (error == ERDLAB) { - if (partition) - /* User specified a parititon, but there is none */ + if (partition) { + + /* + * User specified a parititon, + * but there is none. + */ + goto bad; - /* No, label, just use complete disk */ + } + + /* No label, just use complete disk */ ofdev.partoff = 0; } else { part = partition ? partition - 'a' : 0; ofdev.partoff = label.d_partitions[part].p_offset; } - + of->f_dev = devsw; of->f_devdata = &ofdev; file_system[0] = file_system_ufs; file_system[1] = file_system_cd9660; - file_system[1] = file_system_dosfs; - nfsys = 2; + file_system[2] = file_system_dosfs; + nfsys = 3; return 0; } if (!strcmp(buf, "network")) {