1 /* $NetBSD: dev.c,v 1.4 1994/10/30 21:48:23 cgd Exp $ */ 2 3 /*- 4 * Copyright (c) 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include <sys/param.h> 33 #include <sys/reboot.h> 34 35 #include "stand.h" 36 37 int 38 nodev(void) 39 { 40 return (ENXIO); 41 } 42 43 void 44 nullsys(void) 45 { 46 } 47 48 /* ARGSUSED */ 49 int 50 noioctl(struct open_file *f __unused, u_long cmd __unused, void *data __unused) 51 { 52 return (EINVAL); 53 } 54 55 char * 56 devformat(struct devdesc *d) 57 { 58 static char name[DEV_DEVLEN]; 59 60 if (d->d_dev->dv_fmtdev != NULL) 61 return (d->d_dev->dv_fmtdev(d)); 62 snprintf(name, sizeof(name), "%s%d:", d->d_dev->dv_name, d->d_unit); 63 return (name); 64 } 65 66 /* NB: devspec points to the remainder of the device name after dv_name */ 67 static int 68 default_parsedev(struct devdesc **dev, const char *devspec, 69 const char **path) 70 { 71 struct devdesc *idev; 72 int unit, err; 73 char *cp; 74 75 idev = malloc(sizeof(struct devdesc)); 76 if (idev == NULL) 77 return (ENOMEM); 78 79 unit = 0; 80 cp = (char *)devspec; /* strtol interface, alas */ 81 82 if (*devspec != '\0' && *devspec != ':') { 83 errno = 0; 84 unit = strtol(devspec, &cp, 0); 85 if (errno != 0 || cp == devspec) { 86 err = EUNIT; 87 goto fail; 88 } 89 } 90 if (*cp != '\0' && *cp != ':') { 91 err = EINVAL; 92 goto fail; 93 } 94 95 idev->d_unit = unit; 96 if (path != NULL) 97 *path = (*cp == 0) ? cp : cp + 1; 98 *dev = idev; 99 return (0); 100 fail: 101 free(idev); 102 return (err); 103 } 104 105 /* NB: devspec points to the whole device spec, and possible trailing path */ 106 int 107 devparse(struct devdesc **dev, const char *devspec, const char **path) 108 { 109 struct devdesc *idev; 110 struct devsw *dv; 111 int i, err; 112 const char *np; 113 114 /* minimum length check */ 115 if (strlen(devspec) < 2) 116 return (EINVAL); 117 118 /* look for a device that matches */ 119 for (i = 0; devsw[i] != NULL; i++) { 120 dv = devsw[i]; 121 if (dv->dv_match != NULL) { 122 if (dv->dv_match(dv, devspec) != 0) 123 break; 124 } else { 125 if (!strncmp(devspec, dv->dv_name, strlen(dv->dv_name))) 126 break; 127 } 128 } 129 if (devsw[i] == NULL) 130 return (ENOENT); 131 idev = NULL; 132 err = 0; 133 if (dv->dv_parsedev) { 134 err = dv->dv_parsedev(&idev, devspec, path); 135 } else { 136 np = devspec + strlen(dv->dv_name); 137 err = default_parsedev(&idev, np, path); 138 } 139 if (err != 0) 140 return (err); 141 142 idev->d_dev = dv; 143 if (dev != NULL) 144 *dev = idev; 145 else 146 free(idev); 147 return (0); 148 } 149 150 int 151 devinit(void) 152 { 153 int err = 0; 154 155 /* 156 * March through the device switch probing for things. 157 */ 158 for (int i = 0; devsw[i] != NULL; i++) { 159 if (devsw[i]->dv_init != NULL) { 160 if ((devsw[i]->dv_init)() != 0) { 161 err++; 162 } 163 } 164 } 165 return (err); 166 } 167 168 void 169 dev_cleanup(void) 170 { 171 int i; 172 173 /* Call cleanup routines */ 174 for (i = 0; devsw[i] != NULL; ++i) 175 if (devsw[i]->dv_cleanup != NULL) 176 (devsw[i]->dv_cleanup)(); 177 } 178