summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/dcopy_device.h
blob: 25e95b2aa817f53c3b33b4262118b6acec4ecd7a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef _SYS_DCOPY_DEVICE_H
#define	_SYS_DCOPY_DEVICE_H

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#ifdef __cplusplus
extern "C" {
#endif

#include <sys/types.h>
#include <sys/dcopy.h>

/*
 * private command state. Space for this structure should be allocated during
 * (*cb_cmd_alloc). The DMA driver must set dp_private in dcopy_cmd_t to point
 * to the memory it allocated. Other than pr_device_cmd_private, the DMA driver
 * should not touch any of the fields in this structure. pr_device_cmd_private
 * is a private pointer for the DMA engine to use.
 */
struct dcopy_cmd_priv_s {
	/*
	 * we only init the state used to track a command which blocks when it
	 * actually blocks. pr_block_init tells us when we need to clean it
	 * up during a cmd_free.
	 */
	boolean_t		pr_block_init;

	/* dcopy_poll blocking state */
	list_node_t		pr_poll_list_node;
	volatile boolean_t	pr_wait;
	kmutex_t		pr_mutex;
	kcondvar_t		pr_cv;

	/* back pointer to the command */
	dcopy_cmd_t		pr_cmd;

	/* shortcut to the channel we're on */
	struct dcopy_channel_s	*pr_channel;

	/* DMA driver private pointer */
	void			*pr_device_cmd_private;
};

/* cb_version */
#define	DCOPY_DEVICECB_V0	0

typedef struct dcopy_device_chaninfo_s {
	uint_t	di_chan_num;
} dcopy_device_chaninfo_t;

typedef struct dcopy_device_cb_s {
	int	cb_version;
	int	cb_res1;

	/* allocate/free a DMA channel. See dcopy.h for return status  */
	int	(*cb_channel_alloc)(void *device_private,
		    dcopy_handle_t handle, int flags, uint_t size,
		    dcopy_query_channel_t *info, void *channel_private);
	void	(*cb_channel_free)(void *channel_private);

	/* allocate/free a command. See dcopy.h for return status  */
	int	(*cb_cmd_alloc)(void *channel_private, int flags,
		    dcopy_cmd_t *cmd);
	void	(*cb_cmd_free)(void *channel_private, dcopy_cmd_t *cmd);

	/*
	 * post a command/poll for command status. See dcopy.h for return
	 * status
	 */
	int	(*cb_cmd_post)(void *channel_private, dcopy_cmd_t cmd);
	int	(*cb_cmd_poll)(void *channel_private, dcopy_cmd_t cmd);

	/*
	 * if dcopy_device_unregister() returns DCOPY_PENDING, dcopy will
	 * call this routine when all the channels are no longer being
	 * used and have been free'd up. e.g. it's safe for the DMA driver
	 * to detach.
	 *   status = DCOPY_SUCCESS || DCOPY_FAILURE
	 */
	void	(*cb_unregister_complete)(void *device_private, int status);
} dcopy_device_cb_t;


typedef struct dcopy_device_info_s {
	dev_info_t		*di_dip;
	dcopy_device_cb_t	*di_cb; /* must be a static array */
	uint_t			di_num_dma;
	uint_t			di_maxxfer;
	uint_t			di_capabilities;
	uint64_t		di_id;
} dcopy_device_info_t;

typedef struct dcopy_device_s *dcopy_device_handle_t;

/* dcopy_device_notify() status */
#define	DCOPY_COMPLETION	0

/*
 * dcopy_device_register()
 *   register the DMA device with dcopy.
 *    return status => DCOPY_FAILURE, DCOPY_SUCCESS
 */
int dcopy_device_register(void *device_private, dcopy_device_info_t *info,
    dcopy_device_handle_t *handle);

/*
 * dcopy_device_unregister()
 *   try to unregister the DMA device with dcopy. If the DMA engines are
 *   still being used by upper layer modules, DCOPY_PENDING will be returned.
 *    return status => DCOPY_FAILURE, DCOPY_SUCCESS, DCOPY_PENDING
 *      if DCOPY_PENDING, (*cb_unregister_complete)() will be called when
 *      completed.
 */
int dcopy_device_unregister(dcopy_device_handle_t *handle);

/*
 * dcopy_device_channel_notify()
 *   Notify dcopy of an event.
 *     dcopy_handle_t handle => what was passed into (*cb_alloc)()
 *     status => DCOPY_COMPLETION
 */
void dcopy_device_channel_notify(dcopy_handle_t handle, int status);

#ifdef __cplusplus
}
#endif

#endif /* _SYS_DCOPY_DEVICE_H */