/* * Print information about a device. */ int print_device(struct devinfo_dev *dev, void *arg) { struct indent_arg ia; int i, indent; if (vflag || (dev->dd_name[0] != 0 && dev->dd_state >= DS_ATTACHED)) { indent = (int)(intptr_t)arg; for (i = 0; i < indent; i++) printf(" "); printf("%s", dev->dd_name[0] ? dev->dd_name : "unknown"); if (vflag && *dev->dd_pnpinfo) printf(" pnpinfo %s", dev->dd_pnpinfo); if (vflag && *dev->dd_location) printf(" at %s", dev->dd_location); printf("\n"); if (rflag) { ia.indent = indent + 4; ia.arg = dev; devinfo_foreach_rman(print_device_rman_resources, (void *)&ia); } } return(devinfo_foreach_device_child(dev, print_device, (void *)((char *)arg + 2))); }
/* * Look for the exact location specified by the nomatch event. The * loc and pnpinfo run together to get the string we're looking for, * so we have to synthesize the same thing that subr_bus.c is * generating in devnomatch/devaddq to do the string comparison. */ static int find_exact_dev(struct devinfo_dev *dev, void *arg) { struct devinfo_dev *parent; char *loc; struct exact_info *info; info = arg; do { if (info->dev != NULL) break; if (!(dev->dd_flags & DF_ENABLED)) break; parent = devinfo_handle_to_device(dev->dd_parent); if (strcmp(info->bus, parent->dd_name) != 0) break; asprintf(&loc, "%s %s", parent->dd_pnpinfo, parent->dd_location); if (strcmp(loc, info->loc) == 0) info->dev = dev; free(loc); } while (0); return (devinfo_foreach_device_child(dev, find_exact_dev, arg)); }
static int find_unmatched(struct devinfo_dev *dev, void *arg) { struct devinfo_dev *parent; char *bus, *p; do { if (!all_flag && dev->dd_name[0] != '\0') break; if (!(dev->dd_flags & DF_ENABLED)) break; if (dev->dd_flags & DF_ATTACHED_ONCE) break; parent = devinfo_handle_to_device(dev->dd_parent); bus = strdup(parent->dd_name); p = bus + strlen(bus) - 1; while (p >= bus && isdigit(*p)) p--; *++p = '\0'; if (verbose_flag) printf("Searching %s %s bus at %s for pnpinfo %s\n", dev->dd_name, bus, dev->dd_location, dev->dd_pnpinfo); search_hints(bus, dev->dd_name, dev->dd_pnpinfo); free(bus); } while (0); return (devinfo_foreach_device_child(dev, find_unmatched, arg)); }
static int acpi0_check(struct devinfo_dev *dd, void *arg) { printf("%s: %s %s\n", __func__, dd->dd_name, devstate(dd->dd_state)); /* NB: device must be present AND attached */ if (strcmp(dd->dd_name, "acpi0") == 0) return (dd->dd_state == DS_ATTACHED || dd->dd_state == DS_BUSY); return devinfo_foreach_device_child(dd, acpi0_check, arg); }
static void find_nomatch(char *nomatch) { char *bus, *pnpinfo, *tmp, *busnameunit; struct exact_info info; /* * Find our bus name. It will include the unit number. We have to search * backwards to avoid false positive for any PNP string that has ' on ' * in them, which would come earlier in the string. Like if there were * an 'Old Bard' ethernet card made by 'Stratford on Avon Hardware' or * something silly like that. */ tmp = nomatch + strlen(nomatch) - 4; while (tmp > nomatch && strncmp(tmp, " on ", 4) != 0) tmp--; if (tmp == nomatch) errx(1, "No bus found in nomatch string: '%s'", nomatch); bus = tmp + 4; *tmp = '\0'; busnameunit = strdup(bus); if (busnameunit == NULL) errx(1, "Can't allocate memory for strings"); tmp = bus + strlen(bus) - 1; while (tmp > bus && isdigit(*tmp)) tmp--; *++tmp = '\0'; /* * Note: the NOMATCH events place both the bus location as well as the * pnp info after the 'at' and we don't know where one stops and the * other begins, so we pass the whole thing to our search routine. */ if (*nomatch == '?') nomatch++; if (strncmp(nomatch, " at ", 4) != 0) errx(1, "Malformed NOMATCH string: '%s'", nomatch); pnpinfo = nomatch + 4; /* * See if we can find the devinfo_dev for this device. If we * can, and it's been attached before, we should filter it out * so that a kldunload foo doesn't cause an immediate reload. */ info.loc = pnpinfo; info.bus = busnameunit; info.dev = NULL; devinfo_foreach_device_child(root, find_exact_dev, (void *)&info); if (info.dev != NULL && info.dev->dd_flags & DF_ATTACHED_ONCE) exit(0); search_hints(bus, "", pnpinfo); exit(0); }
int main(int argc, char **argv) { int ch; while ((ch = getopt_long(argc, argv, "adh:p:uv", longopts, NULL)) != -1) { switch (ch) { case 'a': all_flag++; break; case 'd': dump_flag++; break; case 'h': linker_hints = optarg; break; case 'p': nomatch_str = optarg; break; case 'u': unbound_flag++; break; case 'v': verbose_flag++; break; default: usage(); } } argc -= optind; argv += optind; if (argc >= 1) usage(); read_linker_hints(); if (dump_flag) { search_hints(NULL, NULL, NULL); exit(0); } if (devinfo_init()) err(1, "devinfo_init"); if ((root = devinfo_handle_to_device(DEVINFO_ROOT_DEVICE)) == NULL) errx(1, "can't find root device"); if (nomatch_str != NULL) find_nomatch(nomatch_str); else devinfo_foreach_device_child(root, find_unmatched, (void *)0); devinfo_free(); }
static int acpi0_present(void) { struct devinfo_dev *root; int found; found = 0; devinfo_init(); root = devinfo_handle_to_device(DEVINFO_ROOT_DEVICE); if (root != NULL) found = devinfo_foreach_device_child(root, acpi0_check, NULL); devinfo_free(); return found; }