/alps/pcitool

To get this branch, use:
bzr branch http://darksoft.org/webbzr/alps/pcitool
45 by root
North West Logick DMA implementation
1
#ifndef _PCILIB_KMEM_H
2
#define _PCILIB_KMEM_H
3
236 by Suren A. Chilingaryan
Big redign of model structures
4
typedef struct pcilib_s pcilib_t;
201 by Suren A. Chilingaryan
Xilinx benchmark
5
typedef struct pcilib_kmem_list_s pcilib_kmem_list_t;
6
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
7
#define PCILIB_KMEM_PAGE_SIZE	0x1000			/**< Default pages size is 4096 bytes */
275 by Suren A. Chilingaryan
Integration of software registers
8
236 by Suren A. Chilingaryan
Big redign of model structures
9
typedef enum {
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
10
    PCILIB_TRISTATE_NO = 0,				/**< All values are evaluated as false */
11
    PCILIB_TRISTATE_PARTIAL = 1,			/**< Some values are evaluated as false and others as true */
12
    PCILIB_TRISTATE_YES = 2				/**< All values are evaluated as true */
236 by Suren A. Chilingaryan
Big redign of model structures
13
} pcilib_tristate_t;
14
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
15
#define PCILIB_KMEM_TYPE_MASK	0xFFFF0000		/**< Mask selecting the general type in \ref pcilib_kmem_type_t. The subtype is may specify DMA mapping and other minor details of allocation */
16
#define PCILIB_KMEM_USE_TYPE(use) (use >> 16)		/**< Returns general use of the kernel buffers, for instance DMA buffer (see \ref pcilib_kmem_use_t) */
17
#define PCILIB_KMEM_USE_SUBTYPE(use) (use & 0xFFFF)	/**< Additional information about the use of the kernel buffers. The actual meaning depends on general use, for instance in case of DMA buffers the subtype specifies DMA engine */
18
#define PCILIB_KMEM_USE(type, subtype) ((pcilib_kmem_use_t)(((type) << 16)|(subtype)))		/**< Constructs full use from use type and use subtype */
236 by Suren A. Chilingaryan
Big redign of model structures
19
20
typedef enum {
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
21
    PCILIB_KMEM_TYPE_CONSISTENT = 0x00000,		/**< Consistent memory can be simultaneously accessed by the device and applications and is normally used for DMA descriptors */
22
    PCILIB_KMEM_TYPE_PAGE = 0x10000,			/**< A number of physically consequitive pages of memory */
23
    PCILIB_KMEM_TYPE_DMA_S2C_PAGE = 0x10001,		/**< Memory pages mapped for S2C DMA operation (device reads) */
24
    PCILIB_KMEM_TYPE_DMA_C2S_PAGE = 0x10002,		/**< Memory pages mapped for C2S DMA operation (device writes) */
25
    PCILIB_KMEM_TYPE_REGION = 0x20000,			/**< Just map buffers to the contiguous user-supplied memory region (normally reserved during the boot with option memmap=512M$2G) */
26
    PCILIB_KMEM_TYPE_REGION_S2C = 0x20001,		/**< Memory region mapped for S2C DMA operation (device reads) */
27
    PCILIB_KMEM_TYPE_REGION_C2S = 0x20002		/**< Memory region mapped for C2S DMA operation (device writes */
236 by Suren A. Chilingaryan
Big redign of model structures
28
} pcilib_kmem_type_t;
29
30
typedef enum {
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
31
    PCILIB_KMEM_USE_STANDARD = 0,			/**< Undefined use, buffers of standard use are not grouped together and can be used individually */
32
    PCILIB_KMEM_USE_DMA_RING = 1,			/**< The kmem used for DMA descriptor, the sub type specifies the id of considered DMA engine */
33
    PCILIB_KMEM_USE_DMA_PAGES = 2,			/**< The kmem used for DMA buffers, the sub type specifies the address of considered DMA engine (can be engine specific) */
34
    PCILIB_KMEM_USE_SOFTWARE_REGISTERS = 3,		/**< The kmem used to store software registers, the sub type holds the bank address */
35
    PCILIB_KMEM_USE_LOCKS = 4,				/**< The kmem used to hold locks, the sub type is not used */
36
    PCILIB_KMEM_USE_USER = 0x10				/**< Further uses can be defined by event engines */
236 by Suren A. Chilingaryan
Big redign of model structures
37
} pcilib_kmem_use_t;
38
39
typedef enum {
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
40
    PCILIB_KMEM_SYNC_BIDIRECTIONAL = 0,			/**< Two-way synchronization (should not be used) */
41
    PCILIB_KMEM_SYNC_TODEVICE = 1,			/**< Allow device to read the data in the DMA-able buffer */
42
    PCILIB_KMEM_SYNC_FROMDEVICE = 2			/**< Allow application to read the data written by device in the DMA-able buffer */
236 by Suren A. Chilingaryan
Big redign of model structures
43
} pcilib_kmem_sync_direction_t;
44
45
typedef enum {
46
    PCILIB_KMEM_FLAG_REUSE = 1,				/**< Try to reuse existing buffer with the same use & item */
47
    PCILIB_KMEM_FLAG_EXCLUSIVE = 2,			/**< Allow only a single application accessing a specified use & item */
48
    PCILIB_KMEM_FLAG_PERSISTENT = 4,			/**< Sets persistent mode */
49
    PCILIB_KMEM_FLAG_HARDWARE = 8,			/**< The buffer may be accessed by hardware, the hardware access will not occur any more if passed to _free function */
50
    PCILIB_KMEM_FLAG_FORCE = 16,			/**< Force memory cleanup even if references are present */
51
    PCILIB_KMEM_FLAG_MASS = 32,				/**< Apply to all buffers of selected use */
52
    PCILIB_KMEM_FLAG_TRY =  64				/**< Do not allocate buffers, try to reuse and fail if not possible */
71 by Suren A. Chilingaryan
First iteration of work to preserve DMA state between executions
53
} pcilib_kmem_flags_t;
54
74 by Suren A. Chilingaryan
Implement DMA access synchronization for NWL implementation
55
71 by Suren A. Chilingaryan
First iteration of work to preserve DMA state between executions
56
typedef enum {
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
57
    PCILIB_KMEM_REUSE_ALLOCATED = PCILIB_TRISTATE_NO,	/**< The kernel memory was allocated anew */
58
    PCILIB_KMEM_REUSE_REUSED = PCILIB_TRISTATE_YES,	/**< Already allocated kernel memory was re-used */
59
    PCILIB_KMEM_REUSE_PARTIAL = PCILIB_TRISTATE_PARTIAL,/**< The kernel memory was partially re-used and partially allocated */
60
    PCILIB_KMEM_REUSE_PERSISTENT = 0x100,		/**< Flag indicating that persistent kmem was allocated/reused (will not be cleaned on pcilib_free_kernel_memory() unless forced with PCILIB_KMEM_FLAG_PERSISTENT */
61
    PCILIB_KMEM_REUSE_HARDWARE = 0x200			/**< Flag indicating that kmem may be used by hardware device */
73 by Suren A. Chilingaryan
Implement DMA access synchronization in the driver
62
} pcilib_kmem_reuse_state_t;
63
45 by root
North West Logick DMA implementation
64
65
typedef struct {
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
66
    int handle_id;					/**< handled id is used to indentify buffer to kernel module */
67
    pcilib_kmem_reuse_state_t reused;			/**< indicates if the buffer was allocated or used */
68
69
    uintptr_t pa;					/**< physical address of buffer */
70
    uintptr_t ba;					/**< bus address of buffer (if it is mapped for DMA operations) */
370 by Suren A. Chilingaryan
RPM generation
71
    volatile void *ua;					/**< pointer to buffer in the process address space */
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
72
    size_t size;					/**< size of the buffer in bytes */
73
74
    size_t alignment_offset;				/**< we may request alignment of allocated buffers. To enusre proper alignment the larger buffer will be allocated and the offset will specify the first position in the buffer fullfilling alignment request */
75
    size_t mmap_offset;					/**< mmap always maps pages, if physical address is not aligned to page boundary, this is the offset of the buffer relative to the pointer returned by mmap (and stored in \a ua) */
45 by root
North West Logick DMA implementation
76
} pcilib_kmem_addr_t;
77
78
/**
79
 * single allocation - we set only addr, n_blocks = 0
80
 * multiple allocation - addr is not set, blocks are set, n_blocks > 0
81
 * sgmap allocation - addr contains ua, but pa's are set in blocks, n_blocks > 0
82
 */
