21
const pcilib_dma_info_t *pcilib_get_dma_info(pcilib_t *ctx) {
23
pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
21
const pcilib_dma_description_t *pcilib_get_dma_info(pcilib_t *ctx) {
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);
33
if (!ctx->dma_ctx) return NULL;
24
err = pcilib_init_dma(ctx);
26
pcilib_error("Error (%i) while initializing DMA", err);
36
return &ctx->dma_info;
30
if (!ctx->dma_ctx) return NULL;
32
return ctx->model_info.dma;
39
36
pcilib_dma_engine_t pcilib_find_dma_by_addr(pcilib_t *ctx, pcilib_dma_direction_t direction, pcilib_dma_engine_addr_t dma) {
40
37
pcilib_dma_engine_t i;
42
const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx);
39
const pcilib_dma_description_t *info = pcilib_get_dma_info(ctx);
44
41
pcilib_error("DMA Engine is not configured in the current model");
45
42
return PCILIB_ERROR_NOTSUPPORTED;
48
for (i = 0; info->engines[i]; i++) {
49
if ((info->engines[i]->addr == dma)&&((info->engines[i]->direction&direction)==direction)) break;
45
for (i = 0; info->engines[i].addr_bits; i++) {
46
if ((info->engines[i].addr == dma)&&((info->engines[i].direction&direction)==direction)) break;
52
if (info->engines[i]) return i;
49
if (info->engines[i].addr_bits) return i;
53
50
return PCILIB_DMA_ENGINE_INVALID;
56
int pcilib_set_dma_engine_description(pcilib_t *ctx, pcilib_dma_engine_t engine, pcilib_dma_engine_description_t *desc) {
57
ctx->dma_info.engines[engine] = desc;
54
pcilib_dma_engine_t pcilib_add_dma_engine(pcilib_t *ctx, pcilib_dma_engine_description_t *desc) {
55
pcilib_dma_engine_t engine = ctx->num_engines++;
56
memcpy (&ctx->engines[engine], desc, sizeof(pcilib_dma_engine_description_t));
61
int pcilib_init_dma(pcilib_t *ctx) {
63
pcilib_dma_context_t *dma_ctx = NULL;
64
const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
70
if ((ctx->event_ctx)&&(model_info->api)&&(model_info->api->init_dma)) {
71
err = pcilib_init_register_banks(ctx);
73
pcilib_error("Error (%i) while initializing register banks", err);
77
dma_ctx = model_info->api->init_dma(ctx->event_ctx);
78
} else if ((model_info->dma)&&(model_info->dma->api)&&(model_info->dma->api->init)) {
79
const pcilib_dma_description_t *dma = model_info->dma;
81
err = pcilib_init_register_banks(ctx);
83
pcilib_error("Error (%i) while initializing register banks", err);
87
dma_ctx = dma->api->init(ctx, (dma->model?dma->model:ctx->model), dma->args);
91
dma_ctx->pcilib = ctx;
93
ctx->dma_ctx = dma_ctx;
62
99
int pcilib_start_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags) {
63
const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx);
100
const pcilib_dma_description_t *info = pcilib_get_dma_info(ctx);
65
102
pcilib_error("DMA is not supported by the device");
66
103
return PCILIB_ERROR_NOTSUPPORTED;
69
if (!ctx->model_info.dma_api) {
106
if (!ctx->model_info.dma->api) {
70
107
pcilib_error("DMA Engine is not configured in the current model");
71
108
return PCILIB_ERROR_NOTAVAILABLE;
74
if (!ctx->model_info.dma_api->start_dma) {
111
if (!ctx->model_info.dma->api->start_dma) {
78
return ctx->model_info.dma_api->start_dma(ctx->dma_ctx, dma, flags);
115
return ctx->model_info.dma->api->start_dma(ctx->dma_ctx, dma, flags);
81
118
int pcilib_stop_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags) {
82
const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx);
119
const pcilib_dma_description_t *info = pcilib_get_dma_info(ctx);
85
122
pcilib_error("DMA is not supported by the device");
86
123
return PCILIB_ERROR_NOTSUPPORTED;
89
if (!ctx->model_info.dma_api) {
126
if (!ctx->model_info.dma->api) {
90
127
pcilib_error("DMA Engine is not configured in the current model");
91
128
return PCILIB_ERROR_NOTAVAILABLE;
94
if (!ctx->model_info.dma_api->stop_dma) {
131
if (!ctx->model_info.dma->api->stop_dma) {
98
return ctx->model_info.dma_api->stop_dma(ctx->dma_ctx, dma, flags);
135
return ctx->model_info.dma->api->stop_dma(ctx->dma_ctx, dma, flags);
101
138
int pcilib_enable_irq(pcilib_t *ctx, pcilib_irq_type_t irq_type, pcilib_dma_flags_t flags) {
102
const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx);
104
if ((!info)||(!ctx->model_info.dma_api)||(!ctx->model_info.dma_api->enable_irq)) return 0;
106
return ctx->model_info.dma_api->enable_irq(ctx->dma_ctx, irq_type, flags);
139
const pcilib_dma_description_t *info = pcilib_get_dma_info(ctx);
141
if ((!info)||(!ctx->model_info.dma->api)||(!ctx->model_info.dma->api->enable_irq)) return 0;
143
return ctx->model_info.dma->api->enable_irq(ctx->dma_ctx, irq_type, flags);
109
146
int pcilib_disable_irq(pcilib_t *ctx, pcilib_dma_flags_t flags) {
110
const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx);
112
if ((!info)||(!ctx->model_info.dma_api)||(!ctx->model_info.dma_api->disable_irq)) return 0;
114
return ctx->model_info.dma_api->disable_irq(ctx->dma_ctx, flags);
147
const pcilib_dma_description_t *info = pcilib_get_dma_info(ctx);
149
if ((!info)||(!ctx->model_info.dma->api)||(!ctx->model_info.dma->api->disable_irq)) return 0;
151
return ctx->model_info.dma->api->disable_irq(ctx->dma_ctx, flags);
117
154
int pcilib_acknowledge_irq(pcilib_t *ctx, pcilib_irq_type_t irq_type, pcilib_irq_source_t irq_source) {
118
const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx);
120
if ((!info)||(!ctx->model_info.dma_api)||(!ctx->model_info.dma_api->acknowledge_irq)) return 0;
122
return ctx->model_info.dma_api->acknowledge_irq(ctx->dma_ctx, irq_type, irq_source);
155
const pcilib_dma_description_t *info = pcilib_get_dma_info(ctx);
157
if ((!info)||(!ctx->model_info.dma->api)||(!ctx->model_info.dma->api->acknowledge_irq)) return 0;
159
return ctx->model_info.dma->api->acknowledge_irq(ctx->dma_ctx, irq_type, irq_source);
130
167
pcilib_dma_flags_t flags;
131
168
} pcilib_dma_read_callback_context_t;
168
205
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) {
169
const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx);
206
const pcilib_dma_description_t *info = pcilib_get_dma_info(ctx);
171
208
pcilib_error("DMA is not supported by the device");
172
209
return PCILIB_ERROR_NOTSUPPORTED;
175
if (!ctx->model_info.dma_api) {
212
if (!ctx->model_info.dma->api) {
176
213
pcilib_error("DMA Engine is not configured in the current model");
177
214
return PCILIB_ERROR_NOTAVAILABLE;
180
if (!ctx->model_info.dma_api->stream) {
217
if (!ctx->model_info.dma->api->stream) {
181
218
pcilib_error("The DMA read is not supported by configured DMA engine");
182
219
return PCILIB_ERROR_NOTSUPPORTED;
185
if (!info->engines[dma]) {
222
// DS: We should check we are not going outside of allocated engine space
223
if (!info->engines[dma].addr_bits) {
186
224
pcilib_error("The DMA engine (%i) is not supported by device", dma);
187
225
return PCILIB_ERROR_NOTAVAILABLE;
190
if ((info->engines[dma]->direction&PCILIB_DMA_FROM_DEVICE) == 0) {
228
if ((info->engines[dma].direction&PCILIB_DMA_FROM_DEVICE) == 0) {
191
229
pcilib_error("The selected engine (%i) is S2C-only and does not support reading", dma);
192
230
return PCILIB_ERROR_NOTSUPPORTED;
195
return ctx->model_info.dma_api->stream(ctx->dma_ctx, dma, addr, size, flags, timeout, cb, cbattr);
233
return ctx->model_info.dma->api->stream(ctx->dma_ctx, dma, addr, size, flags, timeout, cb, cbattr);
198
236
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) {
244
282
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) {
245
const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx);
283
const pcilib_dma_description_t *info = pcilib_get_dma_info(ctx);
247
285
pcilib_error("DMA is not supported by the device");
248
286
return PCILIB_ERROR_NOTSUPPORTED;
251
if (!ctx->model_info.dma_api) {
289
if (!ctx->model_info.dma->api) {
252
290
pcilib_error("DMA Engine is not configured in the current model");
253
291
return PCILIB_ERROR_NOTAVAILABLE;
256
if (!ctx->model_info.dma_api->push) {
294
if (!ctx->model_info.dma->api->push) {
257
295
pcilib_error("The DMA write is not supported by configured DMA engine");
258
296
return PCILIB_ERROR_NOTSUPPORTED;
261
if (!info->engines[dma]) {
299
// DS: We should check we don't exceed allocated engine range
300
if (!info->engines[dma].addr_bits) {
262
301
pcilib_error("The DMA engine (%i) is not supported by device", dma);
263
302
return PCILIB_ERROR_NOTAVAILABLE;
266
if ((info->engines[dma]->direction&PCILIB_DMA_TO_DEVICE) == 0) {
305
if ((info->engines[dma].direction&PCILIB_DMA_TO_DEVICE) == 0) {
267
306
pcilib_error("The selected engine (%i) is C2S-only and does not support writes", dma);
268
307
return PCILIB_ERROR_NOTSUPPORTED;
271
return ctx->model_info.dma_api->push(ctx->dma_ctx, dma, addr, size, flags, timeout, buf, written);
310
return ctx->model_info.dma->api->push(ctx->dma_ctx, dma, addr, size, flags, timeout, buf, written);
279
318
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) {
280
const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx);
319
const pcilib_dma_description_t *info = pcilib_get_dma_info(ctx);
282
321
pcilib_error("DMA is not supported by the device");
286
if (!ctx->model_info.dma_api) {
325
if (!ctx->model_info.dma->api) {
287
326
pcilib_error("DMA Engine is not configured in the current model");
291
if (!ctx->model_info.dma_api->benchmark) {
330
if (!ctx->model_info.dma->api->benchmark) {
292
331
pcilib_error("The DMA benchmark is not supported by configured DMA engine");
296
if (!info->engines[dma]) {
297
pcilib_error("The DMA engine (%i) is not supported by device", dma);
301
return ctx->model_info.dma_api->benchmark(ctx->dma_ctx, dma, addr, size, iterations, direction);
335
return ctx->model_info.dma->api->benchmark(ctx->dma_ctx, dma, addr, size, iterations, direction);
304
338
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) {
305
const pcilib_dma_info_t *info = pcilib_get_dma_info(ctx);
339
const pcilib_dma_description_t *info = pcilib_get_dma_info(ctx);
307
341
pcilib_error("DMA is not supported by the device");
311
if (!ctx->model_info.dma_api) {
345
if (!ctx->model_info.dma->api) {
312
346
pcilib_error("DMA Engine is not configured in the current model");
316
if (!ctx->model_info.dma_api->status) {
350
if (!ctx->model_info.dma->api->status) {
317
351
memset(status, 0, sizeof(pcilib_dma_engine_status_t));
321
if (!info->engines[dma]) {
355
// DS: We should check we don't exceed allocated engine range
356
if (!info->engines[dma].addr_bits) {
322
357
pcilib_error("The DMA engine (%i) is not supported by device", dma);
326
return ctx->model_info.dma_api->status(ctx->dma_ctx, dma, status, n_buffers, buffers);
361
return ctx->model_info.dma->api->status(ctx->dma_ctx, dma, status, n_buffers, buffers);