/alps/pcitool

To get this branch, use:
bzr branch http://suren.me/webbzr/alps/pcitool
65 by Suren A. Chilingaryan
Separate NWL loopback code, provide DMA start/stop interfaces
1
#define _BSD_SOURCE
302 by Suren A. Chilingaryan
Fixes out-of-source builds and minor build issues
2
#define _DEFAULT_SOURCE
65 by Suren A. Chilingaryan
Separate NWL loopback code, provide DMA start/stop interfaces
3
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
4
#include <stdio.h>
5
#include <stdlib.h>
6
#include <string.h>
7
#include <unistd.h>
8
#include <sys/time.h>
9
10
#include "pci.h"
11
#include "pcilib.h"
12
#include "error.h"
13
#include "tools.h"
250 by Suren A. Chilingaryan
Provide an interface for logging debug messages
14
#include "debug.h"
236 by Suren A. Chilingaryan
Big redign of model structures
15
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
16
#include "nwl_private.h"
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
17
#include "nwl_defines.h"
78 by Suren A. Chilingaryan
Correctly detect the tail pointer of C2S ring
18
#include "nwl_engine_buffers.h"
65 by Suren A. Chilingaryan
Separate NWL loopback code, provide DMA start/stop interfaces
19
236 by Suren A. Chilingaryan
Big redign of model structures
20
int dma_nwl_read_engine_config(nwl_dma_t *ctx, pcilib_dma_engine_description_t *info, const char *base) {
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
21
    uint32_t val;
22
    
23
    nwl_read_register(val, ctx, base, REG_DMA_ENG_CAP);
24
25
    if ((val & DMA_ENG_PRESENT_MASK) == 0) return PCILIB_ERROR_NOTAVAILABLE;
26
    
236 by Suren A. Chilingaryan
Big redign of model structures
27
    info->addr = (val & DMA_ENG_NUMBER) >> DMA_ENG_NUMBER_SHIFT;
28
    if ((info->addr > PCILIB_MAX_DMA_ENGINES)||(info->addr < 0)) return PCILIB_ERROR_INVALID_DATA;
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
29
    
30
    switch (val & DMA_ENG_DIRECTION_MASK) {
31
	case  DMA_ENG_C2S:
236 by Suren A. Chilingaryan
Big redign of model structures
32
	    info->direction = PCILIB_DMA_FROM_DEVICE;
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
33
	break;
34
	default:
236 by Suren A. Chilingaryan
Big redign of model structures
35
	    info->direction = PCILIB_DMA_TO_DEVICE;
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
36
    }
37
    
38
    switch (val & DMA_ENG_TYPE_MASK) {
39
	case DMA_ENG_BLOCK:
236 by Suren A. Chilingaryan
Big redign of model structures
40
	    info->type = PCILIB_DMA_TYPE_BLOCK;
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
41
	break;
42
	case DMA_ENG_PACKET:
236 by Suren A. Chilingaryan
Big redign of model structures
43
	    info->type = PCILIB_DMA_TYPE_PACKET;
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
44
	break;
45
	default:
236 by Suren A. Chilingaryan
Big redign of model structures
46
	    info->type = PCILIB_DMA_TYPE_UNKNOWN;
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
47
    }
48
    
236 by Suren A. Chilingaryan
Big redign of model structures
49
    info->addr_bits = (val & DMA_ENG_BD_MAX_BC) >> DMA_ENG_BD_MAX_BC_SHIFT;
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
50
    
51
    return 0;
52
}
53
54
int dma_nwl_start_engine(nwl_dma_t *ctx, pcilib_dma_engine_t dma) {
55
    int err;
56
    uint32_t val;
57
    uint32_t ring_pa;
58
    struct timeval start, cur;
59
236 by Suren A. Chilingaryan
Big redign of model structures
60
    pcilib_nwl_engine_context_t *ectx = ctx->engines + dma;
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
61
    char *base = ctx->engines[dma].base_addr;
65 by Suren A. Chilingaryan
Separate NWL loopback code, provide DMA start/stop interfaces
62
    
236 by Suren A. Chilingaryan
Big redign of model structures
63
    if (ectx->started) return 0;
79 by Suren A. Chilingaryan
Few more fixes
64
71 by Suren A. Chilingaryan
First iteration of work to preserve DMA state between executions
65
	// This will only successed if there are no parallel access to DMA engine
236 by Suren A. Chilingaryan
Big redign of model structures
66
    err = dma_nwl_allocate_engine_buffers(ctx, ectx);
77 by Suren A. Chilingaryan
Stop only started engines
67
    if (err) {
236 by Suren A. Chilingaryan
Big redign of model structures
68
	ectx->started = 1;
77 by Suren A. Chilingaryan
Stop only started engines
69
	dma_nwl_stop_engine(ctx, dma);
70
	return err;
71
    }
71 by Suren A. Chilingaryan
First iteration of work to preserve DMA state between executions
72
    
236 by Suren A. Chilingaryan
Big redign of model structures
73
    if (ectx->reused) {
74
    	ectx->preserve = 1;
74 by Suren A. Chilingaryan
Implement DMA access synchronization for NWL implementation
75
109 by Suren A. Chilingaryan
Improvements of DMA engine
76
	dma_nwl_acknowledge_irq((pcilib_dma_context_t*)ctx, PCILIB_DMA_IRQ, dma);
74 by Suren A. Chilingaryan
Implement DMA access synchronization for NWL implementation
77
78
#ifdef NWL_GENERATE_DMA_IRQ
79
	dma_nwl_enable_engine_irq(ctx, dma);
80
#endif /* NWL_GENERATE_DMA_IRQ */
81
    } else {
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
82
	// Disable IRQs
74 by Suren A. Chilingaryan
Implement DMA access synchronization for NWL implementation
83
	err = dma_nwl_disable_engine_irq(ctx, dma);
77 by Suren A. Chilingaryan
Stop only started engines
84
	if (err) {
236 by Suren A. Chilingaryan
Big redign of model structures
85
	    ectx->started = 1;
77 by Suren A. Chilingaryan
Stop only started engines
86
	    dma_nwl_stop_engine(ctx, dma);
87
	    return err;
88
	}
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
89
90
	// Disable Engine & Reseting 
74 by Suren A. Chilingaryan
Implement DMA access synchronization for NWL implementation
91
	val = DMA_ENG_DISABLE|DMA_ENG_USER_RESET;
92
	nwl_write_register(val, ctx, base, REG_DMA_ENG_CTRL_STATUS);
93
94
	gettimeofday(&start, NULL);
95
	do {
96
	    nwl_read_register(val, ctx, base, REG_DMA_ENG_CTRL_STATUS);
97
    	    gettimeofday(&cur, NULL);
241 by Suren A. Chilingaryan
Further adjustments to get ready for independent event plugins
98
	} while ((val & (DMA_ENG_STATE_MASK|DMA_ENG_USER_RESET))&&(((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) < PCILIB_NWL_REGISTER_TIMEOUT));
74 by Suren A. Chilingaryan
Implement DMA access synchronization for NWL implementation
99
    
100
	if (val & (DMA_ENG_STATE_MASK|DMA_ENG_USER_RESET)) {
236 by Suren A. Chilingaryan
Big redign of model structures
101
	    pcilib_error("Timeout during reset of DMA engine %i", ectx->desc->addr);
77 by Suren A. Chilingaryan
Stop only started engines
102
236 by Suren A. Chilingaryan
Big redign of model structures
103
	    ectx->started = 1;
77 by Suren A. Chilingaryan
Stop only started engines
104
	    dma_nwl_stop_engine(ctx, dma);
74 by Suren A. Chilingaryan
Implement DMA access synchronization for NWL implementation
105
	    return PCILIB_ERROR_TIMEOUT;
106
	}
107
108
	val = DMA_ENG_RESET; 
109
	nwl_write_register(val, ctx, base, REG_DMA_ENG_CTRL_STATUS);
110
    
111
	gettimeofday(&start, NULL);
112
	do {
113
	    nwl_read_register(val, ctx, base, REG_DMA_ENG_CTRL_STATUS);
114
    	    gettimeofday(&cur, NULL);
241 by Suren A. Chilingaryan
Further adjustments to get ready for independent event plugins
115
	} while ((val & DMA_ENG_RESET)&&(((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) < PCILIB_NWL_REGISTER_TIMEOUT));
74 by Suren A. Chilingaryan
Implement DMA access synchronization for NWL implementation
116
    
117
	if (val & DMA_ENG_RESET) {
236 by Suren A. Chilingaryan
Big redign of model structures
118
	    pcilib_error("Timeout during reset of DMA engine %i", ectx->desc->addr);
77 by Suren A. Chilingaryan
Stop only started engines
119
236 by Suren A. Chilingaryan
Big redign of model structures
120
	    ectx->started = 1;
77 by Suren A. Chilingaryan
Stop only started engines
121
	    dma_nwl_stop_engine(ctx, dma);
74 by Suren A. Chilingaryan
Implement DMA access synchronization for NWL implementation
122
	    return PCILIB_ERROR_TIMEOUT;
123
	}
124
    
109 by Suren A. Chilingaryan
Improvements of DMA engine
125
    	dma_nwl_acknowledge_irq((pcilib_dma_context_t*)ctx, PCILIB_DMA_IRQ, dma);
74 by Suren A. Chilingaryan
Implement DMA access synchronization for NWL implementation
126
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
127
	ring_pa = pcilib_kmem_get_ba(ctx->dmactx.pcilib, ectx->ring);
236 by Suren A. Chilingaryan
Big redign of model structures
128
	nwl_write_register(ring_pa, ctx, ectx->base_addr, REG_DMA_ENG_NEXT_BD);
129
	nwl_write_register(ring_pa, ctx, ectx->base_addr, REG_SW_NEXT_BD);
74 by Suren A. Chilingaryan
Implement DMA access synchronization for NWL implementation
130
131
	__sync_synchronize();
132
236 by Suren A. Chilingaryan
Big redign of model structures
133
	nwl_read_register(val, ctx, ectx->base_addr, REG_DMA_ENG_CTRL_STATUS);
74 by Suren A. Chilingaryan
Implement DMA access synchronization for NWL implementation
134
	val |= (DMA_ENG_ENABLE);
236 by Suren A. Chilingaryan
Big redign of model structures
135
	nwl_write_register(val, ctx, ectx->base_addr, REG_DMA_ENG_CTRL_STATUS);
74 by Suren A. Chilingaryan
Implement DMA access synchronization for NWL implementation
136
137
	__sync_synchronize();
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
138
139
#ifdef NWL_GENERATE_DMA_IRQ
74 by Suren A. Chilingaryan
Implement DMA access synchronization for NWL implementation
140
	dma_nwl_enable_engine_irq(ctx, dma);
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
141
#endif /* NWL_GENERATE_DMA_IRQ */
142
236 by Suren A. Chilingaryan
Big redign of model structures
143
	if (ectx->desc->direction == PCILIB_DMA_FROM_DEVICE) {
144
	    ring_pa += (ectx->ring_size - 1) * PCILIB_NWL_DMA_DESCRIPTOR_SIZE;
145
    	    nwl_write_register(ring_pa, ctx, ectx->base_addr, REG_SW_NEXT_BD);
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
146
236 by Suren A. Chilingaryan
Big redign of model structures
147
	    ectx->tail = 0;
148
	    ectx->head = (ectx->ring_size - 1);
74 by Suren A. Chilingaryan
Implement DMA access synchronization for NWL implementation
149
	} else {
236 by Suren A. Chilingaryan
Big redign of model structures
150
	    ectx->tail = 0;
151
	    ectx->head = 0;
74 by Suren A. Chilingaryan
Implement DMA access synchronization for NWL implementation
152
	}
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
153
    }
154
    
236 by Suren A. Chilingaryan
Big redign of model structures
155
    ectx->started = 1;
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
156
    
157
    return 0;
158
}
159
160
161
int dma_nwl_stop_engine(nwl_dma_t *ctx, pcilib_dma_engine_t dma) {
162
    int err;
163
    uint32_t val;
164
    uint32_t ring_pa;
165
    struct timeval start, cur;
75 by Suren A. Chilingaryan
Few fixes
166
    pcilib_kmem_flags_t flags;
167
    
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
168
    
236 by Suren A. Chilingaryan
Big redign of model structures
169
    pcilib_nwl_engine_context_t *ectx = ctx->engines + dma;
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
170
    char *base = ctx->engines[dma].base_addr;
171
236 by Suren A. Chilingaryan
Big redign of model structures
172
    if (!ectx->started) return 0;
77 by Suren A. Chilingaryan
Stop only started engines
173
    
236 by Suren A. Chilingaryan
Big redign of model structures
174
    ectx->started = 0;
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
175
176
    err = dma_nwl_disable_engine_irq(ctx, dma);
177
    if (err) return err;
178
236 by Suren A. Chilingaryan
Big redign of model structures
179
    if (!ectx->preserve) {
71 by Suren A. Chilingaryan
First iteration of work to preserve DMA state between executions
180
	    // Stopping DMA is not enough reset is required
181
	val = DMA_ENG_DISABLE|DMA_ENG_USER_RESET|DMA_ENG_RESET;
182
	nwl_write_register(val, ctx, base, REG_DMA_ENG_CTRL_STATUS);
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
183
74 by Suren A. Chilingaryan
Implement DMA access synchronization for NWL implementation
184
	gettimeofday(&start, NULL);
185
	do {
186
	    nwl_read_register(val, ctx, base, REG_DMA_ENG_CTRL_STATUS);
187
    	    gettimeofday(&cur, NULL);
241 by Suren A. Chilingaryan
Further adjustments to get ready for independent event plugins
188
	} while ((val & (DMA_ENG_RUNNING))&&(((cur.tv_sec - start.tv_sec)*1000000 + (cur.tv_usec - start.tv_usec)) < PCILIB_NWL_REGISTER_TIMEOUT));
74 by Suren A. Chilingaryan
Implement DMA access synchronization for NWL implementation
189
236 by Suren A. Chilingaryan
Big redign of model structures
190
	if (ectx->ring) {
352.1.4 by Suren A. Chilingaryan
Distinguish between hardware and bus addresses in pcilib
191
	    ring_pa = pcilib_kmem_get_ba(ctx->dmactx.pcilib, ectx->ring);
236 by Suren A. Chilingaryan
Big redign of model structures
192
	    nwl_write_register(ring_pa, ctx, ectx->base_addr, REG_DMA_ENG_NEXT_BD);
193
	    nwl_write_register(ring_pa, ctx, ectx->base_addr, REG_SW_NEXT_BD);
71 by Suren A. Chilingaryan
First iteration of work to preserve DMA state between executions
194
	}
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
195
    }
88 by Suren A. Chilingaryan
IRQ acknowledgement support in the engine API
196
    
109 by Suren A. Chilingaryan
Improvements of DMA engine
197
    dma_nwl_acknowledge_irq((pcilib_dma_context_t*)ctx, PCILIB_DMA_IRQ, dma);
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
198
236 by Suren A. Chilingaryan
Big redign of model structures
199
    if (ectx->preserve) {
75 by Suren A. Chilingaryan
Few fixes
200
	flags = PCILIB_KMEM_FLAG_REUSE;
201
    } else {
202
        flags = PCILIB_KMEM_FLAG_HARDWARE|PCILIB_KMEM_FLAG_PERSISTENT;
203
    }
204
    
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
205
	// Clean buffers
236 by Suren A. Chilingaryan
Big redign of model structures
206
    if (ectx->ring) {
207
	pcilib_free_kernel_memory(ctx->dmactx.pcilib, ectx->ring, flags);
208
	ectx->ring = NULL;
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
209
    }
210
236 by Suren A. Chilingaryan
Big redign of model structures
211
    if (ectx->pages) {
212
	pcilib_free_kernel_memory(ctx->dmactx.pcilib, ectx->pages, flags);
213
	ectx->pages = NULL;
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
214
    }
215
216
    return 0;
217
}
218
219
int dma_nwl_write_fragment(pcilib_dma_context_t *vctx, pcilib_dma_engine_t dma, uintptr_t addr, size_t size, pcilib_dma_flags_t flags, pcilib_timeout_t timeout, void *data, size_t *written) {
220
    int err;
221
    size_t pos;
222
    size_t bufnum;
223
    nwl_dma_t *ctx = (nwl_dma_t*)vctx;
224
236 by Suren A. Chilingaryan
Big redign of model structures
225
    pcilib_nwl_engine_context_t *ectx = ctx->engines + dma;
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
226
109 by Suren A. Chilingaryan
Improvements of DMA engine
227
    err = dma_nwl_start(vctx, dma, PCILIB_DMA_FLAGS_DEFAULT);
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
228
    if (err) return err;
229
230
    if (data) {
236 by Suren A. Chilingaryan
Big redign of model structures
231
	for (pos = 0; pos < size; pos += ectx->page_size) {
232
	    int block_size = min2(size - pos, ectx->page_size);
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
233
	    
236 by Suren A. Chilingaryan
Big redign of model structures
234
    	    bufnum = dma_nwl_get_next_buffer(ctx, ectx, 1, timeout);
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
235
	    if (bufnum == PCILIB_DMA_BUFFER_INVALID) {
236
		if (written) *written = pos;
237
		return PCILIB_ERROR_TIMEOUT;
238
	    }
239
	
370 by Suren A. Chilingaryan
RPM generation
240
    	    void *buf = (void*)pcilib_kmem_get_block_ua(ctx->dmactx.pcilib, ectx->pages, bufnum);
108 by Suren A. Chilingaryan
Fix DMA synchronization for writes as well
241
236 by Suren A. Chilingaryan
Big redign of model structures
242
	    pcilib_kmem_sync_block(ctx->dmactx.pcilib, ectx->pages, PCILIB_KMEM_SYNC_FROMDEVICE, bufnum);
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
243
	    memcpy(buf, data, block_size);
236 by Suren A. Chilingaryan
Big redign of model structures
244
	    pcilib_kmem_sync_block(ctx->dmactx.pcilib, ectx->pages, PCILIB_KMEM_SYNC_TODEVICE, bufnum);
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
245
236 by Suren A. Chilingaryan
Big redign of model structures
246
	    err = dma_nwl_push_buffer(ctx, ectx, block_size, (flags&PCILIB_DMA_FLAG_EOP)&&((pos + block_size) == size), timeout);
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
247
	    if (err) {
248
		if (written) *written = pos;
249
		return err;
250
	    }
251
	}    
252
    }
253
    
254
    if (written) *written = size;
255
    
256
    if (flags&PCILIB_DMA_FLAG_WAIT) {
236 by Suren A. Chilingaryan
Big redign of model structures
257
	bufnum =  dma_nwl_get_next_buffer(ctx, ectx, PCILIB_NWL_DMA_PAGES - 1, timeout);
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
258
	if (bufnum == PCILIB_DMA_BUFFER_INVALID) return PCILIB_ERROR_TIMEOUT;
259
    }
260
    
261
    return 0;
262
}
263
264
int dma_nwl_stream_read(pcilib_dma_context_t *vctx, 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) {
117 by Suren A. Chilingaryan
new event architecture, first trial
265
    int err, ret = PCILIB_STREAMING_REQ_PACKET;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
266
    pcilib_timeout_t wait = 0;
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
267
    size_t res = 0;
268
    size_t bufnum;
269
    size_t bufsize;
117 by Suren A. Chilingaryan
new event architecture, first trial
270
    
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
271
    nwl_dma_t *ctx = (nwl_dma_t*)vctx;
272
273
    int eop;
274
236 by Suren A. Chilingaryan
Big redign of model structures
275
    pcilib_nwl_engine_context_t *ectx = ctx->engines + dma;
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
276
109 by Suren A. Chilingaryan
Improvements of DMA engine
277
    err = dma_nwl_start(vctx, dma, PCILIB_DMA_FLAGS_DEFAULT);
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
278
    if (err) return err;
109 by Suren A. Chilingaryan
Improvements of DMA engine
279
    
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
280
    do {
117 by Suren A. Chilingaryan
new event architecture, first trial
281
	switch (ret&PCILIB_STREAMING_TIMEOUT_MASK) {
282
	    case PCILIB_STREAMING_CONTINUE: wait = PCILIB_DMA_TIMEOUT; break;
283
	    case PCILIB_STREAMING_WAIT: wait = timeout; break;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
284
//	    case PCILIB_STREAMING_CHECK: wait = 0; break;
117 by Suren A. Chilingaryan
new event architecture, first trial
285
	}
286
    
236 by Suren A. Chilingaryan
Big redign of model structures
287
        bufnum = dma_nwl_wait_buffer(ctx, ectx, &bufsize, &eop, wait);
117 by Suren A. Chilingaryan
new event architecture, first trial
288
        if (bufnum == PCILIB_DMA_BUFFER_INVALID) {
289
	    return (ret&PCILIB_STREAMING_FAIL)?PCILIB_ERROR_TIMEOUT:0;
109 by Suren A. Chilingaryan
Improvements of DMA engine
290
	}
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
291
109 by Suren A. Chilingaryan
Improvements of DMA engine
292
	    // EOP is not respected in IPE Camera
236 by Suren A. Chilingaryan
Big redign of model structures
293
	if (ctx->ignore_eop) eop = 1;
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
294
	
236 by Suren A. Chilingaryan
Big redign of model structures
295
	pcilib_kmem_sync_block(ctx->dmactx.pcilib, ectx->pages, PCILIB_KMEM_SYNC_FROMDEVICE, bufnum);
370 by Suren A. Chilingaryan
RPM generation
296
        void *buf = (void*)pcilib_kmem_get_block_ua(ctx->dmactx.pcilib, ectx->pages, bufnum);
109 by Suren A. Chilingaryan
Improvements of DMA engine
297
	ret = cb(cbattr, (eop?PCILIB_DMA_FLAG_EOP:0), bufsize, buf);
190 by Suren A. Chilingaryan
Do not return DMA buffer in streaming read if the callback returns error
298
	if (ret < 0) return -ret;
107 by Suren A. Chilingaryan
Do not sync to device, looks like it is not required
299
//	DS: Fixme, it looks like we can avoid calling this for the sake of performance
236 by Suren A. Chilingaryan
Big redign of model structures
300
//	pcilib_kmem_sync_block(ctx->dmactx.pcilib, ectx->pages, PCILIB_KMEM_SYNC_TODEVICE, bufnum);
301
	dma_nwl_return_buffer(ctx, ectx);
64 by Suren A. Chilingaryan
Another reorganization of NWL sources
302
	
303
	res += bufsize;
304
305
    } while (ret);
306
    
307
    return 0;
308
}
109 by Suren A. Chilingaryan
Improvements of DMA engine
309
310
int dma_nwl_wait_completion(nwl_dma_t * ctx, pcilib_dma_engine_t dma, pcilib_timeout_t timeout) {
311
    if (dma_nwl_get_next_buffer(ctx, ctx->engines + dma, PCILIB_NWL_DMA_PAGES - 1, PCILIB_DMA_TIMEOUT) == (PCILIB_NWL_DMA_PAGES - 1)) return 0;
312
    else return PCILIB_ERROR_TIMEOUT;
313
}
314