xref: /onnv-gate/usr/src/uts/common/sys/port_impl.h (revision 8587:b37cc627811a)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
51885Sraf  * Common Development and Distribution License (the "License").
61885Sraf  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
211885Sraf 
220Sstevel@tonic-gate /*
23*8587SPramod.Batni@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #ifndef	_SYS_PORT_IMPL_H
280Sstevel@tonic-gate #define	_SYS_PORT_IMPL_H
290Sstevel@tonic-gate 
300Sstevel@tonic-gate 
310Sstevel@tonic-gate #ifdef	__cplusplus
320Sstevel@tonic-gate extern "C" {
330Sstevel@tonic-gate #endif
340Sstevel@tonic-gate 
350Sstevel@tonic-gate /*
360Sstevel@tonic-gate  * Note:
370Sstevel@tonic-gate  * The contents of this file are private to the implementation of the
380Sstevel@tonic-gate  * Solaris system and event ports subsystem and are subject to change
390Sstevel@tonic-gate  * at any time without notice.
400Sstevel@tonic-gate  */
410Sstevel@tonic-gate 
420Sstevel@tonic-gate #include <sys/poll_impl.h>
430Sstevel@tonic-gate #include <sys/port.h>
440Sstevel@tonic-gate #include <sys/port_kernel.h>
450Sstevel@tonic-gate #include <sys/vnode.h>
464863Spraks #include <sys/fem.h>
470Sstevel@tonic-gate 
480Sstevel@tonic-gate /*
490Sstevel@tonic-gate  * port system call codes
500Sstevel@tonic-gate  */
510Sstevel@tonic-gate #define	PORT_CREATE	0	/* create a port */
520Sstevel@tonic-gate #define	PORT_ASSOCIATE	1	/* register object or object list */
530Sstevel@tonic-gate #define	PORT_DISSOCIATE	2	/* remove object association */
540Sstevel@tonic-gate #define	PORT_SEND	3	/* send user-defined event to a port */
550Sstevel@tonic-gate #define	PORT_SENDN	4	/* send user-defined event to a list of ports */
560Sstevel@tonic-gate #define	PORT_GET	5	/* receive object with events */
570Sstevel@tonic-gate #define	PORT_GETN	6	/* receive list of objects with events */
580Sstevel@tonic-gate #define	PORT_ALERT	7	/* set port in alert mode */
590Sstevel@tonic-gate #define	PORT_DISPATCH	8	/* dispatch object with events */
600Sstevel@tonic-gate 
610Sstevel@tonic-gate #define	PORT_SYS_NOPORT		0x100	/* system call without port-id */
620Sstevel@tonic-gate #define	PORT_SYS_NOSHARE	0x200	/* non shareable event */
630Sstevel@tonic-gate #define	PORT_CODE_MASK		0xff
640Sstevel@tonic-gate 
650Sstevel@tonic-gate /* port_dispatch() flags */
660Sstevel@tonic-gate #define	PORT_SHARE_EVENT	0x01	/* event can be shared between procs */
670Sstevel@tonic-gate 
680Sstevel@tonic-gate /* port limits */
690Sstevel@tonic-gate #define	PORT_MAX_LIST	8192	/* max. # of list ent. per syscall */
700Sstevel@tonic-gate 
710Sstevel@tonic-gate #ifdef _KERNEL
720Sstevel@tonic-gate 
730Sstevel@tonic-gate #define	PORT_SCACHE_SIZE	16	/* start source cache size */
740Sstevel@tonic-gate #define	PORT_SHASH(cookie)	(cookie & (PORT_SCACHE_SIZE-1))
750Sstevel@tonic-gate 
760Sstevel@tonic-gate /* portkev_flags masks */
770Sstevel@tonic-gate #define	PORT_CLEANUP_DONE	(PORT_KEV_FREE|PORT_KEV_DONEQ)
780Sstevel@tonic-gate #define	PORT_KEV_CACHE		(PORT_KEV_CACHED|PORT_KEV_SCACHED)
790Sstevel@tonic-gate #define	PORT_KEV_WIRED		(PORT_KEV_PRIVATE|PORT_KEV_CACHE)
800Sstevel@tonic-gate 
810Sstevel@tonic-gate #define	PORT_FREE_EVENT(pev)	(((pev)->portkev_flags & PORT_KEV_CACHE) == 0)
820Sstevel@tonic-gate 
830Sstevel@tonic-gate typedef struct port_alert {
840Sstevel@tonic-gate 	int	portal_events;		/* passed to alert event */
850Sstevel@tonic-gate 	pid_t	portal_pid;		/* owner of the alert mode */
860Sstevel@tonic-gate 	uintptr_t portal_object;	/* passed to alert event */
870Sstevel@tonic-gate 	void	*portal_user;		/* passed to alert event */
880Sstevel@tonic-gate } port_alert_t;
890Sstevel@tonic-gate 
900Sstevel@tonic-gate /*
910Sstevel@tonic-gate  * The port_queue_t structure is responsible for the management of all
920Sstevel@tonic-gate  * event activities within a port.
930Sstevel@tonic-gate  */
940Sstevel@tonic-gate typedef struct port_queue {
950Sstevel@tonic-gate 	kmutex_t 	portq_mutex;
960Sstevel@tonic-gate 	kcondvar_t	portq_closecv;
971885Sraf 	kcondvar_t	portq_block_cv;
980Sstevel@tonic-gate 	int		portq_flags;
990Sstevel@tonic-gate 	uint_t		portq_nent;	/* number of events in the queue */
1000Sstevel@tonic-gate 	uint_t		portq_nget;	/* events required for waiting thread */
1010Sstevel@tonic-gate 	uint_t		portq_tnent;	/* number of events in the temp queue */
1020Sstevel@tonic-gate 	int		portq_thrcnt;	/* # of threads waiting for events */
1030Sstevel@tonic-gate 	int		portq_getn;	/* # of threads retrieving events */
1040Sstevel@tonic-gate 	struct	portget	*portq_thread;	/* queue of waiting threads */
1050Sstevel@tonic-gate 	struct port_fdcache *portq_pcp;	/* fd cache */
1060Sstevel@tonic-gate 	list_t		portq_list;	/* port event list */
1070Sstevel@tonic-gate 	list_t		portq_get_list;	/* port event list for port_get(n) */
1080Sstevel@tonic-gate 	kmutex_t	portq_source_mutex;
1090Sstevel@tonic-gate 	port_source_t	**portq_scache;
1100Sstevel@tonic-gate 	port_alert_t	portq_alert;	/* alert event data	*/
1110Sstevel@tonic-gate } port_queue_t;
1120Sstevel@tonic-gate 
1130Sstevel@tonic-gate /* defines for portq_flags */
1140Sstevel@tonic-gate #define	PORTQ_ALERT	   0x01	/* port in alert state */
1150Sstevel@tonic-gate #define	PORTQ_CLOSE	   0x02 /* closing port	*/
1160Sstevel@tonic-gate #define	PORTQ_WAIT_EVENTS  0x04 /* waiting for new events */
1170Sstevel@tonic-gate #define	PORTQ_POLLIN	   0x08 /* events available in the event queue */
1180Sstevel@tonic-gate #define	PORTQ_POLLOUT	   0x10 /* space available for new events */
1191885Sraf #define	PORTQ_BLOCKED	   0x20 /* port is blocked by port_getn() */
1202948Spraks #define	PORTQ_POLLWK_PEND  0x40 /* pollwakeup is pending, blocks port close */
1210Sstevel@tonic-gate 
1220Sstevel@tonic-gate #define	VTOEP(v)  ((struct port *)(v->v_data))
1230Sstevel@tonic-gate #define	EPTOV(ep) ((struct vnode *)(ep)->port_vnode)
1240Sstevel@tonic-gate 
1250Sstevel@tonic-gate 
1260Sstevel@tonic-gate typedef	struct	port {
1270Sstevel@tonic-gate 	vnode_t		*port_vnode;
1280Sstevel@tonic-gate 	kmutex_t	port_mutex;
1290Sstevel@tonic-gate 	kcondvar_t	port_cv;	/* resource control */
1300Sstevel@tonic-gate 	uint_t		port_flags;
1310Sstevel@tonic-gate 	pid_t		port_pid;
1320Sstevel@tonic-gate 	int		port_fd;
1330Sstevel@tonic-gate 	uint_t		port_max_events; /* max. number of event per port */
1340Sstevel@tonic-gate 	uint_t		port_max_list;	/* max. number of list structs	*/
1350Sstevel@tonic-gate 	uint_t		port_curr;	/* current number of event structs */
1360Sstevel@tonic-gate 	pollhead_t	port_pollhd;
1370Sstevel@tonic-gate 	timespec_t	port_ctime;
1380Sstevel@tonic-gate 	uid_t		port_uid;
1390Sstevel@tonic-gate 	gid_t		port_gid;
1400Sstevel@tonic-gate 	port_queue_t	port_queue;	/* global queue */
1410Sstevel@tonic-gate } port_t;
1420Sstevel@tonic-gate 
1430Sstevel@tonic-gate /* defines for port_flags */
1440Sstevel@tonic-gate #define	PORT_INIT	0x01		/* port initialized */
1450Sstevel@tonic-gate #define	PORT_CLOSED	0x02		/* owner closed the port */
1460Sstevel@tonic-gate #define	PORT_EVENTS	0x04		/* waiting for event resources */
1470Sstevel@tonic-gate 
1480Sstevel@tonic-gate /*
1490Sstevel@tonic-gate  * global control structure of port framework
1500Sstevel@tonic-gate  */
1510Sstevel@tonic-gate typedef	struct	port_control {
1520Sstevel@tonic-gate 	kmutex_t	pc_mutex;
1530Sstevel@tonic-gate 	uint_t		pc_nents;	/* ports currently allocated */
1540Sstevel@tonic-gate 	struct	kmem_cache *pc_cache;	/* port event structures */
1550Sstevel@tonic-gate } port_control_t;
1560Sstevel@tonic-gate 
1570Sstevel@tonic-gate 
1580Sstevel@tonic-gate /*
1590Sstevel@tonic-gate  * Every thread waiting on an object will use this structure to store
1600Sstevel@tonic-gate  * all dependencies (flags, counters, events) before it awakes with
1610Sstevel@tonic-gate  * some events/transactions completed
1620Sstevel@tonic-gate  */
1630Sstevel@tonic-gate typedef	struct	portget {
1640Sstevel@tonic-gate 	int		portget_state;
1650Sstevel@tonic-gate 	uint_t		portget_nget;	/* number of expected events */
1660Sstevel@tonic-gate 	pid_t		portget_pid;
1670Sstevel@tonic-gate 	kcondvar_t	portget_cv;
1680Sstevel@tonic-gate 	port_alert_t	portget_alert;
1690Sstevel@tonic-gate 	struct	portget	*portget_next;
1700Sstevel@tonic-gate 	struct	portget	*portget_prev;
1710Sstevel@tonic-gate } portget_t;
1720Sstevel@tonic-gate 
1730Sstevel@tonic-gate /* defines for portget_state */
1740Sstevel@tonic-gate #define	PORTGET_ALERT		0x01	/* wake up and return alert event */
1750Sstevel@tonic-gate 
1760Sstevel@tonic-gate extern	port_control_t	port_control;
1770Sstevel@tonic-gate extern	uint_t	port_max_list;
1780Sstevel@tonic-gate 
1790Sstevel@tonic-gate /*
1800Sstevel@tonic-gate  * port_getn() needs this structure to manage inter-process event delivery.
1810Sstevel@tonic-gate  */
1820Sstevel@tonic-gate typedef struct	port_gettimer {
1830Sstevel@tonic-gate 	ushort_t	pgt_flags;
1840Sstevel@tonic-gate 	ushort_t	pgt_loop;
1854123Sdm120769 	int		pgt_timecheck;
1860Sstevel@tonic-gate 	timespec_t	pgt_rqtime;
1870Sstevel@tonic-gate 	timespec_t	*pgt_rqtp;
1880Sstevel@tonic-gate 	struct timespec	*pgt_timeout;
1890Sstevel@tonic-gate } port_gettimer_t;
1900Sstevel@tonic-gate 
1910Sstevel@tonic-gate /* pgt_flags */
1920Sstevel@tonic-gate #define	PORTGET_ONE		0x01	/* return only 1 object */
1930Sstevel@tonic-gate #define	PORTGET_WAIT_EVENTS	0x02	/* thread is waiting for new events */
1940Sstevel@tonic-gate 
1950Sstevel@tonic-gate /*
1960Sstevel@tonic-gate  * portfd_t is required to synchronize the association of fds with a port
1970Sstevel@tonic-gate  * and the per-process list of open files.
1980Sstevel@tonic-gate  * There is a pointer to a portfd structure in uf_entry_t.
1990Sstevel@tonic-gate  * If a fd is closed then closeandsetf() is able to detect the association of
2000Sstevel@tonic-gate  * the fd with a port or with a list of ports. closeandsetf() will dissociate
2010Sstevel@tonic-gate  * the fd from the port(s).
2020Sstevel@tonic-gate  */
2030Sstevel@tonic-gate typedef struct portfd {
2040Sstevel@tonic-gate 	struct polldat	pfd_pd;
2050Sstevel@tonic-gate 	struct portfd	*pfd_next;
2060Sstevel@tonic-gate 	struct portfd	*pfd_prev;
207*8587SPramod.Batni@Sun.COM 	kthread_t	*pfd_thread;
2080Sstevel@tonic-gate } portfd_t;
2090Sstevel@tonic-gate 
2100Sstevel@tonic-gate #define	PFTOD(pfd)	(&(pfd)->pfd_pd)
2110Sstevel@tonic-gate #define	PDTOF(pdp)	((struct portfd *)(pdp))
2120Sstevel@tonic-gate #define	PORT_FD_BUCKET(pcp, fd) \
2130Sstevel@tonic-gate 	(&(pcp)->pc_hash[((fd) % (pcp)->pc_hashsize)])
2140Sstevel@tonic-gate 
2150Sstevel@tonic-gate /*
2164863Spraks  * PORT_SOURCE_FILE -- File Events Notification sources
2174863Spraks  */
2184863Spraks #define	PORT_FOP_BUCKET(pcp, id) \
2194863Spraks 	(portfop_t **)(&(pcp)->pfc_hash[(((ulong_t)id >> 8) & \
2204863Spraks 	    (PORTFOP_HASHSIZE - 1))])
2214863Spraks 
2224863Spraks /*
2234863Spraks  * This structure is used to register a file object to be watched.
2244863Spraks  *
2254863Spraks  * The pfop_flags are protected by the vnode's pvp_mutex lock.
2264863Spraks  * The pfop list (vnode's list) is protected by the pvp_mutex when it is on
2274863Spraks  * the vnode's list.
2284863Spraks  *
2294863Spraks  * All the rest of the fields are protected by the port's source cache lock
2304863Spraks  * pfcp_lock.
2314863Spraks  */
2324863Spraks typedef struct  portfop {
2334863Spraks 	int		pfop_events;
2344863Spraks 	int		pfop_flags;	/* above flags. */
2354863Spraks 	uintptr_t	pfop_object;	/* object address */
2364863Spraks 	vnode_t		*pfop_vp;
2374863Spraks 	vnode_t		*pfop_dvp;
2384863Spraks 	port_t		*pfop_pp;
2394863Spraks 	fem_t		*pfop_fem;
2404863Spraks 	list_node_t	pfop_node;	/* list of pfop's per vnode */
2414863Spraks 	struct portfop	*pfop_hashnext;	/* hash list */
2424863Spraks 	pid_t		pfop_pid;	/* owner of portfop */
2434863Spraks 	struct portfop_cache *pfop_pcache;
2444863Spraks 	port_kevent_t	*pfop_pev;	/* event pointers */
2454863Spraks 	char		*pfop_cname;	/* file component name */
2464863Spraks 	int		pfop_clen;
2476005Spraks 	kthread_t	*pfop_callrid;	/* thread doing the associate */
2484863Spraks } portfop_t;
2494863Spraks 
2504863Spraks /*
2514863Spraks  * pfop_flags
2524863Spraks  */
2534863Spraks #define		PORT_FOP_ACTIVE		0x1
2544863Spraks #define		PORT_FOP_REMOVING	0x2
2554863Spraks #define		PORT_FOP_KEV_ONQ	0x4
2564863Spraks 
2574863Spraks typedef struct portfop_vfs {
2584863Spraks 	vfs_t		*pvfs;
2594863Spraks 	int		pvfs_unmount;	/* 1 if unmount in progress */
2604863Spraks 	list_t		pvfs_pvplist;	/* list of vnodes from */
2614863Spraks 	fsem_t		*pvfs_fsemp;
2624863Spraks 	struct portfop_vfs *pvfs_next;	/* hash list */
2634863Spraks } portfop_vfs_t;
2644863Spraks 
2654863Spraks typedef struct portfop_vfs_hash {
2664863Spraks 	kmutex_t	pvfshash_mutex;
2674863Spraks 	struct portfop_vfs *pvfshash_pvfsp;
2684863Spraks } portfop_vfs_hash_t;
2694863Spraks 
2704863Spraks typedef struct portfop_vp {
2714863Spraks 	vnode_t		*pvp_vp;
2724863Spraks 	kmutex_t	pvp_mutex;
2734863Spraks 	int		pvp_cnt;	/* number of watches */
2744863Spraks 	list_t		pvp_pfoplist;
2754863Spraks 	list_node_t	pvp_pvfsnode;
2764863Spraks 	struct portfop *pvp_lpfop;	/* oldest pfop */
2774863Spraks 	fem_t		*pvp_femp;
2784863Spraks 	struct portfop_vfs *pvp_pvfsp;
2794863Spraks } portfop_vp_t;
2804863Spraks 
2814863Spraks #define	PORTFOP_PVFSHASH_SZ	256
2824863Spraks #define	PORTFOP_PVFSHASH(vfsp)	(((uintptr_t)(vfsp) >> 4) % PORTFOP_PVFSHASH_SZ)
2834863Spraks 
2844863Spraks /*
2854863Spraks  * file operations flag.
2864863Spraks  */
2874863Spraks 
2884863Spraks /*
2894863Spraks  * PORT_SOURCE_FILE - vnode operations
2904863Spraks  */
2914863Spraks 
2924863Spraks #define	FOP_FILE_OPEN		0x00000001
2934863Spraks #define	FOP_FILE_READ		0x00000002
2944863Spraks #define	FOP_FILE_WRITE		0x00000004
2954863Spraks #define	FOP_FILE_MAP		0x00000008
2964863Spraks #define	FOP_FILE_IOCTL		0x00000010
2974863Spraks #define	FOP_FILE_CREATE		0x00000020
2984863Spraks #define	FOP_FILE_MKDIR		0x00000040
2994863Spraks #define	FOP_FILE_SYMLINK	0x00000080
3004863Spraks #define	FOP_FILE_LINK		0x00000100
3014863Spraks #define	FOP_FILE_RENAME		0x00000200
3024863Spraks #define	FOP_FILE_REMOVE		0x00000400
3034863Spraks #define	FOP_FILE_RMDIR		0x00000800
3044863Spraks #define	FOP_FILE_READDIR	0x00001000
3054863Spraks #define	FOP_FILE_RENAMESRC	0x00002000
3064863Spraks #define	FOP_FILE_RENAMEDST	0x00004000
3074863Spraks #define	FOP_FILE_REMOVEFILE	0x00008000
3084863Spraks #define	FOP_FILE_REMOVEDIR	0x00010000
3094863Spraks #define	FOP_FILE_SETSECATTR	0x00020000
3104863Spraks #define	FOP_FILE_SETATTR_ATIME	0x00040000
3114863Spraks #define	FOP_FILE_SETATTR_MTIME	0x00080000
3124863Spraks #define	FOP_FILE_SETATTR_CTIME	0x00100000
3134863Spraks #define	FOP_FILE_LINK_SRC	0x00200000
3144863Spraks 
3154863Spraks /*
3164863Spraks  * File modification event.
3174863Spraks  */
3184863Spraks #define	FOP_MODIFIED_MASK	(FOP_FILE_WRITE|FOP_FILE_CREATE \
3194863Spraks 				|FOP_FILE_REMOVE|FOP_FILE_LINK \
3204863Spraks 				|FOP_FILE_RENAMESRC|FOP_FILE_RENAMEDST \
3214863Spraks 				|FOP_FILE_MKDIR|FOP_FILE_RMDIR \
3224863Spraks 				|FOP_FILE_SYMLINK|FOP_FILE_SETATTR_MTIME)
3234863Spraks 
3244863Spraks /*
3254863Spraks  * File access event
3264863Spraks  */
3274863Spraks #define	FOP_ACCESS_MASK		(FOP_FILE_READ|FOP_FILE_READDIR \
3284863Spraks 				|FOP_FILE_MAP|FOP_FILE_SETATTR_ATIME)
3294863Spraks 
3304863Spraks /*
3314863Spraks  * File attrib event
3324863Spraks  */
3334863Spraks #define	FOP_ATTRIB_MASK		(FOP_FILE_WRITE|FOP_FILE_CREATE \
3344863Spraks 				|FOP_FILE_REMOVE|FOP_FILE_LINK \
3354863Spraks 				|FOP_FILE_RENAMESRC|FOP_FILE_RENAMEDST \
3364863Spraks 				|FOP_FILE_MKDIR|FOP_FILE_RMDIR \
3374863Spraks 				|FOP_FILE_SYMLINK|FOP_FILE_SETATTR_CTIME \
3384863Spraks 				|FOP_FILE_LINK_SRC|FOP_FILE_SETSECATTR)
3394863Spraks 
3404863Spraks 
3414863Spraks /*
3424863Spraks  * valid watchable events
3434863Spraks  */
3444863Spraks #define	FILE_EVENTS_MASK	(FILE_ACCESS|FILE_MODIFIED|FILE_ATTRIB \
3454863Spraks 				|FILE_NOFOLLOW)
3464863Spraks /* --- End file events --- */
3474863Spraks 
3484863Spraks /*
3490Sstevel@tonic-gate  * port_kstat_t contains the event port kernel values which are
3500Sstevel@tonic-gate  * exported to kstat.
3510Sstevel@tonic-gate  * Currently only the number of active ports is exported.
3520Sstevel@tonic-gate  */
3530Sstevel@tonic-gate typedef struct port_kstat {
3540Sstevel@tonic-gate 	kstat_named_t	pks_ports;
3550Sstevel@tonic-gate } port_kstat_t;
3560Sstevel@tonic-gate 
3570Sstevel@tonic-gate /* misc functions */
3580Sstevel@tonic-gate int	port_alloc_event_block(port_t *, int, int, struct port_kevent **);
3590Sstevel@tonic-gate void	port_push_eventq(port_queue_t *);
3604863Spraks int	port_remove_done_event(struct port_kevent *);
3610Sstevel@tonic-gate struct	port_kevent *port_get_kevent(list_t *, struct port_kevent *);
3621885Sraf void	port_block(port_queue_t *);
3631885Sraf void	port_unblock(port_queue_t *);
3640Sstevel@tonic-gate 
3650Sstevel@tonic-gate /* PORT_SOURCE_FD cache management */
3660Sstevel@tonic-gate void port_pcache_remove_fd(port_fdcache_t *, portfd_t *);
3673734Spraks int port_remove_fd_object(portfd_t *, struct port *, port_fdcache_t *);
3680Sstevel@tonic-gate 
3690Sstevel@tonic-gate /* file close management */
3700Sstevel@tonic-gate extern void addfd_port(int, portfd_t *);
3710Sstevel@tonic-gate extern void delfd_port(int, portfd_t *);
3720Sstevel@tonic-gate 
3730Sstevel@tonic-gate #endif	/* _KERNEL */
3740Sstevel@tonic-gate 
3750Sstevel@tonic-gate #ifdef	__cplusplus
3760Sstevel@tonic-gate }
3770Sstevel@tonic-gate #endif
3780Sstevel@tonic-gate 
3790Sstevel@tonic-gate #endif	/* _SYS_PORT_IMPL_H */
380