NAME
destroy_dev
,
destroy_only_dev
,
devfs_scan_callback
,
dev_ops_intercept
,
dev_ops_remove_all
,
dev_ops_remove_minor
,
dev_ops_restore
, make_dev
,
make_dev_alias
,
make_dev_covering
,
make_only_dev
,
reference_dev
, release_dev
— device entry manipulation
functions
SYNOPSIS
#include
<sys/types.h>
#include <sys/conf.h>
#include <sys/devfs.h>
void
destroy_dev
(cdev_t
dev);
void
destroy_only_dev
(cdev_t
dev);
int
devfs_scan_callback
(devfs_scan_t
*callback, void
*arg);
struct dev_ops *
dev_ops_intercept
(cdev_t
dev, struct dev_ops
*iops);
int
dev_ops_remove_all
(struct
dev_ops *ops);
void
dev_ops_restore
(cdev_t
dev, struct dev_ops
*oops);
int
dev_ops_remove_minor
(struct
dev_ops *ops, int
minor);
cdev_t
make_dev
(struct
dev_ops *ops, int
minor, uid_t uid,
gid_t gid,
int perms,
const char *fmt,
...);
int
make_dev_alias
(cdev_t
target, const char
*fmt, ...);
cdev_t
make_dev_covering
(struct
dev_ops *ops, struct
dev_ops *bops, int
minor, uid_t uid,
gid_t gid,
int perms,
const char *fmt,
...);
cdev_t
make_only_dev
(struct
dev_ops *ops, int
minor, uid_t uid,
gid_t gid,
int perms,
const char *fmt,
...);
cdev_t
reference_dev
(cdev_t
dev);
void
release_dev
(cdev_t
dev);
DESCRIPTION
Themake_dev
()
function creates a cdev_t structure for a new device and
makes the device name visible in the
devfs(5) mount points. The device's name must be unique. The name is
the expansion of fmt and following arguments as
kprintf(9) would print it. The name determines its path under
/dev. The permissions of the file specified in
perms are defined in
<sys/stat.h>
:
#define S_IRWXU 0000700 /* RWX mask for owner */ #define S_IRUSR 0000400 /* R for owner */ #define S_IWUSR 0000200 /* W for owner */ #define S_IXUSR 0000100 /* X for owner */ #define S_IRWXG 0000070 /* RWX mask for group */ #define S_IRGRP 0000040 /* R for group */ #define S_IWGRP 0000020 /* W for group */ #define S_IXGRP 0000010 /* X for group */ #define S_IRWXO 0000007 /* RWX mask for other */ #define S_IROTH 0000004 /* R for other */ #define S_IWOTH 0000002 /* W for other */ #define S_IXOTH 0000001 /* X for other */ #define S_ISUID 0004000 /* set user id on execution */ #define S_ISGID 0002000 /* set group id on execution */ #define S_ISVTX 0001000 /* sticky bit */ #if __BSD_VISIBLE #define S_ISTXT 0001000 #endif
The ops argument is a pointer to a dev_ops data structure, which is defined as follows:
struct dev_ops { struct { const char *name; /* base name, e.g. 'da' */ int maj; /* major device number */ u_int flags; /* D_XXX flags */ void *data; /* custom driver data */ int refs; /* ref count */ int id; } head; #define dev_ops_first_field d_default d_default_t *d_default; d_open_t *d_open; d_close_t *d_close; d_read_t *d_read; d_write_t *d_write; d_ioctl_t *d_ioctl; d_mmap_t *d_mmap; d_strategy_t *d_strategy; d_dump_t *d_dump; d_psize_t *d_psize; d_kqfilter_t *d_kqfilter; d_clone_t *d_clone; /* clone from base dev_ops */ d_revoke_t *d_revoke; #define dev_ops_last_field d_revoke };
While one can and should initialize the name and maj fields, they are effectively ignored. Device major numbers are assigned automatically out of an internal pool of major numbers, so there is no need to specify a unique major number in the dev_ops structure.
Every member of the
d_xxx_t
()
family is defined as:
typedef int d_xxx_t (struct dev_xxx_args *ap);
Therefore, if one wants to implement a
mydev_open
()
function, this is the way:
d_open_t mydev_open; int mydev_open(struct dev_open_args *ap) { }
make_dev_covering
()
is equivalent to make_dev, except that it also takes an argument
bops which is set as the ops of the backing device for
the newly created device. This function should be used whenever a device is
created covering another raw device, as the disk subsystem does.
make_only_dev
()
creates a cdev_t structure and initializes it the same
way make_dev
() would, but the device will not appear
in the devfs(5) namespace.
destroy_dev
()
takes the returned cdev_t from
make_dev
() and destroys the registration for that
device. It should not be used to destroy a cdev_t
created by make_only_dev
().
destroy_only_dev
()
takes the returned cdev_t from
make_only_dev
() and destroys the registration for
that device. It should not be used to destroy a cdev_t
created by make_dev
().
make_dev_alias
()
creates an automatic
devfs(5) link (alias) with the given name to the
cdev_t specified by target. The
cdev_t must have been created either by
make_dev
() or bt a clone handler. Aliases are
alternative names for devices in the
devfs(5) namespace. The lifetime of an alias is that of its
associated cdev_t. Once the
cdev_t is removed or destroyed, the alias is also
destroyed and its name is removed from the
devfs(5) namespace.
reference_dev
()
adds a reference to dev. Callers generally add their
own references when they are going to store a device node in a variable for
long periods of time, to prevent a disassociation from freeing the node.
release_dev
()
releases a reference on dev. The device will be
terminated when the last reference has been released.
dev_ops_intercept
()
intercepts the device operations vector of dev with
iops. The old dev_ops is
returned which may be used in a subsequent
dev_ops_restore
() call. The function sets the
SI_INTERCEPTED
flag in
dev.
dev_ops_restore
()
restores the device operations vector of dev to
oops. Also it unsets the
SI_INTERCEPTED
flag in
dev.
dev_ops_remove_all
()
destroys all the cdev_t with the given
ops and removes the devices from the
devfs(5) namespace. This function is useful when uninitializing a
driver.
dev_ops_remove_minor
()
destroys all the cdev_t with the given
ops and minor and removes the
devices from the
devfs(5) namespace.
devfs_scan_callback
()
calls the given callback function for every device
registered in
devfs(5). The callback function has the
following form:
devfs_scan_t mydev_scan_callback; void mydev_scan_callback(char *name, cdev_t dev, bool is_alias, void *arg) { };
The name argument is the alias' name (if
is_alias is true
) or the
cdev's si_name field.
HISTORY
The make_dev
() and
destroy_dev
() functions first appeared in
FreeBSD 4.0.
A major overhaul of these functions occurred in DragonFly 2.3 with the addition of devfs(5).