1 1.31 thorpej /* $NetBSD: ofbus.c,v 1.31 2022/01/22 11:49:18 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.31 thorpej __KERNEL_RCSID(0, "$NetBSD: ofbus.c,v 1.31 2022/01/22 11:49:18 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.31 thorpej devhandle_t selfh = device_handle(dev); 163 1.31 thorpej 164 1.26 macallan /* attach displays first */ 165 1.11 thorpej for (child = OF_child(oba->oba_phandle); child != 0; 166 1.11 thorpej child = OF_peer(child)) { 167 1.10 mycroft oba2.oba_busname = "ofw"; 168 1.26 macallan type[0] = 0; 169 1.26 macallan if (OF_getprop(child, "device_type", type, sizeof(type)) <= 0) 170 1.26 macallan continue; 171 1.26 macallan if (strncmp(type, "display", sizeof(type)) != 0) 172 1.26 macallan continue; 173 1.13 chs of_packagename(child, name, sizeof name); 174 1.10 mycroft oba2.oba_phandle = child; 175 1.13 chs for (oba2.oba_unit = 0; oba2.oba_unit < units; 176 1.13 chs oba2.oba_unit++) { 177 1.13 chs if (units > 1) { 178 1.18 itojun snprintf(oba2.oba_ofname, 179 1.18 itojun sizeof(oba2.oba_ofname), "%s@%d", name, 180 1.18 itojun oba2.oba_unit); 181 1.13 chs } else { 182 1.18 itojun strlcpy(oba2.oba_ofname, name, 183 1.18 itojun sizeof(oba2.oba_ofname)); 184 1.13 chs } 185 1.27 thorpej config_found(dev, &oba2, ofbus_print, 186 1.31 thorpej CFARGS(.devhandle = devhandle_from_of(selfh, 187 1.31 thorpej child))); 188 1.13 chs } 189 1.1 ws } 190 1.26 macallan 191 1.26 macallan /* now the rest */ 192 1.26 macallan for (child = OF_child(oba->oba_phandle); child != 0; 193 1.26 macallan child = OF_peer(child)) { 194 1.26 macallan oba2.oba_busname = "ofw"; 195 1.26 macallan type[0] = 0; 196 1.26 macallan if (OF_getprop(child, "device_type", type, sizeof(type)) > 0) { 197 1.26 macallan if (strncmp(type, "display", sizeof(type)) == 0) 198 1.26 macallan continue; 199 1.26 macallan } 200 1.29 thorpej if (rootbus && 201 1.29 thorpej ofbus_skip_node_in_root(child, name, sizeof(name))) { 202 1.29 thorpej continue; 203 1.29 thorpej } 204 1.26 macallan of_packagename(child, name, sizeof name); 205 1.26 macallan oba2.oba_phandle = child; 206 1.26 macallan for (oba2.oba_unit = 0; oba2.oba_unit < units; 207 1.26 macallan oba2.oba_unit++) { 208 1.26 macallan if (units > 1) { 209 1.26 macallan snprintf(oba2.oba_ofname, 210 1.26 macallan sizeof(oba2.oba_ofname), "%s@%d", name, 211 1.26 macallan oba2.oba_unit); 212 1.26 macallan } else { 213 1.26 macallan strlcpy(oba2.oba_ofname, name, 214 1.26 macallan sizeof(oba2.oba_ofname)); 215 1.26 macallan } 216 1.27 thorpej config_found(dev, &oba2, ofbus_print, 217 1.31 thorpej CFARGS(.devhandle = devhandle_from_of(selfh, 218 1.31 thorpej child))); 219 1.26 macallan } 220 1.26 macallan } 221 1.1 ws } 222