xref: /illumos-gate/usr/src/uts/common/sys/dcopy.h (revision 8b80e8cb6855118d46f605e91b5ed4ce83417395)
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 /*
23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef _SYS_DCOPY_H
28 #define	_SYS_DCOPY_H
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35 
36 #include <sys/types.h>
37 
38 /*
39  * *** This interface is for private use by the IP stack only ***
40  */
41 
42 /* Private dcopy/uioa interface for dcopy to enable/disable dcopy KAPI */
43 extern void uioa_dcopy_enable();
44 extern void uioa_dcopy_disable();
45 
46 /* Function return status */
47 #define	DCOPY_FAILURE		(-1)
48 #define	DCOPY_SUCCESS		(0)
49 #define	DCOPY_NORESOURCES	(1) /* _alloc & _cmd_alloc, _cmd_post only */
50 #define	DCOPY_PENDING		(0x10) /* dcopy_poll(), dcopy_unregister() */
51 #define	DCOPY_COMPLETED		(0x20) /* dcopy_poll() only */
52 
53 
54 /* dq_version */
55 #define	DCOPY_QUERY_V0	0
56 
57 typedef struct dcopy_query_s {
58 	int		dq_version; /* DCOPY_QUERY_V0 */
59 	uint_t		dq_num_channels; /* number of dma channels */
60 } dcopy_query_t;
61 
62 /*
63  * dcopy_query()
64  *   query for the number of DMA engines usable in the system.
65  */
66 void dcopy_query(dcopy_query_t *query);
67 
68 
69 typedef struct dcopy_channel_s *dcopy_handle_t;
70 
71 /* dcopy_alloc() and dcopy_cmd_alloc() common flags */
72 #define	DCOPY_SLEEP	(0)
73 #define	DCOPY_NOSLEEP	(1 << 0)
74 
75 /*
76  * dcopy_alloc()
77  *   Allocate a DMA channel which is used for posting DMA requests. Note: this
78  *   does not give the caller exclusive access to the DMA engine. Commands
79  *   posted to a channel will complete in order.
80  *     flags - (DCOPY_SLEEP, DCOPY_NOSLEEP)
81  *     returns => DCOPY_FAILURE, DCOPY_SUCCESS, DCOPY_NORESOURCES
82  */
83 int dcopy_alloc(int flags, dcopy_handle_t *handle);
84 
85 /*
86  * dcopy_free()
87  *   Free the DMA channel. The client can no longer use the handle to post or
88  *   poll for status on posts which were previously done on this channel.
89  */
90 void dcopy_free(dcopy_handle_t *handle);
91 
92 /* dq_version */
93 #define	DCOPY_QUERY_CHANNEL_V0	0
94 
95 /* Per DMA channel info */
96 typedef struct dcopy_query_channel_s {
97 	int		qc_version; /* DCOPY_QUERY_CHANNEL_V0 */
98 
99 	/* Does DMA channel support DCA */
100 	boolean_t	qc_dca_supported;
101 
102 	/* device id and device specific capabilities */
103 	uint64_t	qc_id;
104 	uint64_t	qc_capabilities;
105 
106 	/*
107 	 * DMA channel size. This may not be the same as the number of posts
108 	 * that the DMA channel can handle since a post may consume 1 or more
109 	 * entries.
110 	 */
111 	uint64_t	qc_channel_size;
112 
113 	/* DMA channel number within the device. Not unique across devices */
114 	uint64_t	qc_chan_num;
115 } dcopy_query_channel_t;
116 
117 /*
118  * dcopy_query_channel()
119  *   query DMA engines capabilities
120  */
121 void dcopy_query_channel(dcopy_handle_t handle, dcopy_query_channel_t *query);
122 
123 
124 /* dp_version */
125 #define	DCOPY_CMD_V0	0
126 
127 /* dp_cmd */
128 #define	DCOPY_CMD_COPY	0x1
129 
130 /* dp_flags */
131 /*
132  * DCOPY_CMD_QUEUE
133  *    Hint to queue up the post but don't notify the DMA engine. This can be
134  *    used as an optimization when multiple posts are going to be queued up and
135  *    you only want notify the DMA engine after the last post. Note, this does
136  *    not mean the DMA engine won't process the request since it could notice
137  *    it anyway.
138  * DCOPY_CMD_NOSTAT
139  *    Don't generate a status. If this flag is used, You cannot poll for
140  *    completion status on this command. This can be a useful performance
141  *    optimization if your posting multiple commands and just want to poll on
142  *    the last command.
143  * DCOPY_CMD_DCA
144  *    If DCA is supported, direct this and all future command data (until the
145  *    next command with DCOPY_POST_DCA set) to the processor specified in
146  *    dp_dca_id. This flag is ignored if DCA is not supported.
147  * DCOPY_CMD_INTR
148  *    Generate an interrupt when command completes. This flag is required if
149  *    the caller is going to call dcopy_cmd_poll(() with DCOPY_POLL_BLOCK set
150  *    for this command.
151  */
152 #define	DCOPY_CMD_NOFLAGS	(0)
153 #define	DCOPY_CMD_QUEUE		(1 << 0)
154 #define	DCOPY_CMD_NOSTAT	(1 << 1)
155 #define	DCOPY_CMD_DCA		(1 << 2)
156 #define	DCOPY_CMD_INTR		(1 << 3)
157 
158 typedef struct dcopy_cmd_copy_s {
159 	uint64_t	cc_source; /* Source physical address */
160 	uint64_t	cc_dest; /* Destination physical address */
161 	size_t		cc_size;
162 } dcopy_cmd_copy_t;
163 
164 typedef union dcopy_cmd_u {
165 	dcopy_cmd_copy_t	copy;
166 } dcopy_cmd_u_t;
167 
168 typedef struct dcopy_cmd_priv_s *dcopy_cmd_priv_t;
169 
170 struct dcopy_cmd_s {
171 	uint_t			dp_version; /* DCOPY_CMD_V0 */
172 	uint_t			dp_flags;
173 	uint64_t		dp_cmd;
174 	dcopy_cmd_u_t   	dp;
175 	uint32_t		dp_dca_id;
176 	dcopy_cmd_priv_t	dp_private;
177 };
178 typedef struct dcopy_cmd_s *dcopy_cmd_t;
179 
180 
181 /*
182  * dcopy_cmd_alloc() specific flags
183  *   DCOPY_ALLOC_LINK - when set, the caller passes in a previously alloced
184  *     command in cmd. dcopy_cmd_alloc() will allocate a new command and
185  *     link it to the old command. The caller can use this to build a
186  *     chain of commands, keeping only the last cmd alloced. calling
187  *     dcopy_cmd_free() with the last cmd alloced in the chain will free all of
188  *     the commands in the chain. dcopy_cmd_post() and dcopy_cmd_poll() have
189  *     no knowledge of a chain of commands.  It's only used for alloc/free.
190  */
191 #define	DCOPY_ALLOC_LINK	(1 << 16)
192 
193 /*
194  * dcopy_cmd_alloc()
195  *   allocate a command. A command can be re-used after it completes.
196  *     flags - (DCOPY_SLEEP || DCOPY_NOSLEEP), DCOPY_ALLOC_LINK
197  *     returns => DCOPY_FAILURE, DCOPY_SUCCESS, DCOPY_NORESOURCES
198  */
199 int dcopy_cmd_alloc(dcopy_handle_t handle, int flags, dcopy_cmd_t *cmd);
200 
201 /*
202  * dcopy_cmd_free()
203  *   free the command. This call cannot be called after dcopy_free().
204  */
205 void dcopy_cmd_free(dcopy_cmd_t *cmd);
206 
207 /*
208  * dcopy_cmd_post()
209  *   post a command (allocated from dcopy_cmd_alloc()) to the DMA channel
210  *     returns => DCOPY_FAILURE, DCOPY_SUCCESS, DCOPY_NORESOURCES
211  */
212 int dcopy_cmd_post(dcopy_cmd_t cmd);
213 
214 /* dcopy_cmd_poll() flags */
215 #define	DCOPY_POLL_NOFLAGS	(0)
216 #define	DCOPY_POLL_BLOCK	(1 << 0)
217 
218 /*
219  * dcopy_cmd_poll()
220  *   poll on completion status of a previous post. This call cannot be called
221  *   after dcopy_free().
222  *
223  *   if flags == DCOPY_POLL_NOFLAGS, return status can be DCOPY_FAILURE,
224  *   DCOPY_PENDING, or DCOPY_COMPLETED.
225  *
226  *   if flags & DCOPY_POLL_BLOCK, return status can be DCOPY_FAILURE or
227  *   DCOPY_COMPLETED. DCOPY_POLL_BLOCK can only be set in base context.
228  *
229  *   The command cannot be re-used or freed until the command has completed
230  *   (e.g. DCOPY_FAILURE or DCOPY_COMPLETED).
231  */
232 int dcopy_cmd_poll(dcopy_cmd_t cmd, int flags);
233 
234 
235 #ifdef __cplusplus
236 }
237 #endif
238 
239 #endif /* _SYS_DCOPY_H */
240