/alps/pcitool

To get this branch, use:
bzr branch http://darksoft.org/webbzr/alps/pcitool

« back to all changes in this revision

Viewing changes to pcilib/dma.c

  • Committer: Suren A. Chilingaryan
  • Date: 2015-04-24 03:35:48 UTC
  • Revision ID: csa@suren.me-20150424033548-7xhacqq2s8s1t2fp
More structural changes to get ready for stand-alone event engines

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
#include "pci.h"
19
19
#include "dma.h"
20
20
 
21
 
const pcilib_dma_description_t *pcilib_get_dma_info(pcilib_t *ctx) {
 
21
const pcilib_dma_description_t *pcilib_get_dma_description(pcilib_t *ctx) {
22
22
    int err;
23
23
 
24
24
    err = pcilib_init_dma(ctx);
29
29
 
30
30
    if (!ctx->dma_ctx) return NULL;
31
31
 
32
 
    return ctx->model_info.dma;
 
32
    return &ctx->dma;
33
33
}
34
34
 
35
35
 
36
36
pcilib_dma_engine_t pcilib_find_dma_by_addr(pcilib_t *ctx, pcilib_dma_direction_t direction, pcilib_dma_engine_addr_t dma) {
37
37
    pcilib_dma_engine_t i;
38
38
 
39
 
    const pcilib_dma_description_t *info =  pcilib_get_dma_info(ctx);
40
 
    if (!info) {
 
39
    const pcilib_dma_description_t *dma_info =  pcilib_get_dma_description(ctx);
 
40
    if (!dma_info) {
41
41
        pcilib_error("DMA Engine is not configured in the current model");
42
42
        return PCILIB_ERROR_NOTSUPPORTED;
43
43
    }
44
44
 
45
 
    for (i = 0; info->engines[i].addr_bits; i++) {
46
 
        if ((info->engines[i].addr == dma)&&((info->engines[i].direction&direction)==direction)) break;
 
45
    for (i = 0; dma_info->engines[i].addr_bits; i++) {
 
46
        if ((dma_info->engines[i].addr == dma)&&((dma_info->engines[i].direction&direction)==direction)) break;
47
47
    }
48
48
 
49
 
    if (info->engines[i].addr_bits) return i;
 
49
    if (dma_info->engines[i].addr_bits) return i;
50
50
    return PCILIB_DMA_ENGINE_INVALID;
51
51
}
52
52
 
75
75
        }
76
76
 
77
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;
80
 
        
 
78
    } else if ((ctx->dma.api)&&(ctx->dma.api->init)) {
81
79
        err = pcilib_init_register_banks(ctx);
82
80
        if (err) {
83
81
            pcilib_error("Error (%i) while initializing register banks", err);
84
82
            return err;
85
83
        }
86
84
 
87
 
        dma_ctx = dma->api->init(ctx, (dma->model?dma->model:ctx->model), dma->args);
 
85
        dma_ctx = ctx->dma.api->init(ctx, (ctx->dma.model?ctx->dma.model:ctx->model), ctx->dma.args);
88
86
    }
89
87
 
90
88
    if (dma_ctx) {
97
95
}
98
96
 
99
97
int pcilib_start_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags) {
100
 
    const pcilib_dma_description_t *info =  pcilib_get_dma_info(ctx);
 
98
    const pcilib_dma_description_t *info =  pcilib_get_dma_description(ctx);
101
99
    if (!info) {
102
100
        pcilib_error("DMA is not supported by the device");
103
101
        return PCILIB_ERROR_NOTSUPPORTED;
104
102
    }
105
103
 
106
 
    if (!ctx->model_info.dma->api) {
 
104
    if (!info->api) {
107
105
        pcilib_error("DMA Engine is not configured in the current model");
108
106
        return PCILIB_ERROR_NOTAVAILABLE;
109
107
    }
110
108
    
111
 
    if (!ctx->model_info.dma->api->start_dma) {
 
109
    if (!info->api->start_dma) {
112
110
        return 0;
113
111
    }
114
112
    
115
 
    return ctx->model_info.dma->api->start_dma(ctx->dma_ctx, dma, flags);
 
113
    return info->api->start_dma(ctx->dma_ctx, dma, flags);
116
114
}
117
115
 
118
116
int pcilib_stop_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, pcilib_dma_flags_t flags) {
119
 
    const pcilib_dma_description_t *info =  pcilib_get_dma_info(ctx);
 
117
    const pcilib_dma_description_t *info =  pcilib_get_dma_description(ctx);
120
118
 
121
119
    if (!info) {
122
120
        pcilib_error("DMA is not supported by the device");
123
121
        return PCILIB_ERROR_NOTSUPPORTED;
124
122
    }
125
123
 
126
 
    if (!ctx->model_info.dma->api) {
 
124
    if (!info->api) {
127
125
        pcilib_error("DMA Engine is not configured in the current model");
128
126
        return PCILIB_ERROR_NOTAVAILABLE;
129
127
    }
130
128
    
131
 
    if (!ctx->model_info.dma->api->stop_dma) {
 
129
    if (!info->api->stop_dma) {
132
130
        return 0;
133
131
    }
134
132
 
135
 
    return ctx->model_info.dma->api->stop_dma(ctx->dma_ctx, dma, flags);
 
133
    return info->api->stop_dma(ctx->dma_ctx, dma, flags);
136
134
}
137
135
 
138
136
int pcilib_enable_irq(pcilib_t *ctx, pcilib_irq_type_t irq_type, pcilib_dma_flags_t flags) {
139
 
    const pcilib_dma_description_t *info =  pcilib_get_dma_info(ctx);
140
 
 
141
 
    if ((!info)||(!ctx->model_info.dma->api)||(!ctx->model_info.dma->api->enable_irq)) return 0;
142
 
 
143
 
    return ctx->model_info.dma->api->enable_irq(ctx->dma_ctx, irq_type, flags);
 
137
    const pcilib_dma_description_t *info =  pcilib_get_dma_description(ctx);
 
138
 
 
139
    if ((!info)||(!info->api)||(!info->api->enable_irq)) return 0;
 
140
 
 
141
    return info->api->enable_irq(ctx->dma_ctx, irq_type, flags);
144
142
}
145
143
 
146
144
int pcilib_disable_irq(pcilib_t *ctx, pcilib_dma_flags_t flags) {
147
 
    const pcilib_dma_description_t *info =  pcilib_get_dma_info(ctx);
148
 
 
149
 
    if ((!info)||(!ctx->model_info.dma->api)||(!ctx->model_info.dma->api->disable_irq)) return 0;
150
 
 
151
 
    return ctx->model_info.dma->api->disable_irq(ctx->dma_ctx, flags);
 
145
    const pcilib_dma_description_t *info =  pcilib_get_dma_description(ctx);
 
146
 
 
147
    if ((!info)||(!info->api)||(!info->api->disable_irq)) return 0;
 
148
 
 
149
    return info->api->disable_irq(ctx->dma_ctx, flags);
152
150
}
153
151
 
154
152
int pcilib_acknowledge_irq(pcilib_t *ctx, pcilib_irq_type_t irq_type, pcilib_irq_source_t irq_source) {
155
 
    const pcilib_dma_description_t *info =  pcilib_get_dma_info(ctx);
156
 
 
157
 
    if ((!info)||(!ctx->model_info.dma->api)||(!ctx->model_info.dma->api->acknowledge_irq)) return 0;
158
 
 
159
 
    return ctx->model_info.dma->api->acknowledge_irq(ctx->dma_ctx, irq_type, irq_source);
 
153
    const pcilib_dma_description_t *info =  pcilib_get_dma_description(ctx);
 
154
 
 
155
    if ((!info)||(!info->api)||(!info->api->acknowledge_irq)) return 0;
 
156
 
 
157
    return info->api->acknowledge_irq(ctx->dma_ctx, irq_type, irq_source);
160
158
}
161
159
 
162
160
typedef struct {
203
201
}
204
202
 
205
203
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) {
206
 
    const pcilib_dma_description_t *info =  pcilib_get_dma_info(ctx);
 
204
    const pcilib_dma_description_t *info =  pcilib_get_dma_description(ctx);
207
205
    if (!info) {
208
206
        pcilib_error("DMA is not supported by the device");
209
207
        return PCILIB_ERROR_NOTSUPPORTED;
210
208
    }
211
209
 
212
 
    if (!ctx->model_info.dma->api) {
 
210
    if (!info->api) {
213
211
        pcilib_error("DMA Engine is not configured in the current model");
214
212
        return PCILIB_ERROR_NOTAVAILABLE;
215
213
    }
216
214
    
217
 
    if (!ctx->model_info.dma->api->stream) {
 
215
    if (!info->api->stream) {
218
216
        pcilib_error("The DMA read is not supported by configured DMA engine");
219
217
        return PCILIB_ERROR_NOTSUPPORTED;
220
218
    }
230
228
        return PCILIB_ERROR_NOTSUPPORTED;
231
229
    }
232
230
 
233
 
    return ctx->model_info.dma->api->stream(ctx->dma_ctx, dma, addr, size, flags, timeout, cb, cbattr);
 
231
    return info->api->stream(ctx->dma_ctx, dma, addr, size, flags, timeout, cb, cbattr);
234
232
}
235
233
 
236
234
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) {
280
278
 
281
279
 
282
280
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) {
283
 
    const pcilib_dma_description_t *info =  pcilib_get_dma_info(ctx);
 
281
    const pcilib_dma_description_t *info =  pcilib_get_dma_description(ctx);
284
282
    if (!info) {
285
283
        pcilib_error("DMA is not supported by the device");
286
284
        return PCILIB_ERROR_NOTSUPPORTED;
287
285
    }
288
286
 
289
 
    if (!ctx->model_info.dma->api) {
 
287
    if (!info->api) {
290
288
        pcilib_error("DMA Engine is not configured in the current model");
291
289
        return PCILIB_ERROR_NOTAVAILABLE;
292
290
    }
293
291
    
294
 
    if (!ctx->model_info.dma->api->push) {
 
292
    if (!info->api->push) {
295
293
        pcilib_error("The DMA write is not supported by configured DMA engine");
296
294
        return PCILIB_ERROR_NOTSUPPORTED;
297
295
    }
307
305
        return PCILIB_ERROR_NOTSUPPORTED;
308
306
    }
309
307
    
310
 
    return ctx->model_info.dma->api->push(ctx->dma_ctx, dma, addr, size, flags, timeout, buf, written);
 
308
    return info->api->push(ctx->dma_ctx, dma, addr, size, flags, timeout, buf, written);
311
309
}
312
310
 
313
311
 
316
314
}
317
315
 
318
316
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) {
319
 
    const pcilib_dma_description_t *info =  pcilib_get_dma_info(ctx);
 
317
    const pcilib_dma_description_t *info =  pcilib_get_dma_description(ctx);
320
318
    if (!info) {
321
319
        pcilib_error("DMA is not supported by the device");
322
320
        return 0;
323
321
    }
324
322
 
325
 
    if (!ctx->model_info.dma->api) {
 
323
    if (!info->api) {
326
324
        pcilib_error("DMA Engine is not configured in the current model");
327
325
        return -1;
328
326
    }
329
327
    
330
 
    if (!ctx->model_info.dma->api->benchmark) {
 
328
    if (!info->api->benchmark) {
331
329
        pcilib_error("The DMA benchmark is not supported by configured DMA engine");
332
330
        return -1;
333
331
    }
334
332
 
335
 
    return ctx->model_info.dma->api->benchmark(ctx->dma_ctx, dma, addr, size, iterations, direction);
 
333
    return info->api->benchmark(ctx->dma_ctx, dma, addr, size, iterations, direction);
336
334
}
337
335
 
338
336
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) {
339
 
    const pcilib_dma_description_t *info =  pcilib_get_dma_info(ctx);
 
337
    const pcilib_dma_description_t *info =  pcilib_get_dma_description(ctx);
340
338
    if (!info) {
341
339
        pcilib_error("DMA is not supported by the device");
342
340
        return 0;
343
341
    }
344
342
 
345
 
    if (!ctx->model_info.dma->api) {
 
343
    if (!info->api) {
346
344
        pcilib_error("DMA Engine is not configured in the current model");
347
345
        return -1;
348
346
    }
349
347
    
350
 
    if (!ctx->model_info.dma->api->status) {
 
348
    if (!info->api->status) {
351
349
        memset(status, 0, sizeof(pcilib_dma_engine_status_t));
352
350
        return -1;
353
351
   }
358
356
        return -1;
359
357
    }
360
358
 
361
 
    return ctx->model_info.dma->api->status(ctx->dma_ctx, dma, status, n_buffers, buffers);
 
359
    return info->api->status(ctx->dma_ctx, dma, status, n_buffers, buffers);
362
360
}