Author: imp Date: Thu Aug 23 05:06:22 2018 New Revision: 338237 URL: https://svnweb.freebsd.org/changeset/base/338237
Log: When trying to match the nomatch event passed to us, attempt to look up the device described by the nomatch event in the device tree. If we find it, then if the device is marked as have already attached to a device once, then ignore the device. This keeps us from reloading the device driver when it has just been manually unloaded. All devies that have had a driver attach to them at least once no longer participate in pnp-based autoloading. Differential Revision: https://reviews.freebsd.org/D16735 Modified: head/sbin/devmatch/devmatch.c Modified: head/sbin/devmatch/devmatch.c ============================================================================== --- head/sbin/devmatch/devmatch.c Thu Aug 23 05:06:16 2018 (r338236) +++ head/sbin/devmatch/devmatch.c Thu Aug 23 05:06:22 2018 (r338237) @@ -65,6 +65,7 @@ static int verbose_flag; static void *hints; static void *hints_end; +static struct devinfo_dev *root; static void * read_hints(const char *fn, size_t *len) @@ -440,10 +441,50 @@ find_unmatched(struct devinfo_dev *dev, void *arg) return (devinfo_foreach_device_child(dev, find_unmatched, arg)); } +struct exact_info +{ + const char *bus; + const char *loc; + struct devinfo_dev *dev; +}; + +/* + * 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 void find_nomatch(char *nomatch) { - char *bus, *pnpinfo, *tmp; + char *bus, *pnpinfo, *tmp, *busnameunit; + struct exact_info info; /* * Find our bus name. It will include the unit number. We have to search @@ -459,6 +500,9 @@ find_nomatch(char *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--; @@ -475,6 +519,17 @@ find_nomatch(char *nomatch) 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); @@ -490,7 +545,6 @@ usage(void) int main(int argc, char **argv) { - struct devinfo_dev *root; int ch; while ((ch = getopt_long(argc, argv, "adh:p:uv", @@ -530,12 +584,13 @@ main(int argc, char **argv) exit(0); } - if (nomatch_str != NULL) - find_nomatch(nomatch_str); if (devinfo_init()) err(1, "devinfo_init"); if ((root = devinfo_handle_to_device(DEVINFO_ROOT_DEVICE)) == NULL) errx(1, "can't find root device"); - devinfo_foreach_device_child(root, find_unmatched, (void *)0); + if (nomatch_str != NULL) + find_nomatch(nomatch_str); + else + devinfo_foreach_device_child(root, find_unmatched, (void *)0); devinfo_free(); } _______________________________________________ svn-src-all@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"