Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
MAKE_DEV(9)		   Kernel Developer's Manual		   MAKE_DEV(9)

NAME
       make_dev,   make_dev_cred,   make_dev_credf,   make_dev_p,  make_dev_s,
       make_dev_alias,	 make_dev_alias_p,   destroy_dev,   destroy_dev_sched,
       destroy_dev_sched_cb,  destroy_dev_drain,  dev_depends -- manage	cdev's
       and DEVFS registration for devices

SYNOPSIS
       #include	<sys/param.h>
       #include	<sys/conf.h>

       void
       make_dev_args_init(struct make_dev_args *args);

       int
       make_dev_s(struct   make_dev_args   *args,    struct    cdev    **cdev,
	   const char *fmt, ...);

       int
       make_dev_alias_p(int  flags,  struct  cdev  **cdev,  struct cdev	*pdev,
	   const char *fmt, ...);

       void
       destroy_dev(struct cdev *dev);

       void
       destroy_dev_sched(struct	cdev *dev);

       void
       destroy_dev_sched_cb(struct cdev	*dev, void (*cb)(void *), void *arg);

       void
       destroy_dev_drain(struct	cdevsw *csw);

       void
       dev_depends(struct cdev *pdev, struct cdev *cdev);

       LEGACY INTERFACES

       struct cdev *
       make_dev(struct	cdevsw	*cdevsw,  int  unit,  uid_t  uid,  gid_t  gid,
	   int perms, const char *fmt, ...);

       struct cdev *
       make_dev_cred(struct  cdevsw  *cdevsw,  int  unit,  struct  ucred  *cr,
	   uid_t uid, gid_t gid, int perms, const char *fmt, ...);

       struct cdev *
       make_dev_credf(int   flags,   struct   cdevsw   *cdevsw,	  int	 unit,
	   struct ucred	*cr, uid_t uid,	gid_t gid, int perms, const char *fmt,
	   ...);

       int
       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,
	   ...);

       struct cdev *
       make_dev_alias(struct cdev *pdev, const char *fmt, ...);

