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.\" $DragonFly: src/share/man/man9/make_dev.9,v 1.3 2006/05/26 19:39:40 swildner Exp $ 27.\" 28.Dd February 10, 2009 29.Os 30.Dt MAKE_DEV 9 31.Sh NAME 32.Nm compile_dev_ops , 33.Nm destroy_all_devs , 34.Nm destroy_dev , 35.Nm dev_ops_add , 36.Nm dev_ops_add_override , 37.Nm dev_ops_intercept , 38.Nm dev_ops_release , 39.Nm dev_ops_remove , 40.Nm dev_ops_restore , 41.Nm dev_ops_scan , 42.Nm get_dev , 43.Nm make_dev , 44.Nm make_adhoc_dev , 45.Nm make_sub_dev , 46.Nm reference_dev , 47.Nm release_dev 48.Nd "device entry manipulation functions" 49.Sh SYNOPSIS 50.In sys/types.h 51.In sys/conf.h 52.Ft void 53.Fn compile_dev_ops "struct dev_ops *ops" 54.Ft void 55.Fn destroy_all_devs "struct dev_ops *ops" "u_int mask" "u_int match" 56.Ft void 57.Fn destroy_dev "cdev_t dev" 58.Ft int 59.Fn dev_ops_add "struct dev_ops *ops" "u_int mask" "u_int match" 60.Ft struct dev_ops * 61.Fo dev_ops_add_override 62.Fa "cdev_t backing_dev" 63.Fa "struct dev_ops *template" 64.Fa "u_int mask" 65.Fa "u_int match" 66.Fc 67.Ft struct dev_ops * 68.Fn dev_ops_intercept "cdev_t dev" "struct dev_ops *iops" 69.Ft void 70.Fn dev_ops_release "struct dev_ops *ops" 71.Ft int 72.Fn dev_ops_remove "struct dev_ops *ops" "u_int mask" "u_int match" 73.Ft void 74.Fn dev_ops_restore "cdev_t dev" "struct dev_ops *oops" 75.Ft int 76.Fn dev_ops_scan "int (*callback)(struct dev_ops *, void *)" "void *arg" 77.Ft cdev_t 78.Fn get_dev "int x" "int y" 79.Ft cdev_t 80.Fn make_dev "struct dev_ops *ops" "int minor" "uid_t uid" "gid_t gid" "int perms" "char *fmt" ... 81.Ft cdev_t 82.Fn make_adhoc_dev "struct dev_ops *ops" "int minor" 83.Ft cdev_t 84.Fn make_sub_dev "cdev_t odev" "int minor" 85.Ft cdev_t 86.Fn reference_dev "cdev_t dev" 87.Ft void 88.Fn release_dev "cdev_t dev" 89.Sh DESCRIPTION 90The 91.Fn make_dev 92function creates a 93.Vt cdev_t 94structure for a new device. 95If an entry already exists, this function will set its cred 96requirements and name. 97The device will be owned by 98.Fa uid , 99with the group ownership as 100.Fa gid . 101The name is the expansion of 102.Fa fmt 103and following arguments as 104.Xr kprintf 9 105would print it. 106The name determines its path under 107.Pa /dev . 108The permissions of the file specified in 109.Fa perms 110are defined in 111.In sys/stat.h : 112.Pp 113.Bd -literal -offset indent -compact 114#define S_IRWXU 0000700 /* RWX mask for owner */ 115#define S_IRUSR 0000400 /* R for owner */ 116#define S_IWUSR 0000200 /* W for owner */ 117#define S_IXUSR 0000100 /* X for owner */ 118 119#define S_IRWXG 0000070 /* RWX mask for group */ 120#define S_IRGRP 0000040 /* R for group */ 121#define S_IWGRP 0000020 /* W for group */ 122#define S_IXGRP 0000010 /* X for group */ 123 124#define S_IRWXO 0000007 /* RWX mask for other */ 125#define S_IROTH 0000004 /* R for other */ 126#define S_IWOTH 0000002 /* W for other */ 127#define S_IXOTH 0000001 /* X for other */ 128 129#define S_ISUID 0004000 /* set user id on execution */ 130#define S_ISGID 0002000 /* set group id on execution */ 131#define S_ISVTX 0001000 /* sticky bit */ 132#ifndef _POSIX_SOURCE 133#define S_ISTXT 0001000 134#endif 135.Ed 136.Pp 137.Fn dev_ops_add 138populates a 139.Vt dev_ops 140data structure, which is defined as follows: 141.Bd -literal 142struct dev_ops { 143 struct { 144 const char *name; /* base name, e.g. 'da' */ 145 int maj; /* major device number */ 146 u_int flags; /* D_XXX flags */ 147 void *data; /* custom driver data */ 148 int refs; /* ref count */ 149 } head; 150 151#define dev_ops_first_field d_default 152 d_default_t *d_default; 153 d_open_t *d_open; 154 d_close_t *d_close; 155 d_read_t *d_read; 156 d_write_t *d_write; 157 d_ioctl_t *d_ioctl; 158 d_poll_t *d_poll; 159 d_mmap_t *d_mmap; 160 d_strategy_t *d_strategy; 161 d_dump_t *d_dump; 162 d_psize_t *d_psize; 163 d_kqfilter_t *d_kqfilter; 164 d_clone_t *d_clone; /* clone from base dev_ops */ 165#define dev_ops_last_field d_clone 166}; 167.Ed 168.Pp 169Every member of the 170.Fn d_xxx_t 171family is defined as: 172.Bd -literal 173typedef int d_xxx_t (struct dev_xxx_args *ap); 174.Ed 175.Pp 176Therefore, if one wants to implement a 177.Fn mydev_open 178function, this is the way: 179.Bd -literal 180d_open_t mydev_open; 181 182int 183mydev_open(struct dev_open_args *ap) 184{ 185} 186.Ed 187.Pp 188The 189.Fa mask , 190.Fa match 191supplied in this call are a full 32 bits and the same mask and match must 192be specified in a later 193.Fn dev_ops_remove 194call to match this add. 195However, the match value for the minor number should never have any bits 196set in the major number's bit range (8-15). 197The mask value may be conveniently specified as -1 without creating any 198major number interference. 199.Pp 200.Fn make_adhoc_dev 201is similar to 202.Fn make_dev 203but no cred information or name need to be specified. 204.Pp 205.Fn make_sub_dev 206is similar to 207.Fn make_dev 208except that the new device is created using 209.Fa odev 210as a template. 211.Pp 212.Fn get_dev 213takes as arguments a (major, minor) pair and returns a 214.Vt cdev_t . 215.Pp 216.Fn destroy_dev 217takes the returned 218.Vt cdev_t 219from 220.Fn make_dev 221and destroys the registration for that device. 222.Pp 223.Fn destroy_all_devs 224destroys all ad-hoc device associations associated with a domain within 225a device switch. 226Only the minor numbers are included in the 227.Fa mask , 228.Fa match 229values. 230.Pp 231.Fn reference_dev 232adds a reference to 233.Fa dev . 234Callers generally add their own references when they are going to store a device 235node in a variable for long periods of time, to prevent a disassociation from 236freeing the node. 237Also note that a caller that intends to call 238.Fn destroy_dev 239must first obtain a reference on the device. The ad-hoc reference you get with 240.Fn make_dev 241and friends is 242.Em not 243sufficient to be able to call 244.Fn destroy_dev . 245.Pp 246.Fn release_dev 247releases a reference on 248.Fa dev . 249The device will be terminated when the last reference has been released. 250.Pp 251.Fn dev_ops_add_override 252takes a cookie cutter to the 253.Fa major , 254.Fa minor 255device space for the passed device and generates a new 256.Vt dev_ops 257visible to userland which the caller can then modify. 258The original device is not modified but portions of its major/minor space will 259no longer be visible to userland. 260.Pp 261.Fn compile_dev_ops 262converts a template 263.Vt dev_ops 264into the real thing by filling in uninitialized fields. 265.Pp 266.Fn dev_ops_remove 267removes all matching 268.Vt dev_ops 269entries from the dev_ops_array[] major array so no new user opens can be 270performed, and destroys all devices installed in the hash table that are 271associated with this 272.Fa ops 273(see 274.Fn destroy_all_devs 275also). 276The 277.Fa mask 278and 279.Fa match 280should match a previous call to 281.Fn dev_ops_add* . 282.Pp 283.Fn dev_ops_release 284releases the 285.Fa ops 286entry. 287When fully implemented, if reference count reaches zero it will recurse through 288stack. 289.Pp 290.Fn dev_ops_intercept 291intercepts the device operations vector of 292.Fa dev 293with 294.Fa iops . 295The old 296.Vt dev_ops 297is returned which may be used in a subsequent 298.Fn dev_ops_restore 299call. 300The function sets the 301.Dv SI_INTERCEPTED 302flag in 303.Fa dev . 304.Pp 305.Fn dev_ops_restore 306restores the device operations vector of 307.Fa dev 308to 309.Fa oops . 310Also it unsets the 311.Dv SI_INTERCEPTED 312flag in 313.Fa dev . 314.Pp 315.Fn dev_ops_scan 316issues a callback for all installed 317.Vt dev_ops 318structures. 319The scan will terminate if a callback returns a negative number. 320If not, it will return the sum of the returned values of all callback invocations. 321.Sh HISTORY 322The 323.Fn make_dev 324and 325.Fn destroy_dev 326functions first appeared in 327.Fx 4.0 . 328