xref: /dragonfly/share/man/man9/make_dev.9 (revision 3cb6a21a)
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