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