DragonFly On-Line Manual Pages
MAKE_DEV(9) DragonFly Kernel Developer's Manual MAKE_DEV(9)
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
The make_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 in the same
way as make_dev() would, but the device will not appear in the devfs(5)
namespace. This function is usually used in the clone handler of an
autoclone device created by make_autoclone_dev().
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.
SEE ALSO
devfs(5), make_autoclone_dev(9)
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).
DragonFly 5.9-DEVELOPMENT June 27, 2020 DragonFly 5.9-DEVELOPMENT