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 (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #ifndef	_SYS_SCSI_TARGETS_SD_XBUF_H
27 #define	_SYS_SCSI_TARGETS_SD_XBUF_H
28 
29 #ifdef	__cplusplus
30 extern "C" {
31 #endif
32 
33 #if	defined(_KERNEL) || defined(_KMEMUSER)
34 
35 #include <sys/note.h>
36 #include <sys/taskq.h>
37 
38 
39 #if (defined(__fibre))
40 /*
41  * These #defines are to avoid namespace collisions that occur because this
42  * code is currently used to compile two seperate driver modules: sd and ssd.
43  * All function names need to be treated this way (even if declared static)
44  * in order to allow the debugger to resolve the names properly.
45  * It is anticipated that in the near future the ssd module will be obsoleted,
46  * at which time this ugliness should go away.
47  */
48 #define	ddi_xbuf_attr_create		ssd_ddi_xbuf_attr_create
49 #define	ddi_xbuf_attr_destroy		ssd_ddi_xbuf_attr_destroy
50 #define	ddi_xbuf_attr_register_devinfo	ssd_ddi_xbuf_attr_register_devinfo
51 #define	ddi_xbuf_attr_unregister_devinfo	\
52 					ssd_ddi_xbuf_attr_unregister_devinfo
53 #define	ddi_xbuf_qstrategy		ssd_ddi_xbuf_qstrategy
54 #define	ddi_xbuf_done			ssd_ddi_xbuf_done
55 #define	ddi_xbuf_get			ssd_ddi_xbuf_get
56 #define	xbuf_iostart			ssd_xbuf_iostart
57 #define	xbuf_dispatch			ssd_xbuf_dispatch
58 #define	xbuf_restart_callback		ssd_xbuf_restart_callback
59 #define	xbuf_tq				ssd_xbuf_tq
60 #define	xbuf_attr_tq_minalloc		ssd_xbuf_attr_tq_minalloc
61 #define	xbuf_attr_tq_maxalloc		ssd_xbuf_attr_tq_maxalloc
62 #define	xbuf_mutex			ssd_xbuf_mutex
63 #define	xbuf_refcount			ssd_xbuf_refcount
64 
65 #define	ddi_xbuf_dispatch		ssd_ddi_xbuf_dispatch
66 
67 #define	ddi_xbuf_flushq			ssd_ddi_xbuf_flushq
68 #define	ddi_xbuf_attr_setup_brk		ssd_ddi_xbuf_attr_setup_brk
69 
70 #endif
71 
72 
73 typedef void *		ddi_xbuf_t;
74 
75 
76 /*
77  * Primary attribute struct for buf extensions.
78  */
79 struct __ddi_xbuf_attr {
80 	kmutex_t	xa_mutex;
81 	size_t		xa_allocsize;
82 	uint32_t	xa_pending;	/* call to xbuf_iostart() is iminent */
83 	uint32_t	xa_active_limit;
84 	uint32_t	xa_active_count;
85 	uint32_t	xa_active_lowater;
86 	struct buf	*xa_headp;	/* FIFO buf queue head ptr */
87 	struct buf	*xa_tailp;	/* FIFO buf queue tail ptr */
88 	kmutex_t	xa_reserve_mutex;
89 	uint32_t	xa_reserve_limit;
90 	uint32_t	xa_reserve_count;
91 	void		*xa_reserve_headp;
92 	void		(*xa_strategy)(struct buf *, ddi_xbuf_t, void *);
93 	void		*xa_attr_arg;
94 	timeout_id_t	xa_timeid;
95 	taskq_t		*xa_tq;
96 	struct buf	*xa_flush_headp;
97 	struct buf	*xa_flush_tailp;
98 	size_t		xa_brksize;
99 };
100 
101 
102 typedef struct __ddi_xbuf_attr	*ddi_xbuf_attr_t;
103 
104 #define	DDII
105 
106 DDII   ddi_xbuf_attr_t ddi_xbuf_attr_create(size_t xsize,
107 	void (*xa_strategy)(struct buf *bp, ddi_xbuf_t xp, void *attr_arg),
108 	void *attr_arg, uint32_t active_limit, uint32_t reserve_limit,
109 	major_t major, int flags);
110 DDII   void ddi_xbuf_attr_destroy(ddi_xbuf_attr_t xap);
111 DDII   void ddi_xbuf_attr_register_devinfo(ddi_xbuf_attr_t xbuf_attr,
112 	dev_info_t *dip);
113 DDII   void ddi_xbuf_attr_unregister_devinfo(ddi_xbuf_attr_t xbuf_attr,
114 	dev_info_t *dip);
115 DDII   int ddi_xbuf_qstrategy(struct buf *bp, ddi_xbuf_attr_t xap);
116 DDII   int ddi_xbuf_done(struct buf *bp, ddi_xbuf_attr_t xap);
117 DDII   ddi_xbuf_t ddi_xbuf_get(struct buf *bp, ddi_xbuf_attr_t xap);
118 DDII   void ddi_xbuf_dispatch(ddi_xbuf_attr_t xap);
119 DDII   void ddi_xbuf_flushq(ddi_xbuf_attr_t xap, int (*funcp)(struct buf *));
120 DDII   int ddi_xbuf_attr_setup_brk(ddi_xbuf_attr_t xap, size_t size);
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