1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef	_SYS_SCSI_TARGETS_SD_XBUF_H
28 #define	_SYS_SCSI_TARGETS_SD_XBUF_H
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 #ifdef	__cplusplus
33 extern "C" {
34 #endif
35 
36 #if	defined(_KERNEL) || defined(_KMEMUSER)
37 
38 #include <sys/note.h>
39 #include <sys/taskq.h>
40 
41 
42 #if (defined(__fibre))
43 /*
44  * These #defines are to avoid namespace collisions that occur because this
45  * code is currently used to compile two seperate driver modules: sd and ssd.
46  * All function names need to be treated this way (even if declared static)
47  * in order to allow the debugger to resolve the names properly.
48  * It is anticipated that in the near future the ssd module will be obsoleted,
49  * at which time this ugliness should go away.
50  */
51 #define	ddi_xbuf_attr_create		ssd_ddi_xbuf_attr_create
52 #define	ddi_xbuf_attr_destroy		ssd_ddi_xbuf_attr_destroy
53 #define	ddi_xbuf_attr_register_devinfo	ssd_ddi_xbuf_attr_register_devinfo
54 #define	ddi_xbuf_attr_unregister_devinfo	\
55 					ssd_ddi_xbuf_attr_unregister_devinfo
56 #define	ddi_xbuf_qstrategy		ssd_ddi_xbuf_qstrategy
57 #define	ddi_xbuf_done			ssd_ddi_xbuf_done
58 #define	ddi_xbuf_get			ssd_ddi_xbuf_get
59 #define	xbuf_iostart			ssd_xbuf_iostart
60 #define	xbuf_dispatch			ssd_xbuf_dispatch
61 #define	xbuf_restart_callback		ssd_xbuf_restart_callback
62 #define	xbuf_tq				ssd_xbuf_tq
63 #define	xbuf_attr_tq_minalloc		ssd_xbuf_attr_tq_minalloc
64 #define	xbuf_attr_tq_maxalloc		ssd_xbuf_attr_tq_maxalloc
65 #define	xbuf_mutex			ssd_xbuf_mutex
66 #define	xbuf_refcount			ssd_xbuf_refcount
67 
68 #define	ddi_xbuf_dispatch		ssd_ddi_xbuf_dispatch
69 
70 #define	ddi_xbuf_flushq			ssd_ddi_xbuf_flushq
71 
72 #endif
73 
74 
75 typedef void *		ddi_xbuf_t;
76 
77 
78 /*
79  * Primary attribute struct for buf extensions.
80  */
81 struct __ddi_xbuf_attr {
82 	kmutex_t	xa_mutex;
83 	size_t		xa_allocsize;
84 	uint32_t	xa_pending;	/* call to xbuf_iostart() is iminent */
85 	uint32_t	xa_active_limit;
86 	uint32_t	xa_active_count;
87 	uint32_t	xa_active_lowater;
88 	struct buf	*xa_headp;	/* FIFO buf queue head ptr */
89 	struct buf	*xa_tailp;	/* FIFO buf queue tail ptr */
90 	kmutex_t	xa_reserve_mutex;
91 	uint32_t	xa_reserve_limit;
92 	uint32_t	xa_reserve_count;
93 	void		*xa_reserve_headp;
94 	void		(*xa_strategy)(struct buf *, ddi_xbuf_t, void *);
95 	void		*xa_attr_arg;
96 	timeout_id_t	xa_timeid;
97 	taskq_t		*xa_tq;
98 	struct buf	*xa_flush_headp;
99 	struct buf	*xa_flush_tailp;
100 };
101 
102 
103 typedef struct __ddi_xbuf_attr	*ddi_xbuf_attr_t;
104 
105 #define	DDII
106 
107 DDII   ddi_xbuf_attr_t ddi_xbuf_attr_create(size_t xsize,
108 	void (*xa_strategy)(struct buf *bp, ddi_xbuf_t xp, void *attr_arg),
109 	void *attr_arg, uint32_t active_limit, uint32_t reserve_limit,
110 	major_t major, int flags);
111 DDII   void ddi_xbuf_attr_destroy(ddi_xbuf_attr_t xap);
112 DDII   void ddi_xbuf_attr_register_devinfo(ddi_xbuf_attr_t xbuf_attr,
113 	dev_info_t *dip);
114 DDII   void ddi_xbuf_attr_unregister_devinfo(ddi_xbuf_attr_t xbuf_attr,
115 	dev_info_t *dip);
116 DDII   int ddi_xbuf_qstrategy(struct buf *bp, ddi_xbuf_attr_t xap);
117 DDII   void ddi_xbuf_done(struct buf *bp, ddi_xbuf_attr_t xap);
118 DDII   ddi_xbuf_t ddi_xbuf_get(struct buf *bp, ddi_xbuf_attr_t xap);
119 DDII   void ddi_xbuf_dispatch(ddi_xbuf_attr_t xap);
120 DDII   void ddi_xbuf_flushq(ddi_xbuf_attr_t xap, int (*funcp)(struct buf *));
121 
122 
123 /*
124  * The buf extension facility utilizes an internal pool of threads to perform
125  * callbacks into the given xa_strategy routines.  Clients of the facility
126  * do not need to be concerned with the management of these threads as this is
127  * handled by the framework.  However clients may recommend certain operational
128  * parameters for the framework to consider in performing its thread mangement
129  * by specifying one of the following flags to ddi_xbuf_attr_create():
130  *
131  * DDI_XBUF_QTHREAD_SYSTEM: This should be specified when the client driver
132  * provides an xa_strategy routine that is "well behaved", ie, does not
133  * block for memory, shared resources, or device states that may take a long
134  * or indeterminate amount of time to satisfy. The 'major' argument to
135  * ddi_xbuf_attr_create() may be zero if this flag is specified. (?)
136  *
137  * DDI_XBUF_QTHREAD_DRIVER: This should be specified when the client driver
138  * performs blocking operations within its xa_strategy routine that would
139  * make it unsuitable for being called from a shared system thread.  The
140  * 'major' argument to ddi_xbuf_attr_create() must be the return value of
141  * ddi_driver_major() when this flag is specified.
142  *
143  * DDI_XBUF_QTHREAD_PRIVATE: This should be specified when the client driver
144  * would prefer to have a dedicated thread for a given ddi_xbuf_attr_t
145  * instantiation. The 'major' argument to ddi_xbuf_attr_create() must be
146  * the return value of ddi_driver_major() when this flag is specified. Note
147  * that this option ought to be used judiciously in order to avoid excessive
148  * consumption of system resources, especially if the client driver has a
149  * large number of ddi_xbuf_attr_t instantiations.
150  *
151  * Note that the above flags are mutually exclusive.  Also note that the
152  * behaviors specified by these flags are merely advisory to the framework,
153  * and the framework is still free to implement its internal thread management
154  * policies as necessary and that these policies are opaque to drivers.
155  */
156 
157 #define	DDI_XBUF_QTHREAD_SYSTEM		0x01
158 #define	DDI_XBUF_QTHREAD_DRIVER		0x02
159 #define	DDI_XBUF_QTHREAD_PRIVATE	0x04
160 
161 
162 #endif	/* defined(_KERNEL) || defined(_KMEMUSER) */
163 
164 
165 #ifdef	__cplusplus
166 }
167 #endif
168 
169 
170 #endif	/* _SYS_SCSI_TARGETS_SD_XBUF_H */
171