Home | History | Annotate | Line # | Download | only in kern
subr_devsw.c revision 1.49.2.1
      1  1.49.2.1    martin /*	$NetBSD: subr_devsw.c,v 1.49.2.1 2023/02/14 16:16:30 martin Exp $	*/
      2      1.11        ad 
      3       1.2   gehenna /*-
      4      1.20        ad  * Copyright (c) 2001, 2002, 2007, 2008 The NetBSD Foundation, Inc.
      5       1.2   gehenna  * All rights reserved.
      6       1.2   gehenna  *
      7       1.2   gehenna  * This code is derived from software contributed to The NetBSD Foundation
      8      1.11        ad  * by MAEKAWA Masahide <gehenna (at) NetBSD.org>, and by Andrew Doran.
      9       1.2   gehenna  *
     10       1.2   gehenna  * Redistribution and use in source and binary forms, with or without
     11       1.2   gehenna  * modification, are permitted provided that the following conditions
     12       1.2   gehenna  * are met:
     13       1.2   gehenna  * 1. Redistributions of source code must retain the above copyright
     14       1.2   gehenna  *    notice, this list of conditions and the following disclaimer.
     15       1.2   gehenna  * 2. Redistributions in binary form must reproduce the above copyright
     16       1.2   gehenna  *    notice, this list of conditions and the following disclaimer in the
     17       1.2   gehenna  *    documentation and/or other materials provided with the distribution.
     18       1.2   gehenna  *
     19       1.2   gehenna  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20       1.2   gehenna  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21       1.2   gehenna  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22       1.2   gehenna  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23       1.2   gehenna  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24       1.2   gehenna  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25       1.2   gehenna  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26       1.2   gehenna  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27       1.2   gehenna  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28       1.2   gehenna  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29       1.2   gehenna  * POSSIBILITY OF SUCH DAMAGE.
     30       1.2   gehenna  */
     31      1.45  riastrad 
     32      1.11        ad /*
     33      1.11        ad  * Overview
     34      1.11        ad  *
     35      1.11        ad  *	subr_devsw.c: registers device drivers by name and by major
     36      1.11        ad  *	number, and provides wrapper methods for performing I/O and
     37      1.11        ad  *	other tasks on device drivers, keying on the device number
     38      1.11        ad  *	(dev_t).
     39      1.11        ad  *
     40      1.11        ad  *	When the system is built, the config(8) command generates
     41      1.11        ad  *	static tables of device drivers built into the kernel image
     42      1.11        ad  *	along with their associated methods.  These are recorded in
     43      1.11        ad  *	the cdevsw0 and bdevsw0 tables.  Drivers can also be added to
     44      1.11        ad  *	and removed from the system dynamically.
     45      1.11        ad  *
     46      1.11        ad  * Allocation
     47      1.11        ad  *
     48      1.11        ad  *	When the system initially boots only the statically allocated
     49      1.11        ad  *	indexes (bdevsw0, cdevsw0) are used.  If these overflow due to
     50      1.11        ad  *	allocation, we allocate a fixed block of memory to hold the new,
     51      1.11        ad  *	expanded index.  This "fork" of the table is only ever performed
     52      1.11        ad  *	once in order to guarantee that other threads may safely access
     53      1.11        ad  *	the device tables:
     54      1.11        ad  *
     55      1.11        ad  *	o Once a thread has a "reference" to the table via an earlier
     56      1.11        ad  *	  open() call, we know that the entry in the table must exist
     57      1.11        ad  *	  and so it is safe to access it.
     58      1.11        ad  *
     59      1.11        ad  *	o Regardless of whether other threads see the old or new
     60      1.11        ad  *	  pointers, they will point to a correct device switch
     61      1.11        ad  *	  structure for the operation being performed.
     62      1.11        ad  *
     63      1.11        ad  *	XXX Currently, the wrapper methods such as cdev_read() verify
     64      1.11        ad  *	that a device driver does in fact exist before calling the
     65      1.11        ad  *	associated driver method.  This should be changed so that
     66      1.11        ad  *	once the device is has been referenced by a vnode (opened),
     67      1.11        ad  *	calling	the other methods should be valid until that reference
     68      1.11        ad  *	is dropped.
     69      1.11        ad  */
     70       1.7     lukem 
     71       1.7     lukem #include <sys/cdefs.h>
     72  1.49.2.1    martin __KERNEL_RCSID(0, "$NetBSD: subr_devsw.c,v 1.49.2.1 2023/02/14 16:16:30 martin Exp $");
     73      1.34       riz 
     74      1.34       riz #ifdef _KERNEL_OPT
     75      1.34       riz #include "opt_dtrace.h"
     76      1.34       riz #endif
     77       1.2   gehenna 
     78       1.2   gehenna #include <sys/param.h>
     79       1.2   gehenna #include <sys/conf.h>
     80      1.11        ad #include <sys/kmem.h>
     81       1.2   gehenna #include <sys/systm.h>
     82      1.11        ad #include <sys/poll.h>
     83      1.11        ad #include <sys/tty.h>
     84      1.15      matt #include <sys/cpu.h>
     85      1.11        ad #include <sys/buf.h>
     86      1.29       mrg #include <sys/reboot.h>
     87      1.34       riz #include <sys/sdt.h>
     88      1.40  riastrad #include <sys/atomic.h>
     89      1.40  riastrad #include <sys/localcount.h>
     90      1.40  riastrad #include <sys/pserialize.h>
     91      1.40  riastrad #include <sys/xcall.h>
     92      1.41  riastrad #include <sys/device.h>
     93       1.2   gehenna 
     94       1.2   gehenna #ifdef DEVSW_DEBUG
     95       1.2   gehenna #define	DPRINTF(x)	printf x
     96       1.2   gehenna #else /* DEVSW_DEBUG */
     97       1.2   gehenna #define	DPRINTF(x)
     98       1.2   gehenna #endif /* DEVSW_DEBUG */
     99       1.2   gehenna 
    100      1.11        ad #define	MAXDEVSW	512	/* the maximum of major device number */
    101       1.2   gehenna #define	BDEVSW_SIZE	(sizeof(struct bdevsw *))
    102       1.2   gehenna #define	CDEVSW_SIZE	(sizeof(struct cdevsw *))
    103       1.2   gehenna #define	DEVSWCONV_SIZE	(sizeof(struct devsw_conv))
    104       1.2   gehenna 
    105      1.40  riastrad struct devswref {
    106      1.40  riastrad 	struct localcount	*dr_lc;
    107      1.40  riastrad };
    108      1.40  riastrad 
    109      1.40  riastrad /* XXX bdevsw, cdevsw, max_bdevsws, and max_cdevsws should be volatile */
    110       1.2   gehenna extern const struct bdevsw **bdevsw, *bdevsw0[];
    111       1.2   gehenna extern const struct cdevsw **cdevsw, *cdevsw0[];
    112       1.2   gehenna extern struct devsw_conv *devsw_conv, devsw_conv0[];
    113       1.2   gehenna extern const int sys_bdevsws, sys_cdevsws;
    114       1.2   gehenna extern int max_bdevsws, max_cdevsws, max_devsw_convs;
    115       1.2   gehenna 
    116      1.40  riastrad static struct devswref *cdevswref;
    117      1.40  riastrad static struct devswref *bdevswref;
    118      1.40  riastrad static kcondvar_t devsw_cv;
    119      1.40  riastrad 
    120      1.24  drochner static int bdevsw_attach(const struct bdevsw *, devmajor_t *);
    121      1.24  drochner static int cdevsw_attach(const struct cdevsw *, devmajor_t *);
    122      1.11        ad static void devsw_detach_locked(const struct bdevsw *, const struct cdevsw *);
    123      1.11        ad 
    124      1.23     pooka kmutex_t device_lock;
    125      1.23     pooka 
    126      1.31     pooka void (*biodone_vfs)(buf_t *) = (void *)nullop;
    127      1.31     pooka 
    128      1.49  riastrad /*
    129      1.49  riastrad  * bdev probes
    130      1.49  riastrad  */
    131      1.49  riastrad SDT_PROBE_DEFINE6(sdt, bdev, open, acquire,
    132      1.49  riastrad     "struct bdevsw *"/*bdevsw*/,
    133      1.49  riastrad     "dev_t"/*dev*/,
    134      1.49  riastrad     "int"/*flag*/,
    135      1.49  riastrad     "int"/*devtype*/,
    136      1.49  riastrad     "int"/*unit*/,
    137      1.49  riastrad     "device_t"/*dv*/);
    138      1.49  riastrad SDT_PROBE_DEFINE4(sdt, bdev, open, entry,
    139      1.49  riastrad     "struct bdevsw *"/*bdevsw*/,
    140      1.49  riastrad     "dev_t"/*dev*/,
    141      1.49  riastrad     "int"/*flag*/,
    142      1.49  riastrad     "int"/*devtype*/);
    143      1.49  riastrad SDT_PROBE_DEFINE5(sdt, bdev, open, return,
    144      1.49  riastrad     "struct bdevsw *"/*bdevsw*/,
    145      1.49  riastrad     "dev_t"/*dev*/,
    146      1.49  riastrad     "int"/*flag*/,
    147      1.49  riastrad     "int"/*devtype*/,
    148      1.49  riastrad     "int"/*error*/);
    149      1.49  riastrad SDT_PROBE_DEFINE6(sdt, bdev, open, release,
    150      1.49  riastrad     "struct bdevsw *"/*bdevsw*/,
    151      1.49  riastrad     "dev_t"/*dev*/,
    152      1.49  riastrad     "int"/*flag*/,
    153      1.49  riastrad     "int"/*devtype*/,
    154      1.49  riastrad     "int"/*unit*/,
    155      1.49  riastrad     "device_t"/*dv*/);
    156      1.49  riastrad 
    157      1.49  riastrad SDT_PROBE_DEFINE4(sdt, bdev, cancel, entry,
    158      1.49  riastrad     "struct bdevsw *"/*bdevsw*/,
    159      1.49  riastrad     "dev_t"/*dev*/,
    160      1.49  riastrad     "int"/*flag*/,
    161      1.49  riastrad     "int"/*devtype*/);
    162      1.49  riastrad SDT_PROBE_DEFINE5(sdt, bdev, cancel, return,
    163      1.49  riastrad     "struct bdevsw *"/*bdevsw*/,
    164      1.49  riastrad     "dev_t"/*dev*/,
    165      1.49  riastrad     "int"/*flag*/,
    166      1.49  riastrad     "int"/*devtype*/,
    167      1.49  riastrad     "int"/*error*/);
    168      1.49  riastrad 
    169      1.49  riastrad SDT_PROBE_DEFINE4(sdt, bdev, close, entry,
    170      1.49  riastrad     "struct bdevsw *"/*bdevsw*/,
    171      1.49  riastrad     "dev_t"/*dev*/,
    172      1.49  riastrad     "int"/*flag*/,
    173      1.49  riastrad     "int"/*devtype*/);
    174      1.49  riastrad SDT_PROBE_DEFINE5(sdt, bdev, close, return,
    175      1.49  riastrad     "struct bdevsw *"/*bdevsw*/,
    176      1.49  riastrad     "dev_t"/*dev*/,
    177      1.49  riastrad     "int"/*flag*/,
    178      1.49  riastrad     "int"/*devtype*/,
    179      1.49  riastrad     "int"/*error*/);
    180      1.49  riastrad 
    181      1.49  riastrad SDT_PROBE_DEFINE3(sdt, bdev, strategy, entry,
    182      1.49  riastrad     "struct bdevsw *"/*bdevsw*/,
    183      1.49  riastrad     "dev_t"/*dev*/,
    184      1.49  riastrad     "struct buf *"/*bp*/);
    185      1.49  riastrad SDT_PROBE_DEFINE3(sdt, bdev, strategy, return,
    186      1.49  riastrad     "struct bdevsw *"/*bdevsw*/,
    187      1.49  riastrad     "dev_t"/*dev*/,
    188      1.49  riastrad     "struct buf *"/*bp*/);
    189      1.49  riastrad 
    190      1.49  riastrad SDT_PROBE_DEFINE5(sdt, bdev, ioctl, entry,
    191      1.49  riastrad     "struct bdevsw *"/*bdevsw*/,
    192      1.49  riastrad     "dev_t"/*dev*/,
    193      1.49  riastrad     "unsigned long"/*cmd*/,
    194      1.49  riastrad     "void *"/*data*/,
    195      1.49  riastrad     "int"/*flag*/);
    196      1.49  riastrad SDT_PROBE_DEFINE6(sdt, bdev, ioctl, return,
    197      1.49  riastrad     "struct bdevsw *"/*bdevsw*/,
    198      1.49  riastrad     "dev_t"/*dev*/,
    199      1.49  riastrad     "unsigned long"/*cmd*/,
    200      1.49  riastrad     "void *"/*data*/,
    201      1.49  riastrad     "int"/*flag*/,
    202      1.49  riastrad     "int"/*error*/);
    203      1.49  riastrad 
    204      1.49  riastrad SDT_PROBE_DEFINE2(sdt, bdev, psize, entry,
    205      1.49  riastrad     "struct bdevsw *"/*bdevsw*/,
    206      1.49  riastrad     "dev_t"/*dev*/);
    207      1.49  riastrad SDT_PROBE_DEFINE3(sdt, bdev, psize, return,
    208      1.49  riastrad     "struct bdevsw *"/*bdevsw*/,
    209      1.49  riastrad     "dev_t"/*dev*/,
    210      1.49  riastrad     "int"/*psize*/);
    211      1.49  riastrad 
    212      1.49  riastrad SDT_PROBE_DEFINE4(sdt, bdev, discard, entry,
    213      1.49  riastrad     "struct bdevsw *"/*bdevsw*/,
    214      1.49  riastrad     "dev_t"/*dev*/,
    215      1.49  riastrad     "off_t"/*pos*/,
    216      1.49  riastrad     "off_t"/*len*/);
    217      1.49  riastrad SDT_PROBE_DEFINE5(sdt, bdev, discard, return,
    218      1.49  riastrad     "struct bdevsw *"/*bdevsw*/,
    219      1.49  riastrad     "dev_t"/*dev*/,
    220      1.49  riastrad     "off_t"/*pos*/,
    221      1.49  riastrad     "off_t"/*len*/,
    222      1.49  riastrad     "int"/*error*/);
    223      1.49  riastrad 
    224      1.49  riastrad /*
    225      1.49  riastrad  * cdev probes
    226      1.49  riastrad  */
    227      1.49  riastrad SDT_PROBE_DEFINE6(sdt, cdev, open, acquire,
    228      1.49  riastrad     "struct cdevsw *"/*cdevsw*/,
    229      1.49  riastrad     "dev_t"/*dev*/,
    230      1.49  riastrad     "int"/*flag*/,
    231      1.49  riastrad     "int"/*devtype*/,
    232      1.49  riastrad     "int"/*unit*/,
    233      1.49  riastrad     "device_t"/*dv*/);
    234      1.49  riastrad SDT_PROBE_DEFINE4(sdt, cdev, open, entry,
    235      1.49  riastrad     "struct cdevsw *"/*cdevsw*/,
    236      1.49  riastrad     "dev_t"/*dev*/,
    237      1.49  riastrad     "int"/*flag*/,
    238      1.49  riastrad     "int"/*devtype*/);
    239      1.49  riastrad SDT_PROBE_DEFINE5(sdt, cdev, open, return,
    240      1.49  riastrad     "struct cdevsw *"/*cdevsw*/,
    241      1.49  riastrad     "dev_t"/*dev*/,
    242      1.49  riastrad     "int"/*flag*/,
    243      1.49  riastrad     "int"/*devtype*/,
    244      1.49  riastrad     "int"/*error*/);
    245      1.49  riastrad SDT_PROBE_DEFINE6(sdt, cdev, open, release,
    246      1.49  riastrad     "struct cdevsw *"/*cdevsw*/,
    247      1.49  riastrad     "dev_t"/*dev*/,
    248      1.49  riastrad     "int"/*flag*/,
    249      1.49  riastrad     "int"/*devtype*/,
    250      1.49  riastrad     "int"/*unit*/,
    251      1.49  riastrad     "device_t"/*dv*/);
    252      1.49  riastrad 
    253      1.49  riastrad SDT_PROBE_DEFINE4(sdt, cdev, cancel, entry,
    254      1.49  riastrad     "struct cdevsw *"/*cdevsw*/,
    255      1.49  riastrad     "dev_t"/*dev*/,
    256      1.49  riastrad     "int"/*flag*/,
    257      1.49  riastrad     "int"/*devtype*/);
    258      1.49  riastrad SDT_PROBE_DEFINE5(sdt, cdev, cancel, return,
    259      1.49  riastrad     "struct cdevsw *"/*cdevsw*/,
    260      1.49  riastrad     "dev_t"/*dev*/,
    261      1.49  riastrad     "int"/*flag*/,
    262      1.49  riastrad     "int"/*devtype*/,
    263      1.49  riastrad     "int"/*error*/);
    264      1.49  riastrad 
    265      1.49  riastrad SDT_PROBE_DEFINE4(sdt, cdev, close, entry,
    266      1.49  riastrad     "struct cdevsw *"/*cdevsw*/,
    267      1.49  riastrad     "dev_t"/*dev*/,
    268      1.49  riastrad     "int"/*flag*/,
    269      1.49  riastrad     "int"/*devtype*/);
    270      1.49  riastrad SDT_PROBE_DEFINE5(sdt, cdev, close, return,
    271      1.49  riastrad     "struct cdevsw *"/*cdevsw*/,
    272      1.49  riastrad     "dev_t"/*dev*/,
    273      1.49  riastrad     "int"/*flag*/,
    274      1.49  riastrad     "int"/*devtype*/,
    275      1.49  riastrad     "int"/*error*/);
    276      1.49  riastrad 
    277      1.49  riastrad SDT_PROBE_DEFINE4(sdt, cdev, read, entry,
    278      1.49  riastrad     "struct cdevsw *"/*cdevsw*/,
    279      1.49  riastrad     "dev_t"/*dev*/,
    280      1.49  riastrad     "struct uio *"/*uio*/,
    281      1.49  riastrad     "int"/*flag*/);
    282      1.49  riastrad SDT_PROBE_DEFINE5(sdt, cdev, read, return,
    283      1.49  riastrad     "struct cdevsw *"/*cdevsw*/,
    284      1.49  riastrad     "dev_t"/*dev*/,
    285      1.49  riastrad     "struct uio *"/*uio*/,
    286      1.49  riastrad     "int"/*flag*/,
    287      1.49  riastrad     "int"/*error*/);
    288      1.49  riastrad 
    289      1.49  riastrad SDT_PROBE_DEFINE4(sdt, cdev, write, entry,
    290      1.49  riastrad     "struct cdevsw *"/*cdevsw*/,
    291      1.49  riastrad     "dev_t"/*dev*/,
    292      1.49  riastrad     "struct uio *"/*uio*/,
    293      1.49  riastrad     "int"/*flag*/);
    294      1.49  riastrad SDT_PROBE_DEFINE5(sdt, cdev, write, return,
    295      1.49  riastrad     "struct cdevsw *"/*cdevsw*/,
    296      1.49  riastrad     "dev_t"/*dev*/,
    297      1.49  riastrad     "struct uio *"/*uio*/,
    298      1.49  riastrad     "int"/*flag*/,
    299      1.49  riastrad     "int"/*error*/);
    300      1.49  riastrad 
    301      1.49  riastrad SDT_PROBE_DEFINE5(sdt, cdev, ioctl, entry,
    302      1.49  riastrad     "struct cdevsw *"/*cdevsw*/,
    303      1.49  riastrad     "dev_t"/*dev*/,
    304      1.49  riastrad     "unsigned long"/*cmd*/,
    305      1.49  riastrad     "void *"/*data*/,
    306      1.49  riastrad     "int"/*flag*/);
    307      1.49  riastrad SDT_PROBE_DEFINE6(sdt, cdev, ioctl, return,
    308      1.49  riastrad     "struct cdevsw *"/*cdevsw*/,
    309      1.49  riastrad     "dev_t"/*dev*/,
    310      1.49  riastrad     "unsigned long"/*cmd*/,
    311      1.49  riastrad     "void *"/*data*/,
    312      1.49  riastrad     "int"/*flag*/,
    313      1.49  riastrad     "int"/*error*/);
    314      1.49  riastrad 
    315      1.49  riastrad SDT_PROBE_DEFINE4(sdt, cdev, stop, entry,
    316      1.49  riastrad     "struct cdevsw *"/*cdevsw*/,
    317      1.49  riastrad     "dev_t"/*dev*/,
    318      1.49  riastrad     "struct tty *"/*tp*/,
    319      1.49  riastrad     "int"/*flag*/);
    320      1.49  riastrad SDT_PROBE_DEFINE4(sdt, cdev, stop, return,
    321      1.49  riastrad     "struct cdevsw *"/*cdevsw*/,
    322      1.49  riastrad     "dev_t"/*dev*/,
    323      1.49  riastrad     "struct tty *"/*tp*/,
    324      1.49  riastrad     "int"/*flag*/);
    325      1.49  riastrad 
    326      1.49  riastrad SDT_PROBE_DEFINE3(sdt, cdev, poll, entry,
    327      1.49  riastrad     "struct cdevsw *"/*cdevsw*/,
    328      1.49  riastrad     "dev_t"/*dev*/,
    329      1.49  riastrad     "int"/*events*/);
    330      1.49  riastrad SDT_PROBE_DEFINE4(sdt, cdev, poll, return,
    331      1.49  riastrad     "struct cdevsw *"/*cdevsw*/,
    332      1.49  riastrad     "dev_t"/*dev*/,
    333      1.49  riastrad     "int"/*events*/,
    334      1.49  riastrad     "int"/*revents*/);
    335      1.49  riastrad 
    336      1.49  riastrad SDT_PROBE_DEFINE4(sdt, cdev, mmap, entry,
    337      1.49  riastrad     "struct cdevsw *"/*cdevsw*/,
    338      1.49  riastrad     "dev_t"/*dev*/,
    339      1.49  riastrad     "off_t"/*off*/,
    340      1.49  riastrad     "int"/*flag*/);
    341      1.49  riastrad SDT_PROBE_DEFINE5(sdt, cdev, mmap, return,
    342      1.49  riastrad     "struct cdevsw *"/*cdevsw*/,
    343      1.49  riastrad     "dev_t"/*dev*/,
    344      1.49  riastrad     "off_t"/*off*/,
    345      1.49  riastrad     "int"/*flag*/,
    346      1.49  riastrad     "paddr_t"/*mmapcookie*/);
    347      1.49  riastrad 
    348      1.49  riastrad SDT_PROBE_DEFINE3(sdt, cdev, kqfilter, entry,
    349      1.49  riastrad     "struct cdevsw *"/*cdevsw*/,
    350      1.49  riastrad     "dev_t"/*dev*/,
    351      1.49  riastrad     "struct knote *"/*kn*/);
    352      1.49  riastrad SDT_PROBE_DEFINE4(sdt, cdev, kqfilter, return,
    353      1.49  riastrad     "struct cdevsw *"/*cdevsw*/,
    354      1.49  riastrad     "dev_t"/*dev*/,
    355      1.49  riastrad     "struct knote *"/*kn*/,
    356      1.49  riastrad     "int"/*error*/);
    357      1.49  riastrad 
    358      1.49  riastrad SDT_PROBE_DEFINE4(sdt, cdev, discard, entry,
    359      1.49  riastrad     "struct cdevsw *"/*cdevsw*/,
    360      1.49  riastrad     "dev_t"/*dev*/,
    361      1.49  riastrad     "off_t"/*pos*/,
    362      1.49  riastrad     "off_t"/*len*/);
    363      1.49  riastrad SDT_PROBE_DEFINE5(sdt, cdev, discard, return,
    364      1.49  riastrad     "struct cdevsw *"/*cdevsw*/,
    365      1.49  riastrad     "dev_t"/*dev*/,
    366      1.49  riastrad     "off_t"/*pos*/,
    367      1.49  riastrad     "off_t"/*len*/,
    368      1.49  riastrad     "int"/*error*/);
    369      1.49  riastrad 
    370      1.11        ad void
    371      1.11        ad devsw_init(void)
    372      1.11        ad {
    373      1.11        ad 
    374      1.11        ad 	KASSERT(sys_bdevsws < MAXDEVSW - 1);
    375      1.11        ad 	KASSERT(sys_cdevsws < MAXDEVSW - 1);
    376      1.23     pooka 	mutex_init(&device_lock, MUTEX_DEFAULT, IPL_NONE);
    377      1.40  riastrad 
    378      1.40  riastrad 	cv_init(&devsw_cv, "devsw");
    379      1.11        ad }
    380       1.2   gehenna 
    381       1.2   gehenna int
    382      1.24  drochner devsw_attach(const char *devname,
    383      1.24  drochner 	     const struct bdevsw *bdev, devmajor_t *bmajor,
    384      1.24  drochner 	     const struct cdevsw *cdev, devmajor_t *cmajor)
    385       1.2   gehenna {
    386       1.2   gehenna 	struct devsw_conv *conv;
    387       1.2   gehenna 	char *name;
    388       1.2   gehenna 	int error, i;
    389       1.2   gehenna 
    390       1.2   gehenna 	if (devname == NULL || cdev == NULL)
    391      1.45  riastrad 		return EINVAL;
    392       1.2   gehenna 
    393      1.23     pooka 	mutex_enter(&device_lock);
    394      1.11        ad 
    395      1.45  riastrad 	for (i = 0; i < max_devsw_convs; i++) {
    396       1.2   gehenna 		conv = &devsw_conv[i];
    397       1.2   gehenna 		if (conv->d_name == NULL || strcmp(devname, conv->d_name) != 0)
    398       1.2   gehenna 			continue;
    399       1.2   gehenna 
    400  1.49.2.1    martin 		if ((bdev != NULL) && (*bmajor < 0))
    401       1.2   gehenna 			*bmajor = conv->d_bmajor;
    402       1.2   gehenna 		if (*cmajor < 0)
    403       1.2   gehenna 			*cmajor = conv->d_cmajor;
    404       1.2   gehenna 
    405      1.11        ad 		if (*bmajor != conv->d_bmajor || *cmajor != conv->d_cmajor) {
    406      1.11        ad 			error = EINVAL;
    407      1.45  riastrad 			goto out;
    408      1.11        ad 		}
    409      1.11        ad 		if ((*bmajor >= 0 && bdev == NULL) || *cmajor < 0) {
    410      1.11        ad 			error = EINVAL;
    411      1.45  riastrad 			goto out;
    412      1.11        ad 		}
    413       1.2   gehenna 
    414       1.2   gehenna 		if ((*bmajor >= 0 && bdevsw[*bmajor] != NULL) ||
    415      1.11        ad 		    cdevsw[*cmajor] != NULL) {
    416      1.11        ad 			error = EEXIST;
    417      1.45  riastrad 			goto out;
    418      1.11        ad 		}
    419      1.40  riastrad 		break;
    420       1.2   gehenna 	}
    421       1.2   gehenna 
    422      1.40  riastrad 	/*
    423      1.40  riastrad 	 * XXX This should allocate what it needs up front so we never
    424      1.40  riastrad 	 * need to flail around trying to unwind.
    425      1.40  riastrad 	 */
    426      1.14     pooka 	error = bdevsw_attach(bdev, bmajor);
    427      1.45  riastrad 	if (error != 0)
    428      1.45  riastrad 		goto out;
    429      1.14     pooka 	error = cdevsw_attach(cdev, cmajor);
    430       1.2   gehenna 	if (error != 0) {
    431      1.11        ad 		devsw_detach_locked(bdev, NULL);
    432      1.45  riastrad 		goto out;
    433       1.2   gehenna 	}
    434       1.2   gehenna 
    435      1.40  riastrad 	/*
    436      1.40  riastrad 	 * If we already found a conv, we're done.  Otherwise, find an
    437      1.40  riastrad 	 * empty slot or extend the table.
    438      1.40  riastrad 	 */
    439      1.48  riastrad 	if (i < max_devsw_convs) {
    440      1.47  riastrad 		error = 0;
    441      1.45  riastrad 		goto out;
    442      1.47  riastrad 	}
    443      1.40  riastrad 
    444      1.45  riastrad 	for (i = 0; i < max_devsw_convs; i++) {
    445       1.2   gehenna 		if (devsw_conv[i].d_name == NULL)
    446       1.2   gehenna 			break;
    447       1.2   gehenna 	}
    448       1.2   gehenna 	if (i == max_devsw_convs) {
    449       1.2   gehenna 		struct devsw_conv *newptr;
    450      1.33      matt 		int old_convs, new_convs;
    451       1.2   gehenna 
    452      1.33      matt 		old_convs = max_devsw_convs;
    453      1.33      matt 		new_convs = old_convs + 1;
    454       1.2   gehenna 
    455      1.33      matt 		newptr = kmem_zalloc(new_convs * DEVSWCONV_SIZE, KM_NOSLEEP);
    456       1.2   gehenna 		if (newptr == NULL) {
    457      1.11        ad 			devsw_detach_locked(bdev, cdev);
    458      1.11        ad 			error = ENOMEM;
    459      1.45  riastrad 			goto out;
    460       1.2   gehenna 		}
    461      1.33      matt 		newptr[old_convs].d_name = NULL;
    462      1.33      matt 		newptr[old_convs].d_bmajor = -1;
    463      1.33      matt 		newptr[old_convs].d_cmajor = -1;
    464      1.33      matt 		memcpy(newptr, devsw_conv, old_convs * DEVSWCONV_SIZE);
    465       1.2   gehenna 		if (devsw_conv != devsw_conv0)
    466      1.33      matt 			kmem_free(devsw_conv, old_convs * DEVSWCONV_SIZE);
    467       1.2   gehenna 		devsw_conv = newptr;
    468      1.33      matt 		max_devsw_convs = new_convs;
    469       1.2   gehenna 	}
    470       1.2   gehenna 
    471      1.38  christos 	name = kmem_strdupsize(devname, NULL, KM_NOSLEEP);
    472       1.2   gehenna 	if (name == NULL) {
    473      1.11        ad 		devsw_detach_locked(bdev, cdev);
    474      1.25     enami 		error = ENOMEM;
    475      1.45  riastrad 		goto out;
    476       1.2   gehenna 	}
    477       1.2   gehenna 
    478       1.2   gehenna 	devsw_conv[i].d_name = name;
    479       1.2   gehenna 	devsw_conv[i].d_bmajor = *bmajor;
    480       1.2   gehenna 	devsw_conv[i].d_cmajor = *cmajor;
    481      1.45  riastrad 	error = 0;
    482      1.45  riastrad out:
    483      1.23     pooka 	mutex_exit(&device_lock);
    484      1.45  riastrad 	return error;
    485       1.2   gehenna }
    486       1.2   gehenna 
    487       1.2   gehenna static int
    488      1.24  drochner bdevsw_attach(const struct bdevsw *devsw, devmajor_t *devmajor)
    489       1.2   gehenna {
    490      1.40  riastrad 	const struct bdevsw **newbdevsw = NULL;
    491      1.40  riastrad 	struct devswref *newbdevswref = NULL;
    492      1.40  riastrad 	struct localcount *lc;
    493      1.24  drochner 	devmajor_t bmajor;
    494      1.24  drochner 	int i;
    495       1.2   gehenna 
    496      1.23     pooka 	KASSERT(mutex_owned(&device_lock));
    497      1.11        ad 
    498       1.2   gehenna 	if (devsw == NULL)
    499      1.45  riastrad 		return 0;
    500       1.2   gehenna 
    501       1.2   gehenna 	if (*devmajor < 0) {
    502      1.45  riastrad 		for (bmajor = sys_bdevsws; bmajor < max_bdevsws; bmajor++) {
    503       1.2   gehenna 			if (bdevsw[bmajor] != NULL)
    504       1.2   gehenna 				continue;
    505      1.45  riastrad 			for (i = 0; i < max_devsw_convs; i++) {
    506       1.2   gehenna 				if (devsw_conv[i].d_bmajor == bmajor)
    507       1.2   gehenna 					break;
    508       1.2   gehenna 			}
    509       1.2   gehenna 			if (i != max_devsw_convs)
    510       1.2   gehenna 				continue;
    511       1.2   gehenna 			break;
    512       1.2   gehenna 		}
    513       1.3   gehenna 		*devmajor = bmajor;
    514       1.2   gehenna 	}
    515      1.11        ad 
    516       1.2   gehenna 	if (*devmajor >= MAXDEVSW) {
    517      1.45  riastrad 		printf("%s: block majors exhausted\n", __func__);
    518      1.45  riastrad 		return ENOMEM;
    519       1.2   gehenna 	}
    520       1.2   gehenna 
    521      1.40  riastrad 	if (bdevswref == NULL) {
    522      1.40  riastrad 		newbdevswref = kmem_zalloc(MAXDEVSW * sizeof(newbdevswref[0]),
    523      1.40  riastrad 		    KM_NOSLEEP);
    524      1.40  riastrad 		if (newbdevswref == NULL)
    525      1.40  riastrad 			return ENOMEM;
    526      1.40  riastrad 		atomic_store_release(&bdevswref, newbdevswref);
    527      1.40  riastrad 	}
    528      1.40  riastrad 
    529       1.2   gehenna 	if (*devmajor >= max_bdevsws) {
    530      1.11        ad 		KASSERT(bdevsw == bdevsw0);
    531      1.40  riastrad 		newbdevsw = kmem_zalloc(MAXDEVSW * sizeof(newbdevsw[0]),
    532      1.40  riastrad 		    KM_NOSLEEP);
    533      1.40  riastrad 		if (newbdevsw == NULL)
    534      1.40  riastrad 			return ENOMEM;
    535      1.40  riastrad 		memcpy(newbdevsw, bdevsw, max_bdevsws * sizeof(bdevsw[0]));
    536      1.40  riastrad 		atomic_store_release(&bdevsw, newbdevsw);
    537      1.40  riastrad 		atomic_store_release(&max_bdevsws, MAXDEVSW);
    538       1.2   gehenna 	}
    539       1.2   gehenna 
    540       1.2   gehenna 	if (bdevsw[*devmajor] != NULL)
    541      1.45  riastrad 		return EEXIST;
    542       1.2   gehenna 
    543      1.40  riastrad 	KASSERT(bdevswref[*devmajor].dr_lc == NULL);
    544      1.40  riastrad 	lc = kmem_zalloc(sizeof(*lc), KM_SLEEP);
    545      1.40  riastrad 	localcount_init(lc);
    546      1.40  riastrad 	bdevswref[*devmajor].dr_lc = lc;
    547      1.40  riastrad 
    548      1.40  riastrad 	atomic_store_release(&bdevsw[*devmajor], devsw);
    549       1.2   gehenna 
    550      1.45  riastrad 	return 0;
    551       1.2   gehenna }
    552       1.2   gehenna 
    553       1.2   gehenna static int
    554      1.24  drochner cdevsw_attach(const struct cdevsw *devsw, devmajor_t *devmajor)
    555       1.2   gehenna {
    556      1.40  riastrad 	const struct cdevsw **newcdevsw = NULL;
    557      1.40  riastrad 	struct devswref *newcdevswref = NULL;
    558      1.40  riastrad 	struct localcount *lc;
    559      1.24  drochner 	devmajor_t cmajor;
    560      1.24  drochner 	int i;
    561       1.2   gehenna 
    562      1.23     pooka 	KASSERT(mutex_owned(&device_lock));
    563      1.11        ad 
    564       1.2   gehenna 	if (*devmajor < 0) {
    565      1.45  riastrad 		for (cmajor = sys_cdevsws; cmajor < max_cdevsws; cmajor++) {
    566       1.2   gehenna 			if (cdevsw[cmajor] != NULL)
    567       1.2   gehenna 				continue;
    568      1.45  riastrad 			for (i = 0; i < max_devsw_convs; i++) {
    569       1.2   gehenna 				if (devsw_conv[i].d_cmajor == cmajor)
    570       1.2   gehenna 					break;
    571       1.2   gehenna 			}
    572       1.2   gehenna 			if (i != max_devsw_convs)
    573       1.2   gehenna 				continue;
    574       1.2   gehenna 			break;
    575       1.2   gehenna 		}
    576       1.3   gehenna 		*devmajor = cmajor;
    577       1.2   gehenna 	}
    578      1.11        ad 
    579       1.2   gehenna 	if (*devmajor >= MAXDEVSW) {
    580      1.45  riastrad 		printf("%s: character majors exhausted\n", __func__);
    581      1.45  riastrad 		return ENOMEM;
    582       1.2   gehenna 	}
    583       1.2   gehenna 
    584      1.40  riastrad 	if (cdevswref == NULL) {
    585      1.40  riastrad 		newcdevswref = kmem_zalloc(MAXDEVSW * sizeof(newcdevswref[0]),
    586      1.40  riastrad 		    KM_NOSLEEP);
    587      1.40  riastrad 		if (newcdevswref == NULL)
    588      1.40  riastrad 			return ENOMEM;
    589      1.40  riastrad 		atomic_store_release(&cdevswref, newcdevswref);
    590      1.40  riastrad 	}
    591      1.40  riastrad 
    592       1.2   gehenna 	if (*devmajor >= max_cdevsws) {
    593      1.11        ad 		KASSERT(cdevsw == cdevsw0);
    594      1.40  riastrad 		newcdevsw = kmem_zalloc(MAXDEVSW * sizeof(newcdevsw[0]),
    595      1.40  riastrad 		    KM_NOSLEEP);
    596      1.40  riastrad 		if (newcdevsw == NULL)
    597      1.40  riastrad 			return ENOMEM;
    598      1.40  riastrad 		memcpy(newcdevsw, cdevsw, max_cdevsws * sizeof(cdevsw[0]));
    599      1.40  riastrad 		atomic_store_release(&cdevsw, newcdevsw);
    600      1.40  riastrad 		atomic_store_release(&max_cdevsws, MAXDEVSW);
    601       1.2   gehenna 	}
    602       1.2   gehenna 
    603       1.2   gehenna 	if (cdevsw[*devmajor] != NULL)
    604      1.45  riastrad 		return EEXIST;
    605       1.2   gehenna 
    606      1.40  riastrad 	KASSERT(cdevswref[*devmajor].dr_lc == NULL);
    607      1.40  riastrad 	lc = kmem_zalloc(sizeof(*lc), KM_SLEEP);
    608      1.40  riastrad 	localcount_init(lc);
    609      1.40  riastrad 	cdevswref[*devmajor].dr_lc = lc;
    610      1.40  riastrad 
    611      1.40  riastrad 	atomic_store_release(&cdevsw[*devmajor], devsw);
    612       1.2   gehenna 
    613      1.45  riastrad 	return 0;
    614       1.2   gehenna }
    615       1.2   gehenna 
    616      1.11        ad static void
    617      1.11        ad devsw_detach_locked(const struct bdevsw *bdev, const struct cdevsw *cdev)
    618       1.2   gehenna {
    619      1.46  riastrad 	int bi, ci = -1/*XXXGCC*/, di;
    620      1.46  riastrad 	struct cfdriver *cd;
    621      1.46  riastrad 	device_t dv;
    622       1.2   gehenna 
    623      1.23     pooka 	KASSERT(mutex_owned(&device_lock));
    624      1.11        ad 
    625      1.46  riastrad 	/*
    626      1.46  riastrad 	 * If this is wired to an autoconf device, make sure the device
    627      1.46  riastrad 	 * has no more instances.  No locking here because under
    628      1.46  riastrad 	 * correct use of devsw_detach, none of this state can change
    629      1.46  riastrad 	 * at this point.
    630      1.46  riastrad 	 */
    631      1.46  riastrad 	if (cdev != NULL && (cd = cdev->d_cfdriver) != NULL) {
    632      1.46  riastrad 		for (di = 0; di < cd->cd_ndevs; di++) {
    633      1.46  riastrad 			KASSERTMSG((dv = cd->cd_devs[di]) == NULL,
    634      1.46  riastrad 			    "detaching character device driver %s"
    635      1.46  riastrad 			    " still has attached unit %s",
    636      1.46  riastrad 			    cd->cd_name, device_xname(dv));
    637      1.46  riastrad 		}
    638      1.46  riastrad 	}
    639      1.46  riastrad 	if (bdev != NULL && (cd = bdev->d_cfdriver) != NULL) {
    640      1.46  riastrad 		for (di = 0; di < cd->cd_ndevs; di++) {
    641      1.46  riastrad 			KASSERTMSG((dv = cd->cd_devs[di]) == NULL,
    642      1.46  riastrad 			    "detaching block device driver %s"
    643      1.46  riastrad 			    " still has attached unit %s",
    644      1.46  riastrad 			    cd->cd_name, device_xname(dv));
    645      1.46  riastrad 		}
    646      1.46  riastrad 	}
    647      1.46  riastrad 
    648      1.40  riastrad 	/* Prevent new references.  */
    649       1.2   gehenna 	if (bdev != NULL) {
    650      1.40  riastrad 		for (bi = 0; bi < max_bdevsws; bi++) {
    651      1.40  riastrad 			if (bdevsw[bi] != bdev)
    652       1.2   gehenna 				continue;
    653      1.40  riastrad 			atomic_store_relaxed(&bdevsw[bi], NULL);
    654       1.2   gehenna 			break;
    655       1.2   gehenna 		}
    656      1.40  riastrad 		KASSERT(bi < max_bdevsws);
    657       1.2   gehenna 	}
    658       1.2   gehenna 	if (cdev != NULL) {
    659      1.40  riastrad 		for (ci = 0; ci < max_cdevsws; ci++) {
    660      1.40  riastrad 			if (cdevsw[ci] != cdev)
    661       1.2   gehenna 				continue;
    662      1.40  riastrad 			atomic_store_relaxed(&cdevsw[ci], NULL);
    663       1.2   gehenna 			break;
    664       1.2   gehenna 		}
    665      1.40  riastrad 		KASSERT(ci < max_cdevsws);
    666      1.40  riastrad 	}
    667      1.40  riastrad 
    668      1.40  riastrad 	if (bdev == NULL && cdev == NULL) /* XXX possible? */
    669      1.40  riastrad 		return;
    670      1.40  riastrad 
    671      1.40  riastrad 	/*
    672      1.40  riastrad 	 * Wait for all bdevsw_lookup_acquire, cdevsw_lookup_acquire
    673      1.40  riastrad 	 * calls to notice that the devsw is gone.
    674      1.40  riastrad 	 *
    675      1.40  riastrad 	 * XXX Despite the use of the pserialize_read_enter/exit API
    676      1.40  riastrad 	 * elsewhere in this file, we use xc_barrier here instead of
    677      1.40  riastrad 	 * pserialize_perform -- because devsw_init is too early for
    678      1.40  riastrad 	 * pserialize_create.  Either pserialize_create should be made
    679      1.40  riastrad 	 * to work earlier, or it should be nixed altogether.  Until
    680      1.40  riastrad 	 * that is fixed, xc_barrier will serve the same purpose.
    681      1.40  riastrad 	 */
    682      1.40  riastrad 	xc_barrier(0);
    683      1.40  riastrad 
    684      1.40  riastrad 	/*
    685      1.40  riastrad 	 * Wait for all references to drain.  It is the caller's
    686      1.40  riastrad 	 * responsibility to ensure that at this point, there are no
    687      1.40  riastrad 	 * extant open instances and all new d_open calls will fail.
    688      1.40  riastrad 	 *
    689      1.40  riastrad 	 * Note that localcount_drain may release and reacquire
    690      1.40  riastrad 	 * device_lock.
    691      1.40  riastrad 	 */
    692      1.40  riastrad 	if (bdev != NULL) {
    693      1.40  riastrad 		localcount_drain(bdevswref[bi].dr_lc,
    694      1.40  riastrad 		    &devsw_cv, &device_lock);
    695      1.40  riastrad 		localcount_fini(bdevswref[bi].dr_lc);
    696      1.40  riastrad 		kmem_free(bdevswref[bi].dr_lc, sizeof(*bdevswref[bi].dr_lc));
    697      1.40  riastrad 		bdevswref[bi].dr_lc = NULL;
    698      1.40  riastrad 	}
    699      1.40  riastrad 	if (cdev != NULL) {
    700      1.40  riastrad 		localcount_drain(cdevswref[ci].dr_lc,
    701      1.40  riastrad 		    &devsw_cv, &device_lock);
    702      1.40  riastrad 		localcount_fini(cdevswref[ci].dr_lc);
    703      1.40  riastrad 		kmem_free(cdevswref[ci].dr_lc, sizeof(*cdevswref[ci].dr_lc));
    704      1.40  riastrad 		cdevswref[ci].dr_lc = NULL;
    705       1.2   gehenna 	}
    706       1.2   gehenna }
    707       1.2   gehenna 
    708      1.39  riastrad void
    709      1.11        ad devsw_detach(const struct bdevsw *bdev, const struct cdevsw *cdev)
    710      1.11        ad {
    711      1.11        ad 
    712      1.23     pooka 	mutex_enter(&device_lock);
    713      1.11        ad 	devsw_detach_locked(bdev, cdev);
    714      1.23     pooka 	mutex_exit(&device_lock);
    715      1.11        ad }
    716      1.11        ad 
    717      1.11        ad /*
    718      1.11        ad  * Look up a block device by number.
    719      1.11        ad  *
    720      1.11        ad  * => Caller must ensure that the device is attached.
    721      1.11        ad  */
    722       1.2   gehenna const struct bdevsw *
    723       1.2   gehenna bdevsw_lookup(dev_t dev)
    724       1.2   gehenna {
    725      1.24  drochner 	devmajor_t bmajor;
    726       1.2   gehenna 
    727       1.2   gehenna 	if (dev == NODEV)
    728      1.45  riastrad 		return NULL;
    729       1.2   gehenna 	bmajor = major(dev);
    730      1.40  riastrad 	if (bmajor < 0 || bmajor >= atomic_load_relaxed(&max_bdevsws))
    731      1.45  riastrad 		return NULL;
    732       1.2   gehenna 
    733      1.40  riastrad 	return atomic_load_consume(&bdevsw)[bmajor];
    734      1.40  riastrad }
    735      1.40  riastrad 
    736      1.40  riastrad static const struct bdevsw *
    737      1.40  riastrad bdevsw_lookup_acquire(dev_t dev, struct localcount **lcp)
    738      1.40  riastrad {
    739      1.40  riastrad 	devmajor_t bmajor;
    740      1.40  riastrad 	const struct bdevsw *bdev = NULL, *const *curbdevsw;
    741      1.40  riastrad 	struct devswref *curbdevswref;
    742      1.40  riastrad 	int s;
    743      1.40  riastrad 
    744      1.40  riastrad 	if (dev == NODEV)
    745      1.40  riastrad 		return NULL;
    746      1.40  riastrad 	bmajor = major(dev);
    747      1.40  riastrad 	if (bmajor < 0)
    748      1.40  riastrad 		return NULL;
    749      1.40  riastrad 
    750      1.40  riastrad 	s = pserialize_read_enter();
    751      1.40  riastrad 
    752      1.40  riastrad 	/*
    753      1.40  riastrad 	 * max_bdevsws never goes down, so it is safe to rely on this
    754      1.40  riastrad 	 * condition without any locking for the array access below.
    755      1.40  riastrad 	 * Test sys_bdevsws first so we can avoid the memory barrier in
    756      1.40  riastrad 	 * that case.
    757      1.40  riastrad 	 */
    758      1.40  riastrad 	if (bmajor >= sys_bdevsws &&
    759      1.40  riastrad 	    bmajor >= atomic_load_acquire(&max_bdevsws))
    760      1.40  riastrad 		goto out;
    761      1.40  riastrad 	curbdevsw = atomic_load_consume(&bdevsw);
    762      1.40  riastrad 	if ((bdev = atomic_load_consume(&curbdevsw[bmajor])) == NULL)
    763      1.40  riastrad 		goto out;
    764      1.40  riastrad 
    765      1.40  riastrad 	curbdevswref = atomic_load_consume(&bdevswref);
    766      1.40  riastrad 	if (curbdevswref == NULL) {
    767      1.40  riastrad 		*lcp = NULL;
    768      1.40  riastrad 	} else if ((*lcp = curbdevswref[bmajor].dr_lc) != NULL) {
    769      1.40  riastrad 		localcount_acquire(*lcp);
    770      1.40  riastrad 	}
    771      1.40  riastrad out:
    772      1.40  riastrad 	pserialize_read_exit(s);
    773      1.40  riastrad 	return bdev;
    774      1.40  riastrad }
    775      1.40  riastrad 
    776      1.40  riastrad static void
    777      1.40  riastrad bdevsw_release(const struct bdevsw *bdev, struct localcount *lc)
    778      1.40  riastrad {
    779      1.40  riastrad 
    780      1.40  riastrad 	if (lc == NULL)
    781      1.40  riastrad 		return;
    782      1.40  riastrad 	localcount_release(lc, &devsw_cv, &device_lock);
    783       1.2   gehenna }
    784       1.2   gehenna 
    785      1.11        ad /*
    786      1.11        ad  * Look up a character device by number.
    787      1.11        ad  *
    788      1.11        ad  * => Caller must ensure that the device is attached.
    789      1.11        ad  */
    790       1.2   gehenna const struct cdevsw *
    791       1.2   gehenna cdevsw_lookup(dev_t dev)
    792       1.2   gehenna {
    793      1.24  drochner 	devmajor_t cmajor;
    794       1.2   gehenna 
    795       1.2   gehenna 	if (dev == NODEV)
    796      1.45  riastrad 		return NULL;
    797       1.2   gehenna 	cmajor = major(dev);
    798      1.40  riastrad 	if (cmajor < 0 || cmajor >= atomic_load_relaxed(&max_cdevsws))
    799      1.45  riastrad 		return NULL;
    800       1.2   gehenna 
    801      1.40  riastrad 	return atomic_load_consume(&cdevsw)[cmajor];
    802      1.40  riastrad }
    803      1.40  riastrad 
    804      1.40  riastrad static const struct cdevsw *
    805      1.40  riastrad cdevsw_lookup_acquire(dev_t dev, struct localcount **lcp)
    806      1.40  riastrad {
    807      1.40  riastrad 	devmajor_t cmajor;
    808      1.40  riastrad 	const struct cdevsw *cdev = NULL, *const *curcdevsw;
    809      1.40  riastrad 	struct devswref *curcdevswref;
    810      1.40  riastrad 	int s;
    811      1.40  riastrad 
    812      1.40  riastrad 	if (dev == NODEV)
    813      1.40  riastrad 		return NULL;
    814      1.40  riastrad 	cmajor = major(dev);
    815      1.40  riastrad 	if (cmajor < 0)
    816      1.40  riastrad 		return NULL;
    817      1.40  riastrad 
    818      1.40  riastrad 	s = pserialize_read_enter();
    819      1.40  riastrad 
    820      1.40  riastrad 	/*
    821      1.40  riastrad 	 * max_cdevsws never goes down, so it is safe to rely on this
    822      1.40  riastrad 	 * condition without any locking for the array access below.
    823      1.40  riastrad 	 * Test sys_cdevsws first so we can avoid the memory barrier in
    824      1.40  riastrad 	 * that case.
    825      1.40  riastrad 	 */
    826      1.40  riastrad 	if (cmajor >= sys_cdevsws &&
    827      1.40  riastrad 	    cmajor >= atomic_load_acquire(&max_cdevsws))
    828      1.40  riastrad 		goto out;
    829      1.40  riastrad 	curcdevsw = atomic_load_consume(&cdevsw);
    830      1.40  riastrad 	if ((cdev = atomic_load_consume(&curcdevsw[cmajor])) == NULL)
    831      1.40  riastrad 		goto out;
    832      1.40  riastrad 
    833      1.40  riastrad 	curcdevswref = atomic_load_consume(&cdevswref);
    834      1.40  riastrad 	if (curcdevswref == NULL) {
    835      1.40  riastrad 		*lcp = NULL;
    836      1.40  riastrad 	} else if ((*lcp = curcdevswref[cmajor].dr_lc) != NULL) {
    837      1.40  riastrad 		localcount_acquire(*lcp);
    838      1.40  riastrad 	}
    839      1.40  riastrad out:
    840      1.40  riastrad 	pserialize_read_exit(s);
    841      1.40  riastrad 	return cdev;
    842      1.40  riastrad }
    843      1.40  riastrad 
    844      1.40  riastrad static void
    845      1.40  riastrad cdevsw_release(const struct cdevsw *cdev, struct localcount *lc)
    846      1.40  riastrad {
    847      1.40  riastrad 
    848      1.40  riastrad 	if (lc == NULL)
    849      1.40  riastrad 		return;
    850      1.40  riastrad 	localcount_release(lc, &devsw_cv, &device_lock);
    851       1.2   gehenna }
    852       1.2   gehenna 
    853      1.11        ad /*
    854      1.11        ad  * Look up a block device by reference to its operations set.
    855      1.11        ad  *
    856      1.11        ad  * => Caller must ensure that the device is not detached, and therefore
    857      1.11        ad  *    that the returned major is still valid when dereferenced.
    858      1.11        ad  */
    859      1.24  drochner devmajor_t
    860       1.2   gehenna bdevsw_lookup_major(const struct bdevsw *bdev)
    861       1.2   gehenna {
    862      1.40  riastrad 	const struct bdevsw *const *curbdevsw;
    863      1.40  riastrad 	devmajor_t bmajor, bmax;
    864       1.2   gehenna 
    865      1.40  riastrad 	bmax = atomic_load_acquire(&max_bdevsws);
    866      1.40  riastrad 	curbdevsw = atomic_load_consume(&bdevsw);
    867      1.40  riastrad 	for (bmajor = 0; bmajor < bmax; bmajor++) {
    868      1.40  riastrad 		if (atomic_load_relaxed(&curbdevsw[bmajor]) == bdev)
    869      1.45  riastrad 			return bmajor;
    870       1.2   gehenna 	}
    871       1.2   gehenna 
    872      1.45  riastrad 	return NODEVMAJOR;
    873       1.2   gehenna }
    874       1.2   gehenna 
    875      1.11        ad /*
    876      1.11        ad  * Look up a character device by reference to its operations set.
    877      1.11        ad  *
    878      1.11        ad  * => Caller must ensure that the device is not detached, and therefore
    879      1.11        ad  *    that the returned major is still valid when dereferenced.
    880      1.11        ad  */
    881      1.24  drochner devmajor_t
    882       1.2   gehenna cdevsw_lookup_major(const struct cdevsw *cdev)
    883       1.2   gehenna {
    884      1.40  riastrad 	const struct cdevsw *const *curcdevsw;
    885      1.40  riastrad 	devmajor_t cmajor, cmax;
    886       1.2   gehenna 
    887      1.40  riastrad 	cmax = atomic_load_acquire(&max_cdevsws);
    888      1.40  riastrad 	curcdevsw = atomic_load_consume(&cdevsw);
    889      1.40  riastrad 	for (cmajor = 0; cmajor < cmax; cmajor++) {
    890      1.40  riastrad 		if (atomic_load_relaxed(&curcdevsw[cmajor]) == cdev)
    891      1.45  riastrad 			return cmajor;
    892       1.2   gehenna 	}
    893       1.2   gehenna 
    894      1.45  riastrad 	return NODEVMAJOR;
    895       1.2   gehenna }
    896       1.2   gehenna 
    897       1.2   gehenna /*
    898       1.2   gehenna  * Convert from block major number to name.
    899      1.11        ad  *
    900      1.11        ad  * => Caller must ensure that the device is not detached, and therefore
    901      1.11        ad  *    that the name pointer is still valid when dereferenced.
    902       1.2   gehenna  */
    903       1.2   gehenna const char *
    904      1.24  drochner devsw_blk2name(devmajor_t bmajor)
    905       1.2   gehenna {
    906      1.11        ad 	const char *name;
    907      1.24  drochner 	devmajor_t cmajor;
    908      1.24  drochner 	int i;
    909       1.2   gehenna 
    910      1.11        ad 	name = NULL;
    911      1.11        ad 	cmajor = -1;
    912      1.11        ad 
    913      1.23     pooka 	mutex_enter(&device_lock);
    914      1.11        ad 	if (bmajor < 0 || bmajor >= max_bdevsws || bdevsw[bmajor] == NULL) {
    915      1.23     pooka 		mutex_exit(&device_lock);
    916      1.45  riastrad 		return NULL;
    917       1.2   gehenna 	}
    918      1.45  riastrad 	for (i = 0; i < max_devsw_convs; i++) {
    919      1.11        ad 		if (devsw_conv[i].d_bmajor == bmajor) {
    920      1.11        ad 			cmajor = devsw_conv[i].d_cmajor;
    921      1.11        ad 			break;
    922      1.11        ad 		}
    923      1.11        ad 	}
    924      1.11        ad 	if (cmajor >= 0 && cmajor < max_cdevsws && cdevsw[cmajor] != NULL)
    925      1.11        ad 		name = devsw_conv[i].d_name;
    926      1.23     pooka 	mutex_exit(&device_lock);
    927       1.2   gehenna 
    928      1.45  riastrad 	return name;
    929       1.2   gehenna }
    930       1.2   gehenna 
    931       1.2   gehenna /*
    932      1.26      haad  * Convert char major number to device driver name.
    933      1.26      haad  */
    934      1.27      yamt const char *
    935      1.26      haad cdevsw_getname(devmajor_t major)
    936      1.26      haad {
    937      1.26      haad 	const char *name;
    938      1.26      haad 	int i;
    939      1.26      haad 
    940      1.26      haad 	name = NULL;
    941      1.26      haad 
    942      1.26      haad 	if (major < 0)
    943      1.45  riastrad 		return NULL;
    944      1.45  riastrad 
    945      1.26      haad 	mutex_enter(&device_lock);
    946      1.45  riastrad 	for (i = 0; i < max_devsw_convs; i++) {
    947      1.26      haad 		if (devsw_conv[i].d_cmajor == major) {
    948      1.26      haad 			name = devsw_conv[i].d_name;
    949      1.26      haad 			break;
    950      1.26      haad 		}
    951      1.26      haad 	}
    952      1.26      haad 	mutex_exit(&device_lock);
    953      1.45  riastrad 	return name;
    954      1.26      haad }
    955      1.26      haad 
    956      1.26      haad /*
    957      1.26      haad  * Convert block major number to device driver name.
    958      1.26      haad  */
    959      1.27      yamt const char *
    960      1.26      haad bdevsw_getname(devmajor_t major)
    961      1.26      haad {
    962      1.26      haad 	const char *name;
    963      1.26      haad 	int i;
    964      1.26      haad 
    965      1.26      haad 	name = NULL;
    966      1.26      haad 
    967      1.26      haad 	if (major < 0)
    968      1.45  riastrad 		return NULL;
    969      1.45  riastrad 
    970      1.26      haad 	mutex_enter(&device_lock);
    971      1.45  riastrad 	for (i = 0; i < max_devsw_convs; i++) {
    972      1.26      haad 		if (devsw_conv[i].d_bmajor == major) {
    973      1.26      haad 			name = devsw_conv[i].d_name;
    974      1.26      haad 			break;
    975      1.26      haad 		}
    976      1.26      haad 	}
    977      1.26      haad 	mutex_exit(&device_lock);
    978      1.45  riastrad 	return name;
    979      1.26      haad }
    980      1.26      haad 
    981      1.26      haad /*
    982       1.2   gehenna  * Convert from device name to block major number.
    983      1.11        ad  *
    984      1.11        ad  * => Caller must ensure that the device is not detached, and therefore
    985      1.11        ad  *    that the major number is still valid when dereferenced.
    986       1.2   gehenna  */
    987      1.24  drochner devmajor_t
    988       1.2   gehenna devsw_name2blk(const char *name, char *devname, size_t devnamelen)
    989       1.2   gehenna {
    990       1.2   gehenna 	struct devsw_conv *conv;
    991      1.24  drochner 	devmajor_t bmajor;
    992      1.24  drochner 	int i;
    993       1.2   gehenna 
    994       1.2   gehenna 	if (name == NULL)
    995      1.45  riastrad 		return NODEVMAJOR;
    996       1.2   gehenna 
    997      1.23     pooka 	mutex_enter(&device_lock);
    998      1.45  riastrad 	for (i = 0; i < max_devsw_convs; i++) {
    999       1.5       mrg 		size_t len;
   1000       1.5       mrg 
   1001       1.2   gehenna 		conv = &devsw_conv[i];
   1002       1.2   gehenna 		if (conv->d_name == NULL)
   1003       1.2   gehenna 			continue;
   1004       1.5       mrg 		len = strlen(conv->d_name);
   1005       1.5       mrg 		if (strncmp(conv->d_name, name, len) != 0)
   1006       1.5       mrg 			continue;
   1007      1.45  riastrad 		if (name[len] != '\0' && !isdigit((unsigned char)name[len]))
   1008       1.2   gehenna 			continue;
   1009       1.2   gehenna 		bmajor = conv->d_bmajor;
   1010       1.2   gehenna 		if (bmajor < 0 || bmajor >= max_bdevsws ||
   1011       1.2   gehenna 		    bdevsw[bmajor] == NULL)
   1012       1.5       mrg 			break;
   1013       1.2   gehenna 		if (devname != NULL) {
   1014       1.2   gehenna #ifdef DEVSW_DEBUG
   1015       1.2   gehenna 			if (strlen(conv->d_name) >= devnamelen)
   1016      1.45  riastrad 				printf("%s: too short buffer\n", __func__);
   1017       1.2   gehenna #endif /* DEVSW_DEBUG */
   1018       1.4   tsutsui 			strncpy(devname, conv->d_name, devnamelen);
   1019       1.2   gehenna 			devname[devnamelen - 1] = '\0';
   1020       1.2   gehenna 		}
   1021      1.23     pooka 		mutex_exit(&device_lock);
   1022      1.45  riastrad 		return bmajor;
   1023       1.2   gehenna 	}
   1024       1.2   gehenna 
   1025      1.23     pooka 	mutex_exit(&device_lock);
   1026      1.45  riastrad 	return NODEVMAJOR;
   1027       1.2   gehenna }
   1028       1.2   gehenna 
   1029       1.2   gehenna /*
   1030      1.16    plunky  * Convert from device name to char major number.
   1031      1.16    plunky  *
   1032      1.16    plunky  * => Caller must ensure that the device is not detached, and therefore
   1033      1.16    plunky  *    that the major number is still valid when dereferenced.
   1034      1.16    plunky  */
   1035      1.24  drochner devmajor_t
   1036      1.16    plunky devsw_name2chr(const char *name, char *devname, size_t devnamelen)
   1037      1.16    plunky {
   1038      1.16    plunky 	struct devsw_conv *conv;
   1039      1.24  drochner 	devmajor_t cmajor;
   1040      1.24  drochner 	int i;
   1041      1.16    plunky 
   1042      1.16    plunky 	if (name == NULL)
   1043      1.45  riastrad 		return NODEVMAJOR;
   1044      1.16    plunky 
   1045      1.23     pooka 	mutex_enter(&device_lock);
   1046      1.45  riastrad 	for (i = 0; i < max_devsw_convs; i++) {
   1047      1.16    plunky 		size_t len;
   1048      1.16    plunky 
   1049      1.16    plunky 		conv = &devsw_conv[i];
   1050      1.16    plunky 		if (conv->d_name == NULL)
   1051      1.16    plunky 			continue;
   1052      1.16    plunky 		len = strlen(conv->d_name);
   1053      1.16    plunky 		if (strncmp(conv->d_name, name, len) != 0)
   1054      1.16    plunky 			continue;
   1055      1.45  riastrad 		if (name[len] != '\0' && !isdigit((unsigned char)name[len]))
   1056      1.16    plunky 			continue;
   1057      1.16    plunky 		cmajor = conv->d_cmajor;
   1058      1.16    plunky 		if (cmajor < 0 || cmajor >= max_cdevsws ||
   1059      1.16    plunky 		    cdevsw[cmajor] == NULL)
   1060      1.16    plunky 			break;
   1061      1.16    plunky 		if (devname != NULL) {
   1062      1.16    plunky #ifdef DEVSW_DEBUG
   1063      1.16    plunky 			if (strlen(conv->d_name) >= devnamelen)
   1064      1.37  pgoyette 				printf("%s: too short buffer", __func__);
   1065      1.16    plunky #endif /* DEVSW_DEBUG */
   1066      1.16    plunky 			strncpy(devname, conv->d_name, devnamelen);
   1067      1.16    plunky 			devname[devnamelen - 1] = '\0';
   1068      1.16    plunky 		}
   1069      1.23     pooka 		mutex_exit(&device_lock);
   1070      1.45  riastrad 		return cmajor;
   1071      1.16    plunky 	}
   1072      1.16    plunky 
   1073      1.23     pooka 	mutex_exit(&device_lock);
   1074      1.45  riastrad 	return NODEVMAJOR;
   1075      1.16    plunky }
   1076      1.16    plunky 
   1077      1.16    plunky /*
   1078       1.2   gehenna  * Convert from character dev_t to block dev_t.
   1079      1.11        ad  *
   1080      1.11        ad  * => Caller must ensure that the device is not detached, and therefore
   1081      1.11        ad  *    that the major number is still valid when dereferenced.
   1082       1.2   gehenna  */
   1083       1.2   gehenna dev_t
   1084       1.2   gehenna devsw_chr2blk(dev_t cdev)
   1085       1.2   gehenna {
   1086      1.24  drochner 	devmajor_t bmajor, cmajor;
   1087      1.24  drochner 	int i;
   1088      1.11        ad 	dev_t rv;
   1089       1.2   gehenna 
   1090       1.2   gehenna 	cmajor = major(cdev);
   1091      1.24  drochner 	bmajor = NODEVMAJOR;
   1092      1.11        ad 	rv = NODEV;
   1093       1.2   gehenna 
   1094      1.23     pooka 	mutex_enter(&device_lock);
   1095      1.11        ad 	if (cmajor < 0 || cmajor >= max_cdevsws || cdevsw[cmajor] == NULL) {
   1096      1.23     pooka 		mutex_exit(&device_lock);
   1097      1.45  riastrad 		return NODEV;
   1098      1.11        ad 	}
   1099      1.45  riastrad 	for (i = 0; i < max_devsw_convs; i++) {
   1100      1.11        ad 		if (devsw_conv[i].d_cmajor == cmajor) {
   1101      1.11        ad 			bmajor = devsw_conv[i].d_bmajor;
   1102      1.11        ad 			break;
   1103      1.11        ad 		}
   1104       1.2   gehenna 	}
   1105      1.11        ad 	if (bmajor >= 0 && bmajor < max_bdevsws && bdevsw[bmajor] != NULL)
   1106      1.11        ad 		rv = makedev(bmajor, minor(cdev));
   1107      1.23     pooka 	mutex_exit(&device_lock);
   1108       1.2   gehenna 
   1109      1.45  riastrad 	return rv;
   1110       1.2   gehenna }
   1111       1.2   gehenna 
   1112       1.2   gehenna /*
   1113       1.2   gehenna  * Convert from block dev_t to character dev_t.
   1114      1.11        ad  *
   1115      1.11        ad  * => Caller must ensure that the device is not detached, and therefore
   1116      1.11        ad  *    that the major number is still valid when dereferenced.
   1117       1.2   gehenna  */
   1118       1.2   gehenna dev_t
   1119       1.2   gehenna devsw_blk2chr(dev_t bdev)
   1120       1.2   gehenna {
   1121      1.24  drochner 	devmajor_t bmajor, cmajor;
   1122      1.24  drochner 	int i;
   1123      1.11        ad 	dev_t rv;
   1124       1.2   gehenna 
   1125      1.11        ad 	bmajor = major(bdev);
   1126      1.24  drochner 	cmajor = NODEVMAJOR;
   1127      1.11        ad 	rv = NODEV;
   1128      1.11        ad 
   1129      1.23     pooka 	mutex_enter(&device_lock);
   1130      1.11        ad 	if (bmajor < 0 || bmajor >= max_bdevsws || bdevsw[bmajor] == NULL) {
   1131      1.23     pooka 		mutex_exit(&device_lock);
   1132      1.45  riastrad 		return NODEV;
   1133      1.11        ad 	}
   1134      1.45  riastrad 	for (i = 0; i < max_devsw_convs; i++) {
   1135      1.11        ad 		if (devsw_conv[i].d_bmajor == bmajor) {
   1136      1.11        ad 			cmajor = devsw_conv[i].d_cmajor;
   1137      1.11        ad 			break;
   1138      1.11        ad 		}
   1139      1.11        ad 	}
   1140      1.11        ad 	if (cmajor >= 0 && cmajor < max_cdevsws && cdevsw[cmajor] != NULL)
   1141      1.11        ad 		rv = makedev(cmajor, minor(bdev));
   1142      1.23     pooka 	mutex_exit(&device_lock);
   1143       1.2   gehenna 
   1144      1.45  riastrad 	return rv;
   1145      1.11        ad }
   1146      1.11        ad 
   1147      1.11        ad /*
   1148      1.11        ad  * Device access methods.
   1149      1.11        ad  */
   1150      1.11        ad 
   1151      1.11        ad #define	DEV_LOCK(d)						\
   1152      1.17        ad 	if ((mpflag = (d->d_flag & D_MPSAFE)) == 0) {		\
   1153      1.17        ad 		KERNEL_LOCK(1, NULL);				\
   1154      1.11        ad 	}
   1155       1.2   gehenna 
   1156      1.11        ad #define	DEV_UNLOCK(d)						\
   1157      1.17        ad 	if (mpflag == 0) {					\
   1158      1.17        ad 		KERNEL_UNLOCK_ONE(NULL);			\
   1159       1.2   gehenna 	}
   1160       1.2   gehenna 
   1161      1.11        ad int
   1162      1.11        ad bdev_open(dev_t dev, int flag, int devtype, lwp_t *l)
   1163      1.11        ad {
   1164      1.11        ad 	const struct bdevsw *d;
   1165      1.40  riastrad 	struct localcount *lc;
   1166      1.41  riastrad 	device_t dv = NULL/*XXXGCC*/;
   1167      1.49  riastrad 	int unit = -1/*XXXGCC*/, rv, mpflag;
   1168      1.11        ad 
   1169      1.40  riastrad 	d = bdevsw_lookup_acquire(dev, &lc);
   1170      1.11        ad 	if (d == NULL)
   1171      1.11        ad 		return ENXIO;
   1172      1.11        ad 
   1173      1.41  riastrad 	if (d->d_devtounit) {
   1174      1.41  riastrad 		/*
   1175      1.41  riastrad 		 * If the device node corresponds to an autoconf device
   1176      1.41  riastrad 		 * instance, acquire a reference to it so that during
   1177      1.41  riastrad 		 * d_open, device_lookup is stable.
   1178      1.41  riastrad 		 *
   1179      1.41  riastrad 		 * XXX This should also arrange to instantiate cloning
   1180      1.41  riastrad 		 * pseudo-devices if appropriate, but that requires
   1181      1.41  riastrad 		 * reviewing them all to find and verify a common
   1182      1.41  riastrad 		 * pattern.
   1183      1.41  riastrad 		 */
   1184      1.41  riastrad 		if ((unit = (*d->d_devtounit)(dev)) == -1)
   1185      1.41  riastrad 			return ENXIO;
   1186      1.41  riastrad 		if ((dv = device_lookup_acquire(d->d_cfdriver, unit)) == NULL)
   1187      1.41  riastrad 			return ENXIO;
   1188      1.49  riastrad 		SDT_PROBE6(sdt, bdev, open, acquire,
   1189      1.49  riastrad 		    d, dev, flag, devtype, unit, dv);
   1190      1.41  riastrad 	}
   1191      1.41  riastrad 
   1192      1.11        ad 	DEV_LOCK(d);
   1193      1.49  riastrad 	SDT_PROBE4(sdt, bdev, open, entry,  d, dev, flag, devtype);
   1194      1.11        ad 	rv = (*d->d_open)(dev, flag, devtype, l);
   1195      1.49  riastrad 	SDT_PROBE5(sdt, bdev, open, return,  d, dev, flag, devtype, rv);
   1196      1.11        ad 	DEV_UNLOCK(d);
   1197      1.11        ad 
   1198      1.41  riastrad 	if (d->d_devtounit) {
   1199      1.49  riastrad 		SDT_PROBE6(sdt, bdev, open, release,
   1200      1.49  riastrad 		    d, dev, flag, devtype, unit, dv);
   1201      1.41  riastrad 		device_release(dv);
   1202      1.41  riastrad 	}
   1203      1.41  riastrad 
   1204      1.40  riastrad 	bdevsw_release(d, lc);
   1205      1.40  riastrad 
   1206      1.11        ad 	return rv;
   1207      1.11        ad }
   1208      1.11        ad 
   1209      1.11        ad int
   1210      1.44  riastrad bdev_cancel(dev_t dev, int flag, int devtype, struct lwp *l)
   1211      1.44  riastrad {
   1212      1.44  riastrad 	const struct bdevsw *d;
   1213      1.44  riastrad 	int rv, mpflag;
   1214      1.44  riastrad 
   1215      1.44  riastrad 	if ((d = bdevsw_lookup(dev)) == NULL)
   1216      1.44  riastrad 		return ENXIO;
   1217      1.44  riastrad 	if (d->d_cancel == NULL)
   1218      1.44  riastrad 		return ENODEV;
   1219      1.44  riastrad 
   1220      1.44  riastrad 	DEV_LOCK(d);
   1221      1.49  riastrad 	SDT_PROBE4(sdt, bdev, cancel, entry,  d, dev, flag, devtype);
   1222      1.44  riastrad 	rv = (*d->d_cancel)(dev, flag, devtype, l);
   1223      1.49  riastrad 	SDT_PROBE5(sdt, bdev, cancel, return,  d, dev, flag, devtype, rv);
   1224      1.44  riastrad 	DEV_UNLOCK(d);
   1225      1.44  riastrad 
   1226      1.44  riastrad 	return rv;
   1227      1.44  riastrad }
   1228      1.44  riastrad 
   1229      1.44  riastrad int
   1230      1.11        ad bdev_close(dev_t dev, int flag, int devtype, lwp_t *l)
   1231      1.11        ad {
   1232      1.11        ad 	const struct bdevsw *d;
   1233      1.17        ad 	int rv, mpflag;
   1234      1.11        ad 
   1235      1.11        ad 	if ((d = bdevsw_lookup(dev)) == NULL)
   1236      1.11        ad 		return ENXIO;
   1237      1.11        ad 
   1238      1.11        ad 	DEV_LOCK(d);
   1239      1.49  riastrad 	SDT_PROBE4(sdt, bdev, close, entry,  d, dev, flag, devtype);
   1240      1.11        ad 	rv = (*d->d_close)(dev, flag, devtype, l);
   1241      1.49  riastrad 	SDT_PROBE5(sdt, bdev, close, return,  d, dev, flag, devtype, rv);
   1242      1.11        ad 	DEV_UNLOCK(d);
   1243      1.11        ad 
   1244      1.11        ad 	return rv;
   1245      1.11        ad }
   1246      1.11        ad 
   1247      1.34       riz SDT_PROVIDER_DECLARE(io);
   1248      1.34       riz SDT_PROBE_DEFINE1(io, kernel, , start, "struct buf *"/*bp*/);
   1249      1.34       riz 
   1250      1.11        ad void
   1251      1.11        ad bdev_strategy(struct buf *bp)
   1252      1.11        ad {
   1253      1.11        ad 	const struct bdevsw *d;
   1254      1.17        ad 	int mpflag;
   1255      1.11        ad 
   1256      1.34       riz 	SDT_PROBE1(io, kernel, , start, bp);
   1257      1.34       riz 
   1258      1.28  jmcneill 	if ((d = bdevsw_lookup(bp->b_dev)) == NULL) {
   1259      1.28  jmcneill 		bp->b_error = ENXIO;
   1260      1.28  jmcneill 		bp->b_resid = bp->b_bcount;
   1261      1.31     pooka 		biodone_vfs(bp); /* biodone() iff vfs present */
   1262      1.28  jmcneill 		return;
   1263      1.28  jmcneill 	}
   1264      1.11        ad 
   1265      1.11        ad 	DEV_LOCK(d);
   1266      1.49  riastrad 	SDT_PROBE3(sdt, bdev, strategy, entry,  d, bp->b_dev, bp);
   1267      1.11        ad 	(*d->d_strategy)(bp);
   1268      1.49  riastrad 	SDT_PROBE3(sdt, bdev, strategy, return,  d, bp->b_dev, bp);
   1269      1.11        ad 	DEV_UNLOCK(d);
   1270      1.11        ad }
   1271      1.11        ad 
   1272      1.11        ad int
   1273      1.11        ad bdev_ioctl(dev_t dev, u_long cmd, void *data, int flag, lwp_t *l)
   1274      1.11        ad {
   1275      1.11        ad 	const struct bdevsw *d;
   1276      1.17        ad 	int rv, mpflag;
   1277      1.11        ad 
   1278      1.11        ad 	if ((d = bdevsw_lookup(dev)) == NULL)
   1279      1.11        ad 		return ENXIO;
   1280      1.11        ad 
   1281      1.11        ad 	DEV_LOCK(d);
   1282      1.49  riastrad 	SDT_PROBE5(sdt, bdev, ioctl, entry,  d, dev, cmd, data, flag);
   1283      1.11        ad 	rv = (*d->d_ioctl)(dev, cmd, data, flag, l);
   1284      1.49  riastrad 	SDT_PROBE6(sdt, bdev, ioctl, return,  d, dev, cmd, data, flag, rv);
   1285      1.11        ad 	DEV_UNLOCK(d);
   1286      1.11        ad 
   1287      1.11        ad 	return rv;
   1288      1.11        ad }
   1289      1.11        ad 
   1290      1.11        ad int
   1291      1.11        ad bdev_dump(dev_t dev, daddr_t addr, void *data, size_t sz)
   1292      1.11        ad {
   1293      1.11        ad 	const struct bdevsw *d;
   1294      1.11        ad 	int rv;
   1295      1.11        ad 
   1296      1.11        ad 	/*
   1297      1.11        ad 	 * Dump can be called without the device open.  Since it can
   1298      1.11        ad 	 * currently only be called with the system paused (and in a
   1299      1.11        ad 	 * potentially unstable state), we don't perform any locking.
   1300      1.11        ad 	 */
   1301      1.11        ad 	if ((d = bdevsw_lookup(dev)) == NULL)
   1302      1.11        ad 		return ENXIO;
   1303      1.11        ad 
   1304      1.11        ad 	/* DEV_LOCK(d); */
   1305      1.11        ad 	rv = (*d->d_dump)(dev, addr, data, sz);
   1306      1.11        ad 	/* DEV_UNLOCK(d); */
   1307      1.11        ad 
   1308      1.11        ad 	return rv;
   1309      1.11        ad }
   1310      1.11        ad 
   1311      1.11        ad int
   1312      1.35       nat bdev_flags(dev_t dev)
   1313      1.35       nat {
   1314      1.35       nat 	const struct bdevsw *d;
   1315      1.35       nat 
   1316      1.35       nat 	if ((d = bdevsw_lookup(dev)) == NULL)
   1317      1.35       nat 		return 0;
   1318      1.35       nat 	return d->d_flag & ~D_TYPEMASK;
   1319      1.35       nat }
   1320      1.35       nat 
   1321      1.35       nat int
   1322      1.11        ad bdev_type(dev_t dev)
   1323      1.11        ad {
   1324      1.11        ad 	const struct bdevsw *d;
   1325      1.11        ad 
   1326      1.11        ad 	if ((d = bdevsw_lookup(dev)) == NULL)
   1327      1.11        ad 		return D_OTHER;
   1328      1.11        ad 	return d->d_flag & D_TYPEMASK;
   1329      1.11        ad }
   1330      1.11        ad 
   1331      1.11        ad int
   1332      1.29       mrg bdev_size(dev_t dev)
   1333      1.29       mrg {
   1334      1.29       mrg 	const struct bdevsw *d;
   1335      1.29       mrg 	int rv, mpflag = 0;
   1336      1.29       mrg 
   1337      1.29       mrg 	if ((d = bdevsw_lookup(dev)) == NULL ||
   1338      1.29       mrg 	    d->d_psize == NULL)
   1339      1.29       mrg 		return -1;
   1340      1.29       mrg 
   1341      1.29       mrg 	/*
   1342      1.29       mrg 	 * Don't to try lock the device if we're dumping.
   1343      1.30       mrg 	 * XXX: is there a better way to test this?
   1344      1.29       mrg 	 */
   1345      1.29       mrg 	if ((boothowto & RB_DUMP) == 0)
   1346      1.29       mrg 		DEV_LOCK(d);
   1347      1.49  riastrad 	SDT_PROBE2(sdt, bdev, psize, entry,  d, dev);
   1348      1.29       mrg 	rv = (*d->d_psize)(dev);
   1349      1.49  riastrad 	SDT_PROBE3(sdt, bdev, psize, return,  d, dev, rv);
   1350      1.29       mrg 	if ((boothowto & RB_DUMP) == 0)
   1351      1.29       mrg 		DEV_UNLOCK(d);
   1352      1.29       mrg 
   1353      1.29       mrg 	return rv;
   1354      1.29       mrg }
   1355      1.29       mrg 
   1356      1.29       mrg int
   1357      1.32  dholland bdev_discard(dev_t dev, off_t pos, off_t len)
   1358      1.32  dholland {
   1359      1.32  dholland 	const struct bdevsw *d;
   1360      1.32  dholland 	int rv, mpflag;
   1361      1.32  dholland 
   1362      1.32  dholland 	if ((d = bdevsw_lookup(dev)) == NULL)
   1363      1.32  dholland 		return ENXIO;
   1364      1.32  dholland 
   1365      1.32  dholland 	DEV_LOCK(d);
   1366      1.49  riastrad 	SDT_PROBE4(sdt, bdev, discard, entry,  d, dev, pos, len);
   1367      1.32  dholland 	rv = (*d->d_discard)(dev, pos, len);
   1368      1.49  riastrad 	SDT_PROBE5(sdt, bdev, discard, return,  d, dev, pos, len, rv);
   1369      1.32  dholland 	DEV_UNLOCK(d);
   1370      1.32  dholland 
   1371      1.32  dholland 	return rv;
   1372      1.32  dholland }
   1373      1.32  dholland 
   1374      1.43  riastrad void
   1375      1.43  riastrad bdev_detached(dev_t dev)
   1376      1.43  riastrad {
   1377      1.43  riastrad 	const struct bdevsw *d;
   1378      1.43  riastrad 	device_t dv;
   1379      1.43  riastrad 	int unit;
   1380      1.43  riastrad 
   1381      1.43  riastrad 	if ((d = bdevsw_lookup(dev)) == NULL)
   1382      1.43  riastrad 		return;
   1383      1.43  riastrad 	if (d->d_devtounit == NULL)
   1384      1.43  riastrad 		return;
   1385      1.43  riastrad 	if ((unit = (*d->d_devtounit)(dev)) == -1)
   1386      1.43  riastrad 		return;
   1387      1.43  riastrad 	if ((dv = device_lookup(d->d_cfdriver, unit)) == NULL)
   1388      1.43  riastrad 		return;
   1389      1.43  riastrad 	config_detach_commit(dv);
   1390      1.43  riastrad }
   1391      1.43  riastrad 
   1392      1.32  dholland int
   1393      1.11        ad cdev_open(dev_t dev, int flag, int devtype, lwp_t *l)
   1394      1.11        ad {
   1395      1.11        ad 	const struct cdevsw *d;
   1396      1.40  riastrad 	struct localcount *lc;
   1397      1.41  riastrad 	device_t dv = NULL/*XXXGCC*/;
   1398      1.49  riastrad 	int unit = -1/*XXXGCC*/, rv, mpflag;
   1399      1.11        ad 
   1400      1.40  riastrad 	d = cdevsw_lookup_acquire(dev, &lc);
   1401      1.11        ad 	if (d == NULL)
   1402      1.11        ad 		return ENXIO;
   1403      1.11        ad 
   1404      1.41  riastrad 	if (d->d_devtounit) {
   1405      1.41  riastrad 		/*
   1406      1.41  riastrad 		 * If the device node corresponds to an autoconf device
   1407      1.41  riastrad 		 * instance, acquire a reference to it so that during
   1408      1.41  riastrad 		 * d_open, device_lookup is stable.
   1409      1.41  riastrad 		 *
   1410      1.41  riastrad 		 * XXX This should also arrange to instantiate cloning
   1411      1.41  riastrad 		 * pseudo-devices if appropriate, but that requires
   1412      1.41  riastrad 		 * reviewing them all to find and verify a common
   1413      1.41  riastrad 		 * pattern.
   1414      1.41  riastrad 		 */
   1415      1.41  riastrad 		if ((unit = (*d->d_devtounit)(dev)) == -1)
   1416      1.41  riastrad 			return ENXIO;
   1417      1.41  riastrad 		if ((dv = device_lookup_acquire(d->d_cfdriver, unit)) == NULL)
   1418      1.41  riastrad 			return ENXIO;
   1419      1.49  riastrad 		SDT_PROBE6(sdt, cdev, open, acquire,
   1420      1.49  riastrad 		    d, dev, flag, devtype, unit, dv);
   1421      1.41  riastrad 	}
   1422      1.41  riastrad 
   1423      1.11        ad 	DEV_LOCK(d);
   1424      1.49  riastrad 	SDT_PROBE4(sdt, cdev, open, entry,  d, dev, flag, devtype);
   1425      1.11        ad 	rv = (*d->d_open)(dev, flag, devtype, l);
   1426      1.49  riastrad 	SDT_PROBE5(sdt, cdev, open, return,  d, dev, flag, devtype, rv);
   1427      1.11        ad 	DEV_UNLOCK(d);
   1428      1.11        ad 
   1429      1.41  riastrad 	if (d->d_devtounit) {
   1430      1.49  riastrad 		SDT_PROBE6(sdt, cdev, open, release,
   1431      1.49  riastrad 		    d, dev, flag, devtype, unit, dv);
   1432      1.41  riastrad 		device_release(dv);
   1433      1.41  riastrad 	}
   1434      1.41  riastrad 
   1435      1.40  riastrad 	cdevsw_release(d, lc);
   1436      1.40  riastrad 
   1437      1.11        ad 	return rv;
   1438      1.11        ad }
   1439      1.11        ad 
   1440      1.11        ad int
   1441      1.44  riastrad cdev_cancel(dev_t dev, int flag, int devtype, struct lwp *l)
   1442      1.44  riastrad {
   1443      1.44  riastrad 	const struct cdevsw *d;
   1444      1.44  riastrad 	int rv, mpflag;
   1445      1.44  riastrad 
   1446      1.44  riastrad 	if ((d = cdevsw_lookup(dev)) == NULL)
   1447      1.44  riastrad 		return ENXIO;
   1448      1.44  riastrad 	if (d->d_cancel == NULL)
   1449      1.44  riastrad 		return ENODEV;
   1450      1.44  riastrad 
   1451      1.44  riastrad 	DEV_LOCK(d);
   1452      1.49  riastrad 	SDT_PROBE4(sdt, cdev, cancel, entry,  d, dev, flag, devtype);
   1453      1.44  riastrad 	rv = (*d->d_cancel)(dev, flag, devtype, l);
   1454      1.49  riastrad 	SDT_PROBE5(sdt, cdev, cancel, return,  d, dev, flag, devtype, rv);
   1455      1.44  riastrad 	DEV_UNLOCK(d);
   1456      1.44  riastrad 
   1457      1.44  riastrad 	return rv;
   1458      1.44  riastrad }
   1459      1.44  riastrad 
   1460      1.44  riastrad int
   1461      1.11        ad cdev_close(dev_t dev, int flag, int devtype, lwp_t *l)
   1462      1.11        ad {
   1463      1.11        ad 	const struct cdevsw *d;
   1464      1.17        ad 	int rv, mpflag;
   1465      1.11        ad 
   1466      1.11        ad 	if ((d = cdevsw_lookup(dev)) == NULL)
   1467      1.11        ad 		return ENXIO;
   1468      1.11        ad 
   1469      1.11        ad 	DEV_LOCK(d);
   1470      1.49  riastrad 	SDT_PROBE4(sdt, cdev, close, entry,  d, dev, flag, devtype);
   1471      1.11        ad 	rv = (*d->d_close)(dev, flag, devtype, l);
   1472      1.49  riastrad 	SDT_PROBE5(sdt, cdev, close, return,  d, dev, flag, devtype, rv);
   1473      1.11        ad 	DEV_UNLOCK(d);
   1474      1.11        ad 
   1475      1.11        ad 	return rv;
   1476      1.11        ad }
   1477      1.11        ad 
   1478      1.11        ad int
   1479      1.11        ad cdev_read(dev_t dev, struct uio *uio, int flag)
   1480      1.11        ad {
   1481      1.11        ad 	const struct cdevsw *d;
   1482      1.17        ad 	int rv, mpflag;
   1483      1.11        ad 
   1484      1.11        ad 	if ((d = cdevsw_lookup(dev)) == NULL)
   1485      1.11        ad 		return ENXIO;
   1486      1.11        ad 
   1487      1.11        ad 	DEV_LOCK(d);
   1488      1.49  riastrad 	SDT_PROBE4(sdt, cdev, read, entry,  d, dev, uio, flag);
   1489      1.11        ad 	rv = (*d->d_read)(dev, uio, flag);
   1490      1.49  riastrad 	SDT_PROBE5(sdt, cdev, read, return,  d, dev, uio, flag, rv);
   1491      1.11        ad 	DEV_UNLOCK(d);
   1492      1.11        ad 
   1493      1.11        ad 	return rv;
   1494      1.11        ad }
   1495      1.11        ad 
   1496      1.11        ad int
   1497      1.11        ad cdev_write(dev_t dev, struct uio *uio, int flag)
   1498      1.11        ad {
   1499      1.11        ad 	const struct cdevsw *d;
   1500      1.17        ad 	int rv, mpflag;
   1501      1.11        ad 
   1502      1.11        ad 	if ((d = cdevsw_lookup(dev)) == NULL)
   1503      1.11        ad 		return ENXIO;
   1504      1.11        ad 
   1505      1.11        ad 	DEV_LOCK(d);
   1506      1.49  riastrad 	SDT_PROBE4(sdt, cdev, write, entry,  d, dev, uio, flag);
   1507      1.11        ad 	rv = (*d->d_write)(dev, uio, flag);
   1508      1.49  riastrad 	SDT_PROBE5(sdt, cdev, write, return,  d, dev, uio, flag, rv);
   1509      1.11        ad 	DEV_UNLOCK(d);
   1510      1.11        ad 
   1511      1.11        ad 	return rv;
   1512      1.11        ad }
   1513      1.11        ad 
   1514      1.11        ad int
   1515      1.11        ad cdev_ioctl(dev_t dev, u_long cmd, void *data, int flag, lwp_t *l)
   1516      1.11        ad {
   1517      1.11        ad 	const struct cdevsw *d;
   1518      1.17        ad 	int rv, mpflag;
   1519      1.11        ad 
   1520      1.11        ad 	if ((d = cdevsw_lookup(dev)) == NULL)
   1521      1.11        ad 		return ENXIO;
   1522      1.11        ad 
   1523      1.11        ad 	DEV_LOCK(d);
   1524      1.49  riastrad 	SDT_PROBE5(sdt, cdev, ioctl, entry,  d, dev, cmd, data, flag);
   1525      1.11        ad 	rv = (*d->d_ioctl)(dev, cmd, data, flag, l);
   1526      1.49  riastrad 	SDT_PROBE6(sdt, cdev, ioctl, return,  d, dev, cmd, data, flag, rv);
   1527      1.11        ad 	DEV_UNLOCK(d);
   1528      1.11        ad 
   1529      1.11        ad 	return rv;
   1530      1.11        ad }
   1531      1.11        ad 
   1532      1.11        ad void
   1533      1.11        ad cdev_stop(struct tty *tp, int flag)
   1534      1.11        ad {
   1535      1.11        ad 	const struct cdevsw *d;
   1536      1.17        ad 	int mpflag;
   1537      1.11        ad 
   1538      1.11        ad 	if ((d = cdevsw_lookup(tp->t_dev)) == NULL)
   1539      1.11        ad 		return;
   1540      1.11        ad 
   1541      1.11        ad 	DEV_LOCK(d);
   1542      1.49  riastrad 	SDT_PROBE4(sdt, cdev, stop, entry,  d, tp->t_dev, tp, flag);
   1543      1.11        ad 	(*d->d_stop)(tp, flag);
   1544      1.49  riastrad 	SDT_PROBE4(sdt, cdev, stop, return,  d, tp->t_dev, tp, flag);
   1545      1.11        ad 	DEV_UNLOCK(d);
   1546      1.11        ad }
   1547      1.11        ad 
   1548      1.11        ad struct tty *
   1549      1.11        ad cdev_tty(dev_t dev)
   1550      1.11        ad {
   1551      1.11        ad 	const struct cdevsw *d;
   1552      1.11        ad 
   1553      1.11        ad 	if ((d = cdevsw_lookup(dev)) == NULL)
   1554      1.11        ad 		return NULL;
   1555      1.11        ad 
   1556      1.12        ad 	/* XXX Check if necessary. */
   1557      1.12        ad 	if (d->d_tty == NULL)
   1558      1.12        ad 		return NULL;
   1559      1.12        ad 
   1560      1.21        ad 	return (*d->d_tty)(dev);
   1561      1.11        ad }
   1562      1.11        ad 
   1563      1.11        ad int
   1564      1.11        ad cdev_poll(dev_t dev, int flag, lwp_t *l)
   1565      1.11        ad {
   1566      1.11        ad 	const struct cdevsw *d;
   1567      1.17        ad 	int rv, mpflag;
   1568      1.11        ad 
   1569      1.11        ad 	if ((d = cdevsw_lookup(dev)) == NULL)
   1570      1.11        ad 		return POLLERR;
   1571      1.11        ad 
   1572      1.11        ad 	DEV_LOCK(d);
   1573      1.49  riastrad 	SDT_PROBE3(sdt, cdev, poll, entry,  d, dev, flag);
   1574      1.11        ad 	rv = (*d->d_poll)(dev, flag, l);
   1575      1.49  riastrad 	SDT_PROBE4(sdt, cdev, poll, return,  d, dev, flag, rv);
   1576      1.11        ad 	DEV_UNLOCK(d);
   1577      1.11        ad 
   1578      1.11        ad 	return rv;
   1579      1.11        ad }
   1580      1.11        ad 
   1581      1.11        ad paddr_t
   1582      1.11        ad cdev_mmap(dev_t dev, off_t off, int flag)
   1583      1.11        ad {
   1584      1.11        ad 	const struct cdevsw *d;
   1585      1.11        ad 	paddr_t rv;
   1586      1.17        ad 	int mpflag;
   1587      1.11        ad 
   1588      1.11        ad 	if ((d = cdevsw_lookup(dev)) == NULL)
   1589      1.11        ad 		return (paddr_t)-1LL;
   1590      1.11        ad 
   1591      1.11        ad 	DEV_LOCK(d);
   1592      1.49  riastrad 	SDT_PROBE4(sdt, cdev, mmap, entry,  d, dev, off, flag);
   1593      1.11        ad 	rv = (*d->d_mmap)(dev, off, flag);
   1594      1.49  riastrad 	SDT_PROBE5(sdt, cdev, mmap, return,  d, dev, off, flag, rv);
   1595      1.11        ad 	DEV_UNLOCK(d);
   1596      1.11        ad 
   1597      1.11        ad 	return rv;
   1598      1.11        ad }
   1599      1.11        ad 
   1600      1.11        ad int
   1601      1.11        ad cdev_kqfilter(dev_t dev, struct knote *kn)
   1602      1.11        ad {
   1603      1.11        ad 	const struct cdevsw *d;
   1604      1.17        ad 	int rv, mpflag;
   1605      1.11        ad 
   1606      1.11        ad 	if ((d = cdevsw_lookup(dev)) == NULL)
   1607      1.11        ad 		return ENXIO;
   1608      1.11        ad 
   1609      1.11        ad 	DEV_LOCK(d);
   1610      1.49  riastrad 	SDT_PROBE3(sdt, cdev, kqfilter, entry,  d, dev, kn);
   1611      1.11        ad 	rv = (*d->d_kqfilter)(dev, kn);
   1612      1.49  riastrad 	SDT_PROBE4(sdt, cdev, kqfilter, return,  d, dev, kn, rv);
   1613      1.11        ad 	DEV_UNLOCK(d);
   1614      1.11        ad 
   1615      1.11        ad 	return rv;
   1616      1.11        ad }
   1617      1.11        ad 
   1618      1.11        ad int
   1619      1.32  dholland cdev_discard(dev_t dev, off_t pos, off_t len)
   1620      1.32  dholland {
   1621      1.32  dholland 	const struct cdevsw *d;
   1622      1.32  dholland 	int rv, mpflag;
   1623      1.32  dholland 
   1624      1.32  dholland 	if ((d = cdevsw_lookup(dev)) == NULL)
   1625      1.32  dholland 		return ENXIO;
   1626      1.32  dholland 
   1627      1.32  dholland 	DEV_LOCK(d);
   1628      1.49  riastrad 	SDT_PROBE4(sdt, cdev, discard, entry,  d, dev, pos, len);
   1629      1.32  dholland 	rv = (*d->d_discard)(dev, pos, len);
   1630      1.49  riastrad 	SDT_PROBE5(sdt, cdev, discard, return,  d, dev, pos, len, rv);
   1631      1.32  dholland 	DEV_UNLOCK(d);
   1632      1.32  dholland 
   1633      1.32  dholland 	return rv;
   1634      1.32  dholland }
   1635      1.32  dholland 
   1636      1.32  dholland int
   1637      1.35       nat cdev_flags(dev_t dev)
   1638      1.35       nat {
   1639      1.35       nat 	const struct cdevsw *d;
   1640      1.35       nat 
   1641      1.35       nat 	if ((d = cdevsw_lookup(dev)) == NULL)
   1642      1.35       nat 		return 0;
   1643      1.35       nat 	return d->d_flag & ~D_TYPEMASK;
   1644      1.35       nat }
   1645      1.35       nat 
   1646      1.35       nat int
   1647      1.11        ad cdev_type(dev_t dev)
   1648      1.11        ad {
   1649      1.11        ad 	const struct cdevsw *d;
   1650      1.11        ad 
   1651      1.11        ad 	if ((d = cdevsw_lookup(dev)) == NULL)
   1652      1.11        ad 		return D_OTHER;
   1653      1.11        ad 	return d->d_flag & D_TYPEMASK;
   1654       1.2   gehenna }
   1655      1.36  riastrad 
   1656      1.43  riastrad void
   1657      1.43  riastrad cdev_detached(dev_t dev)
   1658      1.43  riastrad {
   1659      1.43  riastrad 	const struct cdevsw *d;
   1660      1.43  riastrad 	device_t dv;
   1661      1.43  riastrad 	int unit;
   1662      1.43  riastrad 
   1663      1.43  riastrad 	if ((d = cdevsw_lookup(dev)) == NULL)
   1664      1.43  riastrad 		return;
   1665      1.43  riastrad 	if (d->d_devtounit == NULL)
   1666      1.43  riastrad 		return;
   1667      1.43  riastrad 	if ((unit = (*d->d_devtounit)(dev)) == -1)
   1668      1.43  riastrad 		return;
   1669      1.43  riastrad 	if ((dv = device_lookup(d->d_cfdriver, unit)) == NULL)
   1670      1.43  riastrad 		return;
   1671      1.43  riastrad 	config_detach_commit(dv);
   1672      1.43  riastrad }
   1673      1.43  riastrad 
   1674      1.36  riastrad /*
   1675      1.36  riastrad  * nommap(dev, off, prot)
   1676      1.36  riastrad  *
   1677      1.36  riastrad  *	mmap routine that always fails, for non-mmappable devices.
   1678      1.36  riastrad  */
   1679      1.36  riastrad paddr_t
   1680      1.36  riastrad nommap(dev_t dev, off_t off, int prot)
   1681      1.36  riastrad {
   1682      1.36  riastrad 
   1683      1.36  riastrad 	return (paddr_t)-1;
   1684      1.36  riastrad }
   1685      1.42  riastrad 
   1686      1.42  riastrad /*
   1687      1.42  riastrad  * dev_minor_unit(dev)
   1688      1.42  riastrad  *
   1689      1.42  riastrad  *	Returns minor(dev) as an int.  Intended for use with struct
   1690      1.42  riastrad  *	bdevsw, cdevsw::d_devtounit for drivers whose /dev nodes are
   1691      1.42  riastrad  *	implemented by reference to an autoconf instance with the minor
   1692      1.42  riastrad  *	number.
   1693      1.42  riastrad  */
   1694      1.42  riastrad int
   1695      1.42  riastrad dev_minor_unit(dev_t dev)
   1696      1.42  riastrad {
   1697      1.42  riastrad 
   1698      1.42  riastrad 	return minor(dev);
   1699      1.42  riastrad }
   1700