Home | History | Annotate | Line # | Download | only in common
devopen.c revision 1.1
      1 /*	$NetBSD: devopen.c,v 1.1 1997/02/04 03:52:23 thorpej Exp $	*/
      2 
      3 /*-
      4  *  Copyright (c) 1996 Jason R. Thorpe.  All rights reserved.
      5  *  Copyright (c) 1993 John Brezak
      6  *  All rights reserved.
      7  *
      8  *  Redistribution and use in source and binary forms, with or without
      9  *  modification, are permitted provided that the following conditions
     10  *  are met:
     11  *  1. Redistributions of source code must retain the above copyright
     12  *     notice, this list of conditions and the following disclaimer.
     13  *  2. Redistributions in binary form must reproduce the above copyright
     14  *     notice, this list of conditions and the following disclaimer in the
     15  *     documentation and/or other materials provided with the distribution.
     16  *  3. The name of the author may not be used to endorse or promote products
     17  *     derived from this software without specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
     20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     22  * DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
     23  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     25  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     27  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     28  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 #include <sys/param.h>
     33 #include <sys/reboot.h>
     34 
     35 #include <lib/libsa/stand.h>
     36 #include <hp300/stand/common/samachdep.h>
     37 
     38 u_int opendev;
     39 
     40 #define ispart(c)	((c) >= 'a' && (c) <= 'h')
     41 
     42 atoi(char *cp)
     43 {
     44     int val = 0;
     45     while(isdigit(*cp))
     46 	val = val * 10 + (*cp++ - '0');
     47     return(val);
     48 }
     49 
     50 usage()
     51 {
     52     printf("\
     53 Usage: device(adaptor, controller, drive, partition)file\n\
     54        <device><unit><partitionletter>:file\n\
     55 ");
     56 }
     57 
     58 devlookup(d, len)
     59 	const char *d;
     60 	int len;
     61 {
     62     struct devsw *dp = devsw;
     63     int i;
     64 
     65     for (i = 0; i < ndevs; i++, dp++) {
     66 	if (dp->dv_name && strncmp(dp->dv_name, d, len) == 0) {
     67 	    /*
     68 	     * Set the filesystem and startup up according to the device
     69 	     * being opened.
     70 	     */
     71 	    switch (i) {
     72 	    case 0:	/* ct */
     73 		bcopy(file_system_rawfs, file_system, sizeof(struct fs_ops));
     74 		break;
     75 
     76 	    case 2:	/* rd */
     77 	    case 4:	/* sd */
     78 		bcopy(file_system_ufs, file_system, sizeof(struct fs_ops));
     79 		break;
     80 
     81 	    case 6:	/* le */
     82 		bcopy(file_system_nfs, file_system, sizeof(struct fs_ops));
     83 		break;
     84 
     85 	    default:
     86 		/* Agh!  What happened?! */
     87 		goto bad;
     88 	    }
     89 	    return(i);
     90 	}
     91     }
     92 
     93  bad:
     94     printf("No such device - Configured devices are:\n");
     95     for (dp = devsw, i = 0; i < ndevs; i++, dp++)
     96 	if (dp->dv_name)
     97 	    printf(" %s", dp->dv_name);
     98     printf("\n");
     99     errno = ENODEV;
    100     return(-1);
    101 }
    102 
    103 /*
    104  * Parse a device spec in one of two forms.
    105  *
    106  * dev(adapt, ctlr, unit, part)file
    107  * [A-Za-z]*[0-9]*[A-Za-z]:file
    108  *    dev   unit  part
    109  */
    110 devparse(fname, dev, adapt, ctlr, unit, part, file)
    111 	const char *fname;
    112 	int *dev, *adapt, *ctlr, *unit, *part;
    113 	char **file;
    114 {
    115     int *argp, i;
    116     char *s, *args[4];
    117 
    118     /* get device name and make lower case */
    119     for (s = (char *)fname; *s && *s != '/' && *s != ':' && *s != '('; s++)
    120 	if (isupper(*s)) *s = tolower(*s);
    121 
    122     /* first form */
    123     if (*s == '(') {
    124 	/* lookup device and get index */
    125 	if ((*dev = devlookup(fname, s - fname)) < 0)
    126 	    goto baddev;
    127 
    128 	/* tokenize device ident */
    129 	args[0] = ++s;
    130 	for (args[0] = s, i = 1; *s && *s != ')'; s++) {
    131 	    if (*s == ',')
    132 		args[i++] = ++s;
    133 	}
    134 	switch(i) {
    135 	case 4:
    136 	    *adapt = atoi(args[0]);
    137 	    *ctlr  = atoi(args[1]);
    138 	    *unit  = atoi(args[2]);
    139 	    *part  = atoi(args[3]);
    140 	    break;
    141 	case 3:
    142 	    *ctlr  = atoi(args[0]);
    143 	    *unit  = atoi(args[1]);
    144 	    *part  = atoi(args[2]);
    145 	    break;
    146 	case 2:
    147 	    *unit  = atoi(args[0]);
    148 	    *part  = atoi(args[1]);
    149 	    break;
    150 	case 1:
    151 	    *part  = atoi(args[0]);
    152 	    break;
    153 	case 0:
    154 	    break;
    155 	}
    156 	*file = ++s;
    157     }
    158 
    159     /* second form */
    160     else if (*s == ':') {
    161 	int temp;
    162 
    163 	/* isolate device */
    164 	for (s = (char *)fname; *s != ':' && !isdigit(*s); s++);
    165 
    166 	/* lookup device and get index */
    167 	if ((*dev = devlookup(fname, s - fname)) < 0)
    168 	    goto baddev;
    169 
    170 	/* isolate unit */
    171 	if ((temp = atoi(s)) > 255)
    172 	    goto bad;
    173 	*adapt = temp / 8;
    174 	*ctlr = temp % 8;
    175 	for (; isdigit(*s); s++);
    176 
    177 	/* translate partition */
    178 	if (!ispart(*s))
    179 	    goto bad;
    180 
    181 	*part = *s++ - 'a';
    182 	if (*s != ':')
    183 	    goto bad;
    184 	*file = ++s;
    185     }
    186 
    187     /* no device present */
    188     else
    189 	*file = (char *)fname;
    190 
    191     /* return the remaining unparsed part as the file to boot */
    192     return(0);
    193 
    194  bad:
    195     usage();
    196 
    197  baddev:
    198     return(-1);
    199 }
    200 
    201 
    202 devopen(f, fname, file)
    203 	struct open_file *f;
    204 	const char *fname;
    205 	char **file;
    206 {
    207 	int n, error;
    208 	int dev, adapt, ctlr, unit, part;
    209 	struct devsw *dp = &devsw[0];
    210 
    211 	dev   = B_TYPE(bootdev);
    212 	adapt = B_ADAPTOR(bootdev);
    213 	ctlr  = B_CONTROLLER(bootdev);
    214 	unit  = B_UNIT(bootdev);
    215 	part  = B_PARTITION(bootdev);
    216 
    217 	if (error = devparse(fname, &dev, &adapt, &ctlr, &unit, &part, file))
    218 	    return(error);
    219 
    220 	/*
    221 	 * Set up filesystem type based on what device we're opening.
    222 	 */
    223 	switch (dev) {
    224 	case 0:		/* ct */
    225 		bcopy(file_system_rawfs, file_system, sizeof(struct fs_ops));
    226 		break;
    227 
    228 	case 2:		/* rd */
    229 	case 4:		/* sd */
    230 		bcopy(file_system_ufs, file_system, sizeof(struct fs_ops));
    231 		break;
    232 
    233 	case 6:		/* le */
    234 		bcopy(file_system_nfs, file_system, sizeof(struct fs_ops));
    235 		break;
    236 
    237 	default:
    238 		/* XXX what else should we do here? */
    239 		printf("WARNING: BOGUS BOOT DEV TYPE 0x%x!\n", dev);
    240 		return (EIO);
    241 	}
    242 
    243 	dp = &devsw[dev];
    244 
    245 	if (!dp->dv_open)
    246 		return(ENODEV);
    247 
    248 	f->f_dev = dp;
    249 
    250 	if ((error = (*dp->dv_open)(f, adapt, ctlr, part)) == 0) {
    251 		if ((error =
    252 		    (*punitsw[dev].p_punit)(adapt, ctlr, &unit)) != 0) {
    253 			goto bad;
    254 		}
    255 		opendev = MAKEBOOTDEV(dev, adapt, ctlr, unit, part);
    256 		return(0);
    257 	}
    258 
    259  bad:
    260 	printf("%s(%d,%d,%d,%d): %s\n", devsw[dev].dv_name,
    261 	    adapt, ctlr, unit, part, strerror(error));
    262 
    263 	return(error);
    264 }
    265