/alps/pcitool

To get this branch, use:
bzr branch http://suren.me/webbzr/alps/pcitool
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1
#define _PCILIB_PCI_C
45 by root
North West Logick DMA implementation
2
//#define PCILIB_FILE_IO
15 by Suren A. Chilingaryan
Infrastructure for event API
3
#define _POSIX_C_SOURCE 199309L
1 by Suren A. Chilingaryan
Initial import
4
5
#include <stdio.h>
6
#include <string.h>
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
7
#include <strings.h>
1 by Suren A. Chilingaryan
Initial import
8
#include <stdlib.h>
9
#include <stdint.h>
10
#include <stdarg.h>
11
#include <fcntl.h>
12
#include <unistd.h>
13
#include <sys/ioctl.h>
14
#include <sys/mman.h>
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
15
#include <arpa/inet.h>
1 by Suren A. Chilingaryan
Initial import
16
#include <errno.h>
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
17
#include <assert.h>
3 by Suren A. Chilingaryan
Print a bit more details
18
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
19
#include "pci.h"
20
3 by Suren A. Chilingaryan
Print a bit more details
21
#include "kernel.h"
1 by Suren A. Chilingaryan
Initial import
22
#include "tools.h"
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
23
#include "error.h"
1 by Suren A. Chilingaryan
Initial import
24
15 by Suren A. Chilingaryan
Infrastructure for event API
25
#include "ipecamera/model.h"
45 by root
North West Logick DMA implementation
26
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
27
28
static void pcilib_print_error(const char *msg, ...) {
29
    va_list va;
30
    
31
    va_start(va, msg);
32
    vprintf(msg, va);
33
    va_end(va);
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
34
    printf("\n");
35
}
36
37
void (*pcilib_error)(const char *msg, ...) = pcilib_print_error;
38
void (*pcilib_warning)(const char *msg, ...) = pcilib_print_error;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
39
10 by Matthias Vogelgesang
Set warning handler
40
int pcilib_set_error_handler(void (*err)(const char *msg, ...), void (*warn)(const char *msg, ...)) {
13 by Suren A. Chilingaryan
Fix exiting on warnings
41
    if (err) pcilib_error = err;
42
    else pcilib_error = pcilib_print_error;
43
    if (warn) pcilib_warning = warn;
44
    else pcilib_warning = pcilib_print_error;
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
45
}
46
47
pcilib_t *pcilib_open(const char *device, pcilib_model_t model) {
48
    pcilib_t *ctx = malloc(sizeof(pcilib_t));
49
50
    if (ctx) {
39 by root
Move to new FPGA design
51
	memset(ctx, 0, sizeof(pcilib_t));	
52
    
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
53
	ctx->handle = open(device, O_RDWR);
36 by Suren A. Chilingaryan
Some improvements in error handling
54
	if (ctx->handle < 0) {
55
	    pcilib_error("Error opening device (%s)", device);
56
	    free(ctx);
57
	    return NULL;
58
	}
59
	
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
60
	ctx->page_mask = (uintptr_t)-1;
61
	ctx->model = model;
15 by Suren A. Chilingaryan
Infrastructure for event API
62
63
	if (!model) model = pcilib_get_model(ctx);
43 by root
Enumerate DMA engines
64
	
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
65
	memcpy(&ctx->model_info, pcilib_model + model, sizeof(pcilib_model_description_t));
66
117 by Suren A. Chilingaryan
new event architecture, first trial
67
	pcilib_init_event_engine(ctx);
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
68
    }
69
70
    return ctx;
71
}
72
43 by root
Enumerate DMA engines
73
pcilib_model_description_t *pcilib_get_model_description(pcilib_t *ctx) {
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
74
    return &ctx->model_info;
43 by root
Enumerate DMA engines
75
}
76
41 by root
A bit of DMA infrastructure
77
const pcilib_board_info_t *pcilib_get_board_info(pcilib_t *ctx) {
1 by Suren A. Chilingaryan
Initial import
78
    int ret;
79
    
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
80
    if (ctx->page_mask ==  (uintptr_t)-1) {
81
	ret = ioctl( ctx->handle, PCIDRIVER_IOC_PCI_INFO, &ctx->board_info );
36 by Suren A. Chilingaryan
Some improvements in error handling
82
	if (ret) {
83
	    pcilib_error("PCIDRIVER_IOC_PCI_INFO ioctl have failed");
84
	    return NULL;
85
	}
1 by Suren A. Chilingaryan
Initial import
86
	
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
87
	ctx->page_mask = pcilib_get_page_mask();
1 by Suren A. Chilingaryan
Initial import
88
    }
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
89
    
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
90
    return &ctx->board_info;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
91
}
92
45 by root
North West Logick DMA implementation
93
94
31 by Suren A. Chilingaryan
Introduce pcilib_context_t type instead pointer to void
95
pcilib_context_t *pcilib_get_implementation_context(pcilib_t *ctx) {
17 by Suren A. Chilingaryan
Allow access to implementation context and provide call to set size of internal buffer for IPECamera
96
    return ctx->event_ctx;
97
}
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
98
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
99
pcilib_model_t pcilib_get_model(pcilib_t *ctx) {
100
    if (ctx->model == PCILIB_MODEL_DETECT) {
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
101
	unsigned short vendor_id;
102
	unsigned short device_id;
103
39 by root
Move to new FPGA design
104
	//return PCILIB_MODEL_PCI;
105
	
41 by root
A bit of DMA infrastructure
106
	const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
36 by Suren A. Chilingaryan
Some improvements in error handling
107
	if (!board_info) return PCILIB_MODEL_PCI;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
108
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
109
	if ((board_info->vendor_id == PCIE_XILINX_VENDOR_ID)&&(board_info->device_id == PCIE_IPECAMERA_DEVICE_ID))
110
	    ctx->model = PCILIB_MODEL_IPECAMERA;
111
	else
112
	    ctx->model = PCILIB_MODEL_PCI;
113
    }
114
    
115
    return ctx->model;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
116
}
117
39 by root
Move to new FPGA design
118
static pcilib_bar_t pcilib_detect_bar(pcilib_t *ctx, uintptr_t addr, size_t size) {
119
    pcilib_bar_t i;
1 by Suren A. Chilingaryan
Initial import
120
	
41 by root
A bit of DMA infrastructure
121
    const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
39 by root
Move to new FPGA design
122
    if (!board_info) return PCILIB_BAR_INVALID;
1 by Suren A. Chilingaryan
Initial import
123
		
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
124
    for (i = 0; i < PCILIB_MAX_BANKS; i++) {
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
125
	if ((addr >= board_info->bar_start[i])&&((board_info->bar_start[i] + board_info->bar_length[i]) >= (addr + size))) return i;
1 by Suren A. Chilingaryan
Initial import
126
    }
127
	
39 by root
Move to new FPGA design
128
    return PCILIB_BAR_INVALID;
1 by Suren A. Chilingaryan
Initial import
129
}
130
36 by Suren A. Chilingaryan
Some improvements in error handling
131
static int pcilib_detect_address(pcilib_t *ctx, pcilib_bar_t *bar, uintptr_t *addr, size_t size) {
41 by root
A bit of DMA infrastructure
132
    const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
36 by Suren A. Chilingaryan
Some improvements in error handling
133
    if (!board_info) return PCILIB_ERROR_NOTFOUND;
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
134
    
135
    if (*bar == PCILIB_BAR_DETECT) {
136
	*bar = pcilib_detect_bar(ctx, *addr, size);
36 by Suren A. Chilingaryan
Some improvements in error handling
137
	if (*bar < 0) {
138
	    pcilib_error("The requested data block at address 0x%x with size 0x%x does not belongs to any available memory bank", *addr, size);
139
	    return PCILIB_ERROR_NOTFOUND;
140
	}
1 by Suren A. Chilingaryan
Initial import
141
    } else {
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
142
	if ((*addr < board_info->bar_start[*bar])||((board_info->bar_start[*bar] + board_info->bar_length[*bar]) < (((uintptr_t)*addr) + size))) {
36 by Suren A. Chilingaryan
Some improvements in error handling
143
	    if ((board_info->bar_length[*bar]) >= (((uintptr_t)*addr) + size)) {
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
144
		*addr += board_info->bar_start[*bar];
36 by Suren A. Chilingaryan
Some improvements in error handling
145
	    } else {
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
146
		pcilib_error("The requested data block at address 0x%x with size 0x%x does not belong the specified memory bank (Bar %i: starting at 0x%x with size 0x%x)", *addr, size, *bar, board_info->bar_start[*bar], board_info->bar_length[*bar]);
36 by Suren A. Chilingaryan
Some improvements in error handling
147
		return PCILIB_ERROR_NOTFOUND;
148
	    }
1 by Suren A. Chilingaryan
Initial import
149
	}
150
    }
151
    
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
152
    *addr -= board_info->bar_start[*bar];
153
    *addr += board_info->bar_start[*bar] & ctx->page_mask;
36 by Suren A. Chilingaryan
Some improvements in error handling
154
    
155
    return 0;
1 by Suren A. Chilingaryan
Initial import
156
}
157
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
158
void *pcilib_map_bar(pcilib_t *ctx, pcilib_bar_t bar) {
1 by Suren A. Chilingaryan
Initial import
159
    void *res;
160
    int ret; 
161
41 by root
A bit of DMA infrastructure
162
    const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
36 by Suren A. Chilingaryan
Some improvements in error handling
163
    if (!board_info) return NULL;
1 by Suren A. Chilingaryan
Initial import
164
    
39 by root
Move to new FPGA design
165
    if (ctx->bar_space[bar]) return ctx->bar_space[bar];
166
    
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
167
    ret = ioctl( ctx->handle, PCIDRIVER_IOC_MMAP_MODE, PCIDRIVER_MMAP_PCI );
36 by Suren A. Chilingaryan
Some improvements in error handling
168
    if (ret) {
169
	pcilib_error("PCIDRIVER_IOC_MMAP_MODE ioctl have failed", bar);
170
	return NULL;
171
    }
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
172
173
    ret = ioctl( ctx->handle, PCIDRIVER_IOC_MMAP_AREA, PCIDRIVER_BAR0 + bar );
36 by Suren A. Chilingaryan
Some improvements in error handling
174
    if (ret) {
175
	pcilib_error("PCIDRIVER_IOC_MMAP_AREA ioctl have failed for bank %i", bar);
176
	return NULL;
177
    }
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
178
179
#ifdef PCILIB_FILE_IO
180
    file_io_handle = open("/root/data", O_RDWR);
181
    res = mmap( 0, board_info->bar_length[bar], PROT_WRITE | PROT_READ, MAP_SHARED, ctx->file_io_handle, 0 );
1 by Suren A. Chilingaryan
Initial import
182
#else
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
183
    res = mmap( 0, board_info->bar_length[bar], PROT_WRITE | PROT_READ, MAP_SHARED, ctx->handle, 0 );
1 by Suren A. Chilingaryan
Initial import
184
#endif
36 by Suren A. Chilingaryan
Some improvements in error handling
185
    if ((!res)||(res == MAP_FAILED)) {
186
	pcilib_error("Failed to mmap data bank %i", bar);
187
	return NULL;
188
    }
1 by Suren A. Chilingaryan
Initial import
189
190
    
191
    return res;
192
}
193
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
194
void pcilib_unmap_bar(pcilib_t *ctx, pcilib_bar_t bar, void *data) {
41 by root
A bit of DMA infrastructure
195
    const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
36 by Suren A. Chilingaryan
Some improvements in error handling
196
    if (!board_info) return;
39 by root
Move to new FPGA design
197
198
    if (ctx->bar_space[bar]) return;
36 by Suren A. Chilingaryan
Some improvements in error handling
199
    
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
200
    munmap(data, board_info->bar_length[bar]);
201
#ifdef PCILIB_FILE_IO
202
    close(ctx->file_io_handle);
1 by Suren A. Chilingaryan
Initial import
203
#endif
204
}
205
45 by root
North West Logick DMA implementation
206
int pcilib_map_register_space(pcilib_t *ctx) {
39 by root
Move to new FPGA design
207
    int err;
208
    pcilib_register_bank_t i;
209
    
210
    if (!ctx->reg_bar_mapped)  {
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
211
	pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
212
	pcilib_register_bank_description_t *banks = model_info->banks;
39 by root
Move to new FPGA design
213
    
214
	for (i = 0; ((banks)&&(banks[i].access)); i++) {
215
//	    uint32_t buf[2];
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
216
	    void *reg_space;
39 by root
Move to new FPGA design
217
            pcilib_bar_t bar = banks[i].bar;
218
219
	    if (bar == PCILIB_BAR_DETECT) {
220
		uintptr_t addr = banks[0].read_addr;
221
	    
222
		err = pcilib_detect_address(ctx, &bar, &addr, 1);
223
		if (err) return err;
224
		
225
		if (!ctx->bar_space[bar]) {
226
		    reg_space = pcilib_map_bar(ctx, bar);
227
//		    pcilib_memcpy(&buf, reg_space, 8);
228
	    
229
		    if (reg_space) {
230
			ctx->bar_space[bar] = reg_space;
231
		    } else {
232
			return PCILIB_ERROR_FAILED;
233
		    }
234
		}
235
	    } else if (!ctx->bar_space[bar]) {
236
		reg_space = pcilib_map_bar(ctx, bar);
237
		if (reg_space) {
238
		    ctx->bar_space[bar] = reg_space;
239
		} else {
240
		    return PCILIB_ERROR_FAILED;
241
		}
242
//		pcilib_memcpy(&buf, reg_space, 8);
243
		
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
244
	    }
39 by root
Move to new FPGA design
245
	    if (!i) ctx->reg_bar = bar;
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
246
	}
247
	
39 by root
Move to new FPGA design
248
	ctx->reg_bar_mapped = 1;
15 by Suren A. Chilingaryan
Infrastructure for event API
249
    }
250
    
251
    return 0;
252
}
253
45 by root
North West Logick DMA implementation
254
int pcilib_map_data_space(pcilib_t *ctx, uintptr_t addr) {
15 by Suren A. Chilingaryan
Infrastructure for event API
255
    int err;
39 by root
Move to new FPGA design
256
    pcilib_bar_t i;
15 by Suren A. Chilingaryan
Infrastructure for event API
257
    
39 by root
Move to new FPGA design
258
    if (!ctx->data_bar_mapped) {
41 by root
A bit of DMA infrastructure
259
        const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
36 by Suren A. Chilingaryan
Some improvements in error handling
260
	if (!board_info) return PCILIB_ERROR_FAILED;
15 by Suren A. Chilingaryan
Infrastructure for event API
261
262
	err = pcilib_map_register_space(ctx);
263
	if (err) {
264
	    pcilib_error("Error mapping register space");
265
	    return err;
266
	}
267
	
268
	int data_bar = -1;	
269
	
270
	for (i = 0; i < PCILIB_MAX_BANKS; i++) {
39 by root
Move to new FPGA design
271
	    if ((ctx->bar_space[i])||(!board_info->bar_length[i])) continue;
15 by Suren A. Chilingaryan
Infrastructure for event API
272
	    
273
	    if (addr) {
274
	        if (board_info->bar_start[i] == addr) {
275
		    data_bar = i;
276
		    break;
277
		}
278
	    } else {
279
		if (data_bar >= 0) {
280
		    data_bar = -1;
281
		    break;
282
		}
283
		
284
		data_bar = i;
285
	    }
286
	}
287
	    
288
289
	if (data_bar < 0) {
290
	    if (addr) pcilib_error("Unable to find the specified data space (%lx)", addr);
291
	    else pcilib_error("Unable to find the data space");
292
	    return PCILIB_ERROR_NOTFOUND;
293
	}
294
	
295
	ctx->data_bar = data_bar;
296
	
39 by root
Move to new FPGA design
297
	if (!ctx->bar_space[data_bar]) {
298
	    char *data_space = pcilib_map_bar(ctx, data_bar);
299
	    if (data_space) ctx->bar_space[data_bar] = data_space;
300
	    else {
301
	        pcilib_error("Unable to map the data space");
302
		return PCILIB_ERROR_FAILED;
303
	    }
15 by Suren A. Chilingaryan
Infrastructure for event API
304
	}
39 by root
Move to new FPGA design
305
	
306
	ctx->data_bar_mapped = 0;
15 by Suren A. Chilingaryan
Infrastructure for event API
307
    }
308
    
309
    return 0;
310
}
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
311
	
