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" |
|
330
by Suren A. Chilingaryan
Support for 64-bit registes |
20 |
#include "tools.h" |
21 |
#include "pagecpy.h" |
|
45
by root
North West Logick DMA implementation |
22 |
|
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
23 |
const pcilib_dma_description_t *pcilib_get_dma_description(pcilib_t *ctx) { |
236
by Suren A. Chilingaryan
Big redign of model structures |
24 |
int err; |
70
by Suren A. Chilingaryan
Support modifications of DMA engine and allow DMA customizations by Event engine |
25 |
|
236
by Suren A. Chilingaryan
Big redign of model structures |
26 |
err = pcilib_init_dma(ctx); |
27 |
if (err) { |
|
28 |
pcilib_error("Error (%i) while initializing DMA", err); |
|
29 |
return NULL; |
|
45
by root
North West Logick DMA implementation |
30 |
}
|
236
by Suren A. Chilingaryan
Big redign of model structures |
31 |
|
32 |
if (!ctx->dma_ctx) return NULL; |
|
33 |
||
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
34 |
return &ctx->dma; |
45
by root
North West Logick DMA implementation |
35 |
}
|
36 |
||
236
by Suren A. Chilingaryan
Big redign of model structures |
37 |
|
49
by Suren A. Chilingaryan
A bit of renaming |
38 |
pcilib_dma_engine_t pcilib_find_dma_by_addr(pcilib_t *ctx, pcilib_dma_direction_t direction, pcilib_dma_engine_addr_t dma) { |
39 |
pcilib_dma_engine_t i; |
|
45
by root
North West Logick DMA implementation |
40 |
|
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
41 |
const pcilib_dma_description_t *dma_info = pcilib_get_dma_description(ctx); |
42 |
if (!dma_info) { |
|
45
by root
North West Logick DMA implementation |
43 |
pcilib_error("DMA Engine is not configured in the current model"); |
44 |
return PCILIB_ERROR_NOTSUPPORTED; |
|
45 |
}
|
|
236
by Suren A. Chilingaryan
Big redign of model structures |
46 |
|
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
47 |
for (i = 0; dma_info->engines[i].addr_bits; i++) { |
48 |
if ((dma_info->engines[i].addr == dma)&&((dma_info->engines[i].direction&direction)==direction)) break; |
|
45
by root
North West Logick DMA implementation |
49 |
}
|
236
by Suren A. Chilingaryan
Big redign of model structures |
50 |
|
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
51 |
if (dma_info->engines[i].addr_bits) return i; |
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
52 |
return PCILIB_DMA_ENGINE_INVALID; |
45
by root
North West Logick DMA implementation |
53 |
}
|
54 |
||
236
by Suren A. Chilingaryan
Big redign of model structures |
55 |
|
56 |
pcilib_dma_engine_t pcilib_add_dma_engine(pcilib_t *ctx, pcilib_dma_engine_description_t *desc) { |
|
57 |
pcilib_dma_engine_t engine = ctx->num_engines++; |
|
58 |
memcpy (&ctx->engines[engine], desc, sizeof(pcilib_dma_engine_description_t)); |
|
59 |
return engine; |
|
60 |
}
|
|
61 |
||
62 |
||
63 |
int pcilib_init_dma(pcilib_t *ctx) { |
|
64 |
int err; |
|
65 |
pcilib_dma_context_t *dma_ctx = NULL; |
|
292
by Suren A. Chilingaryan
Protect access to the DMA engine with locks |
66 |
const pcilib_dma_description_t *info = &ctx->dma; |
236
by Suren A. Chilingaryan
Big redign of model structures |
67 |
const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); |
68 |
||
292
by Suren A. Chilingaryan
Protect access to the DMA engine with locks |
69 |
pcilib_dma_engine_t dma; |
70 |
||
236
by Suren A. Chilingaryan
Big redign of model structures |
71 |
if (ctx->dma_ctx) |
72 |
return 0; |
|
73 |
||
74 |
||
75 |
if ((ctx->event_ctx)&&(model_info->api)&&(model_info->api->init_dma)) { |
|
76 |
err = pcilib_init_register_banks(ctx); |
|
77 |
if (err) { |
|
78 |
pcilib_error("Error (%i) while initializing register banks", err); |
|
79 |
return err; |
|
80 |
}
|
|
81 |
||
82 |
dma_ctx = model_info->api->init_dma(ctx->event_ctx); |
|
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
83 |
} else if ((ctx->dma.api)&&(ctx->dma.api->init)) { |
236
by Suren A. Chilingaryan
Big redign of model structures |
84 |
err = pcilib_init_register_banks(ctx); |
85 |
if (err) { |
|
86 |
pcilib_error("Error (%i) while initializing register banks", err); |
|
87 |
return err; |
|
88 |
}
|
|
89 |
||
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
90 |
dma_ctx = ctx->dma.api->init(ctx, (ctx->dma.model?ctx->dma.model:ctx->model), ctx->dma.args); |
236
by Suren A. Chilingaryan
Big redign of model structures |
91 |
}
|
92 |
||
93 |
if (dma_ctx) { |
|
292
by Suren A. Chilingaryan
Protect access to the DMA engine with locks |
94 |
for (dma = 0; info->engines[dma].addr_bits; dma++) { |
95 |
if (info->engines[dma].direction&PCILIB_DMA_FROM_DEVICE) { |
|
96 |
ctx->dma_rlock[dma] = pcilib_get_lock(ctx, PCILIB_LOCK_FLAGS_DEFAULT, "dma%ir/%s", info->engines[dma].addr, info->name); |
|
97 |
if (!ctx->dma_rlock[dma]) break; |
|
98 |
}
|
|
99 |
if (info->engines[dma].direction&PCILIB_DMA_TO_DEVICE) { |
|
100 |
ctx->dma_wlock[dma] = pcilib_get_lock(ctx, PCILIB_LOCK_FLAGS_DEFAULT, "dma%iw/%s", info->engines[dma].addr, info->name); |
|
101 |
if (!ctx->dma_wlock[dma]) break; |
|
102 |
}
|
|
103 |
}
|
|
104 |
||
105 |
if (info->engines[dma].addr_bits) { |
|
106 |
if (ctx->dma.api->free) |
|
107 |
ctx->dma.api->free(dma_ctx); |
|
108 |
pcilib_error("Failed to intialize DMA locks"); |
|
109 |
return PCILIB_ERROR_FAILED; |
|
110 |
}
|
|
111 |
||
236
by Suren A. Chilingaryan
Big redign of model structures |
112 |
dma_ctx->pcilib = ctx; |
113 |
// DS: parameters?
|
|
114 |
ctx->dma_ctx = dma_ctx; |
|
115 |
}
|
|
126
by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization |
116 |
|
117 |
return 0; |
|
45
by root
North West Logick DMA implementation |
118 |
}
|
119 |
||
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
120 |
int pcilib_start_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags) { |
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
121 |
const pcilib_dma_description_t *info = pcilib_get_dma_description(ctx); |
65
by Suren A. Chilingaryan
Separate NWL loopback code, provide DMA start/stop interfaces |
122 |
if (!info) { |
123 |
pcilib_error("DMA is not supported by the device"); |
|
124 |
return PCILIB_ERROR_NOTSUPPORTED; |
|
125 |
}
|
|
126 |
||
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
127 |
if (!info->api) { |
65
by Suren A. Chilingaryan
Separate NWL loopback code, provide DMA start/stop interfaces |
128 |
pcilib_error("DMA Engine is not configured in the current model"); |
129 |
return PCILIB_ERROR_NOTAVAILABLE; |
|
130 |
}
|
|
292
by Suren A. Chilingaryan
Protect access to the DMA engine with locks |
131 |
|
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
132 |
if (!info->api->start_dma) { |
65
by Suren A. Chilingaryan
Separate NWL loopback code, provide DMA start/stop interfaces |
133 |
return 0; |
134 |
}
|
|
292
by Suren A. Chilingaryan
Protect access to the DMA engine with locks |
135 |
|
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
136 |
return info->api->start_dma(ctx->dma_ctx, dma, flags); |
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
137 |
}
|
138 |
||
139 |
int pcilib_stop_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags) { |
|
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
140 |
const pcilib_dma_description_t *info = pcilib_get_dma_description(ctx); |
194
by Suren A. Chilingaryan
DMA-independent IRQ functions |
141 |
|
65
by Suren A. Chilingaryan
Separate NWL loopback code, provide DMA start/stop interfaces |
142 |
if (!info) { |
143 |
pcilib_error("DMA is not supported by the device"); |
|
144 |
return PCILIB_ERROR_NOTSUPPORTED; |
|
145 |
}
|
|
146 |
||
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
147 |
if (!info->api) { |
65
by Suren A. Chilingaryan
Separate NWL loopback code, provide DMA start/stop interfaces |
148 |
pcilib_error("DMA Engine is not configured in the current model"); |
149 |
return PCILIB_ERROR_NOTAVAILABLE; |
|
150 |
}
|
|
151 |
||
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
152 |
if (!info->api->stop_dma) { |
65
by Suren A. Chilingaryan
Separate NWL loopback code, provide DMA start/stop interfaces |
153 |
return 0; |
154 |
}
|
|
75
by Suren A. Chilingaryan
Few fixes |
155 |
|
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
156 |
return info->api->stop_dma(ctx->dma_ctx, dma, flags); |
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
157 |
}
|
158 |
||
63
by Suren A. Chilingaryan
Provide IRQ enable/disable call |
159 |
int pcilib_enable_irq(pcilib_t *ctx, pcilib_irq_type_t irq_type, pcilib_dma_flags_t flags) { |
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
160 |
const pcilib_dma_description_t *info = pcilib_get_dma_description(ctx); |
161 |
||
162 |
if ((!info)||(!info->api)||(!info->api->enable_irq)) return 0; |
|
163 |
||
164 |
return info->api->enable_irq(ctx->dma_ctx, irq_type, flags); |
|
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
165 |
}
|
166 |
||
167 |
int pcilib_disable_irq(pcilib_t *ctx, pcilib_dma_flags_t flags) { |
|
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
168 |
const pcilib_dma_description_t *info = pcilib_get_dma_description(ctx); |
169 |
||
170 |
if ((!info)||(!info->api)||(!info->api->disable_irq)) return 0; |
|
171 |
||
172 |
return info->api->disable_irq(ctx->dma_ctx, flags); |
|
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
173 |
}
|
174 |
||
88
by Suren A. Chilingaryan
IRQ acknowledgement support in the engine API |
175 |
int pcilib_acknowledge_irq(pcilib_t *ctx, pcilib_irq_type_t irq_type, pcilib_irq_source_t irq_source) { |
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
176 |
const pcilib_dma_description_t *info = pcilib_get_dma_description(ctx); |
177 |
||
178 |
if ((!info)||(!info->api)||(!info->api->acknowledge_irq)) return 0; |
|
179 |
||
180 |
return info->api->acknowledge_irq(ctx->dma_ctx, irq_type, irq_source); |
|
88
by Suren A. Chilingaryan
IRQ acknowledgement support in the engine API |
181 |
}
|
182 |
||
45
by root
North West Logick DMA implementation |
183 |
typedef struct { |
184 |
size_t size; |
|
185 |
void *data; |
|
186 |
size_t pos; |
|
236
by Suren A. Chilingaryan
Big redign of model structures |
187 |
|
109
by Suren A. Chilingaryan
Improvements of DMA engine |
188 |
pcilib_dma_flags_t flags; |
45
by root
North West Logick DMA implementation |
189 |
} pcilib_dma_read_callback_context_t; |
190 |
||
191 |
static int pcilib_dma_read_callback(void *arg, pcilib_dma_flags_t flags, size_t bufsize, void *buf) { |
|
192 |
pcilib_dma_read_callback_context_t *ctx = (pcilib_dma_read_callback_context_t*)arg; |
|
193 |
||
194 |
if (ctx->pos + bufsize > ctx->size) { |
|
109
by Suren A. Chilingaryan
Improvements of DMA engine |
195 |
if ((ctx->flags&PCILIB_DMA_FLAG_IGNORE_ERRORS) == 0) |
196 |
pcilib_error("Buffer size (%li) is not large enough for DMA packet, at least %li bytes is required", ctx->size, ctx->pos + bufsize); |
|
197 |
return -PCILIB_ERROR_TOOBIG; |
|
45
by root
North West Logick DMA implementation |
198 |
}
|
330
by Suren A. Chilingaryan
Support for 64-bit registes |
199 |
|
200 |
pcilib_pagecpy(ctx->data + ctx->pos, buf, bufsize); |
|
45
by root
North West Logick DMA implementation |
201 |
ctx->pos += bufsize; |
202 |
||
109
by Suren A. Chilingaryan
Improvements of DMA engine |
203 |
if (flags & PCILIB_DMA_FLAG_EOP) { |
204 |
if ((ctx->pos < ctx->size)&&(ctx->flags&PCILIB_DMA_FLAG_MULTIPACKET)) { |
|
117
by Suren A. Chilingaryan
new event architecture, first trial |
205 |
if (ctx->flags&PCILIB_DMA_FLAG_WAIT) return PCILIB_STREAMING_WAIT; |
206 |
else return PCILIB_STREAMING_CONTINUE; |
|
109
by Suren A. Chilingaryan
Improvements of DMA engine |
207 |
}
|
117
by Suren A. Chilingaryan
new event architecture, first trial |
208 |
return PCILIB_STREAMING_STOP; |
109
by Suren A. Chilingaryan
Improvements of DMA engine |
209 |
}
|
117
by Suren A. Chilingaryan
new event architecture, first trial |
210 |
|
211 |
return PCILIB_STREAMING_REQ_FRAGMENT; |
|
45
by root
North West Logick DMA implementation |
212 |
}
|
213 |
||
214 |
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 |
215 |
struct timeval *tv = (struct timeval*)arg; |
216 |
struct timeval cur; |
|
217 |
||
218 |
if (tv) { |
|
219 |
gettimeofday(&cur, NULL); |
|
117
by Suren A. Chilingaryan
new event architecture, first trial |
220 |
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 |
221 |
}
|
222 |
||
117
by Suren A. Chilingaryan
new event architecture, first trial |
223 |
return PCILIB_STREAMING_REQ_PACKET; |
45
by root
North West Logick DMA implementation |
224 |
}
|
225 |
||
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
226 |
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) { |
292
by Suren A. Chilingaryan
Protect access to the DMA engine with locks |
227 |
int err; |
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
228 |
const pcilib_dma_description_t *info = pcilib_get_dma_description(ctx); |
45
by root
North West Logick DMA implementation |
229 |
if (!info) { |
230 |
pcilib_error("DMA is not supported by the device"); |
|
58
by Suren A. Chilingaryan
Wait for the completion of DMA operations during writes |
231 |
return PCILIB_ERROR_NOTSUPPORTED; |
45
by root
North West Logick DMA implementation |
232 |
}
|
233 |
||
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
234 |
if (!info->api) { |
45
by root
North West Logick DMA implementation |
235 |
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 |
236 |
return PCILIB_ERROR_NOTAVAILABLE; |
45
by root
North West Logick DMA implementation |
237 |
}
|
238 |
||
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
239 |
if (!info->api->stream) { |
45
by root
North West Logick DMA implementation |
240 |
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 |
241 |
return PCILIB_ERROR_NOTSUPPORTED; |
45
by root
North West Logick DMA implementation |
242 |
}
|
236
by Suren A. Chilingaryan
Big redign of model structures |
243 |
|
244 |
// DS: We should check we are not going outside of allocated engine space
|
|
245 |
if (!info->engines[dma].addr_bits) { |
|
45
by root
North West Logick DMA implementation |
246 |
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 |
247 |
return PCILIB_ERROR_NOTAVAILABLE; |
45
by root
North West Logick DMA implementation |
248 |
}
|
249 |
||
236
by Suren A. Chilingaryan
Big redign of model structures |
250 |
if ((info->engines[dma].direction&PCILIB_DMA_FROM_DEVICE) == 0) { |
45
by root
North West Logick DMA implementation |
251 |
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 |
252 |
return PCILIB_ERROR_NOTSUPPORTED; |
45
by root
North West Logick DMA implementation |
253 |
}
|
254 |
||
292
by Suren A. Chilingaryan
Protect access to the DMA engine with locks |
255 |
err = pcilib_try_lock(ctx->dma_rlock[dma]); |
256 |
if (err) { |
|
257 |
if ((err == PCILIB_ERROR_BUSY)||(err == PCILIB_ERROR_TIMEOUT)) |
|
258 |
pcilib_error("DMA engine (%i) is busy", dma); |
|
259 |
else
|
|
260 |
pcilib_error("Error (%i) locking DMA engine (%i)", err, dma); |
|
261 |
||
262 |
return err; |
|
263 |
}
|
|
264 |
||
265 |
err = info->api->stream(ctx->dma_ctx, dma, addr, size, flags, timeout, cb, cbattr); |
|
266 |
||
267 |
pcilib_unlock(ctx->dma_rlock[dma]); |
|
268 |
||
269 |
return err; |
|
45
by root
North West Logick DMA implementation |
270 |
}
|
271 |
||
109
by Suren A. Chilingaryan
Improvements of DMA engine |
272 |
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) { |
273 |
int err; |
|
274 |
||
275 |
pcilib_dma_read_callback_context_t opts = { |
|
276 |
size, buf, 0, flags |
|
277 |
};
|
|
278 |
||
279 |
err = pcilib_stream_dma(ctx, dma, addr, size, flags, timeout, pcilib_dma_read_callback, &opts); |
|
280 |
if (read_bytes) *read_bytes = opts.pos; |
|
281 |
return err; |
|
282 |
}
|
|
283 |
||
58
by Suren A. Chilingaryan
Wait for the completion of DMA operations during writes |
284 |
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 |
285 |
int err; |
286 |
||
287 |
pcilib_dma_read_callback_context_t opts = { |
|
109
by Suren A. Chilingaryan
Improvements of DMA engine |
288 |
size, buf, 0, 0 |
45
by root
North West Logick DMA implementation |
289 |
};
|
103
by Suren A. Chilingaryan
Provide information about active DMA engines & buffers |
290 |
|
58
by Suren A. Chilingaryan
Wait for the completion of DMA operations during writes |
291 |
err = pcilib_stream_dma(ctx, dma, addr, size, PCILIB_DMA_FLAGS_DEFAULT, PCILIB_DMA_TIMEOUT, pcilib_dma_read_callback, &opts); |
292 |
if (read_bytes) *read_bytes = opts.pos; |
|
293 |
return err; |
|
45
by root
North West Logick DMA implementation |
294 |
}
|
295 |
||
109
by Suren A. Chilingaryan
Improvements of DMA engine |
296 |
|
49
by Suren A. Chilingaryan
A bit of renaming |
297 |
int pcilib_skip_dma(pcilib_t *ctx, pcilib_dma_engine_t dma) { |
61
by Suren A. Chilingaryan
Few fixes |
298 |
int err; |
69
by Suren A. Chilingaryan
Add timeout to pcilib_skip_dma |
299 |
struct timeval tv, cur; |
300 |
||
301 |
gettimeofday(&tv, NULL); |
|
302 |
tv.tv_usec += PCILIB_DMA_SKIP_TIMEOUT; |
|
303 |
tv.tv_sec += tv.tv_usec / 1000000; |
|
304 |
tv.tv_usec += tv.tv_usec % 1000000; |
|
305 |
||
45
by root
North West Logick DMA implementation |
306 |
do { |
307 |
// IMMEDIATE timeout is not working properly, so default is set
|
|
69
by Suren A. Chilingaryan
Add timeout to pcilib_skip_dma |
308 |
err = pcilib_stream_dma(ctx, dma, 0, 0, PCILIB_DMA_FLAGS_DEFAULT, PCILIB_DMA_TIMEOUT, pcilib_dma_skip_callback, &tv); |
309 |
gettimeofday(&cur, NULL); |
|
310 |
} while ((!err)&&((cur.tv_sec < tv.tv_sec)||((cur.tv_sec == tv.tv_sec)&&(cur.tv_usec < tv.tv_usec)))); |
|
311 |
||
312 |
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 |
313 |
|
314 |
return 0; |
|
315 |
}
|
|
316 |
||
317 |
||
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
318 |
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) { |
292
by Suren A. Chilingaryan
Protect access to the DMA engine with locks |
319 |
int err; |
320 |
||
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
321 |
const pcilib_dma_description_t *info = pcilib_get_dma_description(ctx); |
45
by root
North West Logick DMA implementation |
322 |
if (!info) { |
323 |
pcilib_error("DMA is not supported by the device"); |
|
58
by Suren A. Chilingaryan
Wait for the completion of DMA operations during writes |
324 |
return PCILIB_ERROR_NOTSUPPORTED; |
45
by root
North West Logick DMA implementation |
325 |
}
|
326 |
||
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
327 |
if (!info->api) { |
45
by root
North West Logick DMA implementation |
328 |
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 |
329 |
return PCILIB_ERROR_NOTAVAILABLE; |
45
by root
North West Logick DMA implementation |
330 |
}
|
331 |
||
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
332 |
if (!info->api->push) { |
45
by root
North West Logick DMA implementation |
333 |
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 |
334 |
return PCILIB_ERROR_NOTSUPPORTED; |
45
by root
North West Logick DMA implementation |
335 |
}
|
336 |
||
236
by Suren A. Chilingaryan
Big redign of model structures |
337 |
// DS: We should check we don't exceed allocated engine range
|
338 |
if (!info->engines[dma].addr_bits) { |
|
45
by root
North West Logick DMA implementation |
339 |
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 |
340 |
return PCILIB_ERROR_NOTAVAILABLE; |
45
by root
North West Logick DMA implementation |
341 |
}
|
342 |
||
236
by Suren A. Chilingaryan
Big redign of model structures |
343 |
if ((info->engines[dma].direction&PCILIB_DMA_TO_DEVICE) == 0) { |
45
by root
North West Logick DMA implementation |
344 |
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 |
345 |
return PCILIB_ERROR_NOTSUPPORTED; |
45
by root
North West Logick DMA implementation |
346 |
}
|
292
by Suren A. Chilingaryan
Protect access to the DMA engine with locks |
347 |
|
348 |
err = pcilib_try_lock(ctx->dma_wlock[dma]); |
|
349 |
if (err) { |
|
350 |
if (err == PCILIB_ERROR_BUSY) |
|
351 |
pcilib_error("DMA engine (%i) is busy", dma); |
|
352 |
else
|
|
353 |
pcilib_error("Error (%i) locking DMA engine (%i)", err, dma); |
|
354 |
||
355 |
return err; |
|
356 |
}
|
|
357 |
||
358 |
err = info->api->push(ctx->dma_ctx, dma, addr, size, flags, timeout, buf, written); |
|
359 |
||
360 |
pcilib_unlock(ctx->dma_wlock[dma]); |
|
361 |
||
362 |
return err; |
|
45
by root
North West Logick DMA implementation |
363 |
}
|
364 |
||
365 |
||
58
by Suren A. Chilingaryan
Wait for the completion of DMA operations during writes |
366 |
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 |
367 |
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 |
368 |
}
|
369 |
||
49
by Suren A. Chilingaryan
A bit of renaming |
370 |
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) { |
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
371 |
const pcilib_dma_description_t *info = pcilib_get_dma_description(ctx); |
45
by root
North West Logick DMA implementation |
372 |
if (!info) { |
373 |
pcilib_error("DMA is not supported by the device"); |
|
374 |
return 0; |
|
375 |
}
|
|
376 |
||
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
377 |
if (!info->api) { |
45
by root
North West Logick DMA implementation |
378 |
pcilib_error("DMA Engine is not configured in the current model"); |
379 |
return -1; |
|
380 |
}
|
|
381 |
||
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
382 |
if (!info->api->benchmark) { |
45
by root
North West Logick DMA implementation |
383 |
pcilib_error("The DMA benchmark is not supported by configured DMA engine"); |
384 |
return -1; |
|
385 |
}
|
|
386 |
||
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
387 |
return info->api->benchmark(ctx->dma_ctx, dma, addr, size, iterations, direction); |
45
by root
North West Logick DMA implementation |
388 |
}
|
103
by Suren A. Chilingaryan
Provide information about active DMA engines & buffers |
389 |
|
390 |
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) { |
|
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
391 |
const pcilib_dma_description_t *info = pcilib_get_dma_description(ctx); |
103
by Suren A. Chilingaryan
Provide information about active DMA engines & buffers |
392 |
if (!info) { |
393 |
pcilib_error("DMA is not supported by the device"); |
|
394 |
return 0; |
|
395 |
}
|
|
396 |
||
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
397 |
if (!info->api) { |
103
by Suren A. Chilingaryan
Provide information about active DMA engines & buffers |
398 |
pcilib_error("DMA Engine is not configured in the current model"); |
399 |
return -1; |
|
400 |
}
|
|
401 |
||
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
402 |
if (!info->api->status) { |
103
by Suren A. Chilingaryan
Provide information about active DMA engines & buffers |
403 |
memset(status, 0, sizeof(pcilib_dma_engine_status_t)); |
404 |
return -1; |
|
405 |
}
|
|
406 |
||
236
by Suren A. Chilingaryan
Big redign of model structures |
407 |
// DS: We should check we don't exceed allocated engine range
|
408 |
if (!info->engines[dma].addr_bits) { |
|
103
by Suren A. Chilingaryan
Provide information about active DMA engines & buffers |
409 |
pcilib_error("The DMA engine (%i) is not supported by device", dma); |
410 |
return -1; |
|
411 |
}
|
|
412 |
||
240
by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines |
413 |
return info->api->status(ctx->dma_ctx, dma, status, n_buffers, buffers); |
103
by Suren A. Chilingaryan
Provide information about active DMA engines & buffers |
414 |
}
|