File:  [DragonFly] / src / sys / sys / conf.h
Revision 1.7: download - view: text, annotated - select for diffs
Wed May 19 22:53:02 2004 UTC (10 years, 3 months ago) by dillon
Branches: MAIN
CVS tags: HEAD, DragonFly_1_0_RC1
Device layer rollup commit.

* cdevsw_add() is now required.  cdevsw_add() and cdevsw_remove() may specify
  a mask/match indicating the range of supported minor numbers.  Multiple
  cdevsw_add()'s using the same major number, but distinctly different
  ranges, may be issued.  All devices that failed to call cdevsw_add() before
  now do.

* cdevsw_remove() now automatically marks all devices within its supported
  range as being destroyed.

* vnode->v_rdev is no longer resolved when the vnode is created.  Instead,
  only v_udev (a newly added field) is resolved.  v_rdev is resolved when
  the vnode is opened and cleared on the last close.

* A great deal of code was making rather dubious assumptions with regards
  to the validity of devices associated with vnodes, primarily due to
  the persistence of a device structure due to being indexed by (major, minor)
  instead of by (cdevsw, major, minor).  In particular, if you run a program
  which connects to a USB device and then you pull the USB device and plug
  it back in, the vnode subsystem will continue to believe that the device
  is open when, in fact, it isn't (because it was destroyed and recreated).

  In particular, note that all the VFS mount procedures now check devices
  via v_udev instead of v_rdev prior to calling VOP_OPEN(), since v_rdev
  is NULL prior to the first open.

* The disk layer's device interaction has been rewritten.  The disk layer
  (i.e. the slice and disklabel management layer) no longer overloads
  its data onto the device structure representing the underlying physical
  disk.  Instead, the disk layer uses the new cdevsw_add() functionality
  to register its own cdevsw using the underlying device's major number,
  and simply does NOT register the underlying device's cdevsw.  No
  confusion is created because the device hash is now based on
  (cdevsw,major,minor) rather then (major,minor).

  NOTE: This also means that underlying raw disk devices may use the entire
  device minor number instead of having to reserve the bits used by the disk
  layer, and also means that can we (theoretically) stack a fully
  disklabel-supported 'disk' on top of any block device.

* The new reference counting scheme prevents this by associating a device
  with a cdevsw and disconnecting the device from its cdevsw when the cdevsw
  is removed.  Additionally, all udev2dev() lookups run through the cdevsw
  mask/match and only successfully find devices still associated with an
  active cdevsw.

* Major work on MFS:  MFS no longer shortcuts vnode and device creation.  It
  now creates a real vnode and a real device and implements real open and
  close VOPs.  Additionally, due to the disk layer changes, MFS is no longer
  limited to 255 mounts.  The new limit is 16 million.  Since MFS creates a
  real device node, mount_mfs will now create a real /dev/mfs<PID> device
  that can be read from userland (e.g. so you can dump an MFS filesystem).

* BUF AND DEVICE STRATEGY changes.  The struct buf contains a b_dev field.
  In order to properly handle stacked devices we now require that the b_dev
  field be initialized before the device strategy routine is called.  This
  required some additional work in various VFS implementations.  To enforce
  this requirement, biodone() now sets b_dev to NODEV.  The new disk layer
  will adjust b_dev before forwarding a request to the actual physical
  device.

* A bug in the ISO CD boot sequence which resulted in a panic has been fixed.

