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 67e3975643SJake Burkholder static LIST_HEAD(, specinfo) dev_hash[DEVT_HASH]; 68d137acccSPoul-Henning Kamp 69e3975643SJake Burkholder 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 772447bec8SPoul-Henning Kamp struct cdevsw * 782447bec8SPoul-Henning Kamp devsw(dev_t dev) 792447bec8SPoul-Henning Kamp { 807dc5cd04SPoul-Henning Kamp if (dev->si_devsw) 817dc5cd04SPoul-Henning Kamp return (dev->si_devsw); 823de280c4SPoul-Henning Kamp return(cdevsw[major(dev)]); 832447bec8SPoul-Henning Kamp } 842447bec8SPoul-Henning Kamp 852447bec8SPoul-Henning Kamp /* 862447bec8SPoul-Henning Kamp * Add a cdevsw entry 872447bec8SPoul-Henning Kamp */ 882447bec8SPoul-Henning Kamp 89f7ea2f55SJulian Elischer int 902447bec8SPoul-Henning Kamp cdevsw_add(struct cdevsw *newentry) 91f7ea2f55SJulian Elischer { 92f7ea2f55SJulian Elischer int i; 93bfbb9ce6SPoul-Henning Kamp static int setup; 94bfbb9ce6SPoul-Henning Kamp 95bfbb9ce6SPoul-Henning Kamp if (!setup) { 962447bec8SPoul-Henning Kamp for (i = 0; i < NUMCDEVSW; i++) 97bfbb9ce6SPoul-Henning Kamp if (!bmaj2cmaj[i]) 98698bfad7SPoul-Henning Kamp bmaj2cmaj[i] = 254; 99bfbb9ce6SPoul-Henning Kamp setup++; 100bfbb9ce6SPoul-Henning Kamp } 101f7ea2f55SJulian Elischer 1022447bec8SPoul-Henning Kamp if (newentry->d_maj < 0 || newentry->d_maj >= NUMCDEVSW) { 1032447bec8SPoul-Henning Kamp printf("%s: ERROR: driver has bogus cdevsw->d_maj = %d\n", 1042447bec8SPoul-Henning Kamp newentry->d_name, newentry->d_maj); 105662761a7SPoul-Henning Kamp return (EINVAL); 106662761a7SPoul-Henning Kamp } 107662761a7SPoul-Henning Kamp if (newentry->d_bmaj >= NUMCDEVSW) { 108662761a7SPoul-Henning Kamp printf("%s: ERROR: driver has bogus cdevsw->d_bmaj = %d\n", 109662761a7SPoul-Henning Kamp newentry->d_name, newentry->d_bmaj); 110662761a7SPoul-Henning Kamp return (EINVAL); 111662761a7SPoul-Henning Kamp } 112662761a7SPoul-Henning Kamp if (newentry->d_bmaj >= 0 && (newentry->d_flags & D_DISK) == 0) { 113662761a7SPoul-Henning Kamp printf("ERROR: \"%s\" bmaj but is not a disk\n", 114662761a7SPoul-Henning Kamp newentry->d_name); 115662761a7SPoul-Henning Kamp return (EINVAL); 116f7ea2f55SJulian Elischer } 117f7ea2f55SJulian Elischer 118c31558b2SPoul-Henning Kamp if (cdevsw[newentry->d_maj]) { 119c31558b2SPoul-Henning Kamp printf("WARNING: \"%s\" is usurping \"%s\"'s cdevsw[]\n", 120c31558b2SPoul-Henning Kamp newentry->d_name, cdevsw[newentry->d_maj]->d_name); 121c31558b2SPoul-Henning Kamp } 122662761a7SPoul-Henning Kamp 1232447bec8SPoul-Henning Kamp cdevsw[newentry->d_maj] = newentry; 124f7ea2f55SJulian Elischer 125662761a7SPoul-Henning Kamp if (newentry->d_bmaj < 0) 126662761a7SPoul-Henning Kamp return (0); 127662761a7SPoul-Henning Kamp 128698bfad7SPoul-Henning Kamp if (bmaj2cmaj[newentry->d_bmaj] != 254) { 129c31558b2SPoul-Henning Kamp printf("WARNING: \"%s\" is usurping \"%s\"'s bmaj\n", 130c31558b2SPoul-Henning Kamp newentry->d_name, 131c31558b2SPoul-Henning Kamp cdevsw[bmaj2cmaj[newentry->d_bmaj]]->d_name); 132c31558b2SPoul-Henning Kamp } 1332447bec8SPoul-Henning Kamp bmaj2cmaj[newentry->d_bmaj] = newentry->d_maj; 134662761a7SPoul-Henning Kamp return (0); 135f7ea2f55SJulian Elischer } 136f7ea2f55SJulian Elischer 1379a9eb2b9SGreg Lehey /* 1389a9eb2b9SGreg Lehey * Remove a cdevsw entry 1399a9eb2b9SGreg Lehey */ 1409a9eb2b9SGreg Lehey 1419a9eb2b9SGreg Lehey int 1429a9eb2b9SGreg Lehey cdevsw_remove(struct cdevsw *oldentry) 1439a9eb2b9SGreg Lehey { 1449a9eb2b9SGreg Lehey if (oldentry->d_maj < 0 || oldentry->d_maj >= NUMCDEVSW) { 1459a9eb2b9SGreg Lehey printf("%s: ERROR: driver has bogus cdevsw->d_maj = %d\n", 1469a9eb2b9SGreg Lehey oldentry->d_name, oldentry->d_maj); 1479a9eb2b9SGreg Lehey return EINVAL; 1489a9eb2b9SGreg Lehey } 1499a9eb2b9SGreg Lehey 1509a9eb2b9SGreg Lehey cdevsw[oldentry->d_maj] = NULL; 1519a9eb2b9SGreg Lehey 1529a9eb2b9SGreg Lehey if (oldentry->d_bmaj >= 0 && oldentry->d_bmaj < NUMCDEVSW) 15332c0c324SGreg Lehey bmaj2cmaj[oldentry->d_bmaj] = 254; 1549a9eb2b9SGreg Lehey 1559a9eb2b9SGreg Lehey return 0; 1569a9eb2b9SGreg Lehey } 1579a9eb2b9SGreg Lehey 158bfbb9ce6SPoul-Henning Kamp /* 159bfbb9ce6SPoul-Henning Kamp * dev_t and u_dev_t primitives 160bfbb9ce6SPoul-Henning Kamp */ 161bfbb9ce6SPoul-Henning Kamp 162bfbb9ce6SPoul-Henning Kamp int 163bfbb9ce6SPoul-Henning Kamp major(dev_t x) 164bfbb9ce6SPoul-Henning Kamp { 165698bfad7SPoul-Henning Kamp if (x == NODEV) 166698bfad7SPoul-Henning Kamp return NOUDEV; 167698bfad7SPoul-Henning Kamp return((x->si_udev >> 8) & 0xff); 168bfbb9ce6SPoul-Henning Kamp } 169bfbb9ce6SPoul-Henning Kamp 170bfbb9ce6SPoul-Henning Kamp int 171bfbb9ce6SPoul-Henning Kamp minor(dev_t x) 172bfbb9ce6SPoul-Henning Kamp { 173698bfad7SPoul-Henning Kamp if (x == NODEV) 174698bfad7SPoul-Henning Kamp return NOUDEV; 175698bfad7SPoul-Henning Kamp return(x->si_udev & 0xffff00ff); 176bfbb9ce6SPoul-Henning Kamp } 177bfbb9ce6SPoul-Henning Kamp 1789a27d579SPoul-Henning Kamp int 1799a27d579SPoul-Henning Kamp lminor(dev_t x) 1809a27d579SPoul-Henning Kamp { 1819a27d579SPoul-Henning Kamp int i; 1829a27d579SPoul-Henning Kamp 1839a27d579SPoul-Henning Kamp if (x == NODEV) 1849a27d579SPoul-Henning Kamp return NOUDEV; 1859a27d579SPoul-Henning Kamp i = minor(x); 1869a27d579SPoul-Henning Kamp return ((i & 0xff) | (i >> 8)); 1879a27d579SPoul-Henning Kamp } 1889a27d579SPoul-Henning Kamp 189bfbb9ce6SPoul-Henning Kamp dev_t 1906fcd8a7cSPoul-Henning Kamp makebdev(int x, int y) 1916fcd8a7cSPoul-Henning Kamp { 192fb01c24cSPoul-Henning Kamp 193fb01c24cSPoul-Henning Kamp if (x == umajor(NOUDEV) && y == uminor(NOUDEV)) 194fb01c24cSPoul-Henning Kamp Debugger("makebdev of NOUDEV"); 1953de280c4SPoul-Henning Kamp return (makedev(bmaj2cmaj[x], y)); 1966fcd8a7cSPoul-Henning Kamp } 1976fcd8a7cSPoul-Henning Kamp 1983f54a085SPoul-Henning Kamp static dev_t 1993f54a085SPoul-Henning Kamp allocdev(void) 200bfbb9ce6SPoul-Henning Kamp { 201698bfad7SPoul-Henning Kamp static int stashed; 2023f54a085SPoul-Henning Kamp struct specinfo *si; 203698bfad7SPoul-Henning Kamp 204698bfad7SPoul-Henning Kamp if (stashed >= DEVT_STASH) { 205698bfad7SPoul-Henning Kamp MALLOC(si, struct specinfo *, sizeof(*si), M_DEVT, 206698bfad7SPoul-Henning Kamp M_USE_RESERVE); 207d137acccSPoul-Henning Kamp bzero(si, sizeof(*si)); 208d137acccSPoul-Henning Kamp } else if (LIST_FIRST(&dev_free)) { 209d137acccSPoul-Henning Kamp si = LIST_FIRST(&dev_free); 210d137acccSPoul-Henning Kamp LIST_REMOVE(si, si_hash); 211698bfad7SPoul-Henning Kamp } else { 212698bfad7SPoul-Henning Kamp si = devt_stash + stashed++; 213d137acccSPoul-Henning Kamp si->si_flags |= SI_STASHED; 214698bfad7SPoul-Henning Kamp } 2153f54a085SPoul-Henning Kamp LIST_INIT(&si->si_names); 2163f54a085SPoul-Henning Kamp return (si); 2173f54a085SPoul-Henning Kamp } 2183f54a085SPoul-Henning Kamp 2193f54a085SPoul-Henning Kamp dev_t 2203f54a085SPoul-Henning Kamp makedev(int x, int y) 2213f54a085SPoul-Henning Kamp { 2223f54a085SPoul-Henning Kamp struct specinfo *si; 2233f54a085SPoul-Henning Kamp udev_t udev; 2243f54a085SPoul-Henning Kamp int hash; 2253f54a085SPoul-Henning Kamp 2263f54a085SPoul-Henning Kamp if (x == umajor(NOUDEV) && y == uminor(NOUDEV)) 2273f54a085SPoul-Henning Kamp Debugger("makedev of NOUDEV"); 2283f54a085SPoul-Henning Kamp udev = (x << 8) | y; 2293f54a085SPoul-Henning Kamp hash = udev % DEVT_HASH; 2303f54a085SPoul-Henning Kamp LIST_FOREACH(si, &dev_hash[hash], si_hash) { 2313f54a085SPoul-Henning Kamp if (si->si_udev == udev) 2323f54a085SPoul-Henning Kamp return (si); 2333f54a085SPoul-Henning Kamp } 2343f54a085SPoul-Henning Kamp si = allocdev(); 235698bfad7SPoul-Henning Kamp si->si_udev = udev; 236d137acccSPoul-Henning Kamp LIST_INSERT_HEAD(&dev_hash[hash], si, si_hash); 237698bfad7SPoul-Henning Kamp return (si); 238bfbb9ce6SPoul-Henning Kamp } 239bfbb9ce6SPoul-Henning Kamp 240d137acccSPoul-Henning Kamp void 241d137acccSPoul-Henning Kamp freedev(dev_t dev) 242d137acccSPoul-Henning Kamp { 2433f54a085SPoul-Henning Kamp dev_t adev; 244d137acccSPoul-Henning Kamp 245d137acccSPoul-Henning Kamp if (!free_devt) 246d137acccSPoul-Henning Kamp return; 247d137acccSPoul-Henning Kamp if (SLIST_FIRST(&dev->si_hlist)) 248d137acccSPoul-Henning Kamp return; 249d137acccSPoul-Henning Kamp if (dev->si_devsw || dev->si_drv1 || dev->si_drv2) 250d137acccSPoul-Henning Kamp return; 2513f54a085SPoul-Henning Kamp while (!LIST_EMPTY(&dev->si_names)) { 2523f54a085SPoul-Henning Kamp adev = LIST_FIRST(&dev->si_names); 2533f54a085SPoul-Henning Kamp adev->si_drv1 = NULL; 2543f54a085SPoul-Henning Kamp freedev(adev); 2553f54a085SPoul-Henning Kamp } 256d137acccSPoul-Henning Kamp LIST_REMOVE(dev, si_hash); 257d137acccSPoul-Henning Kamp if (dev->si_flags & SI_STASHED) { 258d137acccSPoul-Henning Kamp bzero(dev, sizeof(*dev)); 259d137acccSPoul-Henning Kamp LIST_INSERT_HEAD(&dev_free, dev, si_hash); 260d137acccSPoul-Henning Kamp } else { 261d137acccSPoul-Henning Kamp FREE(dev, M_DEVT); 262d137acccSPoul-Henning Kamp } 263d137acccSPoul-Henning Kamp } 264d137acccSPoul-Henning Kamp 265bfbb9ce6SPoul-Henning Kamp udev_t 266bfbb9ce6SPoul-Henning Kamp dev2udev(dev_t x) 267bfbb9ce6SPoul-Henning Kamp { 268698bfad7SPoul-Henning Kamp if (x == NODEV) 269698bfad7SPoul-Henning Kamp return NOUDEV; 270698bfad7SPoul-Henning Kamp return (x->si_udev); 271bfbb9ce6SPoul-Henning Kamp } 272bfbb9ce6SPoul-Henning Kamp 273bfbb9ce6SPoul-Henning Kamp dev_t 274bfbb9ce6SPoul-Henning Kamp udev2dev(udev_t x, int b) 275bfbb9ce6SPoul-Henning Kamp { 276fb01c24cSPoul-Henning Kamp 277fb01c24cSPoul-Henning Kamp if (x == NOUDEV) 278fb01c24cSPoul-Henning Kamp return (NODEV); 279d21c632cSPoul-Henning Kamp switch (b) { 280d21c632cSPoul-Henning Kamp case 0: 281bfbb9ce6SPoul-Henning Kamp return makedev(umajor(x), uminor(x)); 282d21c632cSPoul-Henning Kamp case 1: 283d21c632cSPoul-Henning Kamp return makebdev(umajor(x), uminor(x)); 284d21c632cSPoul-Henning Kamp default: 285d21c632cSPoul-Henning Kamp Debugger("udev2dev(...,X)"); 286d21c632cSPoul-Henning Kamp return NODEV; 287d21c632cSPoul-Henning Kamp } 288bfbb9ce6SPoul-Henning Kamp } 289bfbb9ce6SPoul-Henning Kamp 290bfbb9ce6SPoul-Henning Kamp int 291bfbb9ce6SPoul-Henning Kamp uminor(udev_t dev) 292bfbb9ce6SPoul-Henning Kamp { 293bfbb9ce6SPoul-Henning Kamp return(dev & 0xffff00ff); 294bfbb9ce6SPoul-Henning Kamp } 295bfbb9ce6SPoul-Henning Kamp 296bfbb9ce6SPoul-Henning Kamp int 297bfbb9ce6SPoul-Henning Kamp umajor(udev_t dev) 298bfbb9ce6SPoul-Henning Kamp { 299bfbb9ce6SPoul-Henning Kamp return((dev & 0xff00) >> 8); 300bfbb9ce6SPoul-Henning Kamp } 301bfbb9ce6SPoul-Henning Kamp 302bfbb9ce6SPoul-Henning Kamp udev_t 303f008cfccSPoul-Henning Kamp makeudev(int x, int y) 304bfbb9ce6SPoul-Henning Kamp { 305bfbb9ce6SPoul-Henning Kamp return ((x << 8) | y); 306bfbb9ce6SPoul-Henning Kamp } 307bfbb9ce6SPoul-Henning Kamp 3080ef1c826SPoul-Henning Kamp dev_t 3090ef1c826SPoul-Henning Kamp make_dev(struct cdevsw *devsw, int minor, uid_t uid, gid_t gid, int perms, char *fmt, ...) 3100ef1c826SPoul-Henning Kamp { 3110ef1c826SPoul-Henning Kamp dev_t dev; 3120ef1c826SPoul-Henning Kamp va_list ap; 3130ef1c826SPoul-Henning Kamp int i; 3140ef1c826SPoul-Henning Kamp 3150ef1c826SPoul-Henning Kamp dev = makedev(devsw->d_maj, minor); 3160ef1c826SPoul-Henning Kamp va_start(ap, fmt); 3178dc74b62SBoris Popov i = kvprintf(fmt, NULL, dev->si_name, 32, ap); 3180ef1c826SPoul-Henning Kamp dev->si_name[i] = '\0'; 3190ef1c826SPoul-Henning Kamp va_end(ap); 3200ef1c826SPoul-Henning Kamp dev->si_devsw = devsw; 3213f54a085SPoul-Henning Kamp dev->si_uid = uid; 3223f54a085SPoul-Henning Kamp dev->si_gid = gid; 3233f54a085SPoul-Henning Kamp dev->si_mode = perms; 3241744fcd0SJulian Elischer 3259dcbe240SPoul-Henning Kamp if (devfs_create_hook) 3263f54a085SPoul-Henning Kamp devfs_create_hook(dev); 3273f54a085SPoul-Henning Kamp return (dev); 3283f54a085SPoul-Henning Kamp } 3293f54a085SPoul-Henning Kamp 3303f54a085SPoul-Henning Kamp dev_t 3313f54a085SPoul-Henning Kamp make_dev_alias(dev_t pdev, char *fmt, ...) 3323f54a085SPoul-Henning Kamp { 3333f54a085SPoul-Henning Kamp dev_t dev; 3343f54a085SPoul-Henning Kamp va_list ap; 3353f54a085SPoul-Henning Kamp int i; 3363f54a085SPoul-Henning Kamp 3373f54a085SPoul-Henning Kamp dev = allocdev(); 3383f54a085SPoul-Henning Kamp dev->si_flags |= SI_ALIAS; 3393f54a085SPoul-Henning Kamp dev->si_drv1 = pdev; 3403f54a085SPoul-Henning Kamp LIST_INSERT_HEAD(&pdev->si_names, dev, si_hash); 3413f54a085SPoul-Henning Kamp 3423f54a085SPoul-Henning Kamp va_start(ap, fmt); 3433f54a085SPoul-Henning Kamp i = kvprintf(fmt, NULL, dev->si_name, 32, ap); 3443f54a085SPoul-Henning Kamp dev->si_name[i] = '\0'; 3453f54a085SPoul-Henning Kamp va_end(ap); 3463f54a085SPoul-Henning Kamp 3473f54a085SPoul-Henning Kamp if (devfs_create_hook) 3483f54a085SPoul-Henning Kamp devfs_create_hook(dev); 3490ef1c826SPoul-Henning Kamp return (dev); 3500ef1c826SPoul-Henning Kamp } 3510ef1c826SPoul-Henning Kamp 352d137acccSPoul-Henning Kamp void 35344d1184eSPoul-Henning Kamp destroy_dev(dev_t dev) 354d137acccSPoul-Henning Kamp { 355d137acccSPoul-Henning Kamp if (devfs_remove_hook) 356d137acccSPoul-Henning Kamp devfs_remove_hook(dev); 357d137acccSPoul-Henning Kamp dev->si_drv1 = 0; 358d137acccSPoul-Henning Kamp dev->si_drv2 = 0; 359d137acccSPoul-Henning Kamp dev->si_devsw = 0; 360d137acccSPoul-Henning Kamp freedev(dev); 361d137acccSPoul-Henning Kamp } 362d137acccSPoul-Henning Kamp 363c32cc149SBruce Evans const char * 364b8e49f68SBill Fumerola devtoname(dev_t dev) 365b8e49f68SBill Fumerola { 366d137acccSPoul-Henning Kamp char *p; 367c32cc149SBruce Evans int mynor; 368b8e49f68SBill Fumerola 369d137acccSPoul-Henning Kamp if (dev->si_name[0] == '#' || dev->si_name[0] == '\0') { 370d137acccSPoul-Henning Kamp p = dev->si_name; 371d137acccSPoul-Henning Kamp if (devsw(dev)) 372d137acccSPoul-Henning Kamp sprintf(p, "#%s/", devsw(dev)->d_name); 373d137acccSPoul-Henning Kamp else 374d137acccSPoul-Henning Kamp sprintf(p, "#%d/", major(dev)); 375d137acccSPoul-Henning Kamp p += strlen(p); 376c32cc149SBruce Evans mynor = minor(dev); 377c32cc149SBruce Evans if (mynor < 0 || mynor > 255) 378c32cc149SBruce Evans sprintf(p, "%#x", (u_int)mynor); 379c32cc149SBruce Evans else 380c32cc149SBruce Evans sprintf(p, "%d", mynor); 381d137acccSPoul-Henning Kamp } 382b8e49f68SBill Fumerola return (dev->si_name); 383b8e49f68SBill Fumerola } 384