1127282Salc/* $NetBSD: devopen.c,v 1.8 2013/11/03 00:53:11 christos Exp $ */
2127282Salc
3127282Salc/*-
4127282Salc * Copyright (c) 1992, 1993
5127282Salc *	The Regents of the University of California.  All rights reserved.
6127282Salc *
7127282Salc * This code is derived from software contributed to Berkeley by
8127282Salc * Ralph Campbell.
9127282Salc *
10127282Salc * Redistribution and use in source and binary forms, with or without
11127282Salc * modification, are permitted provided that the following conditions
12127282Salc * are met:
13127282Salc * 1. Redistributions of source code must retain the above copyright
14127282Salc *    notice, this list of conditions and the following disclaimer.
15127282Salc * 2. Redistributions in binary form must reproduce the above copyright
16127282Salc *    notice, this list of conditions and the following disclaimer in the
17127282Salc *    documentation and/or other materials provided with the distribution.
18127282Salc * 3. Neither the name of the University nor the names of its contributors
19127282Salc *    may be used to endorse or promote products derived from this software
20127282Salc *    without specific prior written permission.
21127282Salc *
22127282Salc * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23127282Salc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24127282Salc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25127282Salc * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26127282Salc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27127282Salc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28127282Salc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29127282Salc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30127282Salc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31127282Salc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32127282Salc * SUCH DAMAGE.
33127282Salc *
34127282Salc *	@(#)devopen.c	8.1 (Berkeley) 6/10/93
35127282Salc */
36127282Salc
37127282Salc#include <lib/libsa/stand.h>
38127282Salc
39127282Salc/*
40127282Salc * Decode the string 'fname', open the device and return the remaining
41127282Salc * file name if any.
42127282Salc */
43127282Salcint
44127282Salcdevopen(struct open_file *f, const char *fname, char **file)
45127282Salc	/* file:	 out */
46127282Salc{
47127282Salc	register char *cp;
48127282Salc	register struct devsw *dp;
49127282Salc#if 0
50127282Salc	register char *ncp;
51127282Salc	register int c, i;
52127282Salc	char namebuf[20];
53127282Salc#endif
54127282Salc	int ctlr = 0, unit = 0, part = 0;
55127282Salc	int rc;
56127282Salc
57127282Salc	cp = (char *)fname;
58127282Salc
59127282Salc#if 0
60127282Salc	ncp = namebuf;
61127282Salc	/* look for a string like '5/rz0/vmunix' or '5/rz3f/vmunix */
62127282Salc	if ((c = *cp) >= '0' && c <= '9') {
63127282Salc		ctlr = c - '0';
64127282Salc		/* skip the '/' */
65127282Salc		if (*++cp != '/')
66127282Salc			return (ENXIO);
67127282Salc		cp++;
68127282Salc		while ((c = *cp) != '\0') {
69127282Salc			if (c == '/')
70127282Salc				break;
71127282Salc			if (c >= '0' && c <= '9') {
72127282Salc				/* read unit number */
73127282Salc				unit = c - '0';
74127282Salc
75127282Salc				/* look for a partition */
76127282Salc				if ((c = *++cp) >= 'a' && c <= 'h') {
77127282Salc					part = c - 'a';
78127282Salc					c = *++cp;
79127282Salc				}
80127282Salc				if (c != '/')
81127282Salc					return (ENXIO);
82127282Salc				break;
83127282Salc			}
84127282Salc			if (ncp < namebuf + sizeof(namebuf) - 1)
85127282Salc				*ncp++ = c;
86127282Salc			cp++;
87127282Salc		}
88127282Salc		*ncp = '\0';
89127282Salc	/*
90127282Salc	 * XXX
91127282Salc	 * pulling strchr from the C library, should pull from libkern.
92127282Salc	 */
93127282Salc	} else if (strchr(cp, '(')) {
94127282Salc		/* expect a string like 'rz(0,0,0)vmunix' */
95127282Salc		while ((c = *cp) != '\0') {
96127282Salc			if (c == '(') {
97127282Salc				cp++;
98127282Salc				break;
99127282Salc			}
100127282Salc			if (ncp < namebuf + sizeof(namebuf) - 1)
101127282Salc				*ncp++ = c;
102127282Salc			cp++;
103127282Salc		}
104127282Salc
105127282Salc		/* get controller number */
106127282Salc		if ((c = *cp) >= '0' && c <= '9') {
107127282Salc			ctlr = c - '0';
108127282Salc			c = *++cp;
109127282Salc		}
110127282Salc
111127282Salc		if (c == ',') {
112127282Salc			/* get SCSI device number */
113127282Salc			if ((c = *++cp) >= '0' && c <= '9') {
114127282Salc				unit = c - '0';
115127282Salc				c = *++cp;
116127282Salc			}
117127282Salc
118127282Salc			if (c == ',') {
119127282Salc				/* get partition number */
120127282Salc				if ((c = *++cp) >= '0' && c <= '9') {
121127282Salc					part = c - '0';
122127282Salc					c = *++cp;
123127282Salc				}
124127282Salc			}
125127282Salc		}
126127282Salc		if (c != ')')
127127282Salc			return (ENXIO);
128127282Salc		cp++;
129127282Salc		*ncp = '\0';
130127282Salc	} else {
131127282Salc#endif
132127282Salc		dp = devsw;
133		ctlr = unit = part = 0;
134		goto fnd;
135#if 0
136	}
137
138	for (dp = devsw, i = 0; i < ndevs; dp++, i++)
139		if (dp->dv_name && strcmp(namebuf, dp->dv_name) == 0)
140			goto fnd;
141	printf("Unknown device '%s'\nKnown devices are:", namebuf);
142	for (dp = devsw, i = 0; i < ndevs; dp++, i++)
143		if (dp->dv_name)
144			printf(" %s", dp->dv_name);
145	printf("\n");
146	return (ENXIO);
147#endif
148
149fnd:
150	rc = (dp->dv_open)(f, ctlr, unit, part);
151	if (rc)
152		return (rc);
153
154	f->f_dev = dp;
155	if (file && *cp != '\0')
156		*file = cp;
157	return (0);
158}
159