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