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