devicename.c revision 106738
1169691Skan/*- 2169691Skan * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> 3169691Skan * All rights reserved. 4169691Skan * 5169691Skan * Redistribution and use in source and binary forms, with or without 6169691Skan * modification, are permitted provided that the following conditions 7169691Skan * are met: 8169691Skan * 1. Redistributions of source code must retain the above copyright 9169691Skan * notice, this list of conditions and the following disclaimer. 10169691Skan * 2. Redistributions in binary form must reproduce the above copyright 11169691Skan * notice, this list of conditions and the following disclaimer in the 12169691Skan * documentation and/or other materials provided with the distribution. 13169691Skan * 14169691Skan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15169691Skan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16169691Skan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17169691Skan * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18169691Skan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19169691Skan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20169691Skan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21169691Skan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22169691Skan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23169691Skan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24169691Skan * SUCH DAMAGE. 25169691Skan * 26169691Skan * $FreeBSD: head/sys/boot/ofw/libofw/devicename.c 106738 2002-11-10 19:17:36Z jake $ 27169691Skan */ 28169691Skan 29169691Skan#include <stand.h> 30169691Skan#include <sys/disklabel.h> 31169691Skan#include "libofw.h" 32169691Skan 33169691Skanstatic int ofw_parsedev(struct ofw_devdesc **, const char *, const char **); 34169691Skan 35169691Skan/* 36169691Skan * Point (dev) at an allocated device specifier for the device matching the 37169691Skan * path in (devspec). If it contains an explicit device specification, 38169691Skan * use that. If not, use the default device. 39169691Skan */ 40169691Skanint 41169691Skanofw_getdev(void **vdev, const char *devspec, const char **path) 42169691Skan{ 43169691Skan struct ofw_devdesc **dev = (struct ofw_devdesc **)vdev; 44169691Skan int rv; 45169691Skan 46169691Skan /* 47169691Skan * If it looks like this is just a path and no 48169691Skan * device, go with the current device. 49169691Skan */ 50169691Skan if ((devspec == NULL) || 51169691Skan (strchr(devspec, '@') == NULL)) { 52169691Skan 53169691Skan if (((rv = ofw_parsedev(dev, getenv("currdev"), NULL)) == 0) && 54169691Skan (path != NULL)) 55169691Skan *path = devspec; 56169691Skan return(rv); 57169691Skan } 58169691Skan 59169691Skan /* 60169691Skan * Try to parse the device name off the beginning of the devspec 61169691Skan */ 62169691Skan return(ofw_parsedev(dev, devspec, path)); 63169691Skan} 64169691Skan 65169691Skan/* 66169691Skan * Point (dev) at an allocated device specifier matching the string version 67169691Skan * at the beginning of (devspec). Return a pointer to the remaining 68169691Skan * text in (path). 69169691Skan */ 70169691Skanstatic int 71169691Skanofw_parsedev(struct ofw_devdesc **dev, const char *devspec, const char **path) 72169691Skan{ 73169691Skan struct ofw_devdesc *idev; 74169691Skan struct devsw *dv; 75169691Skan phandle_t handle; 76169691Skan const char *p; 77169691Skan const char *s; 78169691Skan char name[256]; 79169691Skan char type[64]; 80169691Skan int len; 81169691Skan int i; 82169691Skan 83169691Skan for (p = s = devspec; *s != '\0'; p = s) { 84169691Skan if ((s = strchr(p + 1, '/')) == NULL) 85 s = strchr(p, '\0'); 86 len = s - devspec; 87 bcopy(devspec, name, len); 88 name[len] = '\0'; 89 if ((handle = OF_finddevice(name)) == -1) 90 break; 91 if (OF_getprop(handle, "device_type", type, sizeof(type)) == -1) 92 continue; 93 for (i = 0; (dv = devsw[i]) != NULL; i++) { 94 if (strncmp(dv->dv_name, type, strlen(type)) == 0) 95 goto found; 96 } 97 } 98 return(ENOENT); 99 100found: 101 if (*s != '\0') 102 *path = s; 103 idev = malloc(sizeof(struct ofw_devdesc)); 104 strcpy(idev->d_path, name); 105 idev->d_dev = dv; 106 idev->d_type = dv->dv_type; 107 if (dev == NULL) { 108 free(idev); 109 } else { 110 *dev = idev; 111 } 112 return(0); 113} 114 115int 116ofw_setcurrdev(struct env_var *ev, int flags, void *value) 117{ 118 struct ofw_devdesc *ncurr; 119 int rv; 120 121 if ((rv = ofw_parsedev(&ncurr, value, NULL)) != 0) 122 return rv; 123 124 free(ncurr); 125 env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL); 126 return 0; 127} 128