bzr branch
http://suren.me/webbzr/alps/pcitool
45
by root
North West Logick DMA implementation |
1 |
#include <stdio.h> |
2 |
#include <string.h> |
|
3 |
#include <strings.h> |
|
4 |
#include <stdlib.h> |
|
5 |
#include <stdint.h> |
|
6 |
#include <stdarg.h> |
|
7 |
#include <fcntl.h> |
|
8 |
#include <unistd.h> |
|
9 |
#include <sys/ioctl.h> |
|
10 |
#include <sys/mman.h> |
|
11 |
#include <arpa/inet.h> |
|
69
by Suren A. Chilingaryan
Add timeout to pcilib_skip_dma |
12 |
#include <sys/time.h> |
45
by root
North West Logick DMA implementation |
13 |
#include <errno.h> |
14 |
#include <assert.h> |
|
15 |
||
16 |
#include "error.h" |
|
17 |
#include "pcilib.h" |
|
18 |
#include "pci.h" |
|
19 |
#include "dma.h" |
|
20 |
||
21 |
const pcilib_dma_info_t *pcilib_get_dma_info(pcilib_t *ctx) { |
|
22 |
if (!ctx->dma_ctx) { |
|
70
by Suren A. Chilingaryan
Support modifications of DMA engine and allow DMA customizations by Event engine |
23 |
pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); |
24 |
||
25 |
if ((ctx->event_ctx)&&(model_info->event_api->init_dma)) { |
|
26 |
pcilib_map_register_space(ctx); |
|
27 |
ctx->dma_ctx = model_info->event_api->init_dma(ctx->event_ctx); |
|
28 |
} else if ((model_info->dma_api)&&(model_info->dma_api->init)) { |
|
29 |
pcilib_map_register_space(ctx); |
|
30 |
ctx->dma_ctx = model_info->dma_api->init(ctx, PCILIB_DMA_MODIFICATION_DEFAULT, NULL); |
|
45
by root
North West Logick DMA implementation |
31 |
}
|
32 |
||
33 |
if (!ctx->dma_ctx) return NULL; |
|
34 |
}
|
|
35 |
||
36 |
return &ctx->dma_info; |
|
37 |
}
|
|
38 |
||
49
by Suren A. Chilingaryan
A bit of renaming |
39 |
pcilib_dma_engine_t pcilib_find_dma_by_addr(pcilib_t *ctx, pcilib_dma_direction_t direction, pcilib_dma_engine_addr_t dma) { |
40 |
pcilib_dma_engine_t i; |
|
45
by root
North West Logick DMA implementation |
41 |
|
42 |
const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx); |
|
43 |
if (!info) { |
|
44 |
pcilib_error("DMA Engine is not configured in the current model"); |
|
45 |
return PCILIB_ERROR_NOTSUPPORTED; |
|
46 |
}
|
|
47 |
||
48 |
for (i = 0; info->engines[i]; i++) { |
|
49 |
if ((info->engines[i]->addr == dma)&&((info->engines[i]->direction&direction)==direction)) break; |
|
50 |
}
|
|
51 |
||
52 |
if (info->engines[i]) return i; |
|
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
53 |
return PCILIB_DMA_ENGINE_INVALID; |
45
by root
North West Logick DMA implementation |
54 |
}
|
55 |
||
49
by Suren A. Chilingaryan
A bit of renaming |
56 |
int pcilib_set_dma_engine_description(pcilib_t *ctx, pcilib_dma_engine_t engine, pcilib_dma_engine_description_t *desc) { |
45
by root
North West Logick DMA implementation |
57 |
ctx->dma_info.engines[engine] = desc; |
58 |
}
|
|
59 |
||
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
60 |
int pcilib_start_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags) { |
65
by Suren A. Chilingaryan
Separate NWL loopback code, provide DMA start/stop interfaces |
61 |
int err; |
62 |
||
63 |
const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx); |
|
64 |
if (!info) { |
|
65 |
pcilib_error("DMA is not supported by the device"); |
|
66 |
return PCILIB_ERROR_NOTSUPPORTED; |
|
67 |
}
|
|
68 |
||
69 |
if (!ctx->model_info.dma_api) { |
|
70 |
pcilib_error("DMA Engine is not configured in the current model"); |
|
71 |
return PCILIB_ERROR_NOTAVAILABLE; |
|
72 |
}
|
|
73 |
||
74 |
if (!ctx->model_info.dma_api->start_dma) { |
|
75 |
return 0; |
|
76 |
}
|
|
77 |
||
78 |
return ctx->model_info.dma_api->start_dma(ctx->dma_ctx, dma, flags); |
|
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
79 |
}
|
80 |
||
81 |
int pcilib_stop_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags) { |
|
65
by Suren A. Chilingaryan
Separate NWL loopback code, provide DMA start/stop interfaces |
82 |
int err; |
83 |
||
84 |
const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx); |
|
85 |
if (!info) { |
|
86 |
pcilib_error("DMA is not supported by the device"); |
|
87 |
return PCILIB_ERROR_NOTSUPPORTED; |
|
88 |
}
|
|
89 |
||
90 |
if (!ctx->model_info.dma_api) { |
|
91 |
pcilib_error("DMA Engine is not configured in the current model"); |
|
92 |
return PCILIB_ERROR_NOTAVAILABLE; |
|
93 |
}
|
|
94 |
||
95 |
if (!ctx->model_info.dma_api->stop_dma) { |
|
96 |
return 0; |
|
97 |
}
|
|
75
by Suren A. Chilingaryan
Few fixes |
98 |
|
65
by Suren A. Chilingaryan
Separate NWL loopback code, provide DMA start/stop interfaces |
99 |
return ctx->model_info.dma_api->stop_dma(ctx->dma_ctx, dma, flags); |
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
100 |
}
|
101 |
||
63
by Suren A. Chilingaryan
Provide IRQ enable/disable call |
102 |
int pcilib_enable_irq(pcilib_t *ctx, pcilib_irq_type_t irq_type, pcilib_dma_flags_t flags) { |
103 |
int err; |
|
104 |
||
105 |
const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx); |
|
106 |
if (!info) { |
|
107 |
pcilib_error("DMA is not supported by the device"); |
|
108 |
return PCILIB_ERROR_NOTSUPPORTED; |
|
109 |
}
|
|
110 |
||
111 |
if (!ctx->model_info.dma_api) { |
|
112 |
pcilib_error("DMA Engine is not configured in the current model"); |
|
113 |
return PCILIB_ERROR_NOTAVAILABLE; |
|
114 |
}
|
|
115 |
||
116 |
if (!ctx->model_info.dma_api->enable_irq) { |
|
65
by Suren A. Chilingaryan
Separate NWL loopback code, provide DMA start/stop interfaces |
117 |
return 0; |
63
by Suren A. Chilingaryan
Provide IRQ enable/disable call |
118 |
}
|
75
by Suren A. Chilingaryan
Few fixes |
119 |
|
63
by Suren A. Chilingaryan
Provide IRQ enable/disable call |
120 |
return ctx->model_info.dma_api->enable_irq(ctx->dma_ctx, irq_type, flags); |
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
121 |
}
|
122 |
||
123 |
int pcilib_disable_irq(pcilib_t *ctx, pcilib_dma_flags_t flags) { |
|
63
by Suren A. Chilingaryan
Provide IRQ enable/disable call |
124 |
int err; |
125 |
||
126 |
const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx); |
|
127 |
if (!info) { |
|
128 |
pcilib_error("DMA is not supported by the device"); |
|
129 |
return PCILIB_ERROR_NOTSUPPORTED; |
|
130 |
}
|
|
131 |
||
132 |
if (!ctx->model_info.dma_api) { |
|
133 |
pcilib_error("DMA Engine is not configured in the current model"); |
|
134 |
return PCILIB_ERROR_NOTAVAILABLE; |
|
135 |
}
|
|
136 |
||
137 |
if (!ctx->model_info.dma_api->disable_irq) { |
|
65
by Suren A. Chilingaryan
Separate NWL loopback code, provide DMA start/stop interfaces |
138 |
return 0; |
63
by Suren A. Chilingaryan
Provide IRQ enable/disable call |
139 |
}
|
140 |
||
141 |
return ctx->model_info.dma_api->disable_irq(ctx->dma_ctx, flags); |
|
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
142 |
}
|
143 |
||
88
by Suren A. Chilingaryan
IRQ acknowledgement support in the engine API |
144 |
int pcilib_acknowledge_irq(pcilib_t *ctx, pcilib_irq_type_t irq_type, pcilib_irq_source_t irq_source) { |
145 |
int err; |
|
146 |
||
147 |
const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx); |
|
148 |
if (!info) { |
|
149 |
pcilib_error("DMA is not supported by the device"); |
|
150 |
return PCILIB_ERROR_NOTSUPPORTED; |
|
151 |
}
|
|
152 |
||
153 |
if (!ctx->model_info.dma_api) { |
|
154 |
pcilib_error("DMA Engine is not configured in the current model"); |
|
155 |
return PCILIB_ERROR_NOTAVAILABLE; |
|
156 |
}
|
|
157 |
||
158 |
if (!ctx->model_info.dma_api->acknowledge_irq) { |
|
159 |
return 0; |
|
160 |
}
|
|
161 |
||
162 |
return ctx->model_info.dma_api->acknowledge_irq(ctx->dma_ctx, irq_type, irq_source); |
|
163 |
}
|
|
164 |
||
165 |
||
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
166 |
|
45
by root
North West Logick DMA implementation |
167 |
typedef struct { |
168 |
size_t size; |
|
169 |
void *data; |
|
170 |
size_t pos; |
|
109
by Suren A. Chilingaryan
Improvements of DMA engine |
171 |
|
172 |
pcilib_dma_flags_t flags; |
|
45
by root
North West Logick DMA implementation |
173 |
} pcilib_dma_read_callback_context_t; |
174 |
||
175 |
static int pcilib_dma_read_callback(void *arg, pcilib_dma_flags_t flags, size_t bufsize, void *buf) { |
|
176 |
pcilib_dma_read_callback_context_t *ctx = (pcilib_dma_read_callback_context_t*)arg; |
|
177 |
||
178 |
if (ctx->pos + bufsize > ctx->size) { |
|
109
by Suren A. Chilingaryan
Improvements of DMA engine |
179 |
if ((ctx->flags&PCILIB_DMA_FLAG_IGNORE_ERRORS) == 0) |
180 |
pcilib_error("Buffer size (%li) is not large enough for DMA packet, at least %li bytes is required", ctx->size, ctx->pos + bufsize); |
|
181 |
return -PCILIB_ERROR_TOOBIG; |
|
45
by root
North West Logick DMA implementation |
182 |
}
|
183 |
||
184 |
memcpy(ctx->data + ctx->pos, buf, bufsize); |
|
185 |
ctx->pos += bufsize; |
|
186 |
||
109
by Suren A. Chilingaryan
Improvements of DMA engine |
187 |
if (flags & PCILIB_DMA_FLAG_EOP) { |
188 |
if ((ctx->pos < ctx->size)&&(ctx->flags&PCILIB_DMA_FLAG_MULTIPACKET)) { |
|
117
by Suren A. Chilingaryan
new event architecture, first trial |
189 |
if (ctx->flags&PCILIB_DMA_FLAG_WAIT) return PCILIB_STREAMING_WAIT; |
190 |
else return PCILIB_STREAMING_CONTINUE; |
|
109
by Suren A. Chilingaryan
Improvements of DMA engine |
191 |
}
|
117
by Suren A. Chilingaryan
new event architecture, first trial |
192 |
return PCILIB_STREAMING_STOP; |
109
by Suren A. Chilingaryan
Improvements of DMA engine |
193 |
}
|
117
by Suren A. Chilingaryan
new event architecture, first trial |
194 |
|
195 |
return PCILIB_STREAMING_REQ_FRAGMENT; |
|
45
by root
North West Logick DMA implementation |
196 |
}
|
197 |
||
198 |
static int pcilib_dma_skip_callback(void *arg, pcilib_dma_flags_t flags, size_t bufsize, void *buf) { |
|
69
by Suren A. Chilingaryan
Add timeout to pcilib_skip_dma |
199 |
struct timeval *tv = (struct timeval*)arg; |
200 |
struct timeval cur; |
|
201 |
||
202 |
if (tv) { |
|
203 |
gettimeofday(&cur, NULL); |
|
117
by Suren A. Chilingaryan
new event architecture, first trial |
204 |
if ((cur.tv_sec > tv->tv_sec)||((cur.tv_sec == tv->tv_sec)&&(cur.tv_usec > tv->tv_usec))) return PCILIB_STREAMING_STOP; |
69
by Suren A. Chilingaryan
Add timeout to pcilib_skip_dma |
205 |
}
|
206 |
||
117
by Suren A. Chilingaryan
new event architecture, first trial |
207 |
return PCILIB_STREAMING_REQ_PACKET; |
45
by root
North West Logick DMA implementation |
208 |
}
|
209 |
||
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
210 |
int pcilib_stream_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, pcilib_dma_callback_t cb, void *cbattr) { |
45
by root
North West Logick DMA implementation |
211 |
int err; |
212 |
||
213 |
const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx); |
|
214 |
if (!info) { |
|
215 |
pcilib_error("DMA is not supported by the device"); |
|
58
by Suren A. Chilingaryan
Wait for the completion of DMA operations during writes |
216 |
return PCILIB_ERROR_NOTSUPPORTED; |
45
by root
North West Logick DMA implementation |
217 |
}
|
218 |
||
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
219 |
if (!ctx->model_info.dma_api) { |
45
by root
North West Logick DMA implementation |
220 |
pcilib_error("DMA Engine is not configured in the current model"); |
58
by Suren A. Chilingaryan
Wait for the completion of DMA operations during writes |
221 |
return PCILIB_ERROR_NOTAVAILABLE; |
45
by root
North West Logick DMA implementation |
222 |
}
|
223 |
||
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
224 |
if (!ctx->model_info.dma_api->stream) { |
45
by root
North West Logick DMA implementation |
225 |
pcilib_error("The DMA read is not supported by configured DMA engine"); |
58
by Suren A. Chilingaryan
Wait for the completion of DMA operations during writes |
226 |
return PCILIB_ERROR_NOTSUPPORTED; |
45
by root
North West Logick DMA implementation |
227 |
}
|
228 |
||
229 |
if (!info->engines[dma]) { |
|
230 |
pcilib_error("The DMA engine (%i) is not supported by device", dma); |
|
58
by Suren A. Chilingaryan
Wait for the completion of DMA operations during writes |
231 |
return PCILIB_ERROR_NOTAVAILABLE; |
45
by root
North West Logick DMA implementation |
232 |
}
|
233 |
||
234 |
if (info->engines[dma]->direction&PCILIB_DMA_FROM_DEVICE == 0) { |
|
235 |
pcilib_error("The selected engine (%i) is S2C-only and does not support reading", dma); |
|
58
by Suren A. Chilingaryan
Wait for the completion of DMA operations during writes |
236 |
return PCILIB_ERROR_NOTSUPPORTED; |
45
by root
North West Logick DMA implementation |
237 |
}
|
238 |
||
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
239 |
return ctx->model_info.dma_api->stream(ctx->dma_ctx, dma, addr, size, flags, timeout, cb, cbattr); |
45
by root
North West Logick DMA implementation |
240 |
}
|
241 |
||
109
by Suren A. Chilingaryan
Improvements of DMA engine |
242 |
int pcilib_read_dma_custom(pcilib_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, void *buf, size_t *read_bytes) { |
243 |
int err; |
|
244 |
||
245 |
pcilib_dma_read_callback_context_t opts = { |
|
246 |
size, buf, 0, flags |
|
247 |
};
|
|
248 |
||
249 |
err = pcilib_stream_dma(ctx, dma, addr, size, flags, timeout, pcilib_dma_read_callback, &opts); |
|
250 |
if (read_bytes) *read_bytes = opts.pos; |
|
251 |
return err; |
|
252 |
}
|
|
253 |
||
58
by Suren A. Chilingaryan
Wait for the completion of DMA operations during writes |
254 |
int pcilib_read_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, void *buf, size_t *read_bytes) { |
45
by root
North West Logick DMA implementation |
255 |
int err; |
256 |
||
257 |
pcilib_dma_read_callback_context_t opts = { |
|
109
by Suren A. Chilingaryan
Improvements of DMA engine |
258 |
size, buf, 0, 0 |
45
by root
North West Logick DMA implementation |
259 |
};
|
103
by Suren A. Chilingaryan
Provide information about active DMA engines & buffers |
260 |
|
58
by Suren A. Chilingaryan
Wait for the completion of DMA operations during writes |
261 |
err = pcilib_stream_dma(ctx, dma, addr, size, PCILIB_DMA_FLAGS_DEFAULT, PCILIB_DMA_TIMEOUT, pcilib_dma_read_callback, &opts); |
262 |
if (read_bytes) *read_bytes = opts.pos; |
|
263 |
return err; |
|
45
by root
North West Logick DMA implementation |
264 |
}
|
265 |
||
109
by Suren A. Chilingaryan
Improvements of DMA engine |
266 |
|
49
by Suren A. Chilingaryan
A bit of renaming |
267 |
int pcilib_skip_dma(pcilib_t *ctx, pcilib_dma_engine_t dma) { |
61
by Suren A. Chilingaryan
Few fixes |
268 |
int err; |
69
by Suren A. Chilingaryan
Add timeout to pcilib_skip_dma |
269 |
struct timeval tv, cur; |
270 |
||
271 |
gettimeofday(&tv, NULL); |
|
272 |
tv.tv_usec += PCILIB_DMA_SKIP_TIMEOUT; |
|
273 |
tv.tv_sec += tv.tv_usec / 1000000; |
|
274 |
tv.tv_usec += tv.tv_usec % 1000000; |
|
275 |
||
45
by root
North West Logick DMA implementation |
276 |
do { |
277 |
// IMMEDIATE timeout is not working properly, so default is set
|
|
69
by Suren A. Chilingaryan
Add timeout to pcilib_skip_dma |
278 |
err = pcilib_stream_dma(ctx, dma, 0, 0, PCILIB_DMA_FLAGS_DEFAULT, PCILIB_DMA_TIMEOUT, pcilib_dma_skip_callback, &tv); |
279 |
gettimeofday(&cur, NULL); |
|
280 |
} while ((!err)&&((cur.tv_sec < tv.tv_sec)||((cur.tv_sec == tv.tv_sec)&&(cur.tv_usec < tv.tv_usec)))); |
|
281 |
||
282 |
if ((cur.tv_sec > tv.tv_sec)||((cur.tv_sec == tv.tv_sec)&&(cur.tv_usec > tv.tv_usec))) return PCILIB_ERROR_TIMEOUT; |
|
45
by root
North West Logick DMA implementation |
283 |
|
284 |
return 0; |
|
285 |
}
|
|
286 |
||
287 |
||
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
288 |
int pcilib_push_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, void *buf, size_t *written) { |
45
by root
North West Logick DMA implementation |
289 |
int err; |
290 |
||
291 |
const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx); |
|
292 |
if (!info) { |
|
293 |
pcilib_error("DMA is not supported by the device"); |
|
58
by Suren A. Chilingaryan
Wait for the completion of DMA operations during writes |
294 |
return PCILIB_ERROR_NOTSUPPORTED; |
45
by root
North West Logick DMA implementation |
295 |
}
|
296 |
||
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
297 |
if (!ctx->model_info.dma_api) { |
45
by root
North West Logick DMA implementation |
298 |
pcilib_error("DMA Engine is not configured in the current model"); |
58
by Suren A. Chilingaryan
Wait for the completion of DMA operations during writes |
299 |
return PCILIB_ERROR_NOTAVAILABLE; |
45
by root
North West Logick DMA implementation |
300 |
}
|
301 |
||
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
302 |
if (!ctx->model_info.dma_api->push) { |
45
by root
North West Logick DMA implementation |
303 |
pcilib_error("The DMA write is not supported by configured DMA engine"); |
58
by Suren A. Chilingaryan
Wait for the completion of DMA operations during writes |
304 |
return PCILIB_ERROR_NOTSUPPORTED; |
45
by root
North West Logick DMA implementation |
305 |
}
|
306 |
||
307 |
if (!info->engines[dma]) { |
|
308 |
pcilib_error("The DMA engine (%i) is not supported by device", dma); |
|
58
by Suren A. Chilingaryan
Wait for the completion of DMA operations during writes |
309 |
return PCILIB_ERROR_NOTAVAILABLE; |
45
by root
North West Logick DMA implementation |
310 |
}
|
311 |
||
312 |
if (info->engines[dma]->direction&PCILIB_DMA_TO_DEVICE == 0) { |
|
313 |
pcilib_error("The selected engine (%i) is C2S-only and does not support writes", dma); |
|
58
by Suren A. Chilingaryan
Wait for the completion of DMA operations during writes |
314 |
return PCILIB_ERROR_NOTSUPPORTED; |
45
by root
North West Logick DMA implementation |
315 |
}
|
316 |
||
58
by Suren A. Chilingaryan
Wait for the completion of DMA operations during writes |
317 |
return ctx->model_info.dma_api->push(ctx->dma_ctx, dma, addr, size, flags, timeout, buf, written); |
45
by root
North West Logick DMA implementation |
318 |
}
|
319 |
||
320 |
||
58
by Suren A. Chilingaryan
Wait for the completion of DMA operations during writes |
321 |
int pcilib_write_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, void *buf, size_t *written_bytes) { |
61
by Suren A. Chilingaryan
Few fixes |
322 |
return pcilib_push_dma(ctx, dma, addr, size, PCILIB_DMA_FLAG_EOP|PCILIB_DMA_FLAG_WAIT, PCILIB_DMA_TIMEOUT, buf, written_bytes); |
45
by root
North West Logick DMA implementation |
323 |
}
|
324 |
||
49
by Suren A. Chilingaryan
A bit of renaming |
325 |
double pcilib_benchmark_dma(pcilib_t *ctx, pcilib_dma_engine_addr_t dma, uintptr_t addr, size_t size, size_t iterations, pcilib_dma_direction_t direction) { |
45
by root
North West Logick DMA implementation |
326 |
int err; |
327 |
||
328 |
const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx); |
|
329 |
if (!info) { |
|
330 |
pcilib_error("DMA is not supported by the device"); |
|
331 |
return 0; |
|
332 |
}
|
|
333 |
||
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
334 |
if (!ctx->model_info.dma_api) { |
45
by root
North West Logick DMA implementation |
335 |
pcilib_error("DMA Engine is not configured in the current model"); |
336 |
return -1; |
|
337 |
}
|
|
338 |
||
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
339 |
if (!ctx->model_info.dma_api->benchmark) { |
45
by root
North West Logick DMA implementation |
340 |
pcilib_error("The DMA benchmark is not supported by configured DMA engine"); |
341 |
return -1; |
|
342 |
}
|
|
343 |
||
344 |
if (!info->engines[dma]) { |
|
345 |
pcilib_error("The DMA engine (%i) is not supported by device", dma); |
|
346 |
return -1; |
|
347 |
}
|
|
348 |
||
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
349 |
return ctx->model_info.dma_api->benchmark(ctx->dma_ctx, dma, addr, size, iterations, direction); |
45
by root
North West Logick DMA implementation |
350 |
}
|
103
by Suren A. Chilingaryan
Provide information about active DMA engines & buffers |
351 |
|
352 |
int pcilib_get_dma_status(pcilib_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_engine_status_t *status, size_t n_buffers, pcilib_dma_buffer_status_t *buffers) { |
|
353 |
int err; |
|
354 |
||
355 |
const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx); |
|
356 |
if (!info) { |
|
357 |
pcilib_error("DMA is not supported by the device"); |
|
358 |
return 0; |
|
359 |
}
|
|
360 |
||
361 |
if (!ctx->model_info.dma_api) { |
|
362 |
pcilib_error("DMA Engine is not configured in the current model"); |
|
363 |
return -1; |
|
364 |
}
|
|
365 |
||
366 |
if (!ctx->model_info.dma_api->status) { |
|
367 |
memset(status, 0, sizeof(pcilib_dma_engine_status_t)); |
|
368 |
return -1; |
|
369 |
}
|
|
370 |
||
371 |
if (!info->engines[dma]) { |
|
372 |
pcilib_error("The DMA engine (%i) is not supported by device", dma); |
|
373 |
return -1; |
|
374 |
}
|
|
375 |
||
376 |
return ctx->model_info.dma_api->status(ctx->dma_ctx, dma, status, n_buffers, buffers); |
|
377 |
||
378 |
}
|