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$ 26.\" 27.Dd October 24, 2010 28.Dt MAKE_DEV 9 29.Os 30.Sh NAME 31.Nm make_dev , 32.Nm make_dev_cred , 33.Nm make_dev_credf , 34.Nm make_dev_p , 35.Nm make_dev_alias , 36.Nm destroy_dev , 37.Nm destroy_dev_sched , 38.Nm destroy_dev_sched_cb , 39.Nm destroy_dev_drain , 40.Nm dev_depends 41.Nd manage 42.Vt cdev Ns 's 43and DEVFS registration for devices 44.Sh SYNOPSIS 45.In sys/param.h 46.In sys/conf.h 47.Ft struct cdev * 48.Fn make_dev "struct cdevsw *cdevsw" "int unit" "uid_t uid" "gid_t gid" "int perms" "const char *fmt" ... 49.Ft struct cdev * 50.Fn make_dev_cred "struct cdevsw *cdevsw" "int unit" "struct ucred *cr" "uid_t uid" "gid_t gid" "int perms" "const char *fmt" ... 51.Ft struct cdev * 52.Fn make_dev_credf "int flags" "struct cdevsw *cdevsw" "int unit" "struct ucred *cr" "uid_t uid" "gid_t gid" "int perms" "const char *fmt" ... 53.Ft int 54.Fn make_dev_p "int flags" "struct cdev **cdev" "struct cdevsw *devsw" "struct ucred *cr" "uid_t uid" "gid_t gid" "int mode" "const char *fmt" ... 55.Ft struct cdev * 56.Fn make_dev_alias "struct cdev *pdev" "const char *fmt" ... 57.Ft void 58.Fn destroy_dev "struct cdev *dev" 59.Ft void 60.Fn destroy_dev_sched "struct cdev *dev" 61.Ft void 62.Fn destroy_dev_sched_cb "struct cdev *dev" "void (*cb)(void *)" "void *arg" 63.Ft void 64.Fn destroy_dev_drain "struct cdevsw *csw" 65.Ft void 66.Fn dev_depends "struct cdev *pdev" "struct cdev *cdev" 67.Sh DESCRIPTION 68The 69.Fn make_dev_credf 70function creates a 71.Fa cdev 72structure for a new device. 73It also notifies 74.Xr devfs 5 75of the presence of the new device, that causes corresponding nodes 76to be created. 77Besides this, a 78.Xr devctl 4 79notification is sent. 80The device will be owned by 81.Va uid , 82with the group ownership as 83.Va gid . 84The name is the expansion of 85.Va fmt 86and following arguments as 87.Xr printf 9 88would print it. 89The name determines its path under 90.Pa /dev 91or other 92.Xr devfs 5 93mount point and may contain slash 94.Ql / 95characters to denote subdirectories. 96The permissions of the file specified in 97.Va perms 98are defined in 99.In sys/stat.h : 100.Pp 101.Bd -literal -offset indent -compact 102#define S_IRWXU 0000700 /* RWX mask for owner */ 103#define S_IRUSR 0000400 /* R for owner */ 104#define S_IWUSR 0000200 /* W for owner */ 105#define S_IXUSR 0000100 /* X for owner */ 106 107#define S_IRWXG 0000070 /* RWX mask for group */ 108#define S_IRGRP 0000040 /* R for group */ 109#define S_IWGRP 0000020 /* W for group */ 110#define S_IXGRP 0000010 /* X for group */ 111 112#define S_IRWXO 0000007 /* RWX mask for other */ 113#define S_IROTH 0000004 /* R for other */ 114#define S_IWOTH 0000002 /* W for other */ 115#define S_IXOTH 0000001 /* X for other */ 116 117#define S_ISUID 0004000 /* set user id on execution */ 118#define S_ISGID 0002000 /* set group id on execution */ 119#define S_ISVTX 0001000 /* sticky bit */ 120#ifndef _POSIX_SOURCE 121#define S_ISTXT 0001000 122#endif 123.Ed 124.Pp 125The 126.Va cr 127argument specifies credentials that will be stored in the 128.Fa si_cred 129member of the initialized 130.Fa struct cdev . 131The 132.Va flags 133argument alters the operation of 134.Fn make_dev_credf 135or 136.Fn make_dev_p . 137The following values are currently accepted: 138.Pp 139.Bl -tag -width "MAKEDEV_CHECKNAME" -compact -offset indent 140.It MAKEDEV_REF 141reference the created device 142.It MAKEDEV_NOWAIT 143do not sleep, the call may fail 144.It MAKEDEV_WAITOK 145allow the function to sleep to satisfy malloc 146.It MAKEDEV_ETERNAL 147created device will be never destroyed 148.It MAKEDEV_CHECKNAME 149return an error if the device name is invalid or already exists 150.El 151.Pp 152The 153.Dv MAKEDEV_WAITOK 154flag is assumed if none of 155.Dv MAKEDEV_WAITOK , 156.Dv MAKEDEV_NOWAIT 157is specified. 158.Pp 159The 160.Xr dev_clone 9 161event handler shall specify 162.Dv MAKEDEV_REF 163flag when creating a device in response to lookup, to avoid race where 164the device created is destroyed immediately after 165.Xr devfs_lookup 9 166drops his reference to cdev. 167.Pp 168The 169.Dv MAKEDEV_ETERNAL 170flag allows the kernel to not acquire some locks when translating system 171calls into the cdevsw methods calls. 172It is responsibility of the driver author to make sure that 173.Fn destroy_dev 174is never called on the returned cdev. 175For the convenience, use the 176.Dv MAKEDEV_ETERNAL_KLD 177flag for the code that can be compiled into kernel or loaded 178(and unloaded) as loadable module. 179.Pp 180A panic will occur if the MAKEDEV_CHECKNAME flag is not specified 181and the device name is invalid or already exists. 182.Pp 183The 184.Fn make_dev_cred 185function is equivalent to the call 186.Bd -literal -offset indent 187make_dev_credf(0, cdevsw, unit, cr, uid, gid, perms, fmt, ...); 188.Ed 189.Pp 190The 191.Fn make_dev 192function call is the same as 193.Bd -literal -offset indent 194make_dev_credf(0, cdevsw, unit, NULL, uid, gid, perms, fmt, ...); 195.Ed 196.Pp 197The 198.Fn make_dev_p 199function is similar to 200.Fn make_dev_credf 201but it may return an error number and takes a pointer to the resulting 202.Ft *cdev 203as an argument. 204.Pp 205The 206.Fn make_dev_alias 207function takes the returned 208.Ft cdev 209from 210.Fn make_dev 211and makes another (aliased) name for this device. 212It is an error to call 213.Fn make_dev_alias 214prior to calling 215.Fn make_dev . 216.Pp 217The 218.Fa cdev 219returned by 220.Fn make_dev 221and 222.Fn make_dev_alias 223has two fields, 224.Fa si_drv1 225and 226.Fa si_drv2 , 227that are available to store state. 228Both fields are of type 229.Ft void * . 230These are designed to replace the 231.Fa unit 232argument to 233.Fn make_dev , 234which can be obtained with 235.Fn dev2unit . 236.Pp 237The 238.Fn destroy_dev 239function takes the returned 240.Fa cdev 241from 242.Fn make_dev 243and destroys the registration for that device. 244The notification is sent to 245.Xr devctl 4 246about the destruction event. 247Do not call 248.Fn destroy_dev 249on devices that were created with 250.Fn make_dev_alias . 251.Pp 252The 253.Fn dev_depends 254function establishes a parent-child relationship between two devices. 255The net effect is that a 256.Fn destroy_dev 257of the parent device will also result in the destruction of the 258child device(s), 259if any exist. 260A device may simultaneously be a parent and a child, 261so it is possible to build a complete hierarchy. 262.Pp 263The 264.Fn destroy_dev_sched_cb 265function schedules execution of the 266.Fn destroy_dev 267for the specified 268.Fa cdev 269in the safe context. 270After 271.Fn destroy_dev 272is finished, and if the supplied 273.Fa cb 274is not 275.Dv NULL , 276the callback 277.Fa cb 278is called, with argument 279.Fa arg . 280The 281.Fn destroy_dev_sched 282function is the same as 283.Bd -literal -offset indent 284destroy_dev_sched_cb(cdev, NULL, NULL); 285.Ed 286.Pp 287The 288.Fn d_close 289driver method cannot call 290.Fn destroy_dev 291directly. Doing so causes deadlock when 292.Fn destroy_dev 293waits for all threads to leave the driver methods. 294Also, because 295.Fn destroy_dev 296sleeps, no non-sleepable locks may be held over the call. 297The 298.Fn destroy_dev_sched 299family of functions overcome these issues. 300.Pp 301The device driver may call the 302.Fn destroy_dev_drain 303function to wait until all devices that have supplied 304.Fa csw 305as cdevsw, are destroyed. This is useful when driver knows that 306.Fn destroy_dev_sched 307is called for all instantiated devices, but need to postpone module 308unload until 309.Fn destroy_dev 310is actually finished for all of them. 311.Sh RETURN VALUES 312If successful, 313.Fn make_dev_p 314will return 0, otherwise it will return an error. 315If successful, 316.Fn make_dev_credf 317will return a valid 318.Fa cdev 319pointer, otherwise it will return 320.Dv NULL . 321.Sh ERRORS 322The 323.Fn make_dev_p 324call will fail and the device will be not registered if: 325.Bl -tag -width Er 326.It Bq Er ENOMEM 327The 328.Dv MAKEDEV_NOWAIT 329flag was specified and a memory allocation request could not be satisfied. 330.It Bq Er ENAMETOOLONG 331The 332.Dv MAKEDEV_CHECKNAME 333flag was specified and the provided device name is longer than 334.Dv SPECNAMELEN . 335.It Bq Er EINVAL 336The 337.Dv MAKEDEV_CHECKNAME 338flag was specified and the provided device name is empty, contains a 339.Qq \&. 340or 341.Qq .. 342path component or ends with 343.Ql / . 344.It Bq Er EEXIST 345The 346.Dv MAKEDEV_CHECKNAME 347flag was specified and the provided device name already exists. 348.El 349.Pp 350.Sh SEE ALSO 351.Xr devctl 4 , 352.Xr destroy_dev_drain 9 , 353.Xr dev_clone 9 , 354.Xr devfs 5 355.Sh HISTORY 356The 357.Fn make_dev 358and 359.Fn destroy_dev 360functions first appeared in 361.Fx 4.0 . 362The function 363.Fn make_dev_alias 364first appeared in 365.Fx 4.1 . 366The function 367.Fn dev_depends 368first appeared in 369.Fx 5.0 . 370The functions 371.Fn make_dev_credf , 372.Fn destroy_dev_sched , 373.Fn destroy_dev_sched_cb 374first appeared in 375.Fx 7.0 . 376The function 377.Fn make_dev_p 378first appeared in 379.Fx 8.2 . 380