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