devopen.c revision 1.1
11.1Sgarbled/*	$NetBSD: devopen.c,v 1.1 2007/12/17 19:09:48 garbled 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 atoi(char *);
371.1Sgarbledint devlookup(char *);
381.1Sgarbledint devparse(const char *, int *, int *, int *, int *, int *, char **);
391.1Sgarbled
401.1Sgarbledint
411.1Sgarbledatoi(char *cp)
421.1Sgarbled{
431.1Sgarbled	int val = 0;
441.1Sgarbled
451.1Sgarbled	while (isdigit(*cp))
461.1Sgarbled		val = val * 10 + (*cp++ - '0');
471.1Sgarbled	return (val);
481.1Sgarbled}
491.1Sgarbled
501.1Sgarbledint
511.1Sgarbleddevlookup(char *d)
521.1Sgarbled{
531.1Sgarbled	struct devsw *dp = devsw;
541.1Sgarbled	int i;
551.1Sgarbled
561.1Sgarbled	for (i = 0; i < ndevs; i++, dp++)
571.1Sgarbled		if (dp->dv_name && strcmp(dp->dv_name, d) == 0)
581.1Sgarbled			return (i);
591.1Sgarbled
601.1Sgarbled	printf("No such device - Configured devices are:\n");
611.1Sgarbled	for (dp = devsw, i = 0; i < ndevs; i++, dp++)
621.1Sgarbled		if (dp->dv_name)
631.1Sgarbled			printf(" %s", dp->dv_name);
641.1Sgarbled	printf("\n");
651.1Sgarbled	return (-1);
661.1Sgarbled}
671.1Sgarbled
681.1Sgarbled/*
691.1Sgarbled * Parse a device spec in one of two forms.
701.1Sgarbled *   dev(ctlr, unit, part)file
711.1Sgarbled */
721.1Sgarbledint
731.1Sgarbleddevparse(const char *fname, int *dev, int *adapt, int *ctlr, int *unit,
741.1Sgarbled	int *part, char **file)
751.1Sgarbled{
761.1Sgarbled	int argc, flag;
771.1Sgarbled	char *s, *args[3];
781.1Sgarbled	extern char nametmp[];
791.1Sgarbled
801.1Sgarbled	/* get device name and make lower case */
811.1Sgarbled	strcpy(nametmp, (char *)fname);
821.1Sgarbled	for (s = nametmp; *s && *s != '('; s++)
831.1Sgarbled		if (isupper(*s)) *s = tolower(*s);
841.1Sgarbled
851.1Sgarbled	if (*s == '(') {
861.1Sgarbled		/* lookup device and get index */
871.1Sgarbled		*s = NULL;
881.1Sgarbled		if ((*dev = devlookup(nametmp)) < 0)
891.1Sgarbled		    goto baddev;
901.1Sgarbled
911.1Sgarbled		/* tokenize device ident */
921.1Sgarbled		for (++s, flag = 0, argc = 0; *s && *s != ')'; s++) {
931.1Sgarbled			if (*s != ',') {
941.1Sgarbled				if (!flag) {
951.1Sgarbled					flag++;
961.1Sgarbled					args[argc++] = s;
971.1Sgarbled				}
981.1Sgarbled			} else {
991.1Sgarbled				if (flag) {
1001.1Sgarbled					*s = NULL;
1011.1Sgarbled					flag = 0;
1021.1Sgarbled				}
1031.1Sgarbled			}
1041.1Sgarbled		}
1051.1Sgarbled		if (*s == ')')
1061.1Sgarbled			*s = NULL;
1071.1Sgarbled
1081.1Sgarbled		switch (argc) {
1091.1Sgarbled		case 3:
1101.1Sgarbled		    *part = atoi(args[2]);
1111.1Sgarbled		    /* FALL THROUGH */
1121.1Sgarbled		case 2:
1131.1Sgarbled		    *unit = atoi(args[1]);
1141.1Sgarbled		    /* FALL THROUGH */
1151.1Sgarbled		case 1:
1161.1Sgarbled		    *ctlr = atoi(args[0]);
1171.1Sgarbled		    break;
1181.1Sgarbled		}
1191.1Sgarbled		*file = ++s;
1201.1Sgarbled	} else {
1211.1Sgarbled		/* no device present */
1221.1Sgarbled		*file = (char *)fname;
1231.1Sgarbled	}
1241.1Sgarbled	return (0);
1251.1Sgarbled
1261.1Sgarbledbaddev:
1271.1Sgarbled	return (EINVAL);
1281.1Sgarbled}
1291.1Sgarbled
1301.1Sgarbledint
1311.1Sgarbleddevopen(struct open_file *f, const char *fname, char **file)
1321.1Sgarbled{
1331.1Sgarbled	int error;
1341.1Sgarbled	int dev = 0, ctlr = 0, unit = 0, part = 0;
1351.1Sgarbled	int adapt = 0;
1361.1Sgarbled	struct devsw *dp = &devsw[0];
1371.1Sgarbled
1381.1Sgarbled	if ((error =
1391.1Sgarbled	    devparse(fname, &dev, &adapt, &ctlr, &unit, &part, file)) != 0)
1401.1Sgarbled		return (error);
1411.1Sgarbled
1421.1Sgarbled	dp = &devsw[dev];
1431.1Sgarbled	if (!dp->dv_open)
1441.1Sgarbled		return (ENODEV);
1451.1Sgarbled
1461.1Sgarbled	f->f_dev = dp;
1471.1Sgarbled	if ((error = (*dp->dv_open)(f, ctlr, unit, part)) == 0)
1481.1Sgarbled		return (0);
1491.1Sgarbled
1501.1Sgarbled	printf("%s(%d,%d,%d): %s\n", devsw[dev].dv_name,
1511.1Sgarbled		ctlr, unit, part, strerror(error));
1521.1Sgarbled
1531.1Sgarbled	return (error);
1541.1Sgarbled}
155