Sun May 24 12:27:50 2009 UTC ()
Bus scans can make it appear as if the system has paused, so
twiddle constantly while config_interrupts() jobs are running.


(ad)
diff -r1.175 -r1.176 src/sys/kern/subr_autoconf.c

cvs diff -r1.175 -r1.176 src/sys/kern/subr_autoconf.c (expand / switch to unified diff)

--- src/sys/kern/subr_autoconf.c 2009/05/01 08:27:41 1.175
+++ src/sys/kern/subr_autoconf.c 2009/05/24 12:27:50 1.176
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: subr_autoconf.c,v 1.175 2009/05/01 08:27:41 cegger Exp $ */ 1/* $NetBSD: subr_autoconf.c,v 1.176 2009/05/24 12:27:50 ad Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1996, 2000 Christopher G. Demetriou 4 * Copyright (c) 1996, 2000 Christopher G. Demetriou
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -67,27 +67,27 @@ @@ -67,27 +67,27 @@
67 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 67 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
68 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 68 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
69 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 69 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
70 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 70 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
71 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 71 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
72 * SUCH DAMAGE. 72 * SUCH DAMAGE.
73 * 73 *
74 * from: Header: subr_autoconf.c,v 1.12 93/02/01 19:31:48 torek Exp (LBL) 74 * from: Header: subr_autoconf.c,v 1.12 93/02/01 19:31:48 torek Exp (LBL)
75 * 75 *
76 * @(#)subr_autoconf.c 8.3 (Berkeley) 5/17/94 76 * @(#)subr_autoconf.c 8.3 (Berkeley) 5/17/94
77 */ 77 */
78 78
79#include <sys/cdefs.h> 79#include <sys/cdefs.h>
80__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.175 2009/05/01 08:27:41 cegger Exp $"); 80__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.176 2009/05/24 12:27:50 ad Exp $");
81 81
82#include "opt_ddb.h" 82#include "opt_ddb.h"
83#include "drvctl.h" 83#include "drvctl.h"
84 84
85#include <sys/param.h> 85#include <sys/param.h>
86#include <sys/device.h> 86#include <sys/device.h>
87#include <sys/disklabel.h> 87#include <sys/disklabel.h>
88#include <sys/conf.h> 88#include <sys/conf.h>
89#include <sys/kauth.h> 89#include <sys/kauth.h>
90#include <sys/malloc.h> 90#include <sys/malloc.h>
91#include <sys/kmem.h> 91#include <sys/kmem.h>
92#include <sys/systm.h> 92#include <sys/systm.h>
93#include <sys/kernel.h> 93#include <sys/kernel.h>
@@ -163,26 +163,27 @@ struct matchinfo { @@ -163,26 +163,27 @@ struct matchinfo {
163 const int *locs; 163 const int *locs;
164 void *aux; 164 void *aux;
165 struct cfdata *match; 165 struct cfdata *match;
166 int pri; 166 int pri;
167}; 167};
168 168
169static char *number(char *, int); 169static char *number(char *, int);
170static void mapply(struct matchinfo *, cfdata_t); 170static void mapply(struct matchinfo *, cfdata_t);
171static device_t config_devalloc(const device_t, const cfdata_t, const int *); 171static device_t config_devalloc(const device_t, const cfdata_t, const int *);
172static void config_devdealloc(device_t); 172static void config_devdealloc(device_t);
173static void config_makeroom(int, struct cfdriver *); 173static void config_makeroom(int, struct cfdriver *);
174static void config_devlink(device_t); 174static void config_devlink(device_t);
175static void config_devunlink(device_t); 175static void config_devunlink(device_t);
 176static void config_twiddle_fn(void *);
176 177
177static void pmflock_debug(device_t, const char *, int); 178static void pmflock_debug(device_t, const char *, int);
178static void pmflock_debug_with_flags(device_t, const char *, int PMF_FN_PROTO); 179static void pmflock_debug_with_flags(device_t, const char *, int PMF_FN_PROTO);
179 180
180static device_t deviter_next1(deviter_t *); 181static device_t deviter_next1(deviter_t *);
181static void deviter_reinit(deviter_t *); 182static void deviter_reinit(deviter_t *);
182 183
183struct deferred_config { 184struct deferred_config {
184 TAILQ_ENTRY(deferred_config) dc_queue; 185 TAILQ_ENTRY(deferred_config) dc_queue;
185 device_t dc_dev; 186 device_t dc_dev;
186 void (*dc_func)(device_t); 187 void (*dc_func)(device_t);
187}; 188};
188 189
@@ -216,26 +217,27 @@ static lwp_t *alldevs_writer = NULL; @@ -216,26 +217,27 @@ static lwp_t *alldevs_writer = NULL;
216 217
217static int config_pending; /* semaphore for mountroot */ 218static int config_pending; /* semaphore for mountroot */
218static kmutex_t config_misc_lock; 219static kmutex_t config_misc_lock;
219static kcondvar_t config_misc_cv; 220static kcondvar_t config_misc_cv;
220 221
221static int detachall = 0; 222static int detachall = 0;
222 223
223#define STREQ(s1, s2) \ 224#define STREQ(s1, s2) \
224 (*(s1) == *(s2) && strcmp((s1), (s2)) == 0) 225 (*(s1) == *(s2) && strcmp((s1), (s2)) == 0)
225 226
226static int config_initialized; /* config_init() has been called. */ 227static int config_initialized; /* config_init() has been called. */
227 228
228static int config_do_twiddle; 229static int config_do_twiddle;
 230static callout_t config_twiddle_ch;
