subr_bus.c (70804) | subr_bus.c (78135) |
---|---|
1/*- 2 * Copyright (c) 1997,1998 Doug Rabson 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 unchanged lines hidden (view full) --- 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 * | 1/*- 2 * Copyright (c) 1997,1998 Doug Rabson 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 unchanged lines hidden (view full) --- 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 * $FreeBSD: head/sys/kern/subr_bus.c 70804 2001-01-08 22:16:26Z n_hibma $ | 26 * $FreeBSD: head/sys/kern/subr_bus.c 78135 2001-06-12 09:40:04Z peter $ |
27 */ 28 29#include "opt_bus.h" 30 31#include <sys/param.h> 32#include <sys/queue.h> 33#include <sys/malloc.h> 34#include <sys/kernel.h> --- 51 unchanged lines hidden (view full) --- 86#define print_driver(d,i) /* nop */ 87#define print_driver_list(d,i) /* nop */ 88#define print_devclass_short(d,i) /* nop */ 89#define print_devclass(d,i) /* nop */ 90#define print_devclass_list_short() /* nop */ 91#define print_devclass_list() /* nop */ 92#endif 93 | 27 */ 28 29#include "opt_bus.h" 30 31#include <sys/param.h> 32#include <sys/queue.h> 33#include <sys/malloc.h> 34#include <sys/kernel.h> --- 51 unchanged lines hidden (view full) --- 86#define print_driver(d,i) /* nop */ 87#define print_driver_list(d,i) /* nop */ 88#define print_devclass_short(d,i) /* nop */ 89#define print_devclass(d,i) /* nop */ 90#define print_devclass_list_short() /* nop */ 91#define print_devclass_list() /* nop */ 92#endif 93 |
94extern char static_hints[]; 95extern int hintmode; 96static int hints_loaded = 0; | 94extern char static_hints[]; /* by config for now */ |
97 98TAILQ_HEAD(,device) bus_data_devices; 99static int bus_data_generation = 1; 100 101kobj_method_t null_methods[] = { 102 { 0, 0 } 103}; 104 --- 998 unchanged lines hidden (view full) --- 1103 return (err); 1104 1105 bus_data_generation_update(); 1106 return (0); 1107} 1108 1109/*======================================*/ 1110/* | 95 96TAILQ_HEAD(,device) bus_data_devices; 97static int bus_data_generation = 1; 98 99kobj_method_t null_methods[] = { 100 { 0, 0 } 101}; 102 --- 998 unchanged lines hidden (view full) --- 1101 return (err); 1102 1103 bus_data_generation_update(); 1104 return (0); 1105} 1106 1107/*======================================*/ 1108/* |
1111 * Access functions for device resources. 1112 */ 1113 1114/* Runtime version */ 1115static struct config_device *devtab; 1116static int devtab_count = 0; 1117 1118static int 1119resource_new_name(const char *name, int unit) 1120{ 1121 struct config_device *new; 1122 1123 new = malloc((devtab_count + 1) * sizeof(*new), M_TEMP, M_NOWAIT); 1124 if (new == NULL) 1125 return (-1); 1126 if (devtab && devtab_count > 0) 1127 bcopy(devtab, new, devtab_count * sizeof(*new)); 1128 bzero(&new[devtab_count], sizeof(*new)); 1129 new[devtab_count].name = malloc(strlen(name) + 1, M_TEMP, M_NOWAIT); 1130 if (new[devtab_count].name == NULL) { 1131 free(new, M_TEMP); 1132 return (-1); 1133 } 1134 strcpy(new[devtab_count].name, name); 1135 new[devtab_count].unit = unit; 1136 new[devtab_count].resource_count = 0; 1137 new[devtab_count].resources = NULL; 1138 devtab = new; 1139 return (devtab_count++); 1140} 1141 1142static int 1143resource_new_resname(int j, const char *resname, resource_type type) 1144{ 1145 struct config_resource *new; 1146 int i; 1147 1148 i = devtab[j].resource_count; 1149 new = malloc((i + 1) * sizeof(*new), M_TEMP, M_NOWAIT); 1150 if (new == NULL) 1151 return (-1); 1152 if (devtab[j].resources && i > 0) 1153 bcopy(devtab[j].resources, new, i * sizeof(*new)); 1154 bzero(&new[i], sizeof(*new)); 1155 new[i].name = malloc(strlen(resname) + 1, M_TEMP, M_NOWAIT); 1156 if (new[i].name == NULL) { 1157 free(new, M_TEMP); 1158 return (-1); 1159 } 1160 strcpy(new[i].name, resname); 1161 new[i].type = type; 1162 if (devtab[j].resources) 1163 free(devtab[j].resources, M_TEMP); 1164 devtab[j].resources = new; 1165 devtab[j].resource_count = i + 1; 1166 return (i); 1167} 1168 1169static int 1170resource_match_string(int i, const char *resname, const char *value) 1171{ 1172 int j; 1173 struct config_resource *res; 1174 1175 for (j = 0, res = devtab[i].resources; 1176 j < devtab[i].resource_count; j++, res++) 1177 if (!strcmp(res->name, resname) 1178 && res->type == RES_STRING 1179 && !strcmp(res->u.stringval, value)) 1180 return (j); 1181 return (-1); 1182} 1183 1184static int 1185resource_find_hard(char *cp, const char *name, int unit, 1186 const char *resname, struct config_resource **result) 1187{ 1188 char match[256]; 1189 int matchlen; 1190 char *op; 1191 long val; 1192 1193 snprintf(match, sizeof(match), "hint.%s.%d.%s=", name, unit, resname); 1194 matchlen = strlen(match); 1195 while (cp) { 1196 if (strncmp(match, cp, matchlen) == 0) 1197 break; 1198 while (*cp != '\0') 1199 cp++; 1200 cp++; 1201 if (*cp == '\0') { 1202 cp = NULL; 1203 break; 1204 } 1205 } 1206 if (cp) 1207 cp += matchlen; /* skip over name and '=' */ 1208 else 1209 return (ENOENT); 1210 val = strtoul(cp, &op, 0); 1211 if (*cp != '\0' && *op == '\0') { 1212 (*result)->type = RES_INT; 1213 (*result)->u.intval = val; 1214 } else { 1215 (*result)->type = RES_STRING; 1216 (*result)->u.stringval = cp; 1217 } 1218 return (0); 1219} 1220 1221static int 1222resource_find(const char *name, int unit, const char *resname, 1223 struct config_resource **result) 1224{ 1225 int i, j; 1226 struct config_resource *res; 1227 1228 if (!hints_loaded) { 1229 /* First specific, then generic. Dynamic over static. */ 1230 i = resource_find_hard(kern_envp, name, unit, resname, result); 1231 if (i == 0) 1232 return (0); 1233 i = resource_find_hard(static_hints, name, unit, resname, 1234 result); 1235 if (i == 0) 1236 return (0); 1237 i = resource_find_hard(kern_envp, name, -1, resname, result); 1238 if (i == 0) 1239 return (0); 1240 i = resource_find_hard(static_hints, name, -1, resname, result); 1241 return (i); 1242 } 1243 1244 /* 1245 * First check specific instances, then generic. 1246 */ 1247 for (i = 0; i < devtab_count; i++) { 1248 if (devtab[i].unit < 0) 1249 continue; 1250 if (!strcmp(devtab[i].name, name) && devtab[i].unit == unit) { 1251 res = devtab[i].resources; 1252 for (j = 0; j < devtab[i].resource_count; j++, res++) 1253 if (!strcmp(res->name, resname)) { 1254 *result = res; 1255 return (0); 1256 } 1257 } 1258 } 1259 for (i = 0; i < devtab_count; i++) { 1260 if (devtab[i].unit >= 0) 1261 continue; 1262 if (!strcmp(devtab[i].name, name)) { 1263 res = devtab[i].resources; 1264 for (j = 0; j < devtab[i].resource_count; j++, res++) 1265 if (!strcmp(res->name, resname)) { 1266 *result = res; 1267 return (0); 1268 } 1269 } 1270 } 1271 return (ENOENT); 1272} 1273 1274int 1275resource_int_value(const char *name, int unit, const char *resname, int *result) 1276{ 1277 struct config_resource tmpres; 1278 struct config_resource *res; 1279 int error; 1280 1281 res = &tmpres; 1282 if ((error = resource_find(name, unit, resname, &res)) != 0) 1283 return (error); 1284 if (res->type != RES_INT) 1285 return (EFTYPE); 1286 *result = res->u.intval; 1287 return (0); 1288} 1289 1290int 1291resource_long_value(const char *name, int unit, const char *resname, 1292 long *result) 1293{ 1294 struct config_resource tmpres; 1295 struct config_resource *res; 1296 int error; 1297 1298 res = &tmpres; 1299 if ((error = resource_find(name, unit, resname, &res)) != 0) 1300 return (error); 1301 if (res->type != RES_LONG) 1302 return (EFTYPE); 1303 *result = res->u.longval; 1304 return (0); 1305} 1306 1307int 1308resource_string_value(const char *name, int unit, const char *resname, 1309 char **result) 1310{ 1311 struct config_resource tmpres; 1312 struct config_resource *res; 1313 int error; 1314 1315 res = &tmpres; 1316 if ((error = resource_find(name, unit, resname, &res)) != 0) 1317 return (error); 1318 if (res->type != RES_STRING) 1319 return (EFTYPE); 1320 *result = res->u.stringval; 1321 return (0); 1322} 1323 1324int 1325resource_query_string(int i, const char *resname, const char *value) 1326{ 1327 if (i < 0) 1328 i = 0; 1329 else 1330 i = i + 1; 1331 for (; i < devtab_count; i++) 1332 if (resource_match_string(i, resname, value) >= 0) 1333 return (i); 1334 return (-1); 1335} 1336 1337int 1338resource_locate(int i, const char *resname) 1339{ 1340 if (i < 0) 1341 i = 0; 1342 else 1343 i = i + 1; 1344 for (; i < devtab_count; i++) 1345 if (!strcmp(devtab[i].name, resname)) 1346 return (i); 1347 return (-1); 1348} 1349 1350int 1351resource_count(void) 1352{ 1353 return (devtab_count); 1354} 1355 1356char * 1357resource_query_name(int i) 1358{ 1359 return (devtab[i].name); 1360} 1361 1362int 1363resource_query_unit(int i) 1364{ 1365 return (devtab[i].unit); 1366} 1367 1368static int 1369resource_create(const char *name, int unit, const char *resname, 1370 resource_type type, struct config_resource **result) 1371{ 1372 int i, j; 1373 struct config_resource *res = NULL; 1374 1375 for (i = 0; i < devtab_count; i++) { 1376 if (!strcmp(devtab[i].name, name) && devtab[i].unit == unit) { 1377 res = devtab[i].resources; 1378 break; 1379 } 1380 } 1381 if (res == NULL) { 1382 i = resource_new_name(name, unit); 1383 if (i < 0) 1384 return (ENOMEM); 1385 res = devtab[i].resources; 1386 } 1387 for (j = 0; j < devtab[i].resource_count; j++, res++) { 1388 if (!strcmp(res->name, resname)) { 1389 *result = res; 1390 return (0); 1391 } 1392 } 1393 j = resource_new_resname(i, resname, type); 1394 if (j < 0) 1395 return (ENOMEM); 1396 res = &devtab[i].resources[j]; 1397 *result = res; 1398 return (0); 1399} 1400 1401int 1402resource_set_int(const char *name, int unit, const char *resname, int value) 1403{ 1404 int error; 1405 struct config_resource *res; 1406 1407 error = resource_create(name, unit, resname, RES_INT, &res); 1408 if (error) 1409 return (error); 1410 if (res->type != RES_INT) 1411 return (EFTYPE); 1412 res->u.intval = value; 1413 return (0); 1414} 1415 1416int 1417resource_set_long(const char *name, int unit, const char *resname, long value) 1418{ 1419 int error; 1420 struct config_resource *res; 1421 1422 error = resource_create(name, unit, resname, RES_LONG, &res); 1423 if (error) 1424 return (error); 1425 if (res->type != RES_LONG) 1426 return (EFTYPE); 1427 res->u.longval = value; 1428 return (0); 1429} 1430 1431int 1432resource_set_string(const char *name, int unit, const char *resname, 1433 const char *value) 1434{ 1435 int error; 1436 struct config_resource *res; 1437 1438 error = resource_create(name, unit, resname, RES_STRING, &res); 1439 if (error) 1440 return (error); 1441 if (res->type != RES_STRING) 1442 return (EFTYPE); 1443 if (res->u.stringval) 1444 free(res->u.stringval, M_TEMP); 1445 res->u.stringval = malloc(strlen(value) + 1, M_TEMP, M_NOWAIT); 1446 if (res->u.stringval == NULL) 1447 return (ENOMEM); 1448 strcpy(res->u.stringval, value); 1449 return (0); 1450} 1451 1452/* 1453 * We use the identify routine to get the hints for all the other devices. 1454 * Strings that are all digits or begin with 0x are integers. 1455 * 1456 * hint.aha.0.bus_speedup=1 1457 * hint.aha.1.irq=10 1458 * hint.wl.0.netid=PLUG 1459 * hint.wl.1.netid=XYZZY 1460 */ 1461static void 1462hint_load(char *cp) 1463{ 1464 char *ep, *op, *walker; 1465 int len; 1466 int val; 1467 char name[20]; 1468 int unit; 1469 char resname[255]; 1470 1471 for (ep = cp; *ep != '=' && *ep != '\0'; ep++) 1472 continue; 1473 len = ep - cp; 1474 if (*ep == '=') 1475 ep++; 1476 walker = cp; 1477 walker += 5; 1478 op = walker; 1479 while (*walker && *walker != '.') 1480 walker++; 1481 if (*walker != '.') 1482 return; 1483 if (walker - op > sizeof(name)) 1484 return; 1485 strncpy(name, op, walker - op); 1486 name[walker - op] = '\0'; 1487 walker++; 1488 op = walker; 1489 while (*walker && *walker != '.') 1490 walker++; 1491 if (*walker != '.') 1492 return; 1493 unit = strtoul(op, &walker, 0); 1494 if (*walker != '.') 1495 return; 1496 walker++; 1497 op = walker; 1498 while (*walker && *walker != '=') 1499 walker++; 1500 if (*walker != '=') 1501 return; 1502 if (walker - op > sizeof(resname)) 1503 return; 1504 strncpy(resname, op, walker - op); 1505 resname[walker - op] = '\0'; 1506 walker++; 1507 if (walker != ep) 1508 return; 1509 if (bootverbose) 1510 printf("Setting %s %d %s to ", name, unit, resname); 1511 val = strtoul(ep, &op, 0); 1512 if (*ep != '\0' && *op == '\0') { 1513 resource_set_int(name, unit, resname, val); 1514 if (bootverbose) 1515 printf("%d (int)\n", val); 1516 } else { 1517 resource_set_string(name, unit, resname, ep); 1518 if (bootverbose) 1519 printf("%s (string)\n", ep); 1520 } 1521} 1522 1523 1524static void 1525hints_load(void *dummy __unused) 1526{ 1527 char *cp; 1528 1529 if (hintmode == 2) { /* default hints only */ 1530 cp = kern_envp; 1531 while (cp) { 1532 if (strncmp(cp, "hint.", 5) == 0) { 1533 /* ok, we found a hint, ignore these defaults */ 1534 hintmode = 0; 1535 break; 1536 } 1537 while (*cp != '\0') 1538 cp++; 1539 cp++; 1540 if (*cp == '\0') 1541 break; 1542 } 1543 } 1544 if (hintmode != 0) { 1545 cp = static_hints; 1546 while (cp) { 1547 if (strncmp(cp, "hint.", 5) == 0) 1548 hint_load(cp); 1549 while (*cp != '\0') 1550 cp++; 1551 cp++; 1552 if (*cp == '\0') 1553 break; 1554 } 1555 } 1556 cp = kern_envp; 1557 while (cp) { 1558 if (strncmp(cp, "hint.", 5) == 0) 1559 hint_load(cp); 1560 while (*cp != '\0') 1561 cp++; 1562 cp++; 1563 if (*cp == '\0') 1564 break; 1565 } 1566 hints_loaded++; 1567} 1568SYSINIT(cfghints, SI_SUB_KMEM, SI_ORDER_ANY + 60, hints_load, 0) 1569 1570/*======================================*/ 1571/* | |
1572 * Some useful method implementations to make life easier for bus drivers. 1573 */ 1574 | 1109 * Some useful method implementations to make life easier for bus drivers. 1110 */ 1111 |
1575 void | 1112void |
1576resource_list_init(struct resource_list *rl) 1577{ 1578 SLIST_INIT(rl); 1579} 1580 1581void 1582resource_list_free(struct resource_list *rl) 1583{ --- 1002 unchanged lines hidden (view full) --- 2586 return (0); 2587} 2588 2589void 2590bus_data_generation_update(void) 2591{ 2592 bus_data_generation++; 2593} | 1113resource_list_init(struct resource_list *rl) 1114{ 1115 SLIST_INIT(rl); 1116} 1117 1118void 1119resource_list_free(struct resource_list *rl) 1120{ --- 1002 unchanged lines hidden (view full) --- 2123 return (0); 2124} 2125 2126void 2127bus_data_generation_update(void) 2128{ 2129 bus_data_generation++; 2130} |
2131 2132/*======================================*/ 2133/* 2134 * Access functions for device resources. 2135 */ 2136 2137/* 2138 * Evil wildcarding resource string lookup. 2139 * This walks the supplied env string table and returns a match. 2140 * The start point can be remembered for incremental searches. 2141 */ 2142static int 2143res_find(const char *cp, int *line, int *startln, 2144 const char *name, int *unit, const char *resname, const char *value, 2145 const char **ret_name, int *ret_namelen, int *ret_unit, 2146 const char **ret_resname, int *ret_resnamelen, const char **ret_value) 2147{ 2148 int n = 0, hit; 2149 char r_name[32]; 2150 int r_unit; 2151 char r_resname[32]; 2152 char r_value[128]; 2153 const char *s; 2154 char *p; 2155 2156 while (cp) { 2157 hit = 1; 2158 (*line)++; 2159 if (strncmp(cp, "hint.", 5) != 0) 2160 hit = 0; 2161 else 2162 n = sscanf(cp, "hint.%32[^.].%d.%32[^=]=%128s", 2163 r_name, &r_unit, r_resname, r_value); 2164 if (hit && n != 4) { 2165 printf("CONFIG: invalid hint '%s'\n", cp); 2166 /* XXX: abuse bogus index() declaration */ 2167 p = index(cp, 'h'); 2168 *p = 'H'; 2169 hit = 0; 2170 } 2171 if (hit && startln && *startln >= 0 && *line < *startln) 2172 hit = 0; 2173 if (hit && name && strcmp(name, r_name) != 0) 2174 hit = 0; 2175 if (hit && unit && *unit != r_unit) 2176 hit = 0; 2177 if (hit && resname && strcmp(resname, r_resname) != 0) 2178 hit = 0; 2179 if (hit && value && strcmp(value, r_value) != 0) 2180 hit = 0; 2181 if (hit) 2182 break; 2183 while (*cp != '\0') 2184 cp++; 2185 cp++; 2186 if (*cp == '\0') { 2187 cp = NULL; 2188 break; 2189 } 2190 } 2191 if (cp == NULL) 2192 return ENOENT; 2193 2194 s = cp; 2195 /* This is a bit of a hack, but at least is reentrant */ 2196 /* Note that it returns some !unterminated! strings. */ 2197 s = index(s, '.') + 1; /* start of device */ 2198 if (ret_name) 2199 *ret_name = s; 2200 s = index(s, '.') + 1; /* start of unit */ 2201 if (ret_namelen) 2202 *ret_namelen = s - *ret_name - 1; /* device length */ 2203 if (ret_unit) 2204 *ret_unit = r_unit; 2205 s = index(s, '.') + 1; /* start of resname */ 2206 if (ret_resname) 2207 *ret_resname = s; 2208 s = index(s, '=') + 1; /* start of value */ 2209 if (ret_resnamelen) 2210 *ret_resnamelen = s - *ret_resname - 1; /* value len */ 2211 if (ret_value) 2212 *ret_value = s; 2213 if (startln) /* line number for anchor */ 2214 *startln = *line + 1; 2215 return 0; 2216} 2217 2218/* 2219 * Search all the data sources for matches to our query. We look for 2220 * dynamic hints first as overrides for static or fallback hints. 2221 */ 2222static int 2223resource_find(int *line, int *startln, 2224 const char *name, int *unit, const char *resname, const char *value, 2225 const char **ret_name, int *ret_namelen, int *ret_unit, 2226 const char **ret_resname, int *ret_resnamelen, const char **ret_value) 2227{ 2228 int i; 2229 int un; 2230 2231 *line = 0; 2232 2233 /* Search for exact unit matches first */ 2234 i = res_find(kern_envp, line, startln, name, unit, resname, value, 2235 ret_name, ret_namelen, ret_unit, ret_resname, ret_resnamelen, 2236 ret_value); 2237 if (i == 0) 2238 return 0; 2239 i = res_find(static_hints, line, startln, name, unit, resname, value, 2240 ret_name, ret_namelen, ret_unit, ret_resname, ret_resnamelen, 2241 ret_value); 2242 if (i == 0) 2243 return 0; 2244 if (unit == NULL) 2245 return ENOENT; 2246 /* If we are still here, search for wildcard matches */ 2247 un = -1; 2248 i = res_find(kern_envp, line, startln, name, &un, resname, value, 2249 ret_name, ret_namelen, ret_unit, ret_resname, ret_resnamelen, 2250 ret_value); 2251 if (i == 0) 2252 return 0; 2253 un = -1; 2254 i = res_find(static_hints, line, startln, name, &un, resname, value, 2255 ret_name, ret_namelen, ret_unit, ret_resname, ret_resnamelen, 2256 ret_value); 2257 if (i == 0) 2258 return 0; 2259 return ENOENT; 2260} 2261 2262int 2263resource_int_value(const char *name, int unit, const char *resname, int *result) 2264{ 2265 int error; 2266 const char *str; 2267 char *op; 2268 unsigned long val; 2269 int line; 2270 2271 line = 0; 2272 error = resource_find(&line, NULL, name, &unit, resname, NULL, 2273 NULL, NULL, NULL, NULL, NULL, &str); 2274 if (error) 2275 return error; 2276 if (*str == '\0') 2277 return EFTYPE; 2278 val = strtoul(str, &op, 0); 2279 if (*op != '\0') 2280 return EFTYPE; 2281 *result = val; 2282 return 0; 2283} 2284 2285int 2286resource_long_value(const char *name, int unit, const char *resname, 2287 long *result) 2288{ 2289 int error; 2290 const char *str; 2291 char *op; 2292 unsigned long val; 2293 int line; 2294 2295 line = 0; 2296 error = resource_find(&line, NULL, name, &unit, resname, NULL, 2297 NULL, NULL, NULL, NULL, NULL, &str); 2298 if (error) 2299 return error; 2300 if (*str == '\0') 2301 return EFTYPE; 2302 val = strtoul(str, &op, 0); 2303 if (*op != '\0') 2304 return EFTYPE; 2305 *result = val; 2306 return 0; 2307} 2308 2309int 2310resource_string_value(const char *name, int unit, const char *resname, 2311 const char **result) 2312{ 2313 int error; 2314 const char *str; 2315 int line; 2316 2317 line = 0; 2318 error = resource_find(&line, NULL, name, &unit, resname, NULL, 2319 NULL, NULL, NULL, NULL, NULL, &str); 2320 if (error) 2321 return error; 2322 *result = str; 2323 return 0; 2324} 2325 2326/* 2327 * This is a bit nasty, but allows us to not modify the env strings. 2328 */ 2329static const char * 2330resource_string_copy(const char *s, int len) 2331{ 2332 static char stringbuf[256]; 2333 static int offset = 0; 2334 const char *ret; 2335 2336 if (len == 0) 2337 len = strlen(s); 2338 if (len > 255) 2339 return NULL; 2340 if ((offset + len + 1) > 255) 2341 offset = 0; 2342 bcopy(s, &stringbuf[offset], len); 2343 stringbuf[offset + len] = '\0'; 2344 ret = &stringbuf[offset]; 2345 offset += len + 1; 2346 return ret; 2347} 2348 2349/* 2350 * err = resource_find_at(&anchor, &name, &unit, resname, value) 2351 * Iteratively fetch a list of devices wired "at" something 2352 * res and value are restrictions. eg: "at", "scbus0". 2353 * For practical purposes, res = required, value = optional. 2354 * *name and *unit are set. 2355 * set *anchor to zero before starting. 2356 */ 2357int 2358resource_find_match(int *anchor, const char **name, int *unit, 2359 const char *resname, const char *value) 2360{ 2361 const char *found_name; 2362 int found_namelen; 2363 int found_unit; 2364 int ret; 2365 int newln; 2366 2367 newln = *anchor; 2368 ret = resource_find(anchor, &newln, NULL, NULL, resname, value, 2369 &found_name, &found_namelen, &found_unit, NULL, NULL, NULL); 2370 if (ret == 0) { 2371 *name = resource_string_copy(found_name, found_namelen); 2372 *unit = found_unit; 2373 } 2374 *anchor = newln; 2375 return ret; 2376} 2377 2378 2379/* 2380 * err = resource_find_dev(&anchor, name, &unit, res, value); 2381 * Iterate through a list of devices, returning their unit numbers. 2382 * res and value are optional restrictions. eg: "at", "scbus0". 2383 * *unit is set to the value. 2384 * set *anchor to zero before starting. 2385 */ 2386int 2387resource_find_dev(int *anchor, const char *name, int *unit, 2388 const char *resname, const char *value) 2389{ 2390 int found_unit; 2391 int newln; 2392 int ret; 2393 2394 newln = *anchor; 2395 ret = resource_find(anchor, &newln, name, NULL, resname, value, 2396 NULL, NULL, &found_unit, NULL, NULL, NULL); 2397 if (ret == 0) { 2398 *unit = found_unit; 2399 } 2400 *anchor = newln; 2401 return ret; 2402} |
|