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