/alps/pcitool

To get this branch, use:
bzr branch http://suren.me/webbzr/alps/pcitool

« back to all changes in this revision

Viewing changes to dma.c

  • Committer: Suren A. Chilingaryan
  • Date: 2011-10-26 05:12:31 UTC
  • Revision ID: csa@dside.dyndns.org-20111026051231-5ntkozz31hvjzvb5
Improvements of DMA engine

Show diffs side-by-side

added added

removed removed

Lines of Context:
168
168
    size_t size;
169
169
    void *data;
170
170
    size_t pos;
 
171
    
 
172
    pcilib_dma_flags_t flags;
171
173
} pcilib_dma_read_callback_context_t;
172
174
 
173
175
static int pcilib_dma_read_callback(void *arg, pcilib_dma_flags_t flags, size_t bufsize, void *buf) {
174
176
    pcilib_dma_read_callback_context_t *ctx = (pcilib_dma_read_callback_context_t*)arg;
175
177
    
176
178
    if (ctx->pos + bufsize > ctx->size) {
177
 
        pcilib_error("Buffer size (%li) is not large enough for DMA packet, at least %li bytes is required", ctx->size, ctx->pos + bufsize); 
178
 
        return PCILIB_ERROR_INVALID_DATA;
 
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;
179
182
    }
180
183
    
181
184
    memcpy(ctx->data + ctx->pos, buf, bufsize);
182
185
    ctx->pos += bufsize;
183
186
 
184
 
    if (flags & PCILIB_DMA_FLAG_EOP) return 0;
 
187
    if (flags & PCILIB_DMA_FLAG_EOP) {
 
188
        if ((ctx->pos < ctx->size)&&(ctx->flags&PCILIB_DMA_FLAG_MULTIPACKET)) {
 
189
            if (ctx->flags&PCILIB_DMA_FLAG_WAIT) return 2;
 
190
            else return 3;
 
191
        }
 
192
        return 0;
 
193
    }
185
194
    return 1;
186
195
}
187
196
 
229
238
    return ctx->model_info.dma_api->stream(ctx->dma_ctx, dma, addr, size, flags, timeout, cb, cbattr);
230
239
}
231
240
 
 
241
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) {
 
242
    int err; 
 
243
 
 
244
    pcilib_dma_read_callback_context_t opts = {
 
245
        size, buf, 0, flags
 
246
    };
 
247
    
 
248
    err = pcilib_stream_dma(ctx, dma, addr, size, flags, timeout, pcilib_dma_read_callback, &opts);
 
249
    if (read_bytes) *read_bytes = opts.pos;
 
250
    return err;
 
251
}
 
252
 
232
253
int pcilib_read_dma(pcilib_t *ctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, void *buf, size_t *read_bytes) {
233
254
    int err; 
234
255
 
235
256
    pcilib_dma_read_callback_context_t opts = {
236
 
        size, buf, 0
 
257
        size, buf, 0, 0
237
258
    };
238
259
    
239
260
    err = pcilib_stream_dma(ctx, dma, addr, size, PCILIB_DMA_FLAGS_DEFAULT, PCILIB_DMA_TIMEOUT, pcilib_dma_read_callback, &opts);
241
262
    return err;
242
263
}
243
264
 
 
265
 
244
266
int pcilib_skip_dma(pcilib_t *ctx, pcilib_dma_engine_t dma) {
245
267
    int err;
246
268
    struct timeval tv, cur;