39 by root
Move to new FPGA design
312
/*
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
313
static void pcilib_unmap_register_space(pcilib_t *ctx) {
314
    if (ctx->reg_space) {
315
	pcilib_unmap_bar(ctx, ctx->reg_bar, ctx->reg_space);
316
	ctx->reg_space = NULL;
317
    }
318
}
319
15 by Suren A. Chilingaryan
Infrastructure for event API
320
static void pcilib_unmap_data_space(pcilib_t *ctx) {
321
    if (ctx->data_space) {
322
	pcilib_unmap_bar(ctx, ctx->data_bar, ctx->data_space);
323
	ctx->data_space = NULL;
324
    }
325
}
39 by root
Move to new FPGA design
326
*/
15 by Suren A. Chilingaryan
Infrastructure for event API
327
39 by root
Move to new FPGA design
328
char  *pcilib_resolve_register_address(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr) {
329
    if (bar == PCILIB_BAR_DETECT) {
330
	    // First checking the default register bar
331
	size_t offset = addr - ctx->board_info.bar_start[ctx->reg_bar];
332
	if ((addr > ctx->board_info.bar_start[ctx->reg_bar])&&(offset < ctx->board_info.bar_length[ctx->reg_bar])) {
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
333
	    if (!ctx->bar_space[ctx->reg_bar]) {
334
		pcilib_error("The register bar is not mapped");
335
		return NULL;
336
	    }
337
39 by root
Move to new FPGA design
338
	    return ctx->bar_space[ctx->reg_bar] + offset + (ctx->board_info.bar_start[ctx->reg_bar] & ctx->page_mask);
339
	}
340
	    
341
	    // Otherwise trying to detect
342
	bar = pcilib_detect_bar(ctx, addr, 1);
343
	if (bar != PCILIB_BAR_INVALID) {
344
	    size_t offset = addr - ctx->board_info.bar_start[bar];
345
	    if ((offset < ctx->board_info.bar_length[bar])&&(ctx->bar_space[bar])) {
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
346
		if (!ctx->bar_space[bar]) {
347
		    pcilib_error("The requested bar (%i) is not mapped", bar);
348
		    return NULL;
349
		}
39 by root
Move to new FPGA design
350
		return ctx->bar_space[bar] + offset + (ctx->board_info.bar_start[bar] & ctx->page_mask);
351
	    }
352
	}
353
    } else {
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
354
	if (!ctx->bar_space[bar]) {
355
	    pcilib_error("The requested bar (%i) is not mapped", bar);
356
	    return NULL;
357
	}
358
	
39 by root
Move to new FPGA design
359
	if (addr < ctx->board_info.bar_length[bar]) {
360
	    return ctx->bar_space[bar] + addr + (ctx->board_info.bar_start[bar] & ctx->page_mask);
361
	}
362
	
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
363
	if ((addr >= ctx->board_info.bar_start[bar])&&(addr < (ctx->board_info.bar_start[bar] + ctx->board_info.bar_length[ctx->reg_bar]))) {
364
	    return ctx->bar_space[bar] + (addr - ctx->board_info.bar_start[bar]) + (ctx->board_info.bar_start[bar] & ctx->page_mask);
365
	}
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
366
    }
39 by root
Move to new FPGA design
367
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
368
    return NULL;
369
}
370
15 by Suren A. Chilingaryan
Infrastructure for event API
371
char *pcilib_resolve_data_space(pcilib_t *ctx, uintptr_t addr, size_t *size) {
372
    int err;
373
    
374
    err = pcilib_map_data_space(ctx, addr);
375
    if (err) {
376
	pcilib_error("Failed to map the specified address space (%lx)", addr);
377
	return NULL;
378
    }
379
    
39 by root
Move to new FPGA design
380
    if (size) *size = ctx->board_info.bar_length[ctx->data_bar];
15 by Suren A. Chilingaryan
Infrastructure for event API
381
    
39 by root
Move to new FPGA design
382
    return ctx->bar_space[ctx->data_bar] + (ctx->board_info.bar_start[ctx->data_bar] & ctx->page_mask);
15 by Suren A. Chilingaryan
Infrastructure for event API
383
}
384
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
385
386
void pcilib_close(pcilib_t *ctx) {
39 by root
Move to new FPGA design
387
    pcilib_bar_t i;
388
    
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
389
    if (ctx) {
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
390
	pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
391
	pcilib_event_api_description_t *eapi = model_info->event_api;
392
	pcilib_dma_api_description_t *dapi = model_info->dma_api;
15 by Suren A. Chilingaryan
Infrastructure for event API
393
    
41 by root
A bit of DMA infrastructure
394
        if ((eapi)&&(eapi->free)) eapi->free(ctx->event_ctx);
395
        if ((dapi)&&(dapi->free)) dapi->free(ctx->dma_ctx);
45 by root
North West Logick DMA implementation
396
	
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
397
	if (ctx->model_info.registers != model_info->registers) {
398
	    free(ctx->model_info.registers);
399
	    ctx->model_info.registers = pcilib_model[ctx->model].registers;
400
	}
401
	
71 by Suren A. Chilingaryan
First iteration of work to preserve DMA state between executions
402
	if (ctx->kmem_list) {
403
	    pcilib_warning("Not all kernel buffers are properly cleaned");
404
	
405
	    while (ctx->kmem_list) {
406
		pcilib_free_kernel_memory(ctx, ctx->kmem_list, 0);
407
	    }
45 by root
North West Logick DMA implementation
408
	}
39 by root
Move to new FPGA design
409
410
	for (i = 0; i < PCILIB_MAX_BANKS; i++) {
411
	    if (ctx->bar_space[i]) {
412
		char *ptr = ctx->bar_space[i];
413
		ctx->bar_space[i] = NULL;
414
		pcilib_unmap_bar(ctx, i, ptr);
415
	    }
416
	}
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
417
	close(ctx->handle);
15 by Suren A. Chilingaryan
Infrastructure for event API
418
	
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
419
	free(ctx);
420
    }
421
}
422
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
423
int pcilib_read(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, size_t size, void *buf) {
424
    int i;
425
    void *data;
426
427
    pcilib_detect_address(ctx, &bar, &addr, size);
428
    data = pcilib_map_bar(ctx, bar);
429
430
    pcilib_memcpy(buf, data + addr, size);
431
    
432
    pcilib_unmap_bar(ctx, bar, data);    
433
}
434
435
int pcilib_write(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, size_t size, void *buf) {
436
    int i;
437
    void *data;
438
439
    pcilib_detect_address(ctx, &bar, &addr, size);
440
    data = pcilib_map_bar(ctx, bar);
441
442
    pcilib_memcpy(data + addr, buf, size);
443
    
444
    pcilib_unmap_bar(ctx, bar, data);    
445
}
446
447
448
int pcilib_read_fifo(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, uint8_t fifo_size, size_t n, void *buf) {
449
    int i;
450
    void *data;
451
    
452
    pcilib_detect_address(ctx, &bar, &addr, fifo_size);
453
    data = pcilib_map_bar(ctx, bar);
454
455
    for (i = 0; i < n; i++) {
456
	pcilib_memcpy(buf + i * fifo_size, data + addr, fifo_size);
457
    }
458
    
459
    pcilib_unmap_bar(ctx, bar, data);    
460
}
461
462
int pcilib_write_fifo(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, uint8_t fifo_size, size_t n, void *buf) {
463
    int i;
464
    void *data;
465
466
    pcilib_detect_address(ctx, &bar, &addr, fifo_size);
467
    data = pcilib_map_bar(ctx, bar);
468
469
    for (i = 0; i < n; i++) {
470
	pcilib_memcpy(data + addr, buf + i * fifo_size, fifo_size);
471
    }
472
473
    pcilib_unmap_bar(ctx, bar, data);    
474
}
475