83
typedef struct {
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
84
    pcilib_kmem_type_t type;				/**< The type of kernel memory (how it is allocated) */
85
    pcilib_kmem_use_t use;				/**< The purpose of kernel memory (how it will be used) */
86
    pcilib_kmem_reuse_state_t reused;			/**< Indicates if kernel memory was allocated anew, reused, or partially re-used. The additional flags will provide information about persistance and the hardware access */
45 by root
North West Logick DMA implementation
87
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
88
    size_t n_blocks;					/**< Number of allocated/re-used buffers in kmem */
89
    pcilib_kmem_addr_t addr;				/**< Information about the buffer of single-buffer kmem */
90
    pcilib_kmem_addr_t blocks[];			/**< Information about all the buffers in kmem (variable size) */
45 by root
North West Logick DMA implementation
91
} pcilib_kmem_buffer_t;
92
93
typedef void pcilib_kmem_handle_t;
94
95
96
struct pcilib_kmem_list_s {
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
97
    pcilib_kmem_list_t *next, *prev;			/**< List storring all allocated/re-used kmem's in application */
98
    pcilib_kmem_buffer_t buf;				/**< The actual kmem context (it is of variable size due to \a blocks and, hence, should be last item in this struct */
45 by root
North West Logick DMA implementation
99
};
100
277 by Suren A. Chilingaryan
Keep C++ compilers happy
101
#ifdef __cplusplus
102
extern "C" {
103
#endif
104
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
105
/**
106
 * This function either allocates new buffers in the kernel space or just re-uses existing buffers.
107
 *
108
 * Sometimes kernel memory is allocated for the specific use-case, for example to provide buffers for DMA engine.
361 by Suren A. Chilingaryan
Documentation update
109
 * It is possible to specify intended use using \p use parameter. 
110
 * The kernel memory with the specified use (i.e. \p use != 0) can be declared persistent (\p flags include 
111
 * ::PCILIB_KMEM_FLAG_PERSISTENT). Such memory will not be de-allocated on clean-up and will be maintained by 
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
112
 * the kernel module across the runs of various pcilib applications. To re-use persistent kernel memory,
361 by Suren A. Chilingaryan
Documentation update
113
 * ::PCILIB_KMEM_FLAG_REUSE should be set. In this case, the pcilib will either allocate new kernel memory 
114
 * or re-use the already allocated kernel buffers with the specified \p use. If ::PCILIB_KMEM_FLAG_REUSE
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
115
 * is not set, but the kernel memory with the specified use is already allocated, an error will be returned.
116
 *
117
 * It is also possible to allocate persistent kernel memory which can be execlusively used by a single process.
361 by Suren A. Chilingaryan
Documentation update
118
 * The ::PCILIB_KMEM_FLAG_EXCLUSIVE flag have to be provided to pcilib_alloc_kernel_memory() function in this
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
119
 * case. Only a single process may call hold a reference to kernel memory. Before next process would be able
120
 * to obtain it, the process holding the reference should return it using pcilib_free_kernel_memory()
121
 * call. For example, DMA engine uses exclusive kernel memory to guarantee that exactly one process is 
122
 * controlling DMA operations.
123
 *
124
 * To clean up allocated persistent kernel memory, pcilib_free_kernel_memory() have to be called with
361 by Suren A. Chilingaryan
Documentation update
125
 * ::PCILIB_KMEM_FLAG_PERSISTENT flag set.
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
126
 *
127
 * @param[in,out] ctx		- pcilib context
128
 * @param[in] type		- specifies type of allocation (simple pages, DMA pages, consistent memory, etc.)
129
 * @param[in] nmemb		- specifies number of buffers to allocated
130
 * @param[in] size		- specifies the size of each buffer in bytes
131
 * @param[in] alignment		- specifies required alignment, the bus addresses are aligned for PCI-mapped buffers and physical addresses are aligned for the rest (if bounce buffers are used, the physical and bus addresses are not always have the same alignment)
132
 * @param[in] use		- specifies how the memory will be used (to store software registers, locks, DMA buffers, etc.)
133
 * @param[in] flags		- various flags defining how buffers should be re-used/allocated and, that, should happen on pcilib_free_kernel_memory()
134
 * @return 			- pointer on context with allocated kernel memory or NULL in case of error
135
 */
45 by root
North West Logick DMA implementation
136
pcilib_kmem_handle_t *pcilib_alloc_kernel_memory(pcilib_t *ctx, pcilib_kmem_type_t type, size_t nmemb, size_t size, size_t alignment, pcilib_kmem_use_t use, pcilib_kmem_flags_t flags);
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
137
138
/**
139
 * This function either frees the allocated kernel memory or just releases some of the references.
140
 *
361 by Suren A. Chilingaryan
Documentation update
141
 * Only reference tracking is performed If the ::PCILIB_KMEM_FLAG_REUSE flag is passed to the 
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
142
 * function. Otherwise, non-persistent memory is released when pcilib_free_kernel_memory() called. 
361 by Suren A. Chilingaryan
Documentation update
143
 * The persistent memory is released if ::PCILIB_KMEM_FLAG_PERSISTENT is passed in \p flags parameter 
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
144
 * unless the hold references are preventing us from releasing this memory. The error is reported
361 by Suren A. Chilingaryan
Documentation update
145
 * in this case. The kernel memory can be freed irrespective of hold references if ::PCILIB_KMEM_FLAG_FORCE 
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
146
 * flag is specified.
147
 *
148
 * There are several types of references:
149
 * - The hardware reference - indicates that the memory may be used by DMA engine of the device. It is set
361 by Suren A. Chilingaryan
Documentation update
150
 * if pcilib_alloc_kernel_memory() is executed with ::PCILIB_KMEM_FLAG_HARDWARE flag. The reference can 
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
151
 * be released if the same flag is passed to pcilib_free_kernel_memory()
152
 * - The software references - are obtained when the memory is reused with pcilib_alloc_kernel_memory(). 
153
 * They are released when corresponding pcilib_free_kernel_memory() is called. 
154
 * - The mmap references - are obtained when the kernel memory is mapped to the virtual memory of application
155
 * which is normally happen on pcilib_alloc_kernel_memory() and fork of the process. The references are
156
 * returned when memory is unmapped. This happens on pcilib_free_kernel_memory() and termination of the 
157
 * process with still mmaped regions.
158
 *
159
 * The software references are in a way replicate functionality of the mmap references. Currently, they are 
160
 * used to keep track of non-persistent memory allocated and re-used within the same application (which is
161
 * actually discouraged). In this case the number of pcilib_alloc_kernel_memory() should be matched by 
162
 * number of pcilib_free_kernel_memory() calls and only on a last call the memory will be really released.
361 by Suren A. Chilingaryan
Documentation update
163
 * Normally, all but last calls have to be accompanied by ::PCILIB_KMEM_FLAG_REUSE flag or the error 
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
164
 * is reported. But to keep code simpler, the pcilib will not complain until there are software references 
165
 * on hold. When the last software reference is released, we try actually clean up the memory and the
166
 * error is reported if other types of references are still present.
167
 * The software references may stuck if application crashes before calling pcilib_free_kernel_memory(). 
168
 * pcilib will prevent us from releasing the kernel memory with stuck references. Such memory can 
361 by Suren A. Chilingaryan
Documentation update
169
 * be cleaned only with ::PCILIB_KMEM_FLAG_FORCE flag or using  pcilib_clean_kernel_memory() call.
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
170
 *
171
 * @param[in,out] ctx		- pcilib context
172
 * @param[in,out] k		- kernel memory handle returned from pcilib_alloc_kernel_memory() call
173
 * @param[in] flags		- various flags defining which referenes to hold and return and if the memory should be preserved or freed
174
 */
71 by Suren A. Chilingaryan
First iteration of work to preserve DMA state between executions
175
void pcilib_free_kernel_memory(pcilib_t *ctx, pcilib_kmem_handle_t *k, pcilib_kmem_flags_t flags);
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
176
177
178
/**
361 by Suren A. Chilingaryan
Documentation update
179
 * Free / dereference all kernel memory buffers associated with the specified \p use
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
180
 *
181
 * @param[in,out] ctx		- pcilib context
182
 * @param[in] use		- use-number to clean
183
 * @param[in] flags		- various flags defining which referenes to hold and return and if the memory should be dereferenced or freed
184
 * @return 			- error or 0 on success
185
 */
186
int pcilib_clean_kernel_memory(pcilib_t *ctx, pcilib_kmem_use_t use, pcilib_kmem_flags_t flags);
187
188
189
/**
190
 * Synchronizes usage of the specified buffer between hardware and the system.
191
 *
192
 * @param[in,out] ctx		- pcilib context
193
 * @param[in] k			- kernel memory handle returned from pcilib_alloc_kernel_memory() call
194
 * @param[in] dir 		- synchronization direction (allows either device or system access)
195
 * @param[in] block		- specifies the buffer within the kernel memory (buffers are numbered from 0)
196
 * @return 			- error or 0 on success
197
 */
106 by Suren A. Chilingaryan
Sync only required buffers
198
int pcilib_kmem_sync_block(pcilib_t *ctx, pcilib_kmem_handle_t *k, pcilib_kmem_sync_direction_t dir, size_t block);
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
199
200
201
/**
202
 * Get a valid pointer on the user-space mapping of a single-buffer kernel memory
203
 *
204
 * @param[in,out] ctx		- pcilib context
205
 * @param[in] k			- kernel memory handle returned from pcilib_alloc_kernel_memory() call
206
 * @return 			- user-space pointer
207
 */
370 by Suren A. Chilingaryan
RPM generation
208
volatile void *pcilib_kmem_get_ua(pcilib_t *ctx, pcilib_kmem_handle_t *k);
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
209
210
/**
211
 * Get a physical address of a single-buffer kernel memory
212
 *
213
 * @param[in,out] ctx		- pcilib context
214
 * @param[in] k			- kernel memory handle returned from pcilib_alloc_kernel_memory() call
215
 * @return 			- physical address
216
 */
45 by root
North West Logick DMA implementation
217
uintptr_t pcilib_kmem_get_pa(pcilib_t *ctx, pcilib_kmem_handle_t *k);
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
218
219
/**
220
 * Get a bus address of a single-buffer kernel memory
221
 *
222
 * @param[in,out] ctx		- pcilib context
223
 * @param[in] k			- kernel memory handle returned from pcilib_alloc_kernel_memory() call
224
 * @return 			- bus address or 0 if no bus mapping
225
 */
192 by Suren A. Chilingaryan
Kernel memory allocation
226
uintptr_t pcilib_kmem_get_ba(pcilib_t *ctx, pcilib_kmem_handle_t *k);
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
227
228
/**
229
 * Get a valid pointer on the user-space mapping of the specified kernel memory buffer
230
 *
231
 * @param[in,out] ctx		- pcilib context
232
 * @param[in] k			- kernel memory handle returned from pcilib_alloc_kernel_memory() call
233
 * @param[in] block		- specifies the buffer within the kernel memory (buffers are numbered from 0)
234
 * @return 			- user-space pointer
235
 */
370 by Suren A. Chilingaryan
RPM generation
236
volatile void *pcilib_kmem_get_block_ua(pcilib_t *ctx, pcilib_kmem_handle_t *k, size_t block);
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
237
238
/**
239
 * Get a physical address of the specified kernel memory buffer
240
 *
241
 * @param[in,out] ctx		- pcilib context
242
 * @param[in] k			- kernel memory handle returned from pcilib_alloc_kernel_memory() call
243
 * @param[in] block		- specifies the buffer within the kernel memory (buffers are numbered from 0)
244
 * @return 			- physical address
245
 */
45 by root
North West Logick DMA implementation
246
uintptr_t pcilib_kmem_get_block_pa(pcilib_t *ctx, pcilib_kmem_handle_t *k, size_t block);
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
247
248
/**
249
 * Get a bus address of the specified kernel memory buffer
250
 *
251
 * @param[in,out] ctx		- pcilib context
252
 * @param[in] k			- kernel memory handle returned from pcilib_alloc_kernel_memory() call
253
 * @param[in] block		- specifies the buffer within the kernel memory (buffers are numbered from 0)
254
 * @return 			- bus address or 0 if no bus mapping
255
 */
192 by Suren A. Chilingaryan
Kernel memory allocation
256
uintptr_t pcilib_kmem_get_block_ba(pcilib_t *ctx, pcilib_kmem_handle_t *k, size_t block);
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
257
258
259
/**
260
 * Get size of the specified kernel memory buffer
261
 *
262
 * @param[in,out] ctx		- pcilib context
263
 * @param[in] k			- kernel memory handle returned from pcilib_alloc_kernel_memory() call
264
 * @param[in] block		- specifies the buffer within the kernel memory (buffers are numbered from 0)
265
 * @return 			- size in bytes
266
 */
45 by root
North West Logick DMA implementation
267
size_t pcilib_kmem_get_block_size(pcilib_t *ctx, pcilib_kmem_handle_t *k, size_t block);
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
268
269
270
/**
271
 * Reports if the kernel memory was reused fully, partially, or allocated completely anew
272
 *
273
 * @param[in,out] ctx		- pcilib context
274
 * @param[in] k			- kernel memory handle returned from pcilib_alloc_kernel_memory() call
275
 * @return 			- re-use information
276
 */
73 by Suren A. Chilingaryan
Implement DMA access synchronization in the driver
277
pcilib_kmem_reuse_state_t pcilib_kmem_is_reused(pcilib_t *ctx, pcilib_kmem_handle_t *k);
45 by root
North West Logick DMA implementation
278
277 by Suren A. Chilingaryan
Keep C++ compilers happy
279
#ifdef __cplusplus
280
}
281
#endif
282
45 by root
North West Logick DMA implementation
283
#endif /* _PCILIB_KMEM_H */