/* $NetBSD: dev.c,v 1.4 1994/10/30 21:48:23 cgd Exp $ */12/*-3* Copyright (c) 19934* The Regents of the University of California. All rights reserved.5*6* Redistribution and use in source and binary forms, with or without7* modification, are permitted provided that the following conditions8* are met:9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11* 2. Redistributions in binary form must reproduce the above copyright12* notice, this list of conditions and the following disclaimer in the13* documentation and/or other materials provided with the distribution.14* 3. Neither the name of the University nor the names of its contributors15* may be used to endorse or promote products derived from this software16* without specific prior written permission.17*18* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND19* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE20* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE21* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE22* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL23* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS24* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)25* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT26* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY27* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF28* SUCH DAMAGE.29*/3031#include <sys/param.h>32#include <sys/reboot.h>3334#include "stand.h"3536int37nodev(void)38{39return (ENXIO);40}4142void43nullsys(void)44{45}4647/* ARGSUSED */48int49noioctl(struct open_file *f __unused, u_long cmd __unused, void *data __unused)50{51return (EINVAL);52}5354char *55devformat(struct devdesc *d)56{57static char name[DEV_DEVLEN];5859if (d->d_dev->dv_fmtdev != NULL)60return (d->d_dev->dv_fmtdev(d));61snprintf(name, sizeof(name), "%s%d:", d->d_dev->dv_name, d->d_unit);62return (name);63}6465/* NB: devspec points to the remainder of the device name after dv_name */66static int67default_parsedev(struct devdesc **dev, const char *devspec,68const char **path)69{70struct devdesc *idev;71int unit, err;72char *cp;7374idev = malloc(sizeof(struct devdesc));75if (idev == NULL)76return (ENOMEM);7778unit = 0;79cp = (char *)devspec; /* strtol interface, alas */8081if (*devspec != '\0' && *devspec != ':') {82errno = 0;83unit = strtol(devspec, &cp, 0);84if (errno != 0 || cp == devspec) {85err = EUNIT;86goto fail;87}88}89if (*cp != '\0' && *cp != ':') {90err = EINVAL;91goto fail;92}9394idev->d_unit = unit;95if (path != NULL)96*path = (*cp == 0) ? cp : cp + 1;97*dev = idev;98return (0);99fail:100free(idev);101return (err);102}103104/* NB: devspec points to the whole device spec, and possible trailing path */105int106devparse(struct devdesc **dev, const char *devspec, const char **path)107{108struct devdesc *idev;109struct devsw *dv;110int i, err;111const char *np;112113/* minimum length check */114if (strlen(devspec) < 2)115return (EINVAL);116117/* look for a device that matches */118for (i = 0; devsw[i] != NULL; i++) {119dv = devsw[i];120if (dv->dv_match != NULL) {121if (dv->dv_match(dv, devspec) != 0)122break;123} else {124if (!strncmp(devspec, dv->dv_name, strlen(dv->dv_name)))125break;126}127}128if (devsw[i] == NULL)129return (ENOENT);130idev = NULL;131err = 0;132if (dv->dv_parsedev) {133err = dv->dv_parsedev(&idev, devspec, path);134} else {135np = devspec + strlen(dv->dv_name);136err = default_parsedev(&idev, np, path);137}138if (err != 0)139return (err);140141idev->d_dev = dv;142if (dev != NULL)143*dev = idev;144else145free(idev);146return (0);147}148149int150devinit(void)151{152int err = 0;153154/*155* March through the device switch probing for things.156*/157for (int i = 0; devsw[i] != NULL; i++) {158if (devsw[i]->dv_init != NULL) {159if ((devsw[i]->dv_init)() != 0) {160err++;161}162}163}164return (err);165}166167void168dev_cleanup(void)169{170int i;171172/* Call cleanup routines */173for (i = 0; devsw[i] != NULL; ++i)174if (devsw[i]->dv_cleanup != NULL)175(devsw[i]->dv_cleanup)();176}177178179