devopen.c revision 1.3
11.3Srin/* $NetBSD: devopen.c,v 1.3 2022/04/30 03:59:15 rin Exp $ */ 21.1Sgarbled 31.1Sgarbled/*- 41.1Sgarbled * Copyright (c) 1993 John Brezak 51.1Sgarbled * All rights reserved. 61.1Sgarbled * 71.1Sgarbled * Redistribution and use in source and binary forms, with or without 81.1Sgarbled * modification, are permitted provided that the following conditions 91.1Sgarbled * are met: 101.1Sgarbled * 1. Redistributions of source code must retain the above copyright 111.1Sgarbled * notice, this list of conditions and the following disclaimer. 121.1Sgarbled * 2. Redistributions in binary form must reproduce the above copyright 131.1Sgarbled * notice, this list of conditions and the following disclaimer in the 141.1Sgarbled * documentation and/or other materials provided with the distribution. 151.1Sgarbled * 3. The name of the author may not be used to endorse or promote products 161.1Sgarbled * derived from this software without specific prior written permission. 171.1Sgarbled * 181.1Sgarbled * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR 191.1Sgarbled * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 201.1Sgarbled * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 211.1Sgarbled * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 221.1Sgarbled * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 231.1Sgarbled * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 241.1Sgarbled * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 251.1Sgarbled * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 261.1Sgarbled * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 271.1Sgarbled * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 281.1Sgarbled * POSSIBILITY OF SUCH DAMAGE. 291.1Sgarbled */ 301.1Sgarbled 311.1Sgarbled#include <lib/libsa/stand.h> 321.1Sgarbled#include <lib/libkern/libkern.h> 331.1Sgarbled 341.1Sgarbled#define ispart(c) ((c) >= 'a' && (c) <= 'h') 351.1Sgarbled 361.1Sgarbledint devlookup(char *); 371.1Sgarbledint devparse(const char *, int *, int *, int *, int *, int *, char **); 381.1Sgarbled 391.1Sgarbledint 401.1Sgarbleddevlookup(char *d) 411.1Sgarbled{ 421.1Sgarbled struct devsw *dp = devsw; 431.1Sgarbled int i; 441.1Sgarbled 451.1Sgarbled for (i = 0; i < ndevs; i++, dp++) 461.1Sgarbled if (dp->dv_name && strcmp(dp->dv_name, d) == 0) 471.1Sgarbled return (i); 481.1Sgarbled 491.1Sgarbled printf("No such device - Configured devices are:\n"); 501.1Sgarbled for (dp = devsw, i = 0; i < ndevs; i++, dp++) 511.1Sgarbled if (dp->dv_name) 521.1Sgarbled printf(" %s", dp->dv_name); 531.1Sgarbled printf("\n"); 541.1Sgarbled return (-1); 551.1Sgarbled} 561.1Sgarbled 571.1Sgarbled/* 581.1Sgarbled * Parse a device spec in one of two forms. 591.1Sgarbled * dev(ctlr, unit, part)file 601.1Sgarbled */ 611.1Sgarbledint 621.1Sgarbleddevparse(const char *fname, int *dev, int *adapt, int *ctlr, int *unit, 631.1Sgarbled int *part, char **file) 641.1Sgarbled{ 651.1Sgarbled int argc, flag; 661.1Sgarbled char *s, *args[3]; 671.1Sgarbled extern char nametmp[]; 681.1Sgarbled 691.1Sgarbled /* get device name and make lower case */ 701.1Sgarbled strcpy(nametmp, (char *)fname); 711.1Sgarbled for (s = nametmp; *s && *s != '('; s++) 721.1Sgarbled if (isupper(*s)) *s = tolower(*s); 731.1Sgarbled 741.1Sgarbled if (*s == '(') { 751.1Sgarbled /* lookup device and get index */ 761.3Srin *s = '\0'; 771.1Sgarbled if ((*dev = devlookup(nametmp)) < 0) 781.1Sgarbled goto baddev; 791.1Sgarbled 801.1Sgarbled /* tokenize device ident */ 811.1Sgarbled for (++s, flag = 0, argc = 0; *s && *s != ')'; s++) { 821.1Sgarbled if (*s != ',') { 831.1Sgarbled if (!flag) { 841.1Sgarbled flag++; 851.1Sgarbled args[argc++] = s; 861.1Sgarbled } 871.1Sgarbled } else { 881.1Sgarbled if (flag) { 891.3Srin *s = '\0'; 901.1Sgarbled flag = 0; 911.1Sgarbled } 921.1Sgarbled } 931.1Sgarbled } 941.1Sgarbled if (*s == ')') 951.3Srin *s = '\0'; 961.1Sgarbled 971.1Sgarbled switch (argc) { 981.1Sgarbled case 3: 991.1Sgarbled *part = atoi(args[2]); 1001.1Sgarbled /* FALL THROUGH */ 1011.1Sgarbled case 2: 1021.1Sgarbled *unit = atoi(args[1]); 1031.1Sgarbled /* FALL THROUGH */ 1041.1Sgarbled case 1: 1051.1Sgarbled *ctlr = atoi(args[0]); 1061.1Sgarbled break; 1071.1Sgarbled } 1081.1Sgarbled *file = ++s; 1091.1Sgarbled } else { 1101.1Sgarbled /* no device present */ 1111.1Sgarbled *file = (char *)fname; 1121.1Sgarbled } 1131.1Sgarbled return (0); 1141.1Sgarbled 1151.1Sgarbledbaddev: 1161.1Sgarbled return (EINVAL); 1171.1Sgarbled} 1181.1Sgarbled 1191.1Sgarbledint 1201.1Sgarbleddevopen(struct open_file *f, const char *fname, char **file) 1211.1Sgarbled{ 1221.1Sgarbled int error; 1231.1Sgarbled int dev = 0, ctlr = 0, unit = 0, part = 0; 1241.1Sgarbled int adapt = 0; 1251.1Sgarbled struct devsw *dp = &devsw[0]; 1261.1Sgarbled 1271.1Sgarbled if ((error = 1281.1Sgarbled devparse(fname, &dev, &adapt, &ctlr, &unit, &part, file)) != 0) 1291.1Sgarbled return (error); 1301.1Sgarbled 1311.1Sgarbled dp = &devsw[dev]; 1321.1Sgarbled if (!dp->dv_open) 1331.1Sgarbled return (ENODEV); 1341.1Sgarbled 1351.1Sgarbled f->f_dev = dp; 1361.1Sgarbled if ((error = (*dp->dv_open)(f, ctlr, unit, part)) == 0) 1371.1Sgarbled return (0); 1381.1Sgarbled 1391.1Sgarbled printf("%s(%d,%d,%d): %s\n", devsw[dev].dv_name, 1401.1Sgarbled ctlr, unit, part, strerror(error)); 1411.1Sgarbled 1421.1Sgarbled return (error); 1431.1Sgarbled} 144