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