Testing by: lots of people, but David Rhodus found the most aggregious bugs.

    1: /*-
    2:  * Copyright (c) 1990, 1993
    3:  *	The Regents of the University of California.  All rights reserved.
    4:  * (c) UNIX System Laboratories, Inc.
    5:  * All or some portions of this file are derived from material licensed
    6:  * to the University of California by American Telephone and Telegraph
    7:  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
    8:  * the permission of UNIX System Laboratories, Inc.
    9:  *
   10:  * Redistribution and use in source and binary forms, with or without
   11:  * modification, are permitted provided that the following conditions
   12:  * are met:
   13:  * 1. Redistributions of source code must retain the above copyright
   14:  *    notice, this list of conditions and the following disclaimer.
   15:  * 2. Redistributions in binary form must reproduce the above copyright
   16:  *    notice, this list of conditions and the following disclaimer in the
   17:  *    documentation and/or other materials provided with the distribution.
   18:  * 3. All advertising materials mentioning features or use of this software
   19:  *    must display the following acknowledgement:
   20:  *	This product includes software developed by the University of
   21:  *	California, Berkeley and its contributors.
   22:  * 4. Neither the name of the University nor the names of its contributors
   23:  *    may be used to endorse or promote products derived from this software
   24:  *    without specific prior written permission.
   25:  *
   26:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   27:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   28:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   29:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   30:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   31:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   32:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   33:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   34:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   35:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   36:  * SUCH DAMAGE.
   37:  *
   38:  *	@(#)conf.h	8.5 (Berkeley) 1/9/95
   39:  * $FreeBSD: src/sys/sys/conf.h,v 1.103.2.6 2002/03/11 01:14:55 dd Exp $
   40:  * $DragonFly: src/sys/sys/conf.h,v 1.7 2004/05/19 22:53:02 dillon Exp $
   41:  */
   42: 
   43: #ifndef _SYS_CONF_H_
   44: #define	_SYS_CONF_H_
   45: 
   46: #include <sys/queue.h>
   47: 
   48: #define SPECNAMELEN	15
   49: 
   50: struct tty;
   51: struct disk;
   52: struct vnode;
   53: struct lwkt_port;
   54: 
   55: struct specinfo {
   56: 	u_int		si_flags;
   57: 	udev_t		si_udev;
   58: 	LIST_ENTRY(specinfo)	si_hash;
   59: 	SLIST_HEAD(, vnode) si_hlist;
   60: 	char		si_name[SPECNAMELEN + 1];
   61: 	void		*si_drv1;
   62: 	void		*si_drv2;
   63: 	struct cdevsw	*si_devsw;	/* direct device switch */
   64: 	struct lwkt_port *si_port;	/* direct port dispatch */
   65: 	int		si_iosize_max;	/* maximum I/O size (for physio &al) */
   66: 	int		si_refs;
   67: 	union {
   68: 		struct {
   69: 			struct tty *__sit_tty;
   70: 		} __si_tty;
   71: 		struct {
   72: 			struct disk *__sid_disk;
   73: 			struct mount *__sid_mountpoint;
   74: 			int __sid_bsize_phys; /* min physical block size */
   75: 			int __sid_bsize_best; /* optimal block size */
   76: 		} __si_disk;
   77: 	} __si_u;
   78: };
   79: 
   80: #define SI_STASHED	0x0001	/* created in stashed storage */
   81: #define SI_HASHED	0x0002	/* in (maj,min) hash table */
   82: #define SI_ADHOC	0x0004	/* created via make_adhoc_dev() or udev2dev() */
   83: 
   84: #define si_tty		__si_u.__si_tty.__sit_tty
   85: #define si_disk		__si_u.__si_disk.__sid_disk
   86: #define si_mountpoint	__si_u.__si_disk.__sid_mountpoint
   87: #define si_bsize_phys	__si_u.__si_disk.__sid_bsize_phys
   88: #define si_bsize_best	__si_u.__si_disk.__sid_bsize_best
   89: 
   90: #define CDEVSW_ALL_MINORS	0	/* mask of 0 always matches 0 */
   91: 
   92: /*
   93:  * Special device management
   94:  */
   95: #define	SPECHSZ	64
   96: #define	SPECHASH(rdev)	(((unsigned)(minor(rdev)))%SPECHSZ)
   97: 
   98: /*
   99:  * Definitions of device driver entry switches
  100:  */
  101: 
  102: struct buf;
  103: struct proc;
  104: struct uio;
  105: struct knote;
  106: 
  107: /*
  108:  * Note: d_thread_t is provided as a transition aid for those drivers
  109:  * that treat struct proc/struct thread as an opaque data type and
  110:  * exist in substantially the same form in both 4.x and 5.x.  Writers
  111:  * of drivers that dips into the d_thread_t structure should use
  112:  * struct thread or struct proc as appropriate for the version of the
  113:  * OS they are using.  It is provided in lieu of each device driver
  114:  * inventing its own way of doing this.  While it does violate style(9)
  115:  * in a number of ways, this violation is deemed to be less
  116:  * important than the benefits that a uniform API between releases
  117:  * gives.
  118:  *
  119:  * Users of struct thread/struct proc that aren't device drivers should
  120:  * not use d_thread_t.
  121:  */
  122: 
  123: struct thread;
  124: struct lwkt_port;
  125: 
  126: typedef struct thread d_thread_t;
  127: typedef int d_clone_t (dev_t dev);
  128: typedef int d_open_t (dev_t dev, int oflags, int devtype, d_thread_t *td);
  129: typedef int d_close_t (dev_t dev, int fflag, int devtype, d_thread_t *td);
  130: typedef void d_strategy_t (struct buf *bp);
  131: typedef int d_ioctl_t (dev_t dev, u_long cmd, caddr_t data,
  132: 			   int fflag, d_thread_t *td);
  133: typedef int d_dump_t (dev_t dev, u_int count, u_int blkno, u_int secsize);
  134: typedef int d_psize_t (dev_t dev);
  135: 
  136: typedef int d_read_t (dev_t dev, struct uio *uio, int ioflag);
  137: typedef int d_write_t (dev_t dev, struct uio *uio, int ioflag);
  138: typedef int d_poll_t (dev_t dev, int events, d_thread_t *td);
  139: typedef int d_kqfilter_t (dev_t dev, struct knote *kn);
  140: typedef int d_mmap_t (dev_t dev, vm_offset_t offset, int nprot);
  141: 
  142: typedef int l_open_t (dev_t dev, struct tty *tp);
  143: typedef int l_close_t (struct tty *tp, int flag);
  144: typedef int l_read_t (struct tty *tp, struct uio *uio, int flag);
  145: typedef int l_write_t (struct tty *tp, struct uio *uio, int flag);
  146: typedef int l_ioctl_t (struct tty *tp, u_long cmd, caddr_t data,
  147: 			   int flag, d_thread_t *td);
  148: typedef int l_rint_t (int c, struct tty *tp);
  149: typedef int l_start_t (struct tty *tp);
  150: typedef int l_modem_t (struct tty *tp, int flag);
  151: 
  152: /*
  153:  * XXX: The dummy argument can be used to do what strategy1() never
  154:  * did anywhere:  Create a per device flag to lock the device during
  155:  * label/slice surgery, all calls with a dummy == 0 gets stalled on
  156:  * a queue somewhere, whereas dummy == 1 are let through.  Once out
  157:  * of surgery, reset the flag and restart all the stuff on the stall
  158:  * queue.
  159:  */
  160: #define BUF_STRATEGY(bp, dummy) dev_dstrategy((bp)->b_dev, bp)
  161: /*
  162:  * Types for d_flags.
  163:  */
  164: #define	D_TAPE	0x0001
  165: #define	D_DISK	0x0002
  166: #define	D_TTY	0x0004
  167: #define	D_MEM	0x0008
  168: 
  169: #define	D_TYPEMASK	0xffff
  170: 
  171: /*
  172:  * Flags for d_flags.
  173:  */
  174: #define	D_MEMDISK	0x00010000	/* memory type disk */
  175: #define	D_NAGGED	0x00020000	/* nagged about missing make_dev() */
  176: #define	D_CANFREE	0x00040000	/* can free blocks */
  177: #define	D_TRACKCLOSE	0x00080000	/* track all closes */
  178: #define D_MASTER	0x00100000	/* used by pty/tty code */
  179: #define	D_KQFILTER	0x00200000	/* has kqfilter entry */
  180: 
  181: /*
  182:  * Character device switch table.
  183:  *
  184:  * NOTE: positions are hard coded for static structure initialization.
  185:  */
  186: struct cdevsw {
  187: 	const char	*d_name;	/* base device name, e.g. 'vn' */
  188: 	int		d_maj;		/* major (char) device number */
  189: 	u_int		d_flags;	/* D_ flags */
  190: 	struct lwkt_port *d_port;	/* port (template only) */
  191: 	d_clone_t	*d_clone;	/* clone from base cdevsw */
  192: 
  193: 	/*
  194: 	 * Old style vectors are used only if d_port is NULL when the cdevsw
  195: 	 * is added to the system.   They have been renamed to prevent misuse.
  196: 	 */
  197: 	d_open_t	*old_open;
  198: 	d_close_t	*old_close;
  199: 	d_read_t	*old_read;
  200: 	d_write_t	*old_write;
  201: 	d_ioctl_t	*old_ioctl;
  202: 	d_poll_t	*old_poll;
  203: 	d_mmap_t	*old_mmap;
  204: 	d_strategy_t	*old_strategy;
  205: 	d_dump_t	*old_dump;
  206: 	d_psize_t	*old_psize;
  207: 	d_kqfilter_t	*old_kqfilter;
  208: 	void		(*old_dummy1)(void);	/* expansion space */
  209: 	void		(*old_dummy2)(void);
  210: 	void		(*old_dummy3)(void);
  211: 	void		(*old_dummy4)(void);
  212: 	int		d_refs;			/* ref count */
  213: 	void		*d_data;		/* custom driver data */
  214: };
  215: 
  216: struct cdevlink {
  217: 	struct cdevlink	*next;
  218: 	u_int		mask;
  219: 	u_int		match;
  220: 	struct cdevsw	*devsw;
  221: };
  222: 
  223: /*
  224:  * Line discipline switch table
  225:  */
  226: struct linesw {
  227: 	l_open_t	*l_open;
  228: 	l_close_t	*l_close;
  229: 	l_read_t	*l_read;
  230: 	l_write_t	*l_write;
  231: 	l_ioctl_t	*l_ioctl;
  232: 	l_rint_t	*l_rint;
  233: 	l_start_t	*l_start;
  234: 	l_modem_t	*l_modem;
  235: 	u_char		l_hotchar;
  236: };
  237: 
  238: #ifdef _KERNEL
  239: extern struct linesw linesw[];
  240: extern int nlinesw;
  241: 
  242: int ldisc_register (int , struct linesw *);
  243: void ldisc_deregister (int);
  244: #define LDISC_LOAD 	-1		/* Loadable line discipline */
  245: #endif
  246: 
  247: /*
  248:  * Swap device table
  249:  */
  250: struct swdevt {
  251: 	udev_t	sw_dev;			/* For quasibogus swapdev reporting */
  252: 	int	sw_flags;
  253: 	int	sw_nblks;
  254: 	struct	vnode *sw_vp;
  255: 	dev_t	sw_device;
  256: };
  257: #define	SW_FREED	0x01
  258: #define	SW_SEQUENTIAL	0x02
  259: #define	sw_freed	sw_flags	/* XXX compat */
  260: 
  261: #ifdef _KERNEL
  262: d_open_t	noopen;
  263: d_close_t	noclose;
  264: d_read_t	noread;
  265: d_write_t	nowrite;
  266: d_ioctl_t	noioctl;
  267: d_clone_t	noclone;
  268: d_mmap_t	nommap;
  269: d_kqfilter_t	nokqfilter;
  270: d_strategy_t	nostrategy;
  271: d_poll_t	nopoll;
  272: d_psize_t	nopsize;
  273: d_dump_t	nodump;
  274: 
  275: #define NUMCDEVSW 256
  276: 
  277: d_open_t	nullopen;
  278: d_close_t	nullclose;
  279: 
  280: l_ioctl_t	l_nullioctl;
  281: l_read_t	l_noread;
  282: l_write_t	l_nowrite;
  283: 
  284: struct module;
  285: 
  286: struct devsw_module_data {
  287: 	int	(*chainevh)(struct module *, int, void *); /* next handler */
  288: 	void	*chainarg;	/* arg for next event handler */
  289: 	/* Do not initialize fields hereafter */
  290: };
  291: 
  292: #define DEV_MODULE(name, evh, arg)					\
  293: static moduledata_t name##_mod = {					\
  294:     #name,								\
  295:     evh,								\
  296:     arg									\
  297: };									\
  298: DECLARE_MODULE(name, name##_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE)
  299: 
  300: extern struct cdevsw dead_cdevsw;
  301: 
  302: void	compile_devsw(struct cdevsw *);
  303: int	cdevsw_add (struct cdevsw *, u_int mask, u_int match);
  304: struct cdevsw *cdevsw_add_override (dev_t, u_int mask, u_int match);
  305: struct lwkt_port *cdevsw_dev_override(dev_t dev, struct lwkt_port *port);
  306: 
  307: int	cdevsw_remove (struct cdevsw *, u_int mask, u_int match);
  308: struct cdevsw *cdevsw_get (int x, int y);
  309: void	cdevsw_release (struct cdevsw *);
  310: int	count_dev (dev_t dev);
  311: int	count_udev (udev_t dev);
  312: void	destroy_dev (dev_t dev);
  313: void	destroy_all_dev (struct cdevsw *, u_int mask, u_int match);
  314: void	release_dev (dev_t dev);
  315: dev_t	reference_dev (dev_t dev);
  316: struct cdevsw *devsw (dev_t dev);
  317: const char *devtoname (dev_t dev);
  318: void	freedev (dev_t dev);
  319: int	iszerodev (dev_t dev);
  320: dev_t	make_dev (struct cdevsw *devsw, int minor, uid_t uid, gid_t gid, int perms, const char *fmt, ...) __printflike(6, 7);
  321: dev_t	make_adhoc_dev (struct cdevsw *devsw, int minor);
  322: dev_t	make_sub_dev (dev_t dev, int minor);
  323: int	lminor (dev_t dev);
  324: void	setconf (void);
  325: dev_t	getdiskbyname(char *name);
  326: int	dev_is_good(dev_t dev);
  327: 
  328: /*
  329:  * XXX: This included for when DEVFS resurfaces 
  330:  */
  331: 
  332: #define		UID_ROOT	0
  333: #define		UID_BIN		3
  334: #define		UID_UUCP	66
  335: 
  336: #define		GID_WHEEL	0
  337: #define		GID_KMEM	2
  338: #define		GID_OPERATOR	5
  339: #define		GID_BIN		7
  340: #define		GID_GAMES	13
  341: #define		GID_DIALER	68
  342: 
  343: #endif /* _KERNEL */
  344: 
  345: #endif /* !_SYS_CONF_H_ */