autoconf.c revision 39982
14Srgrimes/*-
24Srgrimes * Copyright (c) 1990 The Regents of the University of California.
34Srgrimes * All rights reserved.
44Srgrimes *
54Srgrimes * This code is derived from software contributed to Berkeley by
64Srgrimes * William Jolitz.
74Srgrimes *
84Srgrimes * Redistribution and use in source and binary forms, with or without
94Srgrimes * modification, are permitted provided that the following conditions
104Srgrimes * are met:
114Srgrimes * 1. Redistributions of source code must retain the above copyright
124Srgrimes *    notice, this list of conditions and the following disclaimer.
134Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
144Srgrimes *    notice, this list of conditions and the following disclaimer in the
154Srgrimes *    documentation and/or other materials provided with the distribution.
164Srgrimes * 3. All advertising materials mentioning features or use of this software
174Srgrimes *    must display the following acknowledgement:
184Srgrimes *	This product includes software developed by the University of
194Srgrimes *	California, Berkeley and its contributors.
204Srgrimes * 4. Neither the name of the University nor the names of its contributors
214Srgrimes *    may be used to endorse or promote products derived from this software
224Srgrimes *    without specific prior written permission.
234Srgrimes *
244Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
254Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
264Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
274Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
284Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
294Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
304Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
314Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
324Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
334Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
344Srgrimes * SUCH DAMAGE.
354Srgrimes *
36620Srgrimes *	from: @(#)autoconf.c	7.1 (Berkeley) 5/9/91
3739976Sobrien *	$Id: autoconf.c,v 1.106 1998/09/15 10:03:42 gibbs Exp $
384Srgrimes */
394Srgrimes
404Srgrimes/*
414Srgrimes * Setup the system to run on the current machine.
424Srgrimes *
438876Srgrimes * Configure() is called at boot time and initializes the vba
444Srgrimes * device tables and the memory controller monitoring.  Available
454Srgrimes * devices are determined (from possibilities mentioned in ioconf.c),
464Srgrimes * and the drivers are initialized.
474Srgrimes */
4832358Seivind#include "opt_bootp.h"
4932726Seivind#include "opt_ffs.h"
5025460Sjoerg#include "opt_cd9660.h"
5132726Seivind#include "opt_mfs.h"
5237272Sjmg#include "opt_nfsroot.h"
5325164Speter
542056Swollman#include <sys/param.h>
552056Swollman#include <sys/systm.h>
562056Swollman#include <sys/conf.h>
5731328Speter#include <sys/disklabel.h>
5836809Sbde#include <sys/diskslice.h>
592056Swollman#include <sys/reboot.h>
602056Swollman#include <sys/kernel.h>
6136809Sbde#include <sys/malloc.h>
6212604Sbde#include <sys/mount.h>
6312649Speter#include <sys/sysctl.h>
644Srgrimes
6520641Sbde#include <machine/bootinfo.h>
6610665Sbde#include <machine/cons.h>
6731337Sbde#include <machine/ipl.h>
687090Sbde#include <machine/md_var.h>
6927288Sfsmp#ifdef APIC_IO
7025164Speter#include <machine/smp.h>
7125164Speter#endif /* APIC_IO */
7227288Sfsmp
7336809Sbde#include <i386/isa/icu.h>
7425164Speter
7512604Sbde#include "isa.h"
7612604Sbde#if NISA > 0
7712604Sbde#include <i386/isa/isa_device.h>
7812604Sbde#endif
7910665Sbde
8029243Sjmg#include "pnp.h"
8129243Sjmg#if NPNP > 0
8229243Sjmg#include <i386/isa/pnp.h>
8329243Sjmg#endif
8429243Sjmg
8512604Sbde#include "eisa.h"
8612604Sbde#if NEISA > 0
8712604Sbde#include <i386/eisa/eisaconf.h>
8812604Sbde#endif
8910665Sbde
9012604Sbde#include "pci.h"
9112604Sbde#if NPCI > 0
9212604Sbde#include <pci/pcivar.h>
9312604Sbde#endif
94798Swollman
9530720Snate#include "card.h"
9630720Snate#if NCARD > 0
9712604Sbde#include <pccard/driver.h>
9812604Sbde#endif
994Srgrimes
10012604Sbde#include "scbus.h"
10112604Sbde
10238779Snsouch#include <sys/bus.h>
10338779Snsouch
10412604Sbdestatic void	configure __P((void *));
10512604SbdeSYSINIT(configure, SI_SUB_CONFIGURE, SI_ORDER_FIRST, configure, NULL)
10612604Sbde
10712848Sbdestatic void	configure_finish __P((void));
10812848Sbdestatic void	configure_start __P((void));
10912848Sbdestatic int	setdumpdev __P((dev_t dev));
11012848Sbdestatic void	setroot __P((void));
11112848Sbde
11239982Sobrien#if defined(CD9660) || defined(CD9660_ROOT)
11322521Sdyson
11425460Sjoerg#include <sys/fcntl.h>
11525460Sjoerg#include <sys/proc.h>
11625460Sjoerg#include <sys/stat.h>
11725460Sjoerg#include <machine/clock.h>
11822521Sdyson
11925460Sjoerg/*
12025460Sjoerg * XXX All this CD-ROM root stuff is fairly messy.  Ick.
12125460Sjoerg *
12225460Sjoerg * We need to try out all our potential CDROM drives, so we need a table.
12325460Sjoerg */
1247731Sphkstatic struct {
1257731Sphk	char *name;
1267731Sphk	int major;
1277731Sphk} try_cdrom[] = {
1287731Sphk	{ "cd", 6 },
1297731Sphk	{ "mcd", 7 },
1307731Sphk	{ "scd", 16 },
1317731Sphk	{ "matcd", 17 },
13225460Sjoerg	{ "wcd", 19 },
1337731Sphk	{ 0, 0}
1347731Sphk};
1357731Sphk
13625460Sjoergstatic int	find_cdrom_root __P((void));
13712604Sbde
13812604Sbdestatic int
13925460Sjoergfind_cdrom_root()
1407731Sphk{
14125460Sjoerg	int i, j, error;
14237389Sjulian	struct cdevsw *bd;
14325460Sjoerg	dev_t orootdev;
1447731Sphk
14525460Sjoerg#if CD9660_ROOTDELAY > 0
14625460Sjoerg	DELAY(CD9660_ROOTDELAY * 1000000);
14725460Sjoerg#endif
14825460Sjoerg	orootdev = rootdev;
14925460Sjoerg	for (i = 0 ; i < 2; i++)
15025460Sjoerg		for (j = 0 ; try_cdrom[j].name ; j++) {
15125460Sjoerg			if (try_cdrom[j].major >= nblkdev)
15225460Sjoerg				continue;
15325460Sjoerg			rootdev = makedev(try_cdrom[j].major, i * 8);
15425460Sjoerg			bd = bdevsw[major(rootdev)];
15525460Sjoerg			if (bd == NULL || bd->d_open == NULL)
15625460Sjoerg				continue;
15725460Sjoerg			if (bootverbose)
15825460Sjoerg				printf("trying %s%d as rootdev (0x%x)\n",
15925460Sjoerg				       try_cdrom[j].name, i, rootdev);
16025460Sjoerg			error = (bd->d_open)(rootdev, FREAD, S_IFBLK, curproc);
16125460Sjoerg			if (error == 0) {
16225460Sjoerg				if (bd->d_close != NULL)
16325460Sjoerg					(bd->d_close)(rootdev, FREAD, S_IFBLK,
16425460Sjoerg						      curproc);
16525460Sjoerg				return 0;
16625460Sjoerg			}
1677731Sphk		}
16825460Sjoerg
16925460Sjoerg	rootdev = orootdev;
1707731Sphk	return EINVAL;
1717731Sphk}
17239982Sobrien#endif /* CD9660 || CD9660_ROOT */
1737731Sphk
17439243Sgibbsextern void xpt_init __P((void));
17539243Sgibbs
17612604Sbdestatic void
1777818Sdufaultconfigure_start()
1787818Sdufault{
1797818Sdufault#if NSCBUS > 0
18039243Sgibbs	xpt_init();
1817818Sdufault#endif
1827818Sdufault}
1837818Sdufault
18412604Sbdestatic void
1857818Sdufaultconfigure_finish()
1867818Sdufault{
1877818Sdufault}
1887818Sdufault
1894Srgrimes/*
1904Srgrimes * Determine i/o configuration for a machine.
1914Srgrimes */
19210665Sbdestatic void
19310665Sbdeconfigure(dummy)
19410653Sdg	void *dummy;
1954Srgrimes{
19620641Sbde	int i;
1974Srgrimes
1988015Sjulian	configure_start();
1998015Sjulian
20012791Sgibbs	/* Allow all routines to decide for themselves if they want intrs */
20129675Sgibbs	/*
20229675Sgibbs	 * XXX Since this cannot be achieved on all architectures, we should
20329675Sgibbs	 * XXX go back to disabling all interrupts until configuration is
20429675Sgibbs	 * XXX completed and switch any devices that rely on the current
20529675Sgibbs	 * XXX behavior to no longer rely on interrupts or to register an
20629675Sgibbs	 * XXX interrupt_driven_config_hook for the task.
20729675Sgibbs	 */
20831336Sbde	/*
20931336Sbde	 * XXX The above is wrong, because we're implicitly at splhigh(),
21031336Sbde	 * XXX and should stay there, so enabling interrupts in the CPU
21131336Sbde	 * XXX and the ICU at most gives pending interrupts which just get
21231336Sbde	 * XXX in the way.
21331336Sbde	 */
21427288Sfsmp#ifdef APIC_IO
21527288Sfsmp	bsp_apic_configure();
21625172Speter	enable_intr();
21727288Sfsmp#else
21827288Sfsmp	enable_intr();
21925172Speter	INTREN(IRQ_SLAVE);
22027288Sfsmp#endif /* APIC_IO */
22112791Sgibbs
22212091Sgibbs#if NEISA > 0
22312091Sgibbs	eisa_configure();
22412091Sgibbs#endif
22512091Sgibbs
2262430Sse#if NPCI > 0
2272430Sse	pci_configure();
2282430Sse#endif
2292430Sse
23029243Sjmg#if NPNP > 0
23129243Sjmg	pnp_configure();
23229243Sjmg#endif
23329243Sjmg
23412791Sgibbs#if NISA > 0
23512791Sgibbs	isa_configure();
23612791Sgibbs#endif
23712791Sgibbs
23838779Snsouch	/* initialize new bus architecture */
23938779Snsouch	root_bus_configure();
24038779Snsouch
24131336Sbde	/*
24231336Sbde	 * Now we're ready to handle (pending) interrupts.
24331336Sbde	 * XXX this is slightly misplaced.
24431336Sbde	 */
24531336Sbde	spl0();
24631336Sbde
24731337Sbde	/*
24831337Sbde	 * Allow lowering of the ipl to the lowest kernel level if we
24931337Sbde	 * panic (or call tsleep() before clearing `cold').  No level is
25031337Sbde	 * completely safe (since a panic may occur in a critical region
25131337Sbde	 * at splhigh()), but we want at least bio interrupts to work.
25231337Sbde	 */
25331337Sbde	safepri = cpl;
25431337Sbde
25530720Snate#if NCARD > 0
25622564Sbde	/* After everyone else has a chance at grabbing resources */
25722564Sbde	pccard_configure();
25822564Sbde#endif
25922564Sbde
2607818Sdufault	configure_finish();
2617818Sdufault
26210665Sbde	cninit_finish();
26310665Sbde
26420641Sbde	if (bootverbose) {
26527561Sfsmp
26627561Sfsmp#ifdef APIC_IO
26727615Sfsmp		imen_dump();
26827561Sfsmp#endif /* APIC_IO */
26927561Sfsmp
27020641Sbde		/*
27120641Sbde		 * Print out the BIOS's idea of the disk geometries.
27220641Sbde		 */
27320641Sbde		printf("BIOS Geometries:\n");
27420641Sbde		for (i = 0; i < N_BIOS_GEOM; i++) {
27520641Sbde			unsigned long bios_geom;
27620641Sbde			int max_cylinder, max_head, max_sector;
27720641Sbde
27820641Sbde			bios_geom = bootinfo.bi_bios_geom[i];
27920641Sbde
28020641Sbde			/*
28120641Sbde			 * XXX the bootstrap punts a 1200K floppy geometry
28220641Sbde			 * when the get-disk-geometry interrupt fails.  Skip
28320641Sbde			 * drives that have this geometry.
28420641Sbde			 */
28520641Sbde			if (bios_geom == 0x4f010f)
28620641Sbde				continue;
28720641Sbde
28820641Sbde			printf(" %x:%08lx ", i, bios_geom);
28920641Sbde			max_cylinder = bios_geom >> 16;
29020641Sbde			max_head = (bios_geom >> 8) & 0xff;
29120641Sbde			max_sector = bios_geom & 0xff;
29220641Sbde			printf(
29320641Sbde		"0..%d=%d cylinders, 0..%d=%d heads, 1..%d=%d sectors\n",
29420641Sbde			       max_cylinder, max_cylinder + 1,
29520641Sbde			       max_head, max_head + 1,
29620641Sbde			       max_sector, max_sector);
29720641Sbde		}
29820641Sbde		printf(" %d accounted for\n", bootinfo.bi_n_bios_used);
29920641Sbde
30016075Sjoerg		printf("Device configuration finished.\n");
30120641Sbde	}
30229675Sgibbs	cold = 0;
30329675Sgibbs}
30416075Sjoerg
30535319Sjulian
30629675Sgibbsvoid
30729675Sgibbscpu_rootconf()
30829675Sgibbs{
30929675Sgibbs	/*
31029675Sgibbs	 * XXX NetBSD has a much cleaner approach to finding root.
31129675Sgibbs	 * XXX We should adopt their code.
31229675Sgibbs	 */
31339982Sobrien#if defined(CD9660) || defined(CD9660_ROOT)
31422521Sdyson	if ((boothowto & RB_CDROM)) {
31516075Sjoerg		if (bootverbose)
31616075Sjoerg			printf("Considering CD-ROM root f/s.\n");
31725460Sjoerg		/* NB: find_cdrom_root() sets rootdev if successful. */
31825460Sjoerg		if (find_cdrom_root() == 0)
31925460Sjoerg			mountrootfsname = "cd9660";
32025460Sjoerg		else if (bootverbose)
32125460Sjoerg			printf("No CD-ROM available as root f/s.\n");
32216075Sjoerg	}
3237731Sphk#endif
3248007Sphk
32512499Speter#ifdef MFS_ROOT
32622521Sdyson	if (!mountrootfsname) {
32716075Sjoerg		if (bootverbose)
32816075Sjoerg			printf("Considering MFS root f/s.\n");
32922521Sdyson		mountrootfsname = "mfs";
33012499Speter		/*
33112499Speter		 * Ignore the -a flag if this kernel isn't compiled
33212499Speter		 * with a generic root/swap configuration: if we skip
33312499Speter		 * setroot() and we aren't a generic kernel, chaos
33412499Speter		 * will ensue because setconf() will be a no-op.
33512499Speter		 * (rootdev is always initialized to NODEV in a
33612499Speter		 * generic configuration, so we test for that.)
33712499Speter		 */
33812499Speter		if ((boothowto & RB_ASKNAME) == 0 || rootdev != NODEV)
33912499Speter			setroot();
34012499Speter	}
34112499Speter#endif
34222564Sbde
34325723Stegge#ifdef BOOTP_NFSROOT
34425723Stegge	if (!mountrootfsname && !nfs_diskless_valid) {
34525723Stegge		if (bootverbose)
34625723Stegge			printf("Considering BOOTP NFS root f/s.\n");
34725723Stegge		mountrootfsname = "nfs";
34825723Stegge	}
34925723Stegge#endif /* BOOTP_NFSROOT */
35039982Sobrien#if defined(NFS) || defined(NFS_ROOT)
35122564Sbde	if (!mountrootfsname && nfs_diskless_valid) {
35222564Sbde		if (bootverbose)
35322564Sbde			printf("Considering NFS root f/s.\n");
35422564Sbde		mountrootfsname = "nfs";
35522564Sbde	}
35622564Sbde#endif /* NFS */
35722564Sbde
35839982Sobrien#if defined(FFS) || defined(FFS_ROOT)
35922521Sdyson	if (!mountrootfsname) {
36022521Sdyson		mountrootfsname = "ufs";
36116075Sjoerg		if (bootverbose)
36216075Sjoerg			printf("Considering FFS root f/s.\n");
3636547Swpaul		/*
3646547Swpaul		 * Ignore the -a flag if this kernel isn't compiled
3656547Swpaul		 * with a generic root/swap configuration: if we skip
3666547Swpaul		 * setroot() and we aren't a generic kernel, chaos
3676547Swpaul		 * will ensue because setconf() will be a no-op.
3686547Swpaul		 * (rootdev is always initialized to NODEV in a
3696547Swpaul		 * generic configuration, so we test for that.)
3706547Swpaul		 */
3716547Swpaul		if ((boothowto & RB_ASKNAME) == 0 || rootdev != NODEV)
3725321Sjkh			setroot();
3733795Sphk	}
3744Srgrimes#endif
37522564Sbde
37622521Sdyson	if (!mountrootfsname) {
3774370Sphk		panic("Nobody wants to mount my root for me");
3784370Sphk	}
37929742Sbde
38029742Sbde	setconf();
38129675Sgibbs}
38217355Sbde
38335319Sjulian
38429675Sgibbsvoid
38529675Sgibbscpu_dumpconf()
38629675Sgibbs{
38729675Sgibbs	if (setdumpdev(dumpdev) != 0)
38829675Sgibbs		dumpdev = NODEV;
3894Srgrimes}
3904Srgrimes
39112722Sphkstatic int
3928833Sdgsetdumpdev(dev)
3938833Sdg	dev_t dev;
3948481Swollman{
3958833Sdg	int maj, psize;
3968833Sdg	long newdumplo;
3978833Sdg
3988833Sdg	if (dev == NODEV) {
3998481Swollman		dumpdev = dev;
4008833Sdg		return (0);
4018481Swollman	}
4028833Sdg	maj = major(dev);
4038833Sdg	if (maj >= nblkdev)
4048833Sdg		return (ENXIO);
40512889Speter	if (bdevsw[maj] == NULL)
40612889Speter		return (ENXIO);		/* XXX is this right? */
40712813Sjulian	if (bdevsw[maj]->d_psize == NULL)
40812889Speter		return (ENXIO);		/* XXX should be ENODEV ? */
40912813Sjulian	psize = bdevsw[maj]->d_psize(dev);
4108833Sdg	if (psize == -1)
41112889Speter		return (ENXIO);		/* XXX should be ENODEV ? */
41231316Sbde	/*
41331316Sbde	 * XXX should clean up checking in dumpsys() to be more like this,
41431316Sbde	 * and nuke dodump sysctl (too many knobs), and move this to
41531316Sbde	 * kern_shutdown.c...
41631316Sbde	 */
41715538Sphk	newdumplo = psize - Maxmem * PAGE_SIZE / DEV_BSIZE;
4188833Sdg	if (newdumplo < 0)
4198833Sdg		return (ENOSPC);
4208833Sdg	dumpdev = dev;
4218833Sdg	dumplo = newdumplo;
4228833Sdg	return (0);
4238876Srgrimes}
4248481Swollman
42535319Sjulian
4268833Sdgu_long	bootdev = 0;		/* not a dev_t - encoding is different */
4274Srgrimes
4281289Sache#define FDMAJOR 2
4291290Sache#define FDUNITSHIFT     6
4304Srgrimes
4314Srgrimes/*
4324Srgrimes * Attempt to find the device from which we were booted.
4334Srgrimes * If we can do so, and not instructed not to do so,
43436809Sbde * set rootdevs[] and rootdevnames[] to correspond to the
43536809Sbde * boot device(s).
4364Srgrimes */
437798Swollmanstatic void
4384Srgrimessetroot()
4394Srgrimes{
44036809Sbde	int majdev, mindev, unit, slice, part;
44136809Sbde	dev_t newrootdev;
44236809Sbde	char partname[2];
44336809Sbde	char *sname;
4444Srgrimes
44536809Sbde	if (boothowto & RB_DFLTROOT || (bootdev & B_MAGICMASK) != B_DEVMAGIC)
4464Srgrimes		return;
44736809Sbde	majdev = B_TYPE(bootdev);
44836809Sbde	if (bdevsw[majdev] == NULL)
44936809Sbde		return;
45036809Sbde	unit = B_UNIT(bootdev);
45136809Sbde	slice = B_SLICE(bootdev);
45236809Sbde	if (slice == WHOLE_DISK_SLICE)
45334624Smsmith		slice = COMPATIBILITY_SLICE;
45436809Sbde	if (slice < 0 || slice >= MAX_SLICES)
4554Srgrimes		return;
45636809Sbde
45736809Sbde	/*
45836809Sbde	 * XXX kludge for inconsistent unit numbering and lack of slice
45936809Sbde	 * support for floppies.
46036809Sbde	 */
4611290Sache	if (majdev == FDMAJOR) {
46236809Sbde		slice = COMPATIBILITY_SLICE;
4632400Sache		part = RAW_PART;
4641290Sache		mindev = unit << FDUNITSHIFT;
46536809Sbde	} else {
46636809Sbde		part = B_PARTITION(bootdev);
46734622Smsmith		mindev = dkmakeminor(unit, slice, part);
4681290Sache	}
46936809Sbde
47036809Sbde	newrootdev = makedev(majdev, mindev);
47136809Sbde	rootdevs[0] = newrootdev;
47236809Sbde	sname = dsname(bdevsw[majdev]->d_name, unit, slice, part, partname);
47336809Sbde	rootdevnames[0] = malloc(strlen(sname) + 2, M_DEVBUF, M_NOWAIT);
47436809Sbde	sprintf(rootdevnames[0], "%s%s", sname, partname);
47536809Sbde
4764Srgrimes	/*
47736809Sbde	 * For properly dangerously dedicated disks (ones with a historical
47836809Sbde	 * bogus partition table), the boot blocks will give slice = 4, but
47936809Sbde	 * the kernel will only provide the compatibility slice since it
48036809Sbde	 * knows that slice 4 is not a real slice.  Arrange to try mounting
48136809Sbde	 * the compatibility slice as root if mounting the slice passed by
48236809Sbde	 * the boot blocks fails.  This handles the dangerously dedicated
48336809Sbde	 * case and perhaps others.
4844Srgrimes	 */
48536809Sbde	if (slice == COMPATIBILITY_SLICE)
4864Srgrimes		return;
48736809Sbde	slice = COMPATIBILITY_SLICE;
48836809Sbde	rootdevs[1] = dkmodslice(newrootdev, slice);
48936809Sbde	sname = dsname(bdevsw[majdev]->d_name, unit, slice, part, partname);
49036809Sbde	rootdevnames[1] = malloc(strlen(sname) + 2, M_DEVBUF, M_NOWAIT);
49136809Sbde	sprintf(rootdevnames[1], "%s%s", sname, partname);
4924Srgrimes}
49312649Speter
49435319Sjulian
49512649Speterstatic int
49612649Spetersysctl_kern_dumpdev SYSCTL_HANDLER_ARGS
49712649Speter{
49812649Speter	int error;
49912649Speter	dev_t ndumpdev;
50012649Speter
50112649Speter	ndumpdev = dumpdev;
50212649Speter	error = sysctl_handle_opaque(oidp, &ndumpdev, sizeof ndumpdev, req);
50317355Sbde	if (error == 0 && req->newptr != NULL)
50412649Speter		error = setdumpdev(ndumpdev);
50512649Speter	return (error);
50612649Speter}
50712649Speter
50812649SpeterSYSCTL_PROC(_kern, KERN_DUMPDEV, dumpdev, CTLTYPE_OPAQUE|CTLFLAG_RW,
50922564Sbde	0, sizeof dumpdev, sysctl_kern_dumpdev, "T,dev_t", "");
510