ofbus.c revision 1.29 1 1.29 thorpej /* $NetBSD: ofbus.c,v 1.29 2021/04/30 02:34:12 thorpej Exp $ */
2 1.1 ws
3 1.1 ws /*
4 1.1 ws * Copyright (C) 1995, 1996 Wolfgang Solfrank.
5 1.1 ws * Copyright (C) 1995, 1996 TooLs GmbH.
6 1.1 ws * All rights reserved.
7 1.1 ws *
8 1.1 ws * Redistribution and use in source and binary forms, with or without
9 1.1 ws * modification, are permitted provided that the following conditions
10 1.1 ws * are met:
11 1.1 ws * 1. Redistributions of source code must retain the above copyright
12 1.1 ws * notice, this list of conditions and the following disclaimer.
13 1.1 ws * 2. Redistributions in binary form must reproduce the above copyright
14 1.1 ws * notice, this list of conditions and the following disclaimer in the
15 1.1 ws * documentation and/or other materials provided with the distribution.
16 1.1 ws * 3. All advertising materials mentioning features or use of this software
17 1.1 ws * must display the following acknowledgement:
18 1.1 ws * This product includes software developed by TooLs GmbH.
19 1.1 ws * 4. The name of TooLs GmbH may not be used to endorse or promote products
20 1.1 ws * derived from this software without specific prior written permission.
21 1.1 ws *
22 1.1 ws * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
23 1.1 ws * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 1.1 ws * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 1.1 ws * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 1.1 ws * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 1.1 ws * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
28 1.1 ws * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 1.1 ws * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30 1.1 ws * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31 1.1 ws * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 1.1 ws */
33 1.12 lukem
34 1.12 lukem #include <sys/cdefs.h>
35 1.29 thorpej __KERNEL_RCSID(0, "$NetBSD: ofbus.c,v 1.29 2021/04/30 02:34:12 thorpej Exp $");
36 1.1 ws
37 1.1 ws #include <sys/param.h>
38 1.7 cgd #include <sys/systm.h>
39 1.1 ws #include <sys/device.h>
40 1.1 ws
41 1.1 ws #include <dev/ofw/openfirm.h>
42 1.1 ws
43 1.24 cegger int ofbus_match(device_t, cfdata_t, void *);
44 1.24 cegger void ofbus_attach(device_t, device_t, void *);
45 1.19 perry static int ofbus_print(void *, const char *);
46 1.1 ws
47 1.25 matt CFATTACH_DECL_NEW(ofbus, 0,
48 1.16 thorpej ofbus_match, ofbus_attach, NULL, NULL);
49 1.1 ws
50 1.1 ws static int
51 1.21 dsl ofbus_print(void *aux, const char *pnp)
52 1.1 ws {
53 1.10 mycroft struct ofbus_attach_args *oba = aux;
54 1.7 cgd
55 1.7 cgd if (pnp)
56 1.17 thorpej aprint_normal("%s at %s", oba->oba_ofname, pnp);
57 1.1 ws else
58 1.17 thorpej aprint_normal(" (%s)", oba->oba_ofname);
59 1.1 ws return UNCONF;
60 1.1 ws }
61 1.1 ws
62 1.1 ws int
63 1.24 cegger ofbus_match(device_t parent, cfdata_t cf, void *aux)
64 1.1 ws {
65 1.10 mycroft struct ofbus_attach_args *oba = aux;
66 1.10 mycroft
67 1.10 mycroft if (strcmp(oba->oba_busname, "ofw"))
68 1.10 mycroft return (0);
69 1.10 mycroft if (!OF_child(oba->oba_phandle))
70 1.10 mycroft return (0);
71 1.10 mycroft return (1);
72 1.1 ws }
73 1.1 ws
74 1.29 thorpej #if defined(__arm32__) /* XXX temporary */
75 1.29 thorpej #define _OFBUS_ROOT_MACHDEP_SKIPNAMES \
76 1.29 thorpej "udp", \
77 1.29 thorpej "cpus", \
78 1.29 thorpej "mmu", \
79 1.29 thorpej "memory"
80 1.29 thorpej #endif /* __arm32__ */
81 1.29 thorpej
82 1.29 thorpej /*
83 1.29 thorpej * Skip some well-known nodes in the root that contain no useful
84 1.29 thorpej * child devices.
85 1.29 thorpej */
86 1.29 thorpej static bool
87 1.29 thorpej ofbus_skip_node_in_root(int phandle, char *name, size_t namesize)
88 1.29 thorpej {
89 1.29 thorpej static const char * const skip_names[] = {
90 1.29 thorpej "aliases",
91 1.29 thorpej "options",
92 1.29 thorpej "openprom",
93 1.29 thorpej "chosen",
94 1.29 thorpej "packages",
95 1.29 thorpej #ifdef _OFBUS_ROOT_MACHDEP_SKIPNAMES
96 1.29 thorpej _OFBUS_ROOT_MACHDEP_SKIPNAMES
97 1.29 thorpej #endif
98 1.29 thorpej };
99 1.29 thorpej u_int i;
100 1.29 thorpej
101 1.29 thorpej name[0] = '\0';
102 1.29 thorpej if (OF_getprop(phandle, "name", name, namesize) <= 0) {
103 1.29 thorpej return false;
104 1.29 thorpej }
105 1.29 thorpej
106 1.29 thorpej for (i = 0; i < __arraycount(skip_names); i++) {
107 1.29 thorpej if (strcmp(name, skip_names[i]) == 0) {
108 1.29 thorpej return true;
109 1.29 thorpej }
110 1.29 thorpej }
111 1.29 thorpej return false;
112 1.29 thorpej }
113 1.29 thorpej
114 1.1 ws void
115 1.24 cegger ofbus_attach(device_t parent, device_t dev, void *aux)
116 1.1 ws {
117 1.10 mycroft struct ofbus_attach_args *oba = aux;
118 1.10 mycroft struct ofbus_attach_args oba2;
119 1.26 macallan char name[64], type[64];
120 1.13 chs int child, units;
121 1.29 thorpej bool rootbus;
122 1.29 thorpej
123 1.29 thorpej rootbus = oba->oba_phandle == OF_finddevice("/");
124 1.7 cgd
125 1.28 thorpej /*
126 1.28 thorpej * If we are the OFW root, get the banner-name and model
127 1.28 thorpej * properties and display them for informational purposes.
128 1.28 thorpej */
129 1.29 thorpej if (rootbus) {
130 1.28 thorpej int model_len, banner_len;
131 1.28 thorpej
132 1.28 thorpej model_len = OF_getprop(oba->oba_phandle, "model",
133 1.28 thorpej name, sizeof(name));
134 1.28 thorpej banner_len = OF_getprop(oba->oba_phandle, "banner-name",
135 1.28 thorpej type, sizeof(type));
136 1.28 thorpej
137 1.28 thorpej if (banner_len > 0 && model_len > 0) {
138 1.28 thorpej printf(": %s (%s)\n", type, name);
139 1.28 thorpej } else if (model_len > 0) {
140 1.28 thorpej printf(": %s\n", name);
141 1.28 thorpej } else {
142 1.28 thorpej printf("\n");
143 1.28 thorpej }
144 1.28 thorpej } else {
145 1.28 thorpej printf("\n");
146 1.28 thorpej }
147 1.1 ws
148 1.1 ws /*
149 1.1 ws * This is a hack to make the probe work on the scsi (and ide) bus.
150 1.1 ws * YES, I THINK IT IS A BUG IN THE OPENFIRMWARE TO NOT PROBE ALL
151 1.1 ws * DEVICES ON THESE BUSSES.
152 1.1 ws */
153 1.1 ws units = 1;
154 1.13 chs name[0] = 0;
155 1.10 mycroft if (OF_getprop(oba->oba_phandle, "name", name, sizeof name) > 0) {
156 1.1 ws if (!strcmp(name, "scsi"))
157 1.1 ws units = 7; /* What about wide or hostid != 7? XXX */
158 1.1 ws else if (!strcmp(name, "ide"))
159 1.1 ws units = 2;
160 1.1 ws }
161 1.6 cgd
162 1.26 macallan /* attach displays first */
163 1.11 thorpej for (child = OF_child(oba->oba_phandle); child != 0;
164 1.11 thorpej child = OF_peer(child)) {
165 1.10 mycroft oba2.oba_busname = "ofw";
166 1.26 macallan type[0] = 0;
167 1.26 macallan if (OF_getprop(child, "device_type", type, sizeof(type)) <= 0)
168 1.26 macallan continue;
169 1.26 macallan if (strncmp(type, "display", sizeof(type)) != 0)
170 1.26 macallan continue;
171 1.13 chs of_packagename(child, name, sizeof name);
172 1.10 mycroft oba2.oba_phandle = child;
173 1.13 chs for (oba2.oba_unit = 0; oba2.oba_unit < units;
174 1.13 chs oba2.oba_unit++) {
175 1.13 chs if (units > 1) {
176 1.18 itojun snprintf(oba2.oba_ofname,
177 1.18 itojun sizeof(oba2.oba_ofname), "%s@%d", name,
178 1.18 itojun oba2.oba_unit);
179 1.13 chs } else {
180 1.18 itojun strlcpy(oba2.oba_ofname, name,
181 1.18 itojun sizeof(oba2.oba_ofname));
182 1.13 chs }
183 1.27 thorpej config_found(dev, &oba2, ofbus_print,
184 1.27 thorpej CFARG_DEVHANDLE, devhandle_from_of(child),
185 1.27 thorpej CFARG_EOL);
186 1.13 chs }
187 1.1 ws }
188 1.26 macallan
189 1.26 macallan /* now the rest */
190 1.26 macallan for (child = OF_child(oba->oba_phandle); child != 0;
191 1.26 macallan child = OF_peer(child)) {
192 1.26 macallan oba2.oba_busname = "ofw";
193 1.26 macallan type[0] = 0;
194 1.26 macallan if (OF_getprop(child, "device_type", type, sizeof(type)) > 0) {
195 1.26 macallan if (strncmp(type, "display", sizeof(type)) == 0)
196 1.26 macallan continue;
197 1.26 macallan }
198 1.29 thorpej if (rootbus &&
199 1.29 thorpej ofbus_skip_node_in_root(child, name, sizeof(name))) {
200 1.29 thorpej continue;
201 1.29 thorpej }
202 1.26 macallan of_packagename(child, name, sizeof name);
203 1.26 macallan oba2.oba_phandle = child;
204 1.26 macallan for (oba2.oba_unit = 0; oba2.oba_unit < units;
205 1.26 macallan oba2.oba_unit++) {
206 1.26 macallan if (units > 1) {
207 1.26 macallan snprintf(oba2.oba_ofname,
208 1.26 macallan sizeof(oba2.oba_ofname), "%s@%d", name,
209 1.26 macallan oba2.oba_unit);
210 1.26 macallan } else {
211 1.26 macallan strlcpy(oba2.oba_ofname, name,
212 1.26 macallan sizeof(oba2.oba_ofname));
213 1.26 macallan }
214 1.27 thorpej config_found(dev, &oba2, ofbus_print,
215 1.27 thorpej CFARG_DEVHANDLE, devhandle_from_of(child),
216 1.27 thorpej CFARG_EOL);
217 1.26 macallan }
218 1.26 macallan }
219 1.1 ws }
220