diff options
Diffstat (limited to 'sys/arch/loongson/stand/boot/devopen.c')
-rw-r--r-- | sys/arch/loongson/stand/boot/devopen.c | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/sys/arch/loongson/stand/boot/devopen.c b/sys/arch/loongson/stand/boot/devopen.c new file mode 100644 index 00000000000..96fb75af979 --- /dev/null +++ b/sys/arch/loongson/stand/boot/devopen.c @@ -0,0 +1,121 @@ +/* $OpenBSD: devopen.c,v 1.1 2010/02/14 22:39:33 miod Exp $ */ + +/*- + * Copyright (c) 2003 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Rolf Grossmann. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``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 THE FOUNDATION OR CONTRIBUTORS + * 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. + */ + +#include "libsa.h" + +#define MAXDEVNAME 16 + +/* + * Parse a device spec. + * + * [A-Za-z]*[0-9]*[A-Za-z]:file + * dev uint part + */ +int +devparse(const char *fname, int *dev, int *unit, int *part, const char **file) +{ + const char *s; + + *unit = 0; /* default to wd0a */ + *part = 0; + *dev = 0; + + s = strchr(fname, ':'); + if (s != NULL) { + int devlen; + int i, u, p = 0; + struct devsw *dp; + char devname[MAXDEVNAME]; + + devlen = s - fname; + if (devlen > MAXDEVNAME) + return (EINVAL); + + /* extract device name */ + for (i = 0; isalpha(fname[i]) && (i < devlen); i++) + devname[i] = fname[i]; + devname[i] = 0; + + if (!isdigit(fname[i])) + return (EUNIT); + + /* device number */ + for (u = 0; isdigit(fname[i]) && (i < devlen); i++) + u = u * 10 + (fname[i] - '0'); + + if (!isalpha(fname[i])) + return (EPART); + + /* partition number */ + if (i < devlen) + p = fname[i++] - 'a'; + + if (i != devlen) + return (ENXIO); + + /* check device name */ + for (dp = devsw, i = 0; i < ndevs; dp++, i++) { + if (dp->dv_name && !strcmp(devname, dp->dv_name)) + break; + } + + if (i >= ndevs) + return (ENXIO); + + *unit = u; + *part = p; + *dev = i; + fname = ++s; + } + + *file = fname; + + return (0); +} + +int +devopen(struct open_file *f, const char *fname, char **file) +{ + struct devsw *dp; + int dev, unit, part, error; + + error = devparse(fname, &dev, &unit, &part, (const char **)file); + if (error) + return (error); + + dp = &devsw[dev]; + if ((void *)dp->dv_open == (void *)nodev) + return (ENXIO); + + f->f_dev = dp; + + return (*dp->dv_open)(f, unit, part); +} |