1/* $NetBSD: devopen.c,v 1.3 2022/04/30 03:59:15 rin 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#include <lib/libkern/libkern.h> 33 34#define ispart(c) ((c) >= 'a' && (c) <= 'h') 35 36int devlookup(char *); 37int devparse(const char *, int *, int *, int *, int *, int *, char **); 38 39int 40devlookup(char *d) 41{ 42 struct devsw *dp = devsw; 43 int i; 44 45 for (i = 0; i < ndevs; i++, dp++) 46 if (dp->dv_name && strcmp(dp->dv_name, d) == 0) 47 return (i); 48 49 printf("No such device - Configured devices are:\n"); 50 for (dp = devsw, i = 0; i < ndevs; i++, dp++) 51 if (dp->dv_name) 52 printf(" %s", dp->dv_name); 53 printf("\n"); 54 return (-1); 55} 56 57/* 58 * Parse a device spec in one of two forms. 59 * dev(ctlr, unit, part)file 60 */ 61int 62devparse(const char *fname, int *dev, int *adapt, int *ctlr, int *unit, 63 int *part, char **file) 64{ 65 int argc, flag; 66 char *s, *args[3]; 67 extern char nametmp[]; 68 69 /* get device name and make lower case */ 70 strcpy(nametmp, (char *)fname); 71 for (s = nametmp; *s && *s != '('; s++) 72 if (isupper(*s)) *s = tolower(*s); 73 74 if (*s == '(') { 75 /* lookup device and get index */ 76 *s = '\0'; 77 if ((*dev = devlookup(nametmp)) < 0) 78 goto baddev; 79 80 /* tokenize device ident */ 81 for (++s, flag = 0, argc = 0; *s && *s != ')'; s++) { 82 if (*s != ',') { 83 if (!flag) { 84 flag++; 85 args[argc++] = s; 86 } 87 } else { 88 if (flag) { 89 *s = '\0'; 90 flag = 0; 91 } 92 } 93 } 94 if (*s == ')') 95 *s = '\0'; 96 97 switch (argc) { 98 case 3: 99 *part = atoi(args[2]); 100 /* FALL THROUGH */ 101 case 2: 102 *unit = atoi(args[1]); 103 /* FALL THROUGH */ 104 case 1: 105 *ctlr = atoi(args[0]); 106 break; 107 } 108 *file = ++s; 109 } else { 110 /* no device present */ 111 *file = (char *)fname; 112 } 113 return (0); 114 115baddev: 116 return (EINVAL); 117} 118 119int 120devopen(struct open_file *f, const char *fname, char **file) 121{ 122 int error; 123 int dev = 0, ctlr = 0, unit = 0, part = 0; 124 int adapt = 0; 125 struct devsw *dp = &devsw[0]; 126 127 if ((error = 128 devparse(fname, &dev, &adapt, &ctlr, &unit, &part, file)) != 0) 129 return (error); 130 131 dp = &devsw[dev]; 132 if (!dp->dv_open) 133 return (ENODEV); 134 135 f->f_dev = dp; 136 if ((error = (*dp->dv_open)(f, ctlr, unit, part)) == 0) 137 return (0); 138 139 printf("%s(%d,%d,%d): %s\n", devsw[dev].dv_name, 140 ctlr, unit, part, strerror(error)); 141 142 return (error); 143} 144