xref: /netbsd-src/sys/arch/bebox/stand/boot/devopen.c (revision 14bd0028e3f9b2f07d6c61b7b1750642caae49c2)
1*14bd0028Skiyohara /*	$NetBSD: devopen.c,v 1.11 2012/12/19 13:53:47 kiyohara Exp $	*/
2b1bde3fcSsakamoto 
3b1bde3fcSsakamoto /*-
4b1bde3fcSsakamoto  *  Copyright (c) 1993 John Brezak
5b1bde3fcSsakamoto  *  All rights reserved.
6b1bde3fcSsakamoto  *
7b1bde3fcSsakamoto  *  Redistribution and use in source and binary forms, with or without
8b1bde3fcSsakamoto  *  modification, are permitted provided that the following conditions
9b1bde3fcSsakamoto  *  are met:
10b1bde3fcSsakamoto  *  1. Redistributions of source code must retain the above copyright
11b1bde3fcSsakamoto  *     notice, this list of conditions and the following disclaimer.
12b1bde3fcSsakamoto  *  2. Redistributions in binary form must reproduce the above copyright
13b1bde3fcSsakamoto  *     notice, this list of conditions and the following disclaimer in the
14b1bde3fcSsakamoto  *     documentation and/or other materials provided with the distribution.
15b1bde3fcSsakamoto  *  3. The name of the author may not be used to endorse or promote products
16b1bde3fcSsakamoto  *     derived from this software without specific prior written permission.
17b1bde3fcSsakamoto  *
18b1bde3fcSsakamoto  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
19b1bde3fcSsakamoto  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20b1bde3fcSsakamoto  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21b1bde3fcSsakamoto  * DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
22b1bde3fcSsakamoto  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23b1bde3fcSsakamoto  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24b1bde3fcSsakamoto  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25b1bde3fcSsakamoto  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26b1bde3fcSsakamoto  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27b1bde3fcSsakamoto  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28b1bde3fcSsakamoto  * POSSIBILITY OF SUCH DAMAGE.
29b1bde3fcSsakamoto  */
30b1bde3fcSsakamoto 
31e63501d2Sjunyoung #include <lib/libsa/stand.h>
32c359f5efSsakamoto #include <lib/libkern/libkern.h>
33b1bde3fcSsakamoto #include <sys/param.h>
34b1bde3fcSsakamoto #include <sys/reboot.h>
35b1bde3fcSsakamoto 
3633aaae50Skiyohara static int devparse(const char *, int *, int *, int *, int *, int *, char **);
3733aaae50Skiyohara 
3833aaae50Skiyohara 
39b1bde3fcSsakamoto /*
409fe16975Skiyohara  * Parse a device spec.
419fe16975Skiyohara  *   i.e.
429fe16975Skiyohara  *     /dev/disk/floppy
43*14bd0028Skiyohara  *     /dev/disk/ide/0/master/0_n
44*14bd0028Skiyohara  *     /dev/disk/ide/0/slave/0_n
45*14bd0028Skiyohara  *     /dev/disk/scsi/000/0_n
46*14bd0028Skiyohara  *     /dev/disk/scsi/030/0_n
47b1bde3fcSsakamoto  */
4833aaae50Skiyohara static int
devparse(const char * fname,int * dev,int * ctlr,int * unit,int * lunit,int * part,char ** file)499fe16975Skiyohara devparse(const char *fname, int *dev, int *ctlr, int *unit, int *lunit,
507bac1211Sjunyoung 	 int *part, char **file)
51b1bde3fcSsakamoto {
529fe16975Skiyohara 	int i;
539fe16975Skiyohara 	char devdir[] = "/dev/disk/";
549fe16975Skiyohara 	char floppy[] = "floppy";
559fe16975Skiyohara 	char ide[] = "ide";
569fe16975Skiyohara 	char scsi[] = "scsi";
579fe16975Skiyohara 	char *p;
58b1bde3fcSsakamoto 
599fe16975Skiyohara 	if (strncmp(fname, devdir, strlen(devdir)) != 0)
609fe16975Skiyohara 		return EINVAL;
619fe16975Skiyohara 	p = __UNCONST(fname) + strlen(devdir);
62b1bde3fcSsakamoto 
639fe16975Skiyohara 	if (strncmp(p, floppy, strlen(floppy)) == 0) {
649fe16975Skiyohara 		p += strlen(floppy);
659fe16975Skiyohara 		for (i = 0; devsw[i].dv_name != NULL; i++)
669fe16975Skiyohara 			if (strcmp(devsw[i].dv_name, "fd") == 0) {
679fe16975Skiyohara 				*dev = i;
689fe16975Skiyohara 				*ctlr = 0;
699fe16975Skiyohara 				*unit = 1;
709fe16975Skiyohara 				*lunit = 0;
71b1bde3fcSsakamoto 				break;
72b1bde3fcSsakamoto 			}
739fe16975Skiyohara 	} else if (strncmp(p, ide, strlen(ide)) == 0) {
749fe16975Skiyohara 		char master[] = "master";
759fe16975Skiyohara 		char slave[] = "slave";
76b1bde3fcSsakamoto 
779fe16975Skiyohara 		p += strlen(ide);
789fe16975Skiyohara 		if (*p++ != '/' ||
799fe16975Skiyohara 		    !isdigit(*p++) ||
809fe16975Skiyohara 		    *p++ != '/')
817bac1211Sjunyoung 			return EINVAL;
829fe16975Skiyohara 		*ctlr = *(p - 2) - '0';
839fe16975Skiyohara 		if (strncmp(p, master, strlen(master)) == 0) {
849fe16975Skiyohara 			*unit = 0;
859fe16975Skiyohara 			p += strlen(master);
869fe16975Skiyohara 		} else if (strncmp(p, slave, strlen(slave)) == 0) {
879fe16975Skiyohara 			*unit = 1;
889fe16975Skiyohara 			p += strlen(slave);
899fe16975Skiyohara 		} else
909fe16975Skiyohara 			return EINVAL;
919fe16975Skiyohara 		if (*p++ != '/' ||
929fe16975Skiyohara 		    !isdigit(*p++) ||
939fe16975Skiyohara 		    *p++ != '_' ||
949fe16975Skiyohara 		    !isdigit(*p++))
959fe16975Skiyohara 			return EINVAL;
969fe16975Skiyohara 		*lunit = *(p - 3) - '0';
979fe16975Skiyohara 		*part = *(p - 1) - '0';
989fe16975Skiyohara 		for (i = 0; devsw[i].dv_name != NULL; i++)
999fe16975Skiyohara 			if (strcmp(devsw[i].dv_name, "wd") == 0) {
1009fe16975Skiyohara 				*dev = i;
1019fe16975Skiyohara 				break;
1029fe16975Skiyohara 			}
1039fe16975Skiyohara 		if (devsw[i].dv_name == NULL)
1049fe16975Skiyohara 			return EINVAL;
1059fe16975Skiyohara 	} else if (strncmp(p, scsi, strlen(scsi)) == 0) {
1069fe16975Skiyohara 		p += strlen(scsi);
1079fe16975Skiyohara 		if (*p++ != '/' ||
1089fe16975Skiyohara 		    !isdigit(*p++) ||
109*14bd0028Skiyohara 		    !isdigit(*p++) ||
1109fe16975Skiyohara 		    !isdigit(*p++) ||
1119fe16975Skiyohara 		    *p++ != '/' ||
1129fe16975Skiyohara 		    !isdigit(*p++) ||
1139fe16975Skiyohara 		    *p++ != '_' ||
1149fe16975Skiyohara 		    !isdigit(*p++))
1159fe16975Skiyohara 			return EINVAL;
1169fe16975Skiyohara 		*ctlr = *(p - 7) - '0';
117*14bd0028Skiyohara 		*unit = *(p - 6) - '0';
118*14bd0028Skiyohara 		*lunit = *(p - 5) - '0';
1199fe16975Skiyohara 		*part = *(p - 1) - '0';
1209fe16975Skiyohara 		for (i = 0; devsw[i].dv_name != NULL; i++)
1219fe16975Skiyohara 			if (strcmp(devsw[i].dv_name, "sd") == 0) {
1229fe16975Skiyohara 				*dev = i;
1239fe16975Skiyohara 				break;
1249fe16975Skiyohara 			}
1259fe16975Skiyohara 		if (devsw[i].dv_name == NULL)
1269fe16975Skiyohara 			return EINVAL;
1279fe16975Skiyohara 	}
1289fe16975Skiyohara 
1299fe16975Skiyohara 	if (*p++ != ':')
1309fe16975Skiyohara 		return EINVAL;
1319fe16975Skiyohara 	*file = p;
1329fe16975Skiyohara 	return 0;
133b1bde3fcSsakamoto }
134b1bde3fcSsakamoto 
135d32f2272Ssakamoto int
devopen(struct open_file * f,const char * fname,char ** file)1367bac1211Sjunyoung devopen(struct open_file *f, const char *fname, char **file)
137b1bde3fcSsakamoto {
138d32f2272Ssakamoto 	int error;
1399fe16975Skiyohara 	int dev = 0, ctlr = 0, unit = 0, lunit = 0, part = 0;
140b1bde3fcSsakamoto 	struct devsw *dp = &devsw[0];
1419fe16975Skiyohara 	extern struct devsw pseudo_devsw;
142b1bde3fcSsakamoto 
1439fe16975Skiyohara 	**file = '\0';
1449fe16975Skiyohara 	error = devparse(fname, &dev, &ctlr, &unit, &lunit, &part, file);
1459fe16975Skiyohara 	if (error == 0) {
146b1bde3fcSsakamoto 		dp = &devsw[dev];
147b1bde3fcSsakamoto 		if (!dp->dv_open)
1487bac1211Sjunyoung 			return ENODEV;
1499fe16975Skiyohara 	} else {
1509fe16975Skiyohara 		if (strcmp(fname, "in") == 0)
1519fe16975Skiyohara 			/* special case: kernel in memory */
1529fe16975Skiyohara 			dp = &pseudo_devsw;
1539fe16975Skiyohara 		else
1549fe16975Skiyohara 			return error;
1559fe16975Skiyohara 	}
156b1bde3fcSsakamoto 
157b1bde3fcSsakamoto 	f->f_dev = dp;
1589fe16975Skiyohara 	if ((error = (*dp->dv_open)(f, ctlr, unit, lunit, part)) == 0)
1597bac1211Sjunyoung 		return 0;
160b1bde3fcSsakamoto 
1619fe16975Skiyohara 	printf("%s %s\n", fname, strerror(error));
162b1bde3fcSsakamoto 
1637bac1211Sjunyoung 	return error;
164b1bde3fcSsakamoto }
165