DESCRIPTION
       The  make_dev_s()  function  creates a cdev structure for a new device,
       which is	returned into the cdev argument.  It also notifies devfs(5) of
       the presence of the new device, that causes corresponding nodes	to  be
       created.	 Besides this, a devctl(4) notification	is sent.  The function
       takes  the structure struct make_dev_args args, which specifies the pa-
       rameters	for the	device creation:

	     struct make_dev_args {
		     size_t	      mda_size;
		     int	      mda_flags;
		     struct cdevsw   *mda_devsw;
		     struct ucred    *mda_cr;
		     uid_t	      mda_uid;
		     gid_t	      mda_gid;
		     int	      mda_mode;
		     int	      mda_unit;
		     void	     *mda_si_drv1;
		     void	     *mda_si_drv2;
	     };
       Before use and filling with the desired values, the structure  must  be
       initialized  by	the  make_dev_args_init() function, which ensures that
       future kernel interface expansion does not affect driver	source code or
       binary interface.

       The created device will be owned	by args.mda_uid, with the group	owner-
       ship as args.mda_gid.  The name is the expansion	of fmt	and  following
       arguments  as  printf(9)	 would print it.  The name determines its path
       under /dev or other devfs(5) mount point	 and  may  contain  slash  `/'
       characters to denote subdirectories.  The permissions of	the file spec-
       ified in	args.mda_mode 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 */
	     #ifndef _POSIX_SOURCE
	     #define S_ISTXT 0001000
	     #endif

       The  args.mda_cr	 argument specifies credentials	that will be stored in
       the si_cred member of the initialized struct cdev.

       The args.mda_flags argument alters the operation	of  make_dev_s.()  The
       following values	are currently accepted:

	     MAKEDEV_REF	      reference	the created device
	     MAKEDEV_NOWAIT	      do not sleep, the	call may fail
	     MAKEDEV_WAITOK	      allow  the  function to sleep to satisfy
				      malloc
	     MAKEDEV_ETERNAL	      created device will be never destroyed
	     MAKEDEV_CHECKNAME	      return an	error if the  device  name  is
				      invalid or already exists

       Only  MAKEDEV_NOWAIT,  MAKEDEV_WAITOK  and MAKEDEV_CHECKNAME values are
       accepted	for the	make_dev_alias_p() function.

       The  MAKEDEV_WAITOK  flag  is  assumed  if  none	  of   MAKEDEV_WAITOK,
       MAKEDEV_NOWAIT is specified.

       The dev_clone(9)	event handler shall specify MAKEDEV_REF	flag when cre-
       ating  a	 device	 in response to	lookup,	to avoid race where the	device
       created is destroyed immediately	after devfs_lookup(9) drops his	refer-
       ence to cdev.

       The MAKEDEV_ETERNAL flag	allows the kernel to not  acquire  some	 locks
       when translating	system calls into the cdevsw methods calls.  It	is re-
       sponsibility  of	 the  driver author to make sure that destroy_dev() is
       never called on the  returned  cdev.   For  the	convenience,  use  the
       MAKEDEV_ETERNAL_KLD  flag for the code that can be compiled into	kernel
       or loaded (and unloaded)	as loadable module.

       A panic will occur if the MAKEDEV_CHECKNAME flag	is not	specified  and
       the device name is invalid or already exists.

       The make_dev_p()	use of the form

	     struct cdev *dev;
	     int res;
	     res = make_dev_p(flags, &dev, cdevsw, cred, uid, gid, perms, name);
       is equivalent to	the code

	     struct cdev *dev;
	     struct make_dev_args args;
	     int res;

	     make_dev_args_init(&args);
	     args.mda_flags = flags;
	     args.mda_devsw = cdevsw;
	     args.mda_cred = cred;
	     args.mda_uid = uid;
	     args.mda_gid = gid;
	     args.mda_mode = perms;
	     res = make_dev_s(&args, &dev, name);

       Similarly, the make_dev_credf() function	call is	equivalent to

		     (void) make_dev_s(&args, &dev, name);
       In  other  words,  make_dev_credf() does	not allow the caller to	obtain
       the return value, and in	kernels	compiled with the INVARIANTS  options,
       the function asserts that the device creation succeeded.

       The make_dev_cred() function is equivalent to the call

	     make_dev_credf(0, cdevsw, unit, cr, uid, gid, perms, fmt, ...);

       The make_dev() function call is the same	as

	     make_dev_credf(0, cdevsw, unit, NULL, uid,	gid, perms, fmt, ...);

       The make_dev_alias_p() function takes the returned cdev from make_dev()
       and  makes  another  (aliased) name for this device.  It	is an error to
       call make_dev_alias_p() prior to	calling	make_dev().

       The make_dev_alias() function is	similar	to make_dev_alias_p()  but  it
       returns the resulting aliasing *cdev and	may not	return an error.

       The  cdev  returned  by	make_dev_s()  and  make_dev_alias_p()  has two
       fields, si_drv1 and si_drv2, that are available to store	 state.	  Both
       fields  are  of type void *, and	can be initialized simultaneously with
       the cdev	allocation by filling  args.mda_si_drv1	 and  args.mda_si_drv2
       members	of  the	 make_dev_s()  argument	structure, or filled after the
       cdev is allocated, if using legacy interfaces.  In the latter case, the
       driver should handle the	race of	accessing  uninitialized  si_drv1  and
       si_drv2	itself.	  These	 are  designed to replace the unit argument to
       make_dev(), which can be	obtained with dev2unit().

       The destroy_dev() function takes	the returned cdev from make_dev()  and
       destroys	the registration for that device.  The notification is sent to
       devctl(4)  about	 the  destruction event.  Do not call destroy_dev() on
       devices that were created with make_dev_alias().

       The dev_depends() function establishes a	parent-child relationship  be-
       tween  two devices.  The	net effect is that a destroy_dev() of the par-
       ent device will also result in the destruction of the child  device(s),
       if  any exist.  A device	may simultaneously be a	parent and a child, so
       it is possible to build a complete hierarchy.

       The  destroy_dev_sched_cb()  function  schedules	  execution   of   the
       destroy_dev()  for  the	specified  cdev	 in  the  safe context.	 After
       destroy_dev() is	finished, and if the supplied  cb  is  not  NULL,  the
       callback	 cb  is	 called,  with	argument arg.  The destroy_dev_sched()
       function	is the same as

	     destroy_dev_sched_cb(cdev,	NULL, NULL);

       The d_close() driver method cannot call destroy_dev() directly.	 Doing
       so  causes  deadlock  when destroy_dev()	waits for all threads to leave
       the driver methods.  Also, because destroy_dev()	sleeps,	no  non-sleep-
       able  locks  may	be held	over the call.	The destroy_dev_sched()	family
       of functions overcome these issues.

       The device driver may call the destroy_dev_drain() function to wait un-
       til all devices that have supplied csw as cdevsw, are destroyed.	  This
       is  useful when driver knows that destroy_dev_sched() is	called for all
       instantiated  devices,  but  need  to  postpone	module	unload	 until
       destroy_dev() is	actually finished for all of them.

RETURN VALUES
       If  successful,	make_dev_s() and make_dev_p() will return 0, otherwise
       they will return	an error.  If successful, make_dev_credf() will	return
       a valid cdev pointer, otherwise it will return NULL.

ERRORS
       The make_dev_s(), make_dev_p() and make_dev_alias_p() calls  will  fail
       and the device will be not registered if:

       [ENOMEM]		  The  MAKEDEV_NOWAIT  flag was	specified and a	memory
			  allocation request could not be satisfied.

       [ENAMETOOLONG]	  The MAKEDEV_CHECKNAME	flag  was  specified  and  the
			  provided device name is longer than SPECNAMELEN.

       [EINVAL]		  The  MAKEDEV_CHECKNAME  flag	was  specified and the
			  provided device name is empty,  contains  a  "."  or
			  ".." path component or ends with `/'.

       [EINVAL]		  The  MAKEDEV_CHECKNAME  flag	was  specified and the
			  provided device name contains	invalid	characters.

       [EEXIST]		  The MAKEDEV_CHECKNAME	flag  was  specified  and  the
			  provided device name already exists.

SEE ALSO
       devctl(4), devfs(5), dev_clone(9)

HISTORY
       The   make_dev()	  and	destroy_dev()	functions  first  appeared  in
       FreeBSD	4.0.   The  function  make_dev_alias()	 first	 appeared   in
       FreeBSD 4.1.  The function dev_depends()	first appeared in FreeBSD 5.0.
       The	  functions	  make_dev_credf(),	  destroy_dev_sched(),
       destroy_dev_sched_cb() first appeared in	 FreeBSD  7.0.	 The  function
       make_dev_p()  first appeared in FreeBSD 8.2.  The function make_dev_s()
       first appeared in FreeBSD 11.0.

FreeBSD	13.2			 March 2, 2016			   MAKE_DEV(9)

NAME | SYNOPSIS | DESCRIPTION | RETURN VALUES | ERRORS | SEE ALSO | HISTORY

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=make_dev_s&sektion=9&manpath=FreeBSD+14.2-RELEASE+and+Ports>

home | help