devopen.c revision 1.9
1/* $NetBSD: devopen.c,v 1.9 2005/12/11 12:17:19 christos 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/libkern/libkern.h> 71 72#include <lib/libsa/stand.h> 73#include <hp300/stand/common/samachdep.h> 74 75u_int opendev; 76 77#define ispart(c) ((c) >= 'a' && (c) <= 'h') 78 79static void usage(void); 80static int devlookup(const char * ,int); 81static int devparse(const char *, int *, int*, int*, int*, int*, char **); 82 83int 84atoi(char *cp) 85{ 86 int val = 0; 87 88 while (isdigit((unsigned char)*cp)) 89 val = val * 10 + (*cp++ - '0'); 90 return val; 91} 92 93void 94usage(void) 95{ 96 97 printf("Usage: device(adaptor, controller, drive, partition)file\n" 98 " <device><unit><partitionletter>:file\n"); 99} 100 101static int 102devlookup(const char *d, int len) 103{ 104 struct devsw *dp = devsw; 105 int i; 106 107 for (i = 0; i < ndevs; i++, dp++) { 108 if (dp->dv_name && strncmp(dp->dv_name, d, len) == 0) { 109 /* 110 * Set the filesystem and startup up according to 111 * the device being opened. 112 */ 113 switch (i) { 114 case 0: /* ct */ 115 memcpy(file_system, file_system_rawfs, 116 sizeof(struct fs_ops)); 117 break; 118 119 case 2: /* rd */ 120 case 4: /* sd */ 121 memcpy(file_system, file_system_ufs, 122 sizeof(struct fs_ops)); 123 break; 124 125 case 6: /* le */ 126 memcpy(file_system, file_system_nfs, 127 sizeof(struct fs_ops)); 128 break; 129 130 default: 131 /* Agh! What happened?! */ 132 goto bad; 133 } 134 return i; 135 } 136 } 137 138 bad: 139 printf("No such device - Configured devices are:\n"); 140 for (dp = devsw, i = 0; i < ndevs; i++, dp++) 141 if (dp->dv_name) 142 printf(" %s", dp->dv_name); 143 printf("\n"); 144 errno = ENODEV; 145 return -1; 146} 147 148/* 149 * Parse a device spec in one of two forms. 150 * 151 * dev(adapt, ctlr, unit, part)file 152 * [A-Za-z]*[0-9]*[A-Za-z]:file 153 * dev unit part 154 */ 155static int 156devparse(const char *fname, int *dev, int *adapt, int *ctlr, int *unit, 157 int *part, char **file) 158{ 159 int i; 160 char *s, *args[4]; 161 162 /* get device name */ 163 for (s = (char *)fname; *s && *s != '/' && *s != ':' && *s != '('; s++) 164 ; 165 166 /* first form */ 167 if (*s == '(') { 168 /* lookup device and get index */ 169 if ((*dev = devlookup(fname, s - fname)) < 0) 170 goto baddev; 171 172 /* tokenize device ident */ 173 args[0] = ++s; 174 for (args[0] = s, i = 1; *s && *s != ')'; s++) { 175 if (*s == ',') 176 args[i++] = ++s; 177 } 178 switch(i) { 179 case 4: 180 *adapt = atoi(args[0]); 181 *ctlr = atoi(args[1]); 182 *unit = atoi(args[2]); 183 *part = atoi(args[3]); 184 break; 185 case 3: 186 *ctlr = atoi(args[0]); 187 *unit = atoi(args[1]); 188 *part = atoi(args[2]); 189 break; 190 case 2: 191 *unit = atoi(args[0]); 192 *part = atoi(args[1]); 193 break; 194 case 1: 195 *part = atoi(args[0]); 196 break; 197 case 0: 198 break; 199 } 200 *file = ++s; 201 } 202 203 /* second form */ 204 else if (*s == ':') { 205 int temp; 206 207 /* isolate device */ 208 for (s = (char *)fname; *s != ':' && !isdigit(*s); s++); 209 210 /* lookup device and get index */ 211 if ((*dev = devlookup(fname, s - fname)) < 0) 212 goto baddev; 213 214 /* isolate unit */ 215 if ((temp = atoi(s)) > 255) 216 goto bad; 217 *adapt = temp / 8; 218 *ctlr = temp % 8; 219 for (; isdigit(*s); s++) 220 ; 221 222 /* translate partition */ 223 if (!ispart(*s)) 224 goto bad; 225 226 *part = *s++ - 'a'; 227 if (*s != ':') 228 goto bad; 229 *file = ++s; 230 } 231 232 /* no device present */ 233 else 234 *file = (char *)fname; 235 236 /* return the remaining unparsed part as the file to boot */ 237 return 0; 238 239 bad: 240 usage(); 241 242 baddev: 243 return -1; 244} 245 246 247int 248devopen(struct open_file *f, const char *fname, char **file) 249{ 250 int error; 251 int dev, adapt, ctlr, unit, part; 252 struct devsw *dp = &devsw[0]; 253 254 dev = B_TYPE(bootdev); 255 adapt = B_ADAPTOR(bootdev); 256 ctlr = B_CONTROLLER(bootdev); 257 unit = B_UNIT(bootdev); 258 part = B_PARTITION(bootdev); 259 260 if ((error = devparse(fname, &dev, &adapt, &ctlr, &unit, &part, file)) 261 != 0) 262 return error; 263 264 /* 265 * Set up filesystem type based on what device we're opening. 266 */ 267 switch (dev) { 268 case 0: /* ct */ 269 memcpy(file_system, file_system_rawfs, sizeof(struct fs_ops)); 270 break; 271 272 case 2: /* rd */ 273 case 4: /* sd */ 274 memcpy(file_system, file_system_ufs, sizeof(struct fs_ops)); 275 break; 276 277 case 6: /* le */ 278 memcpy(file_system, file_system_nfs, sizeof(struct fs_ops)); 279 break; 280 281 default: 282 /* XXX what else should we do here? */ 283 printf("WARNING: BOGUS BOOT DEV TYPE 0x%x!\n", dev); 284 return EIO; 285 } 286 287 dp = &devsw[dev]; 288 289 if (!dp->dv_open) 290 return ENODEV; 291 292 f->f_dev = dp; 293 294 if ((error = (*dp->dv_open)(f, adapt, ctlr, part)) == 0) { 295 if ((error = 296 (*punitsw[dev].p_punit)(adapt, ctlr, &unit)) != 0) { 297 goto bad; 298 } 299 opendev = MAKEBOOTDEV(dev, adapt, ctlr, unit, part); 300 return 0; 301 } 302 303 bad: 304 printf("%s(%d,%d,%d,%d): %s\n", devsw[dev].dv_name, 305 adapt, ctlr, unit, part, strerror(error)); 306 307 return error; 308} 309