diff -r 91c2ddbf51ba sys/dev/ata/ata.c --- a/sys/dev/ata/ata.c Thu Sep 24 15:54:22 2020 +0000 +++ b/sys/dev/ata/ata.c Sat Oct 03 22:20:47 2020 +0000 @@ -298,7 +298,7 @@ atabusconfig(struct atabus_softc *atabus ata_delref(chp); - config_pending_decr(atac->atac_dev); + config_pending_decr(atabus_sc->sc_dev); } /* @@ -424,7 +424,7 @@ atabusconfig_thread(void *arg) ata_delref(chp); - config_pending_decr(atac->atac_dev); + config_pending_decr(atabus_sc->sc_dev); kthread_exit(0); } diff -r 91c2ddbf51ba sys/kern/subr_autoconf.c --- a/sys/kern/subr_autoconf.c Thu Sep 24 15:54:22 2020 +0000 +++ b/sys/kern/subr_autoconf.c Sat Oct 03 22:20:47 2020 +0000 @@ -224,7 +224,8 @@ static int alldevs_nread = 0; static int alldevs_nwrite = 0; static bool alldevs_garbage = false; -static int config_pending; /* semaphore for mountroot */ +static struct devicelist config_pending = + TAILQ_HEAD_INITIALIZER(config_pending); static kmutex_t config_misc_lock; static kcondvar_t config_misc_cv; @@ -2095,9 +2096,12 @@ config_pending_incr(device_t dev) { mutex_enter(&config_misc_lock); - config_pending++; + KASSERTMSG(dev->dv_pending < INT_MAX, + "%s: excess config_pending_incr", device_xname(dev)); + if (dev->dv_pending++ == 0) + TAILQ_INSERT_TAIL(&config_pending, dev, dv_pending_list); #ifdef DEBUG_AUTOCONF - printf("%s: %s %d\n", __func__, device_xname(dev), config_pending); + printf("%s: %s %d\n", __func__, device_xname(dev), dev->dv_pending); #endif mutex_exit(&config_misc_lock); } @@ -2106,13 +2110,15 @@ void config_pending_decr(device_t dev) { - KASSERT(0 < config_pending); mutex_enter(&config_misc_lock); - config_pending--; + KASSERTMSG(dev->dv_pending > 0, + "%s: excess config_pending_decr", device_xname(dev)); + if (--dev->dv_pending == 0) + TAILQ_REMOVE(&config_pending, dev, dv_pending_list); #ifdef DEBUG_AUTOCONF - printf("%s: %s %d\n", __func__, device_xname(dev), config_pending); + printf("%s: %s %d\n", __func__, device_xname(dev), dev->dv_pending); #endif - if (config_pending == 0) + if (TAILQ_EMPTY(&config_pending)) cv_broadcast(&config_misc_cv); mutex_exit(&config_misc_lock); } @@ -2165,8 +2171,12 @@ config_finalize(void) * them to finish any deferred autoconfiguration. */ mutex_enter(&config_misc_lock); - while (config_pending != 0) + while (!TAILQ_EMPTY(&config_pending)) { + device_t dev; + TAILQ_FOREACH(dev, &config_pending, dv_pending_list) + aprint_debug_dev(dev, "holding up boot\n"); cv_wait(&config_misc_cv, &config_misc_lock); + } mutex_exit(&config_misc_lock); KERNEL_LOCK(1, NULL); diff -r 91c2ddbf51ba sys/sys/device.h --- a/sys/sys/device.h Thu Sep 24 15:54:22 2020 +0000 +++ b/sys/sys/device.h Sat Oct 03 22:20:47 2020 +0000 @@ -165,6 +165,9 @@ struct device { int *dv_locators; /* our actual locators (optional) */ prop_dictionary_t dv_properties;/* properties dictionary */ + int dv_pending; /* config_pending count */ + TAILQ_ENTRY(device) dv_pending_list; + size_t dv_activity_count; void (**dv_activity_handlers)(device_t, devactive_t);