229 231
230struct vnode * 232struct vnode *
231opendisk(struct device *dv) 233opendisk(struct device *dv)
232{ 234{
233 int bmajor, bminor; 235 int bmajor, bminor;
234 struct vnode *tmpvn; 236 struct vnode *tmpvn;
235 int error; 237 int error;
236 dev_t dev; 238 dev_t dev;
237  239
238 /* 240 /*
239 * Lookup major number for disk block device. 241 * Lookup major number for disk block device.
240 */ 242 */
241 bmajor = devsw_name2blk(device_xname(dv), NULL, 0); 243 bmajor = devsw_name2blk(device_xname(dv), NULL, 0);
@@ -343,26 +345,29 @@ config_init(void) @@ -343,26 +345,29 @@ config_init(void)
343{ 345{
344 const struct cfattachinit *cfai; 346 const struct cfattachinit *cfai;
345 int i, j; 347 int i, j;
346 348
347 if (config_initialized) 349 if (config_initialized)
348 return; 350 return;
349 351
350 mutex_init(&alldevs_mtx, MUTEX_DEFAULT, IPL_NONE); 352 mutex_init(&alldevs_mtx, MUTEX_DEFAULT, IPL_NONE);
351 cv_init(&alldevs_cv, "alldevs"); 353 cv_init(&alldevs_cv, "alldevs");
352 354
353 mutex_init(&config_misc_lock, MUTEX_DEFAULT, IPL_NONE); 355 mutex_init(&config_misc_lock, MUTEX_DEFAULT, IPL_NONE);
354 cv_init(&config_misc_cv, "cfgmisc"); 356 cv_init(&config_misc_cv, "cfgmisc");
355 357
 358 callout_init(&config_twiddle_ch, CALLOUT_MPSAFE);
 359 callout_setfunc(&config_twiddle_ch, config_twiddle_fn, NULL);
 360
356 /* allcfdrivers is statically initialized. */ 361 /* allcfdrivers is statically initialized. */
357 for (i = 0; cfdriver_list_initial[i] != NULL; i++) { 362 for (i = 0; cfdriver_list_initial[i] != NULL; i++) {
358 if (config_cfdriver_attach(cfdriver_list_initial[i]) != 0) 363 if (config_cfdriver_attach(cfdriver_list_initial[i]) != 0)
359 panic("configure: duplicate `%s' drivers", 364 panic("configure: duplicate `%s' drivers",
360 cfdriver_list_initial[i]->cd_name); 365 cfdriver_list_initial[i]->cd_name);
361 } 366 }
362 367
363 for (cfai = &cfattachinit[0]; cfai->cfai_name != NULL; cfai++) { 368 for (cfai = &cfattachinit[0]; cfai->cfai_name != NULL; cfai++) {
364 for (j = 0; cfai->cfai_list[j] != NULL; j++) { 369 for (j = 0; cfai->cfai_list[j] != NULL; j++) {
365 if (config_cfattach_attach(cfai->cfai_name, 370 if (config_cfattach_attach(cfai->cfai_name,
366 cfai->cfai_list[j]) != 0) 371 cfai->cfai_list[j]) != 0)
367 panic("configure: duplicate `%s' attachment " 372 panic("configure: duplicate `%s' attachment "
368 "of `%s' driver", 373 "of `%s' driver",
@@ -452,26 +457,32 @@ configure2(void) @@ -452,26 +457,32 @@ configure2(void)
452 for (CPU_INFO_FOREACH(cii, ci)) { 457 for (CPU_INFO_FOREACH(cii, ci)) {
453 uvm_cpu_attach(ci); 458 uvm_cpu_attach(ci);
454 } 459 }
455 mp_online = true; 460 mp_online = true;
456#if defined(MULTIPROCESSOR) 461#if defined(MULTIPROCESSOR)
457 cpu_boot_secondary_processors(); 462 cpu_boot_secondary_processors();
458#endif 463#endif
459 464
460 /* Setup the runqueues and scheduler. */ 465 /* Setup the runqueues and scheduler. */
461 runq_init(); 466 runq_init();
462 sched_init(); 467 sched_init();
463 468
464 /* 469 /*
 470 * Bus scans can make it appear as if the system has paused, so
 471 * twiddle constantly while config_interrupts() jobs are running.
 472 */
 473 config_twiddle_fn(NULL);
 474
 475 /*
465 * Create threads to call back and finish configuration for 476 * Create threads to call back and finish configuration for
466 * devices that want interrupts enabled. 477 * devices that want interrupts enabled.
467 */ 478 */
468 for (i = 0; i < interrupt_config_threads; i++) { 479 for (i = 0; i < interrupt_config_threads; i++) {
469 (void)kthread_create(PRI_NONE, 0, NULL, 480 (void)kthread_create(PRI_NONE, 0, NULL,
470 config_interrupts_thread, NULL, NULL, "config"); 481 config_interrupts_thread, NULL, NULL, "config");
471 } 482 }
472 483
473 /* Get the threads going and into any sleeps before continuing. */ 484 /* Get the threads going and into any sleeps before continuing. */
474 yield(); 485 yield();
475} 486}
476 487
477/* 488/*
@@ -1017,27 +1028,27 @@ config_found_sm_loc(device_t parent, @@ -1017,27 +1028,27 @@ config_found_sm_loc(device_t parent,
1017 const char *ifattr, const int *locs, void *aux, 1028 const char *ifattr, const int *locs, void *aux,
1018 cfprint_t print, cfsubmatch_t submatch) 1029 cfprint_t print, cfsubmatch_t submatch)
1019{ 1030{
1020 cfdata_t cf; 1031 cfdata_t cf;
1021 1032
1022#if defined(SPLASHSCREEN) && defined(SPLASHSCREEN_PROGRESS) 1033#if defined(SPLASHSCREEN) && defined(SPLASHSCREEN_PROGRESS)
1023 if (splash_progress_state) 1034 if (splash_progress_state)
1024 splash_progress_update(splash_progress_state); 1035 splash_progress_update(splash_progress_state);
1025#endif 1036#endif
1026 1037
1027 if ((cf = config_search_loc(submatch, parent, ifattr, locs, aux))) 1038 if ((cf = config_search_loc(submatch, parent, ifattr, locs, aux)))
1028 return(config_attach_loc(parent, cf, locs, aux, print)); 1039 return(config_attach_loc(parent, cf, locs, aux, print));
1029 if (print) { 1040 if (print) {
1030 if (config_do_twiddle) 1041 if (config_do_twiddle && cold)
1031 twiddle(); 1042 twiddle();
1032 aprint_normal("%s", msgs[(*print)(aux, device_xname(parent))]); 1043 aprint_normal("%s", msgs[(*print)(aux, device_xname(parent))]);
1033 } 1044 }
1034 1045
1035#if defined(SPLASHSCREEN) && defined(SPLASHSCREEN_PROGRESS) 1046#if defined(SPLASHSCREEN) && defined(SPLASHSCREEN_PROGRESS)
1036 if (splash_progress_state) 1047 if (splash_progress_state)
1037 splash_progress_update(splash_progress_state); 1048 splash_progress_update(splash_progress_state);
1038#endif 1049#endif
1039 1050
1040 return NULL; 1051 return NULL;
1041} 1052}
1042 1053
1043device_t 1054device_t
@@ -1326,27 +1337,27 @@ config_attach_loc(device_t parent, cfdat @@ -1326,27 +1337,27 @@ config_attach_loc(device_t parent, cfdat
1326 1337
1327 /* XXX redundant - see below? */ 1338 /* XXX redundant - see below? */
1328 if (cf->cf_fstate != FSTATE_STAR) { 1339 if (cf->cf_fstate != FSTATE_STAR) {
1329 KASSERT(cf->cf_fstate == FSTATE_NOTFOUND); 1340 KASSERT(cf->cf_fstate == FSTATE_NOTFOUND);
1330 cf->cf_fstate = FSTATE_FOUND; 1341 cf->cf_fstate = FSTATE_FOUND;
1331 } 1342 }
1332#ifdef __BROKEN_CONFIG_UNIT_USAGE 1343#ifdef __BROKEN_CONFIG_UNIT_USAGE
1333 else 1344 else
1334 cf->cf_unit++; 1345 cf->cf_unit++;
1335#endif 1346#endif
1336 1347
1337 config_devlink(dev); 1348 config_devlink(dev);
1338 1349
1339 if (config_do_twiddle) 1350 if (config_do_twiddle && cold)
1340 twiddle(); 1351 twiddle();
1341 else 1352 else
1342 aprint_naive("Found "); 1353 aprint_naive("Found ");
1343 /* 1354 /*
1344 * We want the next two printfs for normal, verbose, and quiet, 1355 * We want the next two printfs for normal, verbose, and quiet,
1345 * but not silent (in which case, we're twiddling, instead). 1356 * but not silent (in which case, we're twiddling, instead).
1346 */ 1357 */
1347 if (parent == ROOT) { 1358 if (parent == ROOT) {
1348 aprint_naive("%s (root)", device_xname(dev)); 1359 aprint_naive("%s (root)", device_xname(dev));
1349 aprint_normal("%s (root)", device_xname(dev)); 1360 aprint_normal("%s (root)", device_xname(dev));
1350 } else { 1361 } else {
1351 aprint_naive("%s at %s", device_xname(dev), device_xname(parent)); 1362 aprint_naive("%s at %s", device_xname(dev), device_xname(parent));
1352 aprint_normal("%s at %s", device_xname(dev), device_xname(parent)); 1363 aprint_normal("%s at %s", device_xname(dev), device_xname(parent));
@@ -1827,38 +1838,52 @@ config_finalize(void) @@ -1827,38 +1838,52 @@ config_finalize(void)
1827 config_finalize_done = 1; 1838 config_finalize_done = 1;
1828 1839
1829 /* Now free all the hooks. */ 1840 /* Now free all the hooks. */
1830 while ((f = TAILQ_FIRST(&config_finalize_list)) != NULL) { 1841 while ((f = TAILQ_FIRST(&config_finalize_list)) != NULL) {
1831 TAILQ_REMOVE(&config_finalize_list, f, f_list); 1842 TAILQ_REMOVE(&config_finalize_list, f, f_list);
1832 kmem_free(f, sizeof(*f)); 1843 kmem_free(f, sizeof(*f));
1833 } 1844 }
1834 1845
1835 KERNEL_UNLOCK_ONE(NULL); 1846 KERNEL_UNLOCK_ONE(NULL);
1836 1847
1837 errcnt = aprint_get_error_count(); 1848 errcnt = aprint_get_error_count();
1838 if ((boothowto & (AB_QUIET|AB_SILENT)) != 0 && 1849 if ((boothowto & (AB_QUIET|AB_SILENT)) != 0 &&
1839 (boothowto & AB_VERBOSE) == 0) { 1850 (boothowto & AB_VERBOSE) == 0) {
 1851 mutex_enter(&config_misc_lock);
1840 if (config_do_twiddle) { 1852 if (config_do_twiddle) {
1841 config_do_twiddle = 0; 1853 config_do_twiddle = 0;
1842 printf_nolog(" done.\n"); 1854 printf_nolog(" done.\n");
1843 } 1855 }
 1856 mutex_exit(&config_misc_lock);
1844 if (errcnt != 0) { 1857 if (errcnt != 0) {
1845 printf("WARNING: %d error%s while detecting hardware; " 1858 printf("WARNING: %d error%s while detecting hardware; "
1846 "check system log.\n", errcnt, 1859 "check system log.\n", errcnt,
1847 errcnt == 1 ? "" : "s"); 1860 errcnt == 1 ? "" : "s");
1848 } 1861 }
1849 } 1862 }
1850} 1863}
1851 1864
 1865void
 1866config_twiddle_fn(void *cookie)
 1867{
 1868
 1869 mutex_enter(&config_misc_lock);
 1870 if (config_do_twiddle) {
 1871 twiddle();
 1872 callout_schedule(&config_twiddle_ch, mstohz(100));
 1873 }
 1874 mutex_exit(&config_misc_lock);
 1875}
 1876
1852/* 1877/*
1853 * device_lookup: 1878 * device_lookup:
1854 * 1879 *
1855 * Look up a device instance for a given driver. 1880 * Look up a device instance for a given driver.
1856 */ 1881 */
1857device_t 1882device_t
1858device_lookup(cfdriver_t cd, int unit) 1883device_lookup(cfdriver_t cd, int unit)
1859{ 1884{
1860 1885
1861 if (unit < 0 || unit >= cd->cd_ndevs) 1886 if (unit < 0 || unit >= cd->cd_ndevs)
1862 return NULL; 1887 return NULL;
1863  1888
1864 return cd->cd_devs[unit]; 1889 return cd->cd_devs[unit];