xref: /netbsd-src/sys/arch/pmax/stand/common/devopen.c (revision 82357f6d420792564499086cb6440ad2fcce8410)
1*82357f6dSdsl /*	$NetBSD: devopen.c,v 1.17 2009/03/14 21:04:14 dsl Exp $	*/
216c74987Ssimonb 
316c74987Ssimonb /*-
416c74987Ssimonb  * Copyright (c) 1992, 1993
516c74987Ssimonb  *	The Regents of the University of California.  All rights reserved.
616c74987Ssimonb  *
716c74987Ssimonb  * This code is derived from software contributed to Berkeley by
816c74987Ssimonb  * Ralph Campbell.
916c74987Ssimonb  *
1016c74987Ssimonb  * Redistribution and use in source and binary forms, with or without
1116c74987Ssimonb  * modification, are permitted provided that the following conditions
1216c74987Ssimonb  * are met:
1316c74987Ssimonb  * 1. Redistributions of source code must retain the above copyright
1416c74987Ssimonb  *    notice, this list of conditions and the following disclaimer.
1516c74987Ssimonb  * 2. Redistributions in binary form must reproduce the above copyright
1616c74987Ssimonb  *    notice, this list of conditions and the following disclaimer in the
1716c74987Ssimonb  *    documentation and/or other materials provided with the distribution.
18aad01611Sagc  * 3. Neither the name of the University nor the names of its contributors
1916c74987Ssimonb  *    may be used to endorse or promote products derived from this software
2016c74987Ssimonb  *    without specific prior written permission.
2116c74987Ssimonb  *
2216c74987Ssimonb  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2316c74987Ssimonb  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2416c74987Ssimonb  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2516c74987Ssimonb  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2616c74987Ssimonb  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2716c74987Ssimonb  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2816c74987Ssimonb  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2916c74987Ssimonb  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3016c74987Ssimonb  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3116c74987Ssimonb  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3216c74987Ssimonb  * SUCH DAMAGE.
3316c74987Ssimonb  *
3416c74987Ssimonb  *	@(#)devopen.c	8.1 (Berkeley) 6/10/93
3516c74987Ssimonb  */
3616c74987Ssimonb 
370246cad6Ssimonb #include <lib/libsa/stand.h>
384f2661e4Sjdolecek #include <lib/libkern/libkern.h>
3916c74987Ssimonb 
4016c74987Ssimonb /*
4116c74987Ssimonb  * Decode the string 'fname', open the device and return the remaining
4216c74987Ssimonb  * file name if any.
4316c74987Ssimonb  */
4416c74987Ssimonb int
devopen(struct open_file * f,const char * fname,char ** file)45*82357f6dSdsl devopen(struct open_file *f, const char *fname, char **file)
46*82357f6dSdsl 	/* file:	 out */
4716c74987Ssimonb {
4816c74987Ssimonb 	int ctlr = 0, unit = 0, part = 0;
490246cad6Ssimonb 	int c, rc;
5016c74987Ssimonb 	char namebuf[20];
510246cad6Ssimonb 	const char *cp;
520246cad6Ssimonb 	char *ncp;
530246cad6Ssimonb #if !defined(LIBSA_SINGLE_DEVICE)
540246cad6Ssimonb 	int i;
550246cad6Ssimonb 	struct devsw *dp;
560246cad6Ssimonb #endif
5716c74987Ssimonb 
5816c74987Ssimonb 	cp = fname;
5916c74987Ssimonb 	ncp = namebuf;
6016c74987Ssimonb 
610246cad6Ssimonb 	/*
620246cad6Ssimonb 	 * look for a string like '5/rz0/netbsd' or '5/rz3f/netbsd
630246cad6Ssimonb 	 * or 3/tftp/netbsd
640246cad6Ssimonb 	 */
6516c74987Ssimonb 	if ((c = *cp) >= '0' && c <= '9') {
6616c74987Ssimonb 		ctlr = c - '0';
6716c74987Ssimonb 		/* skip the '/' */
6816c74987Ssimonb 		if (*++cp != '/')
6916c74987Ssimonb 			return (ENXIO);
7016c74987Ssimonb 		cp++;
7116c74987Ssimonb 		while ((c = *cp) != '\0') {
7216c74987Ssimonb 			if (c == '/')
7316c74987Ssimonb 				break;
7416c74987Ssimonb 			if (c >= '0' && c <= '9') {
7516c74987Ssimonb 				/* read unit number */
7616c74987Ssimonb 				unit = c - '0';
7716c74987Ssimonb 
7816c74987Ssimonb 				/* look for a partition */
7916c74987Ssimonb 				if ((c = *++cp) >= 'a' && c <= 'h') {
8016c74987Ssimonb 					part = c - 'a';
8116c74987Ssimonb 					c = *++cp;
8216c74987Ssimonb 				}
8316c74987Ssimonb 				if (c != '/')
8416c74987Ssimonb 					return (ENXIO);
850246cad6Ssimonb 				cp++;
8616c74987Ssimonb 				break;
8716c74987Ssimonb 			}
8816c74987Ssimonb 			if (ncp < namebuf + sizeof(namebuf) - 1)
8916c74987Ssimonb 				*ncp++ = c;
9016c74987Ssimonb 			cp++;
9116c74987Ssimonb 		}
9216c74987Ssimonb 	} else {
9316c74987Ssimonb 		/* expect a string like 'rz(0,0,0)netbsd' */
9416c74987Ssimonb 		while ((c = *cp) != '\0') {
9516c74987Ssimonb 			if (c == '(') {
9616c74987Ssimonb 				cp++;
9716c74987Ssimonb 				break;
9816c74987Ssimonb 			}
9916c74987Ssimonb 			if (ncp < namebuf + sizeof(namebuf) - 1)
10016c74987Ssimonb 				*ncp++ = c;
10116c74987Ssimonb 			cp++;
10216c74987Ssimonb 		}
10316c74987Ssimonb 
10416c74987Ssimonb 		/* get controller number */
10516c74987Ssimonb 		if ((c = *cp) >= '0' && c <= '9') {
10616c74987Ssimonb 			ctlr = c - '0';
10716c74987Ssimonb 			c = *++cp;
10816c74987Ssimonb 		}
10916c74987Ssimonb 
11016c74987Ssimonb 		if (c == ',') {
11116c74987Ssimonb 			/* get SCSI device number */
11216c74987Ssimonb 			if ((c = *++cp) >= '0' && c <= '9') {
11316c74987Ssimonb 				unit = c - '0';
11416c74987Ssimonb 				c = *++cp;
11516c74987Ssimonb 			}
11616c74987Ssimonb 
11716c74987Ssimonb 			if (c == ',') {
11816c74987Ssimonb 				/* get partition number */
11916c74987Ssimonb 				if ((c = *++cp) >= '0' && c <= '9') {
12016c74987Ssimonb 					part = c - '0';
12116c74987Ssimonb 					c = *++cp;
12216c74987Ssimonb 				}
12316c74987Ssimonb 			}
12416c74987Ssimonb 		}
12516c74987Ssimonb 		if (c != ')')
12616c74987Ssimonb 			return (ENXIO);
12716c74987Ssimonb 		cp++;
12816c74987Ssimonb 	}
12916c74987Ssimonb 	*ncp = '\0';
13016c74987Ssimonb 
13116c74987Ssimonb #ifdef LIBSA_SINGLE_DEVICE
13216c74987Ssimonb 	rc = DEV_OPEN(dp)(f, ctlr, unit, part);
1330246cad6Ssimonb #else /* !LIBSA_SINGLE_DEVICE */
13416c74987Ssimonb 	for (dp = devsw, i = 0; i < ndevs; dp++, i++)
13516c74987Ssimonb 		if (dp->dv_name && strcmp(namebuf, dp->dv_name) == 0)
13616c74987Ssimonb 			goto fnd;
13716c74987Ssimonb 	printf("Unknown device '%s'\nKnown devices are:", namebuf);
13816c74987Ssimonb 	for (dp = devsw, i = 0; i < ndevs; dp++, i++)
13916c74987Ssimonb 		if (dp->dv_name)
14016c74987Ssimonb 			printf(" %s", dp->dv_name);
14116c74987Ssimonb 	printf("\n");
14216c74987Ssimonb 	return (ENXIO);
14316c74987Ssimonb 
14416c74987Ssimonb fnd:
1450246cad6Ssimonb #ifdef BOOTNET
1460246cad6Ssimonb 	if (strcmp(namebuf, "tftp") == 0)
1470246cad6Ssimonb 		rc = (dp->dv_open)(f, namebuf);
1480246cad6Ssimonb 	else
1490246cad6Ssimonb #endif /* BOOTNET */
15016c74987Ssimonb 		rc = (dp->dv_open)(f, ctlr, unit, part);
1510246cad6Ssimonb #endif /* !LIBSA_SINGLE_DEVICE */
15216c74987Ssimonb 	if (rc)
15316c74987Ssimonb 		return (rc);
15416c74987Ssimonb 
15516c74987Ssimonb #ifndef LIBSA_SINGLE_DEVICE
15616c74987Ssimonb 	f->f_dev = dp;
15716c74987Ssimonb #endif
15816c74987Ssimonb 	if (file && *cp != '\0')
15916c74987Ssimonb 		*file = (char *)cp;	/* XXX */
16016c74987Ssimonb 	return (0);
16116c74987Ssimonb }
162