1 /*-
2 * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27 #include <stand.h>
28
29 #include "bootstrap.h"
30 #include "libofw.h"
31
32 /*
33 * Point (dev) at an allocated device specifier for the device matching the
34 * path in (devspec). If it contains an explicit device specification,
35 * use that. If not, use the default device.
36 */
37 int
ofw_getdev(void ** vdev,const char * devspec,const char ** path)38 ofw_getdev(void **vdev, const char *devspec, const char **path)
39 {
40 struct devdesc **dev = (struct devdesc **)vdev;
41 int rv;
42
43 /*
44 * If it looks like this is just a path and no device, go with the
45 * current device.
46 */
47 if (devspec == NULL || strpbrk(devspec, ":@") == NULL) {
48 rv = devparse(dev, getenv("currdev"), NULL);
49 if (rv == 0 && path != NULL)
50 *path = devspec;
51 return (rv);
52 }
53
54 /*
55 * Try to parse the device name off the beginning of the devspec
56 */
57 return (devparse(dev, devspec, path));
58 }
59
60 /*
61 * Search the OFW (path) for a node that's of (want_type).
62 */
63 phandle_t
ofw_path_to_handle(const char * ofwpath,const char * want_type,const char ** path)64 ofw_path_to_handle(const char *ofwpath, const char *want_type, const char **path)
65 {
66 const char *p, *s;
67 char name[256];
68 char type[64];
69 phandle_t handle;
70 int len;
71
72 for (p = s = ofwpath; *s != '\0'; p = s) {
73 if ((s = strchr(p + 1, '/')) == NULL)
74 s = strchr(p, '\0');
75 len = s - ofwpath;
76 if (len >= sizeof(name))
77 return ((phandle_t)-1);
78 bcopy(ofwpath, name, len);
79 name[len] = '\0';
80 if ((handle = OF_finddevice(name)) == -1)
81 continue;
82 if (OF_getprop(handle, "device_type", type, sizeof(type)) == -1)
83 continue;
84 if (strcmp(want_type, type) == 0) {
85 *path = s;
86 return (handle);
87 }
88 }
89 return ((phandle_t)-1);
90 }
91
92 int
ofw_common_parsedev(struct devdesc ** dev,const char * devspec,const char ** path,const char * ofwtype)93 ofw_common_parsedev(struct devdesc **dev, const char *devspec, const char **path,
94 const char *ofwtype)
95 {
96 const char *rem_path;
97 struct ofw_devdesc *idev;
98
99 if (ofw_path_to_handle(devspec, ofwtype, &rem_path) == -1)
100 return (ENOENT);
101 idev = malloc(sizeof(struct ofw_devdesc));
102 if (idev == NULL) {
103 printf("ofw_parsedev: malloc failed\n");
104 return (ENOMEM);
105 };
106 strlcpy(idev->d_path, devspec, min(rem_path - devspec + 1,
107 sizeof(idev->d_path)));
108 *dev = &idev->dd;
109 if (path != NULL)
110 *path = rem_path;
111 return (0);
112 }
113