autoconf.c revision 36809
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 3736809Sbde * $Id: autoconf.c,v 1.97 1998/05/12 17:33:58 bde 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 */ 4835323Sjulian#include "opt_devfs.h" /* for SLICE */ 4932358Seivind#include "opt_bootp.h" 5032726Seivind#include "opt_ffs.h" 5125460Sjoerg#include "opt_cd9660.h" 5232726Seivind#include "opt_mfs.h" 5332726Seivind#include "opt_nfs.h" 5425164Speter 552056Swollman#include <sys/param.h> 562056Swollman#include <sys/systm.h> 572056Swollman#include <sys/conf.h> 5831328Speter#include <sys/disklabel.h> 5936809Sbde#include <sys/diskslice.h> 602056Swollman#include <sys/reboot.h> 612056Swollman#include <sys/kernel.h> 6236809Sbde#include <sys/malloc.h> 6312604Sbde#include <sys/mount.h> 6412649Speter#include <sys/sysctl.h> 654Srgrimes 6620641Sbde#include <machine/bootinfo.h> 6710665Sbde#include <machine/cons.h> 6831337Sbde#include <machine/ipl.h> 697090Sbde#include <machine/md_var.h> 7027288Sfsmp#ifdef APIC_IO 7125164Speter#include <machine/smp.h> 7225164Speter#endif /* APIC_IO */ 7327288Sfsmp 7436809Sbde#include <i386/isa/icu.h> 7525164Speter 7612604Sbde#include "isa.h" 7712604Sbde#if NISA > 0 7812604Sbde#include <i386/isa/isa_device.h> 7912604Sbde#endif 8010665Sbde 8129243Sjmg#include "pnp.h" 8229243Sjmg#if NPNP > 0 8329243Sjmg#include <i386/isa/pnp.h> 8429243Sjmg#endif 8529243Sjmg 8612604Sbde#include "eisa.h" 8712604Sbde#if NEISA > 0 8812604Sbde#include <i386/eisa/eisaconf.h> 8912604Sbde#endif 9010665Sbde 9112604Sbde#include "pci.h" 9212604Sbde#if NPCI > 0 9312604Sbde#include <pci/pcivar.h> 9412604Sbde#endif 95798Swollman 9630720Snate#include "card.h" 9730720Snate#if NCARD > 0 9812604Sbde#include <pccard/driver.h> 9912604Sbde#endif 1004Srgrimes 10112604Sbde#include "scbus.h" 10212604Sbde#if NSCBUS > 0 10312604Sbde#include <scsi/scsiconf.h> 10412604Sbde#endif 10512604Sbde 10612604Sbdestatic void configure __P((void *)); 10712604SbdeSYSINIT(configure, SI_SUB_CONFIGURE, SI_ORDER_FIRST, configure, NULL) 10812604Sbde 10912848Sbdestatic void configure_finish __P((void)); 11012848Sbdestatic void configure_start __P((void)); 11112848Sbdestatic int setdumpdev __P((dev_t dev)); 11235319Sjulian#ifndef SLICE 11312848Sbdestatic void setroot __P((void)); 11412848Sbde 1158007Sphk#ifdef CD9660 11622521Sdyson 11725460Sjoerg#include <sys/fcntl.h> 11825460Sjoerg#include <sys/proc.h> 11925460Sjoerg#include <sys/stat.h> 12025460Sjoerg#include <machine/clock.h> 12122521Sdyson 12225460Sjoerg/* 12325460Sjoerg * XXX All this CD-ROM root stuff is fairly messy. Ick. 12425460Sjoerg * 12525460Sjoerg * We need to try out all our potential CDROM drives, so we need a table. 12625460Sjoerg */ 1277731Sphkstatic struct { 1287731Sphk char *name; 1297731Sphk int major; 1307731Sphk} try_cdrom[] = { 1317731Sphk { "cd", 6 }, 1327731Sphk { "mcd", 7 }, 1337731Sphk { "scd", 16 }, 1347731Sphk { "matcd", 17 }, 13525460Sjoerg { "wcd", 19 }, 1367731Sphk { 0, 0} 1377731Sphk}; 1387731Sphk 13925460Sjoergstatic int find_cdrom_root __P((void)); 14012604Sbde 14112604Sbdestatic int 14225460Sjoergfind_cdrom_root() 1437731Sphk{ 14425460Sjoerg int i, j, error; 14525460Sjoerg struct bdevsw *bd; 14625460Sjoerg dev_t orootdev; 1477731Sphk 14825460Sjoerg#if CD9660_ROOTDELAY > 0 14925460Sjoerg DELAY(CD9660_ROOTDELAY * 1000000); 15025460Sjoerg#endif 15125460Sjoerg orootdev = rootdev; 15225460Sjoerg for (i = 0 ; i < 2; i++) 15325460Sjoerg for (j = 0 ; try_cdrom[j].name ; j++) { 15425460Sjoerg if (try_cdrom[j].major >= nblkdev) 15525460Sjoerg continue; 15625460Sjoerg rootdev = makedev(try_cdrom[j].major, i * 8); 15725460Sjoerg bd = bdevsw[major(rootdev)]; 15825460Sjoerg if (bd == NULL || bd->d_open == NULL) 15925460Sjoerg continue; 16025460Sjoerg if (bootverbose) 16125460Sjoerg printf("trying %s%d as rootdev (0x%x)\n", 16225460Sjoerg try_cdrom[j].name, i, rootdev); 16325460Sjoerg error = (bd->d_open)(rootdev, FREAD, S_IFBLK, curproc); 16425460Sjoerg if (error == 0) { 16525460Sjoerg if (bd->d_close != NULL) 16625460Sjoerg (bd->d_close)(rootdev, FREAD, S_IFBLK, 16725460Sjoerg curproc); 16825460Sjoerg return 0; 16925460Sjoerg } 1707731Sphk } 17125460Sjoerg 17225460Sjoerg rootdev = orootdev; 1737731Sphk return EINVAL; 1747731Sphk} 1758007Sphk#endif /* CD9660 */ 17635319Sjulian#endif /* !SLICE */ 1777731Sphk 17812604Sbdestatic void 1797818Sdufaultconfigure_start() 1807818Sdufault{ 1817818Sdufault#if NSCBUS > 0 1827818Sdufault scsi_configure_start(); 1837818Sdufault#endif 1847818Sdufault} 1857818Sdufault 18612604Sbdestatic void 1877818Sdufaultconfigure_finish() 1887818Sdufault{ 1897818Sdufault#if NSCBUS > 0 1907818Sdufault scsi_configure_finish(); 1917818Sdufault#endif 1927818Sdufault} 1937818Sdufault 1944Srgrimes/* 1954Srgrimes * Determine i/o configuration for a machine. 1964Srgrimes */ 19710665Sbdestatic void 19810665Sbdeconfigure(dummy) 19910653Sdg void *dummy; 2004Srgrimes{ 20120641Sbde int i; 2024Srgrimes 2038015Sjulian configure_start(); 2048015Sjulian 20512791Sgibbs /* Allow all routines to decide for themselves if they want intrs */ 20629675Sgibbs /* 20729675Sgibbs * XXX Since this cannot be achieved on all architectures, we should 20829675Sgibbs * XXX go back to disabling all interrupts until configuration is 20929675Sgibbs * XXX completed and switch any devices that rely on the current 21029675Sgibbs * XXX behavior to no longer rely on interrupts or to register an 21129675Sgibbs * XXX interrupt_driven_config_hook for the task. 21229675Sgibbs */ 21331336Sbde /* 21431336Sbde * XXX The above is wrong, because we're implicitly at splhigh(), 21531336Sbde * XXX and should stay there, so enabling interrupts in the CPU 21631336Sbde * XXX and the ICU at most gives pending interrupts which just get 21731336Sbde * XXX in the way. 21831336Sbde */ 21927288Sfsmp#ifdef APIC_IO 22027288Sfsmp bsp_apic_configure(); 22125172Speter enable_intr(); 22227288Sfsmp#else 22327288Sfsmp enable_intr(); 22425172Speter INTREN(IRQ_SLAVE); 22527288Sfsmp#endif /* APIC_IO */ 22612791Sgibbs 22712091Sgibbs#if NEISA > 0 22812091Sgibbs eisa_configure(); 22912091Sgibbs#endif 23012091Sgibbs 2312430Sse#if NPCI > 0 2322430Sse pci_configure(); 2332430Sse#endif 2342430Sse 23529243Sjmg#if NPNP > 0 23629243Sjmg pnp_configure(); 23729243Sjmg#endif 23829243Sjmg 23912791Sgibbs#if NISA > 0 24012791Sgibbs isa_configure(); 24112791Sgibbs#endif 24212791Sgibbs 24331336Sbde /* 24431336Sbde * Now we're ready to handle (pending) interrupts. 24531336Sbde * XXX this is slightly misplaced. 24631336Sbde */ 24731336Sbde spl0(); 24831336Sbde 24931337Sbde /* 25031337Sbde * Allow lowering of the ipl to the lowest kernel level if we 25131337Sbde * panic (or call tsleep() before clearing `cold'). No level is 25231337Sbde * completely safe (since a panic may occur in a critical region 25331337Sbde * at splhigh()), but we want at least bio interrupts to work. 25431337Sbde */ 25531337Sbde safepri = cpl; 25631337Sbde 25730720Snate#if NCARD > 0 25822564Sbde /* After everyone else has a chance at grabbing resources */ 25922564Sbde pccard_configure(); 26022564Sbde#endif 26122564Sbde 2627818Sdufault configure_finish(); 2637818Sdufault 26410665Sbde cninit_finish(); 26510665Sbde 26620641Sbde if (bootverbose) { 26727561Sfsmp 26827561Sfsmp#ifdef APIC_IO 26927615Sfsmp imen_dump(); 27027561Sfsmp#endif /* APIC_IO */ 27127561Sfsmp 27220641Sbde /* 27320641Sbde * Print out the BIOS's idea of the disk geometries. 27420641Sbde */ 27520641Sbde printf("BIOS Geometries:\n"); 27620641Sbde for (i = 0; i < N_BIOS_GEOM; i++) { 27720641Sbde unsigned long bios_geom; 27820641Sbde int max_cylinder, max_head, max_sector; 27920641Sbde 28020641Sbde bios_geom = bootinfo.bi_bios_geom[i]; 28120641Sbde 28220641Sbde /* 28320641Sbde * XXX the bootstrap punts a 1200K floppy geometry 28420641Sbde * when the get-disk-geometry interrupt fails. Skip 28520641Sbde * drives that have this geometry. 28620641Sbde */ 28720641Sbde if (bios_geom == 0x4f010f) 28820641Sbde continue; 28920641Sbde 29020641Sbde printf(" %x:%08lx ", i, bios_geom); 29120641Sbde max_cylinder = bios_geom >> 16; 29220641Sbde max_head = (bios_geom >> 8) & 0xff; 29320641Sbde max_sector = bios_geom & 0xff; 29420641Sbde printf( 29520641Sbde "0..%d=%d cylinders, 0..%d=%d heads, 1..%d=%d sectors\n", 29620641Sbde max_cylinder, max_cylinder + 1, 29720641Sbde max_head, max_head + 1, 29820641Sbde max_sector, max_sector); 29920641Sbde } 30020641Sbde printf(" %d accounted for\n", bootinfo.bi_n_bios_used); 30120641Sbde 30216075Sjoerg printf("Device configuration finished.\n"); 30320641Sbde } 30429675Sgibbs cold = 0; 30529675Sgibbs} 30616075Sjoerg 30735319Sjulian#ifndef SLICE 30835319Sjulian 30929675Sgibbsvoid 31029675Sgibbscpu_rootconf() 31129675Sgibbs{ 31229675Sgibbs /* 31329675Sgibbs * XXX NetBSD has a much cleaner approach to finding root. 31429675Sgibbs * XXX We should adopt their code. 31529675Sgibbs */ 31632726Seivind#if defined(CD9660) || defined(CD9660_ROOT) 31722521Sdyson if ((boothowto & RB_CDROM)) { 31816075Sjoerg if (bootverbose) 31916075Sjoerg printf("Considering CD-ROM root f/s.\n"); 32025460Sjoerg /* NB: find_cdrom_root() sets rootdev if successful. */ 32125460Sjoerg if (find_cdrom_root() == 0) 32225460Sjoerg mountrootfsname = "cd9660"; 32325460Sjoerg else if (bootverbose) 32425460Sjoerg printf("No CD-ROM available as root f/s.\n"); 32516075Sjoerg } 3267731Sphk#endif 3278007Sphk 32812499Speter#ifdef MFS_ROOT 32922521Sdyson if (!mountrootfsname) { 33016075Sjoerg if (bootverbose) 33116075Sjoerg printf("Considering MFS root f/s.\n"); 33222521Sdyson mountrootfsname = "mfs"; 33312499Speter /* 33412499Speter * Ignore the -a flag if this kernel isn't compiled 33512499Speter * with a generic root/swap configuration: if we skip 33612499Speter * setroot() and we aren't a generic kernel, chaos 33712499Speter * will ensue because setconf() will be a no-op. 33812499Speter * (rootdev is always initialized to NODEV in a 33912499Speter * generic configuration, so we test for that.) 34012499Speter */ 34112499Speter if ((boothowto & RB_ASKNAME) == 0 || rootdev != NODEV) 34212499Speter setroot(); 34312499Speter } 34412499Speter#endif 34522564Sbde 34625723Stegge#ifdef BOOTP_NFSROOT 34725723Stegge if (!mountrootfsname && !nfs_diskless_valid) { 34825723Stegge if (bootverbose) 34925723Stegge printf("Considering BOOTP NFS root f/s.\n"); 35025723Stegge mountrootfsname = "nfs"; 35125723Stegge } 35225723Stegge#endif /* BOOTP_NFSROOT */ 35332726Seivind#if defined(NFS) || defined(NFS_ROOT) 35422564Sbde if (!mountrootfsname && nfs_diskless_valid) { 35522564Sbde if (bootverbose) 35622564Sbde printf("Considering NFS root f/s.\n"); 35722564Sbde mountrootfsname = "nfs"; 35822564Sbde } 35922564Sbde#endif /* NFS */ 36022564Sbde 36132726Seivind#if defined(FFS) || defined(FFS_ROOT) 36222521Sdyson if (!mountrootfsname) { 36322521Sdyson mountrootfsname = "ufs"; 36416075Sjoerg if (bootverbose) 36516075Sjoerg printf("Considering FFS root f/s.\n"); 3666547Swpaul /* 3676547Swpaul * Ignore the -a flag if this kernel isn't compiled 3686547Swpaul * with a generic root/swap configuration: if we skip 3696547Swpaul * setroot() and we aren't a generic kernel, chaos 3706547Swpaul * will ensue because setconf() will be a no-op. 3716547Swpaul * (rootdev is always initialized to NODEV in a 3726547Swpaul * generic configuration, so we test for that.) 3736547Swpaul */ 3746547Swpaul if ((boothowto & RB_ASKNAME) == 0 || rootdev != NODEV) 3755321Sjkh setroot(); 3763795Sphk } 3774Srgrimes#endif 37822564Sbde 37922521Sdyson if (!mountrootfsname) { 3804370Sphk panic("Nobody wants to mount my root for me"); 3814370Sphk } 38229742Sbde 38329742Sbde setconf(); 38429675Sgibbs} 38517355Sbde 38636809Sbde#endif /* !SLICE */ 38735319Sjulian 38829675Sgibbsvoid 38929675Sgibbscpu_dumpconf() 39029675Sgibbs{ 39129675Sgibbs if (setdumpdev(dumpdev) != 0) 39229675Sgibbs dumpdev = NODEV; 3934Srgrimes} 3944Srgrimes 39512722Sphkstatic int 3968833Sdgsetdumpdev(dev) 3978833Sdg dev_t dev; 3988481Swollman{ 3998833Sdg int maj, psize; 4008833Sdg long newdumplo; 4018833Sdg 4028833Sdg if (dev == NODEV) { 4038481Swollman dumpdev = dev; 4048833Sdg return (0); 4058481Swollman } 4068833Sdg maj = major(dev); 4078833Sdg if (maj >= nblkdev) 4088833Sdg return (ENXIO); 40912889Speter if (bdevsw[maj] == NULL) 41012889Speter return (ENXIO); /* XXX is this right? */ 41112813Sjulian if (bdevsw[maj]->d_psize == NULL) 41212889Speter return (ENXIO); /* XXX should be ENODEV ? */ 41312813Sjulian psize = bdevsw[maj]->d_psize(dev); 4148833Sdg if (psize == -1) 41512889Speter return (ENXIO); /* XXX should be ENODEV ? */ 41631316Sbde /* 41731316Sbde * XXX should clean up checking in dumpsys() to be more like this, 41831316Sbde * and nuke dodump sysctl (too many knobs), and move this to 41931316Sbde * kern_shutdown.c... 42031316Sbde */ 42135974Sbde if (dkpart(dev) != SWAP_PART) 42231316Sbde return (ENODEV); 42315538Sphk newdumplo = psize - Maxmem * PAGE_SIZE / DEV_BSIZE; 4248833Sdg if (newdumplo < 0) 4258833Sdg return (ENOSPC); 4268833Sdg dumpdev = dev; 4278833Sdg dumplo = newdumplo; 4288833Sdg return (0); 4298876Srgrimes} 4308481Swollman 43135319Sjulian#ifndef SLICE 43235319Sjulian 4338833Sdgu_long bootdev = 0; /* not a dev_t - encoding is different */ 4344Srgrimes 4351289Sache#define FDMAJOR 2 4361290Sache#define FDUNITSHIFT 6 4374Srgrimes 4384Srgrimes/* 4394Srgrimes * Attempt to find the device from which we were booted. 4404Srgrimes * If we can do so, and not instructed not to do so, 44136809Sbde * set rootdevs[] and rootdevnames[] to correspond to the 44236809Sbde * boot device(s). 4434Srgrimes */ 444798Swollmanstatic void 4454Srgrimessetroot() 4464Srgrimes{ 44736809Sbde int majdev, mindev, unit, slice, part; 44836809Sbde dev_t newrootdev; 44936809Sbde char partname[2]; 45036809Sbde char *sname; 4514Srgrimes 45236809Sbde if (boothowto & RB_DFLTROOT || (bootdev & B_MAGICMASK) != B_DEVMAGIC) 4534Srgrimes return; 45436809Sbde majdev = B_TYPE(bootdev); 45536809Sbde if (bdevsw[majdev] == NULL) 45636809Sbde return; 45736809Sbde unit = B_UNIT(bootdev); 45836809Sbde slice = B_SLICE(bootdev); 45936809Sbde if (slice == WHOLE_DISK_SLICE) 46034624Smsmith slice = COMPATIBILITY_SLICE; 46136809Sbde if (slice < 0 || slice >= MAX_SLICES) 4624Srgrimes return; 46336809Sbde 46436809Sbde /* 46536809Sbde * XXX kludge for inconsistent unit numbering and lack of slice 46636809Sbde * support for floppies. 46736809Sbde */ 4681290Sache if (majdev == FDMAJOR) { 46936809Sbde slice = COMPATIBILITY_SLICE; 4702400Sache part = RAW_PART; 4711290Sache mindev = unit << FDUNITSHIFT; 47236809Sbde } else { 47336809Sbde part = B_PARTITION(bootdev); 47434622Smsmith mindev = dkmakeminor(unit, slice, part); 4751290Sache } 47636809Sbde 47736809Sbde newrootdev = makedev(majdev, mindev); 47836809Sbde rootdevs[0] = newrootdev; 47936809Sbde sname = dsname(bdevsw[majdev]->d_name, unit, slice, part, partname); 48036809Sbde rootdevnames[0] = malloc(strlen(sname) + 2, M_DEVBUF, M_NOWAIT); 48136809Sbde sprintf(rootdevnames[0], "%s%s", sname, partname); 48236809Sbde 4834Srgrimes /* 48436809Sbde * For properly dangerously dedicated disks (ones with a historical 48536809Sbde * bogus partition table), the boot blocks will give slice = 4, but 48636809Sbde * the kernel will only provide the compatibility slice since it 48736809Sbde * knows that slice 4 is not a real slice. Arrange to try mounting 48836809Sbde * the compatibility slice as root if mounting the slice passed by 48936809Sbde * the boot blocks fails. This handles the dangerously dedicated 49036809Sbde * case and perhaps others. 4914Srgrimes */ 49236809Sbde if (slice == COMPATIBILITY_SLICE) 4934Srgrimes return; 49436809Sbde slice = COMPATIBILITY_SLICE; 49536809Sbde rootdevs[1] = dkmodslice(newrootdev, slice); 49636809Sbde sname = dsname(bdevsw[majdev]->d_name, unit, slice, part, partname); 49736809Sbde rootdevnames[1] = malloc(strlen(sname) + 2, M_DEVBUF, M_NOWAIT); 49836809Sbde sprintf(rootdevnames[1], "%s%s", sname, partname); 4994Srgrimes} 50012649Speter 50136809Sbde#endif /* !SLICE */ 50235319Sjulian 50312649Speterstatic int 50412649Spetersysctl_kern_dumpdev SYSCTL_HANDLER_ARGS 50512649Speter{ 50612649Speter int error; 50712649Speter dev_t ndumpdev; 50812649Speter 50912649Speter ndumpdev = dumpdev; 51012649Speter error = sysctl_handle_opaque(oidp, &ndumpdev, sizeof ndumpdev, req); 51117355Sbde if (error == 0 && req->newptr != NULL) 51212649Speter error = setdumpdev(ndumpdev); 51312649Speter return (error); 51412649Speter} 51512649Speter 51612649SpeterSYSCTL_PROC(_kern, KERN_DUMPDEV, dumpdev, CTLTYPE_OPAQUE|CTLFLAG_RW, 51722564Sbde 0, sizeof dumpdev, sysctl_kern_dumpdev, "T,dev_t", ""); 518