126453f35SJulian Elischer /*- 226453f35SJulian Elischer * Parts Copyright (c) 1995 Terrence R. Lambert 326453f35SJulian Elischer * Copyright (c) 1995 Julian R. Elischer 426453f35SJulian Elischer * All rights reserved. 526453f35SJulian Elischer * 626453f35SJulian Elischer * Redistribution and use in source and binary forms, with or without 726453f35SJulian Elischer * modification, are permitted provided that the following conditions 826453f35SJulian Elischer * are met: 926453f35SJulian Elischer * 1. Redistributions of source code must retain the above copyright 1026453f35SJulian Elischer * notice, this list of conditions and the following disclaimer. 1126453f35SJulian Elischer * 2. Redistributions in binary form must reproduce the above copyright 1226453f35SJulian Elischer * notice, this list of conditions and the following disclaimer in the 1326453f35SJulian Elischer * documentation and/or other materials provided with the distribution. 1426453f35SJulian Elischer * 3. All advertising materials mentioning features or use of this software 1526453f35SJulian Elischer * must display the following acknowledgement: 1626453f35SJulian Elischer * This product includes software developed by Terrence R. Lambert. 1726453f35SJulian Elischer * 4. The name Terrence R. Lambert may not be used to endorse or promote 1826453f35SJulian Elischer * products derived from this software without specific prior written 1926453f35SJulian Elischer * permission. 2026453f35SJulian Elischer * 2126453f35SJulian Elischer * THIS SOFTWARE IS PROVIDED BY Julian R. Elischer ``AS IS'' AND ANY 2226453f35SJulian Elischer * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2326453f35SJulian Elischer * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2426453f35SJulian Elischer * ARE DISCLAIMED. IN NO EVENT SHALL THE TERRENCE R. LAMBERT BE LIABLE 2526453f35SJulian Elischer * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2626453f35SJulian Elischer * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2726453f35SJulian Elischer * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2826453f35SJulian Elischer * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2926453f35SJulian Elischer * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3026453f35SJulian Elischer * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3126453f35SJulian Elischer * SUCH DAMAGE. 3226453f35SJulian Elischer * 33c3aac50fSPeter Wemm * $FreeBSD$ 3426453f35SJulian Elischer */ 3526453f35SJulian Elischer 3626453f35SJulian Elischer #include <sys/param.h> 37698bfad7SPoul-Henning Kamp #include <sys/kernel.h> 38d137acccSPoul-Henning Kamp #include <sys/sysctl.h> 39f8a760b3SJulian Elischer #include <sys/systm.h> 40ecbb00a2SDoug Rabson #include <sys/module.h> 41698bfad7SPoul-Henning Kamp #include <sys/malloc.h> 4226453f35SJulian Elischer #include <sys/conf.h> 431dfcbb0cSJulian Elischer #include <sys/vnode.h> 44698bfad7SPoul-Henning Kamp #include <sys/queue.h> 450ef1c826SPoul-Henning Kamp #include <machine/stdarg.h> 461dfcbb0cSJulian Elischer 472447bec8SPoul-Henning Kamp #define cdevsw_ALLOCSTART (NUMCDEVSW/2) 481dfcbb0cSJulian Elischer 492447bec8SPoul-Henning Kamp struct cdevsw *cdevsw[NUMCDEVSW]; 501dfcbb0cSJulian Elischer 51698bfad7SPoul-Henning Kamp static int bmaj2cmaj[NUMCDEVSW]; 52698bfad7SPoul-Henning Kamp 53698bfad7SPoul-Henning Kamp MALLOC_DEFINE(M_DEVT, "dev_t", "dev_t storage"); 54698bfad7SPoul-Henning Kamp 55a87b5350SPoul-Henning Kamp /* 56a87b5350SPoul-Henning Kamp * This is the number of hash-buckets. Experiements with 'real-life' 57a87b5350SPoul-Henning Kamp * udev_t's show that a prime halfway between two powers of two works 58a87b5350SPoul-Henning Kamp * best. 59a87b5350SPoul-Henning Kamp */ 60698bfad7SPoul-Henning Kamp #define DEVT_HASH 83 61a87b5350SPoul-Henning Kamp 62a87b5350SPoul-Henning Kamp /* The number of dev_t's we can create before malloc(9) kick in. */ 63698bfad7SPoul-Henning Kamp #define DEVT_STASH 50 64698bfad7SPoul-Henning Kamp 65698bfad7SPoul-Henning Kamp static struct specinfo devt_stash[DEVT_STASH]; 66698bfad7SPoul-Henning Kamp 67d137acccSPoul-Henning Kamp static LIST_HEAD(, specinfo) dev_hash[DEVT_HASH]; 68d137acccSPoul-Henning Kamp 69d137acccSPoul-Henning Kamp static LIST_HEAD(, specinfo) dev_free; 7046eede00SPoul-Henning Kamp 719dcbe240SPoul-Henning Kamp devfs_create_t *devfs_create_hook; 72d137acccSPoul-Henning Kamp devfs_remove_t *devfs_remove_hook; 73d137acccSPoul-Henning Kamp 74d137acccSPoul-Henning Kamp static int free_devt; 75d137acccSPoul-Henning Kamp SYSCTL_INT(_debug, OID_AUTO, free_devt, CTLFLAG_RW, &free_devt, 0, ""); 769dcbe240SPoul-Henning Kamp 771dfcbb0cSJulian Elischer /* 781dfcbb0cSJulian Elischer * Routine to convert from character to block device number. 791dfcbb0cSJulian Elischer * 801dfcbb0cSJulian Elischer * A minimal stub routine can always return NODEV. 811dfcbb0cSJulian Elischer */ 821dfcbb0cSJulian Elischer dev_t 831dfcbb0cSJulian Elischer chrtoblk(dev_t dev) 841dfcbb0cSJulian Elischer { 851dfcbb0cSJulian Elischer struct cdevsw *cd; 861dfcbb0cSJulian Elischer 874be2eb8cSPoul-Henning Kamp if((cd = devsw(dev)) != NULL) { 88f7ea2f55SJulian Elischer if (cd->d_bmaj != -1) 89d21c632cSPoul-Henning Kamp return(makebdev(cd->d_bmaj,minor(dev))); 901dfcbb0cSJulian Elischer } 911dfcbb0cSJulian Elischer return(NODEV); 921dfcbb0cSJulian Elischer } 9326453f35SJulian Elischer 942447bec8SPoul-Henning Kamp struct cdevsw * 952447bec8SPoul-Henning Kamp devsw(dev_t dev) 962447bec8SPoul-Henning Kamp { 977dc5cd04SPoul-Henning Kamp if (dev->si_devsw) 987dc5cd04SPoul-Henning Kamp return (dev->si_devsw); 993de280c4SPoul-Henning Kamp return(cdevsw[major(dev)]); 1002447bec8SPoul-Henning Kamp } 1012447bec8SPoul-Henning Kamp 1022447bec8SPoul-Henning Kamp /* 1032447bec8SPoul-Henning Kamp * Add a cdevsw entry 1042447bec8SPoul-Henning Kamp */ 1052447bec8SPoul-Henning Kamp 106f7ea2f55SJulian Elischer int 1072447bec8SPoul-Henning Kamp cdevsw_add(struct cdevsw *newentry) 108f7ea2f55SJulian Elischer { 109f7ea2f55SJulian Elischer int i; 110bfbb9ce6SPoul-Henning Kamp static int setup; 111bfbb9ce6SPoul-Henning Kamp 112bfbb9ce6SPoul-Henning Kamp if (!setup) { 1132447bec8SPoul-Henning Kamp for (i = 0; i < NUMCDEVSW; i++) 114bfbb9ce6SPoul-Henning Kamp if (!bmaj2cmaj[i]) 115698bfad7SPoul-Henning Kamp bmaj2cmaj[i] = 254; 116bfbb9ce6SPoul-Henning Kamp setup++; 117bfbb9ce6SPoul-Henning Kamp } 118f7ea2f55SJulian Elischer 1192447bec8SPoul-Henning Kamp if (newentry->d_maj < 0 || newentry->d_maj >= NUMCDEVSW) { 1202447bec8SPoul-Henning Kamp printf("%s: ERROR: driver has bogus cdevsw->d_maj = %d\n", 1212447bec8SPoul-Henning Kamp newentry->d_name, newentry->d_maj); 122f7ea2f55SJulian Elischer return EINVAL; 123f7ea2f55SJulian Elischer } 124f7ea2f55SJulian Elischer 125c31558b2SPoul-Henning Kamp if (cdevsw[newentry->d_maj]) { 126c31558b2SPoul-Henning Kamp printf("WARNING: \"%s\" is usurping \"%s\"'s cdevsw[]\n", 127c31558b2SPoul-Henning Kamp newentry->d_name, cdevsw[newentry->d_maj]->d_name); 128c31558b2SPoul-Henning Kamp } 1292447bec8SPoul-Henning Kamp cdevsw[newentry->d_maj] = newentry; 130f7ea2f55SJulian Elischer 131c31558b2SPoul-Henning Kamp if (newentry->d_bmaj >= 0 && newentry->d_bmaj < NUMCDEVSW) { 132698bfad7SPoul-Henning Kamp if (bmaj2cmaj[newentry->d_bmaj] != 254) { 133c31558b2SPoul-Henning Kamp printf("WARNING: \"%s\" is usurping \"%s\"'s bmaj\n", 134c31558b2SPoul-Henning Kamp newentry->d_name, 135c31558b2SPoul-Henning Kamp cdevsw[bmaj2cmaj[newentry->d_bmaj]]->d_name); 136c31558b2SPoul-Henning Kamp } 1372447bec8SPoul-Henning Kamp bmaj2cmaj[newentry->d_bmaj] = newentry->d_maj; 138c31558b2SPoul-Henning Kamp } 1392447bec8SPoul-Henning Kamp 140f7ea2f55SJulian Elischer return 0; 141f7ea2f55SJulian Elischer } 142f7ea2f55SJulian Elischer 1439a9eb2b9SGreg Lehey /* 1449a9eb2b9SGreg Lehey * Remove a cdevsw entry 1459a9eb2b9SGreg Lehey */ 1469a9eb2b9SGreg Lehey 1479a9eb2b9SGreg Lehey int 1489a9eb2b9SGreg Lehey cdevsw_remove(struct cdevsw *oldentry) 1499a9eb2b9SGreg Lehey { 1509a9eb2b9SGreg Lehey if (oldentry->d_maj < 0 || oldentry->d_maj >= NUMCDEVSW) { 1519a9eb2b9SGreg Lehey printf("%s: ERROR: driver has bogus cdevsw->d_maj = %d\n", 1529a9eb2b9SGreg Lehey oldentry->d_name, oldentry->d_maj); 1539a9eb2b9SGreg Lehey return EINVAL; 1549a9eb2b9SGreg Lehey } 1559a9eb2b9SGreg Lehey 1569a9eb2b9SGreg Lehey cdevsw[oldentry->d_maj] = NULL; 1579a9eb2b9SGreg Lehey 1589a9eb2b9SGreg Lehey if (oldentry->d_bmaj >= 0 && oldentry->d_bmaj < NUMCDEVSW) 15932c0c324SGreg Lehey bmaj2cmaj[oldentry->d_bmaj] = 254; 1609a9eb2b9SGreg Lehey 1619a9eb2b9SGreg Lehey return 0; 1629a9eb2b9SGreg Lehey } 1639a9eb2b9SGreg Lehey 164ecbb00a2SDoug Rabson int 16546eede00SPoul-Henning Kamp devsw_module_handler(module_t mod, int what, void* arg) 166ecbb00a2SDoug Rabson { 16746eede00SPoul-Henning Kamp struct devsw_module_data* data = (struct devsw_module_data*) arg; 1686d4ce7aaSDoug Rabson int error = 0; 169ecbb00a2SDoug Rabson 170ecbb00a2SDoug Rabson switch (what) { 171ecbb00a2SDoug Rabson case MOD_LOAD: 1722447bec8SPoul-Henning Kamp error = cdevsw_add(data->cdevsw); 1736ca34d85SDoug Rabson if (!error && data->chainevh) 1746ca34d85SDoug Rabson error = data->chainevh(mod, what, data->chainarg); 175ecbb00a2SDoug Rabson return error; 176ecbb00a2SDoug Rabson 177ecbb00a2SDoug Rabson case MOD_UNLOAD: 1786ca34d85SDoug Rabson if (data->chainevh) { 1796ca34d85SDoug Rabson error = data->chainevh(mod, what, data->chainarg); 1806ca34d85SDoug Rabson if (error) 181ecbb00a2SDoug Rabson return error; 1826ca34d85SDoug Rabson } 1836d4ce7aaSDoug Rabson cdevsw_remove(data->cdevsw); 184f7ea2f55SJulian Elischer return error; 185ecbb00a2SDoug Rabson } 186ecbb00a2SDoug Rabson 187ecbb00a2SDoug Rabson if (data->chainevh) 188ecbb00a2SDoug Rabson return data->chainevh(mod, what, data->chainarg); 189ecbb00a2SDoug Rabson else 190ecbb00a2SDoug Rabson return 0; 191ecbb00a2SDoug Rabson } 192bfbb9ce6SPoul-Henning Kamp 193bfbb9ce6SPoul-Henning Kamp /* 194bfbb9ce6SPoul-Henning Kamp * dev_t and u_dev_t primitives 195bfbb9ce6SPoul-Henning Kamp */ 196bfbb9ce6SPoul-Henning Kamp 197bfbb9ce6SPoul-Henning Kamp int 198bfbb9ce6SPoul-Henning Kamp major(dev_t x) 199bfbb9ce6SPoul-Henning Kamp { 200698bfad7SPoul-Henning Kamp if (x == NODEV) 201698bfad7SPoul-Henning Kamp return NOUDEV; 202698bfad7SPoul-Henning Kamp return((x->si_udev >> 8) & 0xff); 203bfbb9ce6SPoul-Henning Kamp } 204bfbb9ce6SPoul-Henning Kamp 205bfbb9ce6SPoul-Henning Kamp int 206bfbb9ce6SPoul-Henning Kamp minor(dev_t x) 207bfbb9ce6SPoul-Henning Kamp { 208698bfad7SPoul-Henning Kamp if (x == NODEV) 209698bfad7SPoul-Henning Kamp return NOUDEV; 210698bfad7SPoul-Henning Kamp return(x->si_udev & 0xffff00ff); 211bfbb9ce6SPoul-Henning Kamp } 212bfbb9ce6SPoul-Henning Kamp 2139a27d579SPoul-Henning Kamp int 2149a27d579SPoul-Henning Kamp lminor(dev_t x) 2159a27d579SPoul-Henning Kamp { 2169a27d579SPoul-Henning Kamp int i; 2179a27d579SPoul-Henning Kamp 2189a27d579SPoul-Henning Kamp if (x == NODEV) 2199a27d579SPoul-Henning Kamp return NOUDEV; 2209a27d579SPoul-Henning Kamp i = minor(x); 2219a27d579SPoul-Henning Kamp return ((i & 0xff) | (i >> 8)); 2229a27d579SPoul-Henning Kamp } 2239a27d579SPoul-Henning Kamp 224bfbb9ce6SPoul-Henning Kamp dev_t 2256fcd8a7cSPoul-Henning Kamp makebdev(int x, int y) 2266fcd8a7cSPoul-Henning Kamp { 2273de280c4SPoul-Henning Kamp return (makedev(bmaj2cmaj[x], y)); 2286fcd8a7cSPoul-Henning Kamp } 2296fcd8a7cSPoul-Henning Kamp 2306fcd8a7cSPoul-Henning Kamp dev_t 231bfbb9ce6SPoul-Henning Kamp makedev(int x, int y) 232bfbb9ce6SPoul-Henning Kamp { 233698bfad7SPoul-Henning Kamp struct specinfo *si; 234698bfad7SPoul-Henning Kamp udev_t udev; 235698bfad7SPoul-Henning Kamp int hash; 236698bfad7SPoul-Henning Kamp static int stashed; 237698bfad7SPoul-Henning Kamp 238698bfad7SPoul-Henning Kamp udev = (x << 8) | y; 239698bfad7SPoul-Henning Kamp hash = udev % DEVT_HASH; 240d137acccSPoul-Henning Kamp LIST_FOREACH(si, &dev_hash[hash], si_hash) { 241698bfad7SPoul-Henning Kamp if (si->si_udev == udev) 242698bfad7SPoul-Henning Kamp return (si); 243698bfad7SPoul-Henning Kamp } 244698bfad7SPoul-Henning Kamp if (stashed >= DEVT_STASH) { 245698bfad7SPoul-Henning Kamp MALLOC(si, struct specinfo *, sizeof(*si), M_DEVT, 246698bfad7SPoul-Henning Kamp M_USE_RESERVE); 247d137acccSPoul-Henning Kamp bzero(si, sizeof(*si)); 248d137acccSPoul-Henning Kamp } else if (LIST_FIRST(&dev_free)) { 249d137acccSPoul-Henning Kamp si = LIST_FIRST(&dev_free); 250d137acccSPoul-Henning Kamp LIST_REMOVE(si, si_hash); 251698bfad7SPoul-Henning Kamp } else { 252698bfad7SPoul-Henning Kamp si = devt_stash + stashed++; 253d137acccSPoul-Henning Kamp si->si_flags |= SI_STASHED; 254698bfad7SPoul-Henning Kamp } 255698bfad7SPoul-Henning Kamp si->si_udev = udev; 256d137acccSPoul-Henning Kamp LIST_INSERT_HEAD(&dev_hash[hash], si, si_hash); 257698bfad7SPoul-Henning Kamp return (si); 258bfbb9ce6SPoul-Henning Kamp } 259bfbb9ce6SPoul-Henning Kamp 260d137acccSPoul-Henning Kamp void 261d137acccSPoul-Henning Kamp freedev(dev_t dev) 262d137acccSPoul-Henning Kamp { 263d137acccSPoul-Henning Kamp int hash; 264d137acccSPoul-Henning Kamp 265d137acccSPoul-Henning Kamp if (!free_devt) 266d137acccSPoul-Henning Kamp return; 267d137acccSPoul-Henning Kamp if (SLIST_FIRST(&dev->si_hlist)) 268d137acccSPoul-Henning Kamp return; 269d137acccSPoul-Henning Kamp if (dev->si_devsw || dev->si_drv1 || dev->si_drv2) 270d137acccSPoul-Henning Kamp return; 271d137acccSPoul-Henning Kamp hash = dev->si_udev % DEVT_HASH; 272d137acccSPoul-Henning Kamp LIST_REMOVE(dev, si_hash); 273d137acccSPoul-Henning Kamp if (dev->si_flags & SI_STASHED) { 274d137acccSPoul-Henning Kamp bzero(dev, sizeof(*dev)); 275d137acccSPoul-Henning Kamp LIST_INSERT_HEAD(&dev_free, dev, si_hash); 276d137acccSPoul-Henning Kamp } else { 277d137acccSPoul-Henning Kamp FREE(dev, M_DEVT); 278d137acccSPoul-Henning Kamp } 279d137acccSPoul-Henning Kamp } 280d137acccSPoul-Henning Kamp 281bfbb9ce6SPoul-Henning Kamp udev_t 282bfbb9ce6SPoul-Henning Kamp dev2udev(dev_t x) 283bfbb9ce6SPoul-Henning Kamp { 284698bfad7SPoul-Henning Kamp if (x == NODEV) 285698bfad7SPoul-Henning Kamp return NOUDEV; 286698bfad7SPoul-Henning Kamp return (x->si_udev); 287bfbb9ce6SPoul-Henning Kamp } 288bfbb9ce6SPoul-Henning Kamp 289fb30b5bdSBrian Feldman udev_t 290fb30b5bdSBrian Feldman dev2budev(dev_t x) 291fb30b5bdSBrian Feldman { 29257d86fc6SBrian Feldman if (x == NODEV) 293fb30b5bdSBrian Feldman return NOUDEV; 294fb30b5bdSBrian Feldman else 295fb30b5bdSBrian Feldman return makeudev(devsw(x)->d_bmaj, minor(x)); 296fb30b5bdSBrian Feldman } 297fb30b5bdSBrian Feldman 298bfbb9ce6SPoul-Henning Kamp dev_t 299bfbb9ce6SPoul-Henning Kamp udev2dev(udev_t x, int b) 300bfbb9ce6SPoul-Henning Kamp { 301d21c632cSPoul-Henning Kamp switch (b) { 302d21c632cSPoul-Henning Kamp case 0: 303bfbb9ce6SPoul-Henning Kamp return makedev(umajor(x), uminor(x)); 304d21c632cSPoul-Henning Kamp case 1: 305d21c632cSPoul-Henning Kamp return makebdev(umajor(x), uminor(x)); 306d21c632cSPoul-Henning Kamp default: 307d21c632cSPoul-Henning Kamp Debugger("udev2dev(...,X)"); 308d21c632cSPoul-Henning Kamp return NODEV; 309d21c632cSPoul-Henning Kamp } 310bfbb9ce6SPoul-Henning Kamp } 311bfbb9ce6SPoul-Henning Kamp 312bfbb9ce6SPoul-Henning Kamp int 313bfbb9ce6SPoul-Henning Kamp uminor(udev_t dev) 314bfbb9ce6SPoul-Henning Kamp { 315bfbb9ce6SPoul-Henning Kamp return(dev & 0xffff00ff); 316bfbb9ce6SPoul-Henning Kamp } 317bfbb9ce6SPoul-Henning Kamp 318bfbb9ce6SPoul-Henning Kamp int 319bfbb9ce6SPoul-Henning Kamp umajor(udev_t dev) 320bfbb9ce6SPoul-Henning Kamp { 321bfbb9ce6SPoul-Henning Kamp return((dev & 0xff00) >> 8); 322bfbb9ce6SPoul-Henning Kamp } 323bfbb9ce6SPoul-Henning Kamp 324bfbb9ce6SPoul-Henning Kamp udev_t 325f008cfccSPoul-Henning Kamp makeudev(int x, int y) 326bfbb9ce6SPoul-Henning Kamp { 327bfbb9ce6SPoul-Henning Kamp return ((x << 8) | y); 328bfbb9ce6SPoul-Henning Kamp } 329bfbb9ce6SPoul-Henning Kamp 3300ef1c826SPoul-Henning Kamp dev_t 3310ef1c826SPoul-Henning Kamp make_dev(struct cdevsw *devsw, int minor, uid_t uid, gid_t gid, int perms, char *fmt, ...) 3320ef1c826SPoul-Henning Kamp { 3330ef1c826SPoul-Henning Kamp dev_t dev; 3340ef1c826SPoul-Henning Kamp va_list ap; 3350ef1c826SPoul-Henning Kamp int i; 3360ef1c826SPoul-Henning Kamp 3370ef1c826SPoul-Henning Kamp dev = makedev(devsw->d_maj, minor); 3380ef1c826SPoul-Henning Kamp va_start(ap, fmt); 3390ef1c826SPoul-Henning Kamp i = kvprintf(fmt, NULL, dev->si_name, 32, ap); 3400ef1c826SPoul-Henning Kamp dev->si_name[i] = '\0'; 3410ef1c826SPoul-Henning Kamp va_end(ap); 3420ef1c826SPoul-Henning Kamp dev->si_devsw = devsw; 3431744fcd0SJulian Elischer 3449dcbe240SPoul-Henning Kamp if (devfs_create_hook) 3459dcbe240SPoul-Henning Kamp devfs_create_hook(dev, uid, gid, perms); 3460ef1c826SPoul-Henning Kamp return (dev); 3470ef1c826SPoul-Henning Kamp } 3480ef1c826SPoul-Henning Kamp 349d137acccSPoul-Henning Kamp void 350d137acccSPoul-Henning Kamp remove_dev(dev_t dev) 351d137acccSPoul-Henning Kamp { 352d137acccSPoul-Henning Kamp if (devfs_remove_hook) 353d137acccSPoul-Henning Kamp devfs_remove_hook(dev); 354d137acccSPoul-Henning Kamp dev->si_drv1 = 0; 355d137acccSPoul-Henning Kamp dev->si_drv2 = 0; 356d137acccSPoul-Henning Kamp dev->si_devsw = 0; 357d137acccSPoul-Henning Kamp freedev(dev); 358d137acccSPoul-Henning Kamp } 359d137acccSPoul-Henning Kamp 360c32cc149SBruce Evans const char * 361b8e49f68SBill Fumerola devtoname(dev_t dev) 362b8e49f68SBill Fumerola { 363d137acccSPoul-Henning Kamp char *p; 364c32cc149SBruce Evans int mynor; 365b8e49f68SBill Fumerola 366d137acccSPoul-Henning Kamp if (dev->si_name[0] == '#' || dev->si_name[0] == '\0') { 367d137acccSPoul-Henning Kamp p = dev->si_name; 368d137acccSPoul-Henning Kamp if (devsw(dev)) 369d137acccSPoul-Henning Kamp sprintf(p, "#%s/", devsw(dev)->d_name); 370d137acccSPoul-Henning Kamp else 371d137acccSPoul-Henning Kamp sprintf(p, "#%d/", major(dev)); 372d137acccSPoul-Henning Kamp p += strlen(p); 373c32cc149SBruce Evans mynor = minor(dev); 374c32cc149SBruce Evans if (mynor < 0 || mynor > 255) 375c32cc149SBruce Evans sprintf(p, "%#x", (u_int)mynor); 376c32cc149SBruce Evans else 377c32cc149SBruce Evans sprintf(p, "%d", mynor); 378d137acccSPoul-Henning Kamp } 379b8e49f68SBill Fumerola return (dev->si_name); 380b8e49f68SBill Fumerola } 381