1 /* $NetBSD: devopen.c,v 1.1 2000/02/29 15:21:49 nonaka Exp $ */ 2 3 /*- 4 * Copyright (c) 1993 John Brezak 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 27 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include <lib/libsa/stand.h> 32 33 #define ispart(c) ((c) >= 'a' && (c) <= 'h') 34 35 int atoi __P((char *)); 36 int devlookup __P((char *)); 37 int devparse __P((const char *, int *, int *, int *, int *, int *, char **)); 38 39 int 40 atoi(cp) 41 char *cp; 42 { 43 int val = 0; 44 45 while (isdigit(*cp)) 46 val = val * 10 + (*cp++ - '0'); 47 return (val); 48 } 49 50 int 51 devlookup(d) 52 char *d; 53 { 54 struct devsw *dp = devsw; 55 int i; 56 57 for (i = 0; i < ndevs; i++, dp++) 58 if (dp->dv_name && strcmp(dp->dv_name, d) == 0) 59 return (i); 60 61 printf("No such device - Configured devices are:\n"); 62 for (dp = devsw, i = 0; i < ndevs; i++, dp++) 63 if (dp->dv_name) 64 printf(" %s", dp->dv_name); 65 printf("\n"); 66 return (-1); 67 } 68 69 /* 70 * Parse a device spec in one of two forms. 71 * dev(ctlr, unit, part)file 72 */ 73 int 74 devparse(fname, dev, adapt, ctlr, unit, part, file) 75 const char *fname; 76 int *dev; 77 int *adapt; 78 int *ctlr; 79 int *unit; 80 int *part; 81 char **file; 82 { 83 int argc, flag; 84 char *s, *args[3]; 85 extern char nametmp[]; 86 87 /* get device name and make lower case */ 88 strcpy(nametmp, (char *)fname); 89 for (s = nametmp; *s && *s != '('; s++) 90 if (isupper(*s)) *s = tolower(*s); 91 92 if (*s == '(') { 93 /* lookup device and get index */ 94 *s = NULL; 95 if ((*dev = devlookup(nametmp)) < 0) 96 goto baddev; 97 98 /* tokenize device ident */ 99 for (++s, flag = 0, argc = 0; *s && *s != ')'; s++) { 100 if (*s != ',') { 101 if (!flag) { 102 flag++; 103 args[argc++] = s; 104 } 105 } else { 106 if (flag) { 107 *s = NULL; 108 flag = 0; 109 } 110 } 111 } 112 if (*s == ')') 113 *s = NULL; 114 115 switch (argc) { 116 case 3: 117 *part = atoi(args[2]); 118 /* FALL THROUGH */ 119 case 2: 120 *unit = atoi(args[1]); 121 /* FALL THROUGH */ 122 case 1: 123 *ctlr = atoi(args[0]); 124 break; 125 } 126 *file = ++s; 127 } else { 128 /* no device present */ 129 *file = (char *)fname; 130 } 131 return (0); 132 133 baddev: 134 return (EINVAL); 135 } 136 137 int 138 devopen(f, fname, file) 139 struct open_file *f; 140 const char *fname; 141 char **file; 142 { 143 int error; 144 int dev = 0, ctlr = 0, unit = 0, part = 0; 145 int adapt = 0; 146 struct devsw *dp = &devsw[0]; 147 148 if ((error = 149 devparse(fname, &dev, &adapt, &ctlr, &unit, &part, file)) != 0) 150 return (error); 151 152 dp = &devsw[dev]; 153 if (!dp->dv_open) 154 return (ENODEV); 155 156 f->f_dev = dp; 157 if ((error = (*dp->dv_open)(f, ctlr, unit, part)) == 0) 158 return (0); 159 160 printf("%s(%d,%d,%d): %s\n", devsw[dev].dv_name, 161 ctlr, unit, part, strerror(error)); 162 163 return (error); 164 } 165