1 1.11 kiyohara /* $NetBSD: devopen.c,v 1.11 2012/12/19 13:53:47 kiyohara Exp $ */ 2 1.1 sakamoto 3 1.1 sakamoto /*- 4 1.1 sakamoto * Copyright (c) 1993 John Brezak 5 1.1 sakamoto * All rights reserved. 6 1.1 sakamoto * 7 1.1 sakamoto * Redistribution and use in source and binary forms, with or without 8 1.1 sakamoto * modification, are permitted provided that the following conditions 9 1.1 sakamoto * are met: 10 1.1 sakamoto * 1. Redistributions of source code must retain the above copyright 11 1.1 sakamoto * notice, this list of conditions and the following disclaimer. 12 1.1 sakamoto * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 sakamoto * notice, this list of conditions and the following disclaimer in the 14 1.1 sakamoto * documentation and/or other materials provided with the distribution. 15 1.1 sakamoto * 3. The name of the author may not be used to endorse or promote products 16 1.1 sakamoto * derived from this software without specific prior written permission. 17 1.5 junyoung * 18 1.1 sakamoto * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR 19 1.1 sakamoto * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 1.1 sakamoto * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 1.1 sakamoto * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 22 1.1 sakamoto * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 1.1 sakamoto * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 1.1 sakamoto * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 1.1 sakamoto * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 1.1 sakamoto * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 27 1.1 sakamoto * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 1.1 sakamoto * POSSIBILITY OF SUCH DAMAGE. 29 1.1 sakamoto */ 30 1.1 sakamoto 31 1.6 junyoung #include <lib/libsa/stand.h> 32 1.4 sakamoto #include <lib/libkern/libkern.h> 33 1.1 sakamoto #include <sys/param.h> 34 1.1 sakamoto #include <sys/reboot.h> 35 1.1 sakamoto 36 1.9 kiyohara static int devparse(const char *, int *, int *, int *, int *, int *, char **); 37 1.9 kiyohara 38 1.9 kiyohara 39 1.1 sakamoto /* 40 1.10 kiyohara * Parse a device spec. 41 1.10 kiyohara * i.e. 42 1.10 kiyohara * /dev/disk/floppy 43 1.11 kiyohara * /dev/disk/ide/0/master/0_n 44 1.11 kiyohara * /dev/disk/ide/0/slave/0_n 45 1.11 kiyohara * /dev/disk/scsi/000/0_n 46 1.11 kiyohara * /dev/disk/scsi/030/0_n 47 1.1 sakamoto */ 48 1.9 kiyohara static int 49 1.10 kiyohara devparse(const char *fname, int *dev, int *ctlr, int *unit, int *lunit, 50 1.5 junyoung int *part, char **file) 51 1.1 sakamoto { 52 1.10 kiyohara int i; 53 1.10 kiyohara char devdir[] = "/dev/disk/"; 54 1.10 kiyohara char floppy[] = "floppy"; 55 1.10 kiyohara char ide[] = "ide"; 56 1.10 kiyohara char scsi[] = "scsi"; 57 1.10 kiyohara char *p; 58 1.10 kiyohara 59 1.10 kiyohara if (strncmp(fname, devdir, strlen(devdir)) != 0) 60 1.10 kiyohara return EINVAL; 61 1.10 kiyohara p = __UNCONST(fname) + strlen(devdir); 62 1.10 kiyohara 63 1.10 kiyohara if (strncmp(p, floppy, strlen(floppy)) == 0) { 64 1.10 kiyohara p += strlen(floppy); 65 1.10 kiyohara for (i = 0; devsw[i].dv_name != NULL; i++) 66 1.10 kiyohara if (strcmp(devsw[i].dv_name, "fd") == 0) { 67 1.10 kiyohara *dev = i; 68 1.10 kiyohara *ctlr = 0; 69 1.10 kiyohara *unit = 1; 70 1.10 kiyohara *lunit = 0; 71 1.10 kiyohara break; 72 1.10 kiyohara } 73 1.10 kiyohara } else if (strncmp(p, ide, strlen(ide)) == 0) { 74 1.10 kiyohara char master[] = "master"; 75 1.10 kiyohara char slave[] = "slave"; 76 1.10 kiyohara 77 1.10 kiyohara p += strlen(ide); 78 1.10 kiyohara if (*p++ != '/' || 79 1.10 kiyohara !isdigit(*p++) || 80 1.10 kiyohara *p++ != '/') 81 1.10 kiyohara return EINVAL; 82 1.10 kiyohara *ctlr = *(p - 2) - '0'; 83 1.10 kiyohara if (strncmp(p, master, strlen(master)) == 0) { 84 1.10 kiyohara *unit = 0; 85 1.10 kiyohara p += strlen(master); 86 1.10 kiyohara } else if (strncmp(p, slave, strlen(slave)) == 0) { 87 1.10 kiyohara *unit = 1; 88 1.10 kiyohara p += strlen(slave); 89 1.10 kiyohara } else 90 1.10 kiyohara return EINVAL; 91 1.10 kiyohara if (*p++ != '/' || 92 1.10 kiyohara !isdigit(*p++) || 93 1.10 kiyohara *p++ != '_' || 94 1.10 kiyohara !isdigit(*p++)) 95 1.10 kiyohara return EINVAL; 96 1.10 kiyohara *lunit = *(p - 3) - '0'; 97 1.10 kiyohara *part = *(p - 1) - '0'; 98 1.10 kiyohara for (i = 0; devsw[i].dv_name != NULL; i++) 99 1.10 kiyohara if (strcmp(devsw[i].dv_name, "wd") == 0) { 100 1.10 kiyohara *dev = i; 101 1.10 kiyohara break; 102 1.10 kiyohara } 103 1.10 kiyohara if (devsw[i].dv_name == NULL) 104 1.10 kiyohara return EINVAL; 105 1.10 kiyohara } else if (strncmp(p, scsi, strlen(scsi)) == 0) { 106 1.10 kiyohara p += strlen(scsi); 107 1.10 kiyohara if (*p++ != '/' || 108 1.10 kiyohara !isdigit(*p++) || 109 1.11 kiyohara !isdigit(*p++) || 110 1.10 kiyohara !isdigit(*p++) || 111 1.10 kiyohara *p++ != '/' || 112 1.10 kiyohara !isdigit(*p++) || 113 1.10 kiyohara *p++ != '_' || 114 1.10 kiyohara !isdigit(*p++)) 115 1.10 kiyohara return EINVAL; 116 1.10 kiyohara *ctlr = *(p - 7) - '0'; 117 1.11 kiyohara *unit = *(p - 6) - '0'; 118 1.11 kiyohara *lunit = *(p - 5) - '0'; 119 1.10 kiyohara *part = *(p - 1) - '0'; 120 1.10 kiyohara for (i = 0; devsw[i].dv_name != NULL; i++) 121 1.10 kiyohara if (strcmp(devsw[i].dv_name, "sd") == 0) { 122 1.10 kiyohara *dev = i; 123 1.10 kiyohara break; 124 1.1 sakamoto } 125 1.10 kiyohara if (devsw[i].dv_name == NULL) 126 1.10 kiyohara return EINVAL; 127 1.1 sakamoto } 128 1.10 kiyohara 129 1.10 kiyohara if (*p++ != ':') 130 1.10 kiyohara return EINVAL; 131 1.10 kiyohara *file = p; 132 1.5 junyoung return 0; 133 1.1 sakamoto } 134 1.1 sakamoto 135 1.3 sakamoto int 136 1.5 junyoung devopen(struct open_file *f, const char *fname, char **file) 137 1.1 sakamoto { 138 1.3 sakamoto int error; 139 1.10 kiyohara int dev = 0, ctlr = 0, unit = 0, lunit = 0, part = 0; 140 1.1 sakamoto struct devsw *dp = &devsw[0]; 141 1.10 kiyohara extern struct devsw pseudo_devsw; 142 1.1 sakamoto 143 1.10 kiyohara **file = '\0'; 144 1.10 kiyohara error = devparse(fname, &dev, &ctlr, &unit, &lunit, &part, file); 145 1.10 kiyohara if (error == 0) { 146 1.10 kiyohara dp = &devsw[dev]; 147 1.10 kiyohara if (!dp->dv_open) 148 1.10 kiyohara return ENODEV; 149 1.10 kiyohara } else { 150 1.10 kiyohara if (strcmp(fname, "in") == 0) 151 1.10 kiyohara /* special case: kernel in memory */ 152 1.10 kiyohara dp = &pseudo_devsw; 153 1.10 kiyohara else 154 1.10 kiyohara return error; 155 1.10 kiyohara } 156 1.1 sakamoto 157 1.1 sakamoto f->f_dev = dp; 158 1.10 kiyohara if ((error = (*dp->dv_open)(f, ctlr, unit, lunit, part)) == 0) 159 1.5 junyoung return 0; 160 1.1 sakamoto 161 1.10 kiyohara printf("%s %s\n", fname, strerror(error)); 162 1.1 sakamoto 163 1.5 junyoung return error; 164 1.1 sakamoto } 165