diff options
Diffstat (limited to 'sys/arch/pegasos/stand/ofdev.c')
-rw-r--r-- | sys/arch/pegasos/stand/ofdev.c | 484 |
1 files changed, 0 insertions, 484 deletions
diff --git a/sys/arch/pegasos/stand/ofdev.c b/sys/arch/pegasos/stand/ofdev.c deleted file mode 100644 index 73d0c33ef0e..00000000000 --- a/sys/arch/pegasos/stand/ofdev.c +++ /dev/null @@ -1,484 +0,0 @@ -/* $OpenBSD: ofdev.c,v 1.2 2003/11/14 20:12:04 drahn Exp $ */ -/* $NetBSD: ofdev.c,v 1.1 1997/04/16 20:29:20 thorpej Exp $ */ - -/* - * Copyright (C) 1995, 1996 Wolfgang Solfrank. - * Copyright (C) 1995, 1996 TooLs GmbH. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by TooLs GmbH. - * 4. The name of TooLs GmbH may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * Device I/O routines using Open Firmware - */ -#include <sys/param.h> -#include <sys/disklabel.h> -#include <netinet/in.h> - -#include <lib/libsa/stand.h> -#include <lib/libsa/ufs.h> -#include <lib/libsa/cd9660.h> -#include <lib/libsa/nfs.h> -#include <offs.h> - -#include "ofdev.h" - -extern char bootdev[]; - -static char * -filename(char *str, char *ppart) -{ - char *cp, *lp; - 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 != '/') - ; - 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 (!strcmp(devtype, "block")) { - /* search for arguments */ - for (cp = lp; - --cp >= str && *cp != '/' && *cp != ':';) - ; - if (cp >= str && *cp == ':') { - /* found arguments */ - 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) - devtype[0] = 0; - } - return 0; -} - -static int -strategy(void *devdata, int rw, daddr_t blk, size_t size, void *buf, - size_t *rsize) -{ - struct of_dev *dev = devdata; - u_quad_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; - - for (;;) { - if (OF_seek(dev->handle, pos) < 0) - break; - n = OF_read(dev->handle, buf, size); - if (n == -2) - continue; - if (n < 0) - break; - *rsize = n; - return 0; - } - return EIO; -} - -static int -devclose(struct open_file *of) -{ - struct of_dev *op = of->f_devdata; - - if (op->type == OFDEV_NET) - net_close(op); - if (op->dmabuf) - OF_call_method("dma-free", op->handle, 2, 0, - op->dmabuf, MAXPHYS); - - OF_close(op->handle); - op->handle = -1; -} - -static struct devsw devsw[1] = { - "OpenFirmware", - strategy, - (int (*)(struct open_file *, ...))nodev, - devclose, - noioctl -}; -int ndevs = sizeof devsw / sizeof devsw[0]; - -static struct fs_ops file_system_ufs = { - ufs_open, ufs_close, ufs_read, ufs_write, ufs_seek, ufs_stat -}; -static struct fs_ops file_system_cd9660 = { - cd9660_open, cd9660_close, cd9660_read, cd9660_write, cd9660_seek, - cd9660_stat -}; -static struct fs_ops file_system_offs = { - offs_open, offs_close, offs_read, offs_write, offs_seek, offs_stat -}; -static struct fs_ops file_system_nfs = { - nfs_open, nfs_close, nfs_read, nfs_write, nfs_seek, nfs_stat -}; - -struct fs_ops file_system[3]; -int nfsys; - -static struct of_dev ofdev = { - -1, -}; - -char opened_name[256]; - -static u_long -get_long(p) - const void *p; -{ - const unsigned char *cp = p; - - return cp[0] | (cp[1] << 8) | (cp[2] << 16) | (cp[3] << 24); -} - -int -read_mac_label(struct of_dev *devp, char *buf, struct disklabel *lp) -{ - struct part_map_entry *part; - size_t read; - int part_cnt; - int i; - char *s; - - if ((strategy(devp, F_READ, 1, DEV_BSIZE, buf, &read) != 0) || - (read != DEV_BSIZE)) - return ERDLAB; - - part = (struct part_map_entry *)buf; - - /* if first partition is not valid, assume not HFS/DPME partitioned */ - if (part->pmSig != PART_ENTRY_MAGIC) - return ERDLAB; - - part_cnt = part->pmMapBlkCnt; - - /* first search for "OpenBSD" partition type - * standard bsd disklabel lives inside at offset 0 - * otherwise, we should fake a bsd partition - * with first HFS partition starting at 'i' - * ? will this cause problems with booting bsd.rd from offs - */ - for (i = 0; i < part_cnt; i++) { - /* read the appropriate block */ - if ((strategy(devp, F_READ, 1+i, DEV_BSIZE, buf, &read) != 0) - || (read != DEV_BSIZE)) - return ERDLAB; - - part = (struct part_map_entry *)buf; - /* toupper the string, in case caps are different... */ - for (s = part->pmPartType; *s; s++) - if ((*s >= 'a') && (*s <= 'z')) - *s = (*s - 'a' + 'A'); - - if (0 == strcmp(part->pmPartType, PART_TYPE_OPENBSD)) { - /* FOUND OUR PARTITION!!! */ - printf("found OpenBSD DPME partition\n"); - if(strategy(devp, F_READ, part->pmPyPartStart, - DEV_BSIZE, buf, &read) == 0 - && read == DEV_BSIZE) - { - if (!getdisklabel(buf, lp)) - return 0; - - /* If we have an OpenBSD region - * but no valid parition table, - * we cannot load a kernel from - * it, punt. - * should not have more than one - * OpenBSD of DPME type. - */ - return ERDLAB; - } - } - } - return ERDLAB; -} - -/* - * Search for RDB OpenBSD paritition. - */ -int -read_rdb_label(struct of_dev *devp, char *buf, struct disklabel *lp) -{ - struct rdblock *rdp; - struct partblock *pbp; - struct partition *pp; - size_t read; - int part_cnt; - int nextb; - int rdbpart; - int i; - char *s; - - for (nextb = 0; nextb < RDB_MAXBLOCKS; nextb++) { - if ((strategy(devp, F_READ, nextb, DEV_BSIZE, buf, &read) - != 0) || (read != DEV_BSIZE)) - return ERDLAB; - rdp = (struct rdblock *)buf; - - /* skips checksum */ - if (rdp->id == RDBLOCK_ID) - break; - } - if (nextb == RDB_MAXBLOCKS) - return ERDLAB; - for (nextb = rdp->partbhead; nextb != RDBNULL; nextb = pbp->next) { - if ((strategy(devp, F_READ, nextb, DEV_BSIZE, buf, &read) - != 0) || (read != DEV_BSIZE)) - return ERDLAB; - pbp = (struct partblock *)buf; - if (pbp->id != PARTBLOCK_ID) - return ERDLAB; - /* skips checksum */ - if (pbp->e.dostype == DOST_OBSD) { - rdbpart = pbp->e.lowcyl * pbp->e.secpertrk; - break; - } - } - if (nextb == RDBNULL) - return ERDLAB; - - printf("found OpenBSD RDB partition\n"); - if(strategy(devp, F_READ, rdbpart, DEV_BSIZE, buf, &read) == 0 - && read == DEV_BSIZE) - { - if (!getdisklabel(buf, lp)) - return 0; - - /* If we have an OpenBSD region - * but no valid parition table, - * we cannot load a kernel from - * it, punt. - * should not have more than one - * RDB of OpenBSD type. - */ - return ERDLAB; - } - - return ERDLAB; -} - -/* - * Find a valid disklabel. - */ -static int -search_label(struct of_dev *devp, u_long off, char *buf, struct disklabel *lp, - u_long off0) -{ - size_t read; - struct dos_partition *p; - int i; - u_long poff; - static int recursion; - - if (strategy(devp, F_READ, off, DEV_BSIZE, buf, &read) || - read != DEV_BSIZE) - return ERDLAB; - - if (buf[510] != 0x55 || buf[511] != 0xaa) - return ERDLAB; - - if (recursion++ <= 1) - off0 += off; - for (p = (struct dos_partition *)(buf + DOSPARTOFF), i = 4; - --i >= 0; p++) { - if (p->dp_typ == DOSPTYP_OPENBSD || - p->dp_typ == DOSPTYP_NETBSD) { - poff = get_long(&p->dp_start) + off0; - if (strategy(devp, F_READ, poff + LABELSECTOR, - DEV_BSIZE, buf, &read) == 0 - && read == DEV_BSIZE) { - if (!getdisklabel(buf, lp)) { - recursion--; - return 0; - } - } - if (strategy(devp, F_READ, off, DEV_BSIZE, buf, &read) - || read != DEV_BSIZE) { - recursion--; - return ERDLAB; - } - } else if (p->dp_typ == DOSPTYP_EXTEND) { - poff = get_long(&p->dp_start); - if (!search_label(devp, poff, buf, lp, off0)) { - recursion--; - return 0; - } - if (strategy(devp, F_READ, off, DEV_BSIZE, buf, &read) - || read != DEV_BSIZE) { - recursion--; - return ERDLAB; - } - } - } - recursion--; - return ERDLAB; -} - -int -devopen(struct open_file *of, const char *name, char **file) -{ - char *cp; - char partition; - char fname[256]; - char buf[DEV_BSIZE]; - struct disklabel label; - int handle, part; - size_t read; - int error = 0; - - if (ofdev.handle != -1) - panic("devopen"); - if (of->f_flags != F_READ) - return EPERM; - strlcpy(fname, name, sizeof fname); - cp = filename(fname, &partition); - if (cp) { - strlcpy(buf, cp, sizeof buf); - *cp = 0; - } - if (!cp || !*buf) - strlcpy(buf, DEFAULT_KERNEL, sizeof buf); - if (!*fname) - strlcpy(fname, bootdev, sizeof fname); - strlcpy(opened_name, fname, sizeof opened_name); - if (partition) { - cp = opened_name + strlen(opened_name); - *cp++ = ':'; - *cp++ = partition; - *cp = 0; - } - if (*buf != '/') - strlcat(opened_name, "/", sizeof opened_name); - strlcat(opened_name, buf, sizeof opened_name); - *file = opened_name + strlen(fname) + 1; - if ((handle = OF_finddevice(fname)) == -1) - return ENOENT; - if (OF_getprop(handle, "name", buf, sizeof buf) < 0) - return ENXIO; - 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) - */ - strlcat(fname, ":0", sizeof fname); - if ((handle = OF_open(fname)) == -1) - return ENXIO; - bzero(&ofdev, sizeof ofdev); - ofdev.handle = handle; - ofdev.dmabuf = NULL; - OF_call_method("dma-alloc", handle, 1, 1, MAXPHYS, &ofdev.dmabuf); - 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 = read_rdb_label(&ofdev, buf, &label); - if (error == ERDLAB) - error = read_mac_label(&ofdev, buf, &label); - - if (error == ERDLAB) - error = search_label(&ofdev, 0, buf, &label, 0); - - if (error && error != ERDLAB) - goto bad; - } - - if (error == ERDLAB) { - if (partition) - /* - * User specified a partition, - * but there is none - */ - goto bad; - /* 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; - bcopy(&file_system_ufs, file_system, sizeof file_system[0]); - bcopy(&file_system_cd9660, file_system + 1, - sizeof file_system[0]); - bcopy(&file_system_offs, file_system + 2, - sizeof file_system[0]); - nfsys = 3; - return 0; - } - if (!strcmp(buf, "network")) { - ofdev.type = OFDEV_NET; - of->f_dev = devsw; - of->f_devdata = &ofdev; - bcopy(&file_system_nfs, file_system, sizeof file_system[0]); - nfsys = 1; - if (error = net_open(&ofdev)) - goto bad; - return 0; - } - error = EFTYPE; -bad: - OF_close(handle); - ofdev.handle = -1; - return error; -} |