1.\" Copyright (c) 1999 Chris Costello 2.\" All rights reserved. 3.\" 4.\" Redistribution and use in source and binary forms, with or without 5.\" modification, are permitted provided that the following conditions 6.\" are met: 7.\" 1. Redistributions of source code must retain the above copyright 8.\" notice, this list of conditions and the following disclaimer. 9.\" 2. Redistributions in binary form must reproduce the above copyright 10.\" notice, this list of conditions and the following disclaimer in the 11.\" documentation and/or other materials provided with the distribution. 12.\" 13.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23.\" SUCH DAMAGE. 24.\" 25.\" $FreeBSD: src/share/man/man9/make_dev.9,v 1.2.2.3 2001/12/17 11:30:18 ru Exp $ 26.\" 27.Dd June 27, 2020 28.Dt MAKE_DEV 9 29.Os 30.Sh NAME 31.Nm destroy_dev , 32.Nm destroy_only_dev , 33.Nm devfs_scan_callback , 34.Nm dev_ops_intercept , 35.Nm dev_ops_remove_all , 36.Nm dev_ops_remove_minor , 37.Nm dev_ops_restore , 38.Nm make_dev , 39.Nm make_dev_alias , 40.Nm make_dev_covering , 41.Nm make_only_dev , 42.Nm reference_dev , 43.Nm release_dev 44.Nd "device entry manipulation functions" 45.Sh SYNOPSIS 46.In sys/types.h 47.In sys/conf.h 48.In sys/devfs.h 49.Ft void 50.Fn destroy_dev "cdev_t dev" 51.Ft void 52.Fn destroy_only_dev "cdev_t dev" 53.Ft int 54.Fn devfs_scan_callback "devfs_scan_t *callback" "void *arg" 55.Ft struct dev_ops * 56.Fn dev_ops_intercept "cdev_t dev" "struct dev_ops *iops" 57.Ft int 58.Fn dev_ops_remove_all "struct dev_ops *ops" 59.Ft void 60.Fn dev_ops_restore "cdev_t dev" "struct dev_ops *oops" 61.Ft int 62.Fn dev_ops_remove_minor "struct dev_ops *ops" "int minor" 63.Ft cdev_t 64.Fn make_dev "struct dev_ops *ops" "int minor" "uid_t uid" "gid_t gid" "int perms" "const char *fmt" ... 65.Ft int 66.Fn make_dev_alias "cdev_t target" "const char *fmt" ... 67.Ft cdev_t 68.Fn make_dev_covering "struct dev_ops *ops" "struct dev_ops *bops" "int minor" "uid_t uid" "gid_t gid" "int perms" "const char *fmt" ... 69.Ft cdev_t 70.Fn make_only_dev "struct dev_ops *ops" "int minor" "uid_t uid" "gid_t gid" "int perms" "const char *fmt" ... 71.Ft cdev_t 72.Fn reference_dev "cdev_t dev" 73.Ft void 74.Fn release_dev "cdev_t dev" 75.Sh DESCRIPTION 76The 77.Fn make_dev 78function creates a 79.Vt cdev_t 80structure for a new device and makes the device name visible in the 81.Xr devfs 5 82mount points. 83The device's name must be unique. 84The name is the expansion of 85.Fa fmt 86and following arguments as 87.Xr kprintf 9 88would print it. 89The name determines its path under 90.Pa /dev . 91The permissions of the file specified in 92.Fa perms 93are defined in 94.In sys/stat.h : 95.Pp 96.Bd -literal -offset indent -compact 97#define S_IRWXU 0000700 /* RWX mask for owner */ 98#define S_IRUSR 0000400 /* R for owner */ 99#define S_IWUSR 0000200 /* W for owner */ 100#define S_IXUSR 0000100 /* X for owner */ 101 102#define S_IRWXG 0000070 /* RWX mask for group */ 103#define S_IRGRP 0000040 /* R for group */ 104#define S_IWGRP 0000020 /* W for group */ 105#define S_IXGRP 0000010 /* X for group */ 106 107#define S_IRWXO 0000007 /* RWX mask for other */ 108#define S_IROTH 0000004 /* R for other */ 109#define S_IWOTH 0000002 /* W for other */ 110#define S_IXOTH 0000001 /* X for other */ 111 112#define S_ISUID 0004000 /* set user id on execution */ 113#define S_ISGID 0002000 /* set group id on execution */ 114#define S_ISVTX 0001000 /* sticky bit */ 115#if __BSD_VISIBLE 116#define S_ISTXT 0001000 117#endif 118.Ed 119.Pp 120The 121.Fa ops 122argument is a pointer to a 123.Vt dev_ops 124data structure, which is defined as follows: 125.Bd -literal 126struct dev_ops { 127 struct { 128 const char *name; /* base name, e.g. 'da' */ 129 int maj; /* major device number */ 130 u_int flags; /* D_XXX flags */ 131 void *data; /* custom driver data */ 132 int refs; /* ref count */ 133 int id; 134 } head; 135 136#define dev_ops_first_field d_default 137 d_default_t *d_default; 138 d_open_t *d_open; 139 d_close_t *d_close; 140 d_read_t *d_read; 141 d_write_t *d_write; 142 d_ioctl_t *d_ioctl; 143 d_mmap_t *d_mmap; 144 d_strategy_t *d_strategy; 145 d_dump_t *d_dump; 146 d_psize_t *d_psize; 147 d_kqfilter_t *d_kqfilter; 148 d_clone_t *d_clone; /* clone from base dev_ops */ 149 d_revoke_t *d_revoke; 150#define dev_ops_last_field d_revoke 151}; 152.Ed 153.Pp 154While one can and should initialize the 155.Fa name 156and 157.Fa maj 158fields, they are effectively ignored. 159Device major numbers are assigned automatically out of an internal pool of 160major numbers, so there is no need to specify a unique major number in the 161.Vt dev_ops 162structure. 163.Pp 164Every member of the 165.Fn d_xxx_t 166family is defined as: 167.Bd -literal 168typedef int d_xxx_t (struct dev_xxx_args *ap); 169.Ed 170.Pp 171Therefore, if one wants to implement a 172.Fn mydev_open 173function, this is the way: 174.Bd -literal 175d_open_t mydev_open; 176 177int 178mydev_open(struct dev_open_args *ap) 179{ 180} 181.Ed 182.Pp 183.Fn make_dev_covering 184is equivalent to 185.Fn make_dev , 186except that it also takes an argument 187.Fa bops 188which is set as the ops of the backing device for the newly created device. 189This function should be used whenever a device is created covering 190another raw device, as the disk subsystem does. 191.Pp 192.Fn make_only_dev 193creates a 194.Vt cdev_t 195structure and initializes it in the same way as 196.Fn make_dev 197would, but the device will not appear in the 198.Xr devfs 5 199namespace. 200This function is usually used in the clone handler of an autoclone device 201created by 202.Fn make_autoclone_dev . 203.Pp 204.Fn destroy_dev 205takes the returned 206.Vt cdev_t 207from 208.Fn make_dev 209and destroys the registration for that device. 210It should not be used to destroy a 211.Vt cdev_t 212created by 213.Fn make_only_dev . 214.Pp 215.Fn destroy_only_dev 216takes the returned 217.Vt cdev_t 218from 219.Fn make_only_dev 220and destroys the registration for that device. 221It should not be used to destroy a 222.Vt cdev_t 223created by 224.Fn make_dev . 225.Pp 226.Fn make_dev_alias 227creates an automatic 228.Xr devfs 5 229link (alias) with the given name to the 230.Vt cdev_t 231specified by 232.Fa target . 233The 234.Vt cdev_t 235must have been created either by 236.Fn make_dev 237or bt a clone handler. 238Aliases are alternative names for devices in the 239.Xr devfs 5 240namespace. 241The lifetime of an alias is that of its associated 242.Vt cdev_t . 243Once the 244.Vt cdev_t 245is removed or destroyed, the alias is also destroyed and its name is 246removed from the 247.Xr devfs 5 248namespace. 249.Pp 250.Fn reference_dev 251adds a reference to 252.Fa dev . 253Callers generally add their own references when they are going to store a device 254node in a variable for long periods of time, to prevent a disassociation from 255freeing the node. 256.Pp 257.Fn release_dev 258releases a reference on 259.Fa dev . 260The device will be terminated when the last reference has been released. 261.Pp 262.Fn dev_ops_intercept 263intercepts the device operations vector of 264.Fa dev 265with 266.Fa iops . 267The old 268.Vt dev_ops 269is returned which may be used in a subsequent 270.Fn dev_ops_restore 271call. 272The function sets the 273.Dv SI_INTERCEPTED 274flag in 275.Fa dev . 276.Pp 277.Fn dev_ops_restore 278restores the device operations vector of 279.Fa dev 280to 281.Fa oops . 282Also it unsets the 283.Dv SI_INTERCEPTED 284flag in 285.Fa dev . 286.Pp 287.Fn dev_ops_remove_all 288destroys all the 289.Vt cdev_t 290with the given 291.Fa ops 292and removes the devices from the 293.Xr devfs 5 294namespace. 295This function is useful when uninitializing a driver. 296.Pp 297.Fn dev_ops_remove_minor 298destroys all the 299.Vt cdev_t 300with the given 301.Fa ops 302and 303.Fa minor 304and removes the devices from the 305.Xr devfs 5 306namespace. 307.Pp 308.Fn devfs_scan_callback 309calls the given 310.Fa callback 311function for every device registered in 312.Xr devfs 5 . 313The 314.Fa callback 315function has the following form: 316.Bd -literal 317devfs_scan_t mydev_scan_callback; 318 319void 320mydev_scan_callback(char *name, cdev_t dev, bool is_alias, void *arg) 321{ 322}; 323.Ed 324.Pp 325The 326.Fa name 327argument is the alias' name (if 328.Fa is_alias 329is 330.Dv true ) 331or the 332.Vt cdev Ap s 333.Fa si_name 334field. 335.Sh SEE ALSO 336.Xr devfs 5 , 337.Xr make_autoclone_dev 9 338.Sh HISTORY 339The 340.Fn make_dev 341and 342.Fn destroy_dev 343functions first appeared in 344.Fx 4.0 . 345.Pp 346A major overhaul of these functions occurred in 347.Dx 2.3 348with the addition of 349.Xr devfs 5 . 350