xref: /titanic_51/usr/src/uts/common/sys/dcopy_device.h (revision 17169044f903cb92234f23d0ba0ce43449614a4d)
1*17169044Sbrutus /*
2*17169044Sbrutus  * CDDL HEADER START
3*17169044Sbrutus  *
4*17169044Sbrutus  * The contents of this file are subject to the terms of the
5*17169044Sbrutus  * Common Development and Distribution License (the "License").
6*17169044Sbrutus  * You may not use this file except in compliance with the License.
7*17169044Sbrutus  *
8*17169044Sbrutus  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*17169044Sbrutus  * or http://www.opensolaris.org/os/licensing.
10*17169044Sbrutus  * See the License for the specific language governing permissions
11*17169044Sbrutus  * and limitations under the License.
12*17169044Sbrutus  *
13*17169044Sbrutus  * When distributing Covered Code, include this CDDL HEADER in each
14*17169044Sbrutus  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*17169044Sbrutus  * If applicable, add the following below this CDDL HEADER, with the
16*17169044Sbrutus  * fields enclosed by brackets "[]" replaced with your own identifying
17*17169044Sbrutus  * information: Portions Copyright [yyyy] [name of copyright owner]
18*17169044Sbrutus  *
19*17169044Sbrutus  * CDDL HEADER END
20*17169044Sbrutus  */
21*17169044Sbrutus 
22*17169044Sbrutus /*
23*17169044Sbrutus  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24*17169044Sbrutus  * Use is subject to license terms.
25*17169044Sbrutus  */
26*17169044Sbrutus 
27*17169044Sbrutus #ifndef _SYS_DCOPY_DEVICE_H
28*17169044Sbrutus #define	_SYS_DCOPY_DEVICE_H
29*17169044Sbrutus 
30*17169044Sbrutus #pragma ident	"%Z%%M%	%I%	%E% SMI"
31*17169044Sbrutus 
32*17169044Sbrutus #ifdef __cplusplus
33*17169044Sbrutus extern "C" {
34*17169044Sbrutus #endif
35*17169044Sbrutus 
36*17169044Sbrutus #include <sys/types.h>
37*17169044Sbrutus #include <sys/dcopy.h>
38*17169044Sbrutus 
39*17169044Sbrutus /*
40*17169044Sbrutus  * private command state. Space for this structure should be allocated during
41*17169044Sbrutus  * (*cb_cmd_alloc). The DMA driver must set dp_private in dcopy_cmd_t to point
42*17169044Sbrutus  * to the memory it allocated. Other than pr_device_cmd_private, the DMA driver
43*17169044Sbrutus  * should not touch any of the fields in this structure. pr_device_cmd_private
44*17169044Sbrutus  * is a private pointer for the DMA engine to use.
45*17169044Sbrutus  */
46*17169044Sbrutus struct dcopy_cmd_priv_s {
47*17169044Sbrutus 	/*
48*17169044Sbrutus 	 * we only init the state used to track a command which blocks when it
49*17169044Sbrutus 	 * actually blocks. pr_block_init tells us when we need to clean it
50*17169044Sbrutus 	 * up during a cmd_free.
51*17169044Sbrutus 	 */
52*17169044Sbrutus 	boolean_t		pr_block_init;
53*17169044Sbrutus 
54*17169044Sbrutus 	/* dcopy_poll blocking state */
55*17169044Sbrutus 	list_node_t		pr_poll_list_node;
56*17169044Sbrutus 	volatile boolean_t	pr_wait;
57*17169044Sbrutus 	kmutex_t		pr_mutex;
58*17169044Sbrutus 	kcondvar_t		pr_cv;
59*17169044Sbrutus 
60*17169044Sbrutus 	/* back pointer to the command */
61*17169044Sbrutus 	dcopy_cmd_t		pr_cmd;
62*17169044Sbrutus 
63*17169044Sbrutus 	/* shortcut to the channel we're on */
64*17169044Sbrutus 	struct dcopy_channel_s	*pr_channel;
65*17169044Sbrutus 
66*17169044Sbrutus 	/* DMA driver private pointer */
67*17169044Sbrutus 	void			*pr_device_cmd_private;
68*17169044Sbrutus };
69*17169044Sbrutus 
70*17169044Sbrutus /* cb_version */
71*17169044Sbrutus #define	DCOPY_DEVICECB_V0	0
72*17169044Sbrutus 
73*17169044Sbrutus typedef struct dcopy_device_chaninfo_s {
74*17169044Sbrutus 	uint_t	di_chan_num;
75*17169044Sbrutus } dcopy_device_chaninfo_t;
76*17169044Sbrutus 
77*17169044Sbrutus typedef struct dcopy_device_cb_s {
78*17169044Sbrutus 	int	cb_version;
79*17169044Sbrutus 	int	cb_res1;
80*17169044Sbrutus 
81*17169044Sbrutus 	/* allocate/free a DMA channel. See dcopy.h for return status  */
82*17169044Sbrutus 	int	(*cb_channel_alloc)(void *device_private,
83*17169044Sbrutus 		    dcopy_handle_t handle, int flags, uint_t size,
84*17169044Sbrutus 		    dcopy_query_channel_t *info, void *channel_private);
85*17169044Sbrutus 	void	(*cb_channel_free)(void *channel_private);
86*17169044Sbrutus 
87*17169044Sbrutus 	/* allocate/free a command. See dcopy.h for return status  */
88*17169044Sbrutus 	int	(*cb_cmd_alloc)(void *channel_private, int flags,
89*17169044Sbrutus 		    dcopy_cmd_t *cmd);
90*17169044Sbrutus 	void	(*cb_cmd_free)(void *channel_private, dcopy_cmd_t *cmd);
91*17169044Sbrutus 
92*17169044Sbrutus 	/*
93*17169044Sbrutus 	 * post a command/poll for command status. See dcopy.h for return
94*17169044Sbrutus 	 * status
95*17169044Sbrutus 	 */
96*17169044Sbrutus 	int	(*cb_cmd_post)(void *channel_private, dcopy_cmd_t cmd);
97*17169044Sbrutus 	int	(*cb_cmd_poll)(void *channel_private, dcopy_cmd_t cmd);
98*17169044Sbrutus 
99*17169044Sbrutus 	/*
100*17169044Sbrutus 	 * if dcopy_device_unregister() returns DCOPY_PENDING, dcopy will
101*17169044Sbrutus 	 * call this routine when all the channels are no longer being
102*17169044Sbrutus 	 * used and have been free'd up. e.g. it's safe for the DMA driver
103*17169044Sbrutus 	 * to detach.
104*17169044Sbrutus 	 *   status = DCOPY_SUCCESS || DCOPY_FAILURE
105*17169044Sbrutus 	 */
106*17169044Sbrutus 	void	(*cb_unregister_complete)(void *device_private, int status);
107*17169044Sbrutus } dcopy_device_cb_t;
108*17169044Sbrutus 
109*17169044Sbrutus 
110*17169044Sbrutus typedef struct dcopy_device_info_s {
111*17169044Sbrutus 	dev_info_t		*di_dip;
112*17169044Sbrutus 	dcopy_device_cb_t	*di_cb; /* must be a static array */
113*17169044Sbrutus 	uint_t			di_num_dma;
114*17169044Sbrutus 	uint_t			di_maxxfer;
115*17169044Sbrutus 	uint_t			di_capabilities;
116*17169044Sbrutus 	uint64_t		di_id;
117*17169044Sbrutus } dcopy_device_info_t;
118*17169044Sbrutus 
119*17169044Sbrutus typedef struct dcopy_device_s *dcopy_device_handle_t;
120*17169044Sbrutus 
121*17169044Sbrutus /* dcopy_device_notify() status */
122*17169044Sbrutus #define	DCOPY_COMPLETION	0
123*17169044Sbrutus 
124*17169044Sbrutus /*
125*17169044Sbrutus  * dcopy_device_register()
126*17169044Sbrutus  *   register the DMA device with dcopy.
127*17169044Sbrutus  *    return status => DCOPY_FAILURE, DCOPY_SUCCESS
128*17169044Sbrutus  */
129*17169044Sbrutus int dcopy_device_register(void *device_private, dcopy_device_info_t *info,
130*17169044Sbrutus     dcopy_device_handle_t *handle);
131*17169044Sbrutus 
132*17169044Sbrutus /*
133*17169044Sbrutus  * dcopy_device_unregister()
134*17169044Sbrutus  *   try to unregister the DMA device with dcopy. If the DMA engines are
135*17169044Sbrutus  *   still being used by upper layer modules, DCOPY_PENDING will be returned.
136*17169044Sbrutus  *    return status => DCOPY_FAILURE, DCOPY_SUCCESS, DCOPY_PENDING
137*17169044Sbrutus  *      if DCOPY_PENDING, (*cb_unregister_complete)() will be called when
138*17169044Sbrutus  *      completed.
139*17169044Sbrutus  */
140*17169044Sbrutus int dcopy_device_unregister(dcopy_device_handle_t *handle);
141*17169044Sbrutus 
142*17169044Sbrutus /*
143*17169044Sbrutus  * dcopy_device_channel_notify()
144*17169044Sbrutus  *   Notify dcopy of an event.
145*17169044Sbrutus  *     dcopy_handle_t handle => what was passed into (*cb_alloc)()
146*17169044Sbrutus  *     status => DCOPY_COMPLETION
147*17169044Sbrutus  */
148*17169044Sbrutus void dcopy_device_channel_notify(dcopy_handle_t handle, int status);
149*17169044Sbrutus 
150*17169044Sbrutus #ifdef __cplusplus
151*17169044Sbrutus }
152*17169044Sbrutus #endif
153*17169044Sbrutus 
154*17169044Sbrutus #endif /* _SYS_DCOPY_DEVICE_H */
155