/alps/pcitool

To get this branch, use:
bzr branch http://darksoft.org/webbzr/alps/pcitool
45 by root
North West Logick DMA implementation
1
//#define PCILIB_FILE_IO
277.1.1 by zilio nicolas
clean version for locks
2
#define _XOPEN_SOURCE 700
236 by Suren A. Chilingaryan
Big redign of model structures
3
#define _BSD_SOURCE
303 by Suren A. Chilingaryan
Initial integration of XML support
4
#define _DEFAULT_SOURCE
236 by Suren A. Chilingaryan
Big redign of model structures
5
#define _POSIX_C_SOURCE 200809L
1 by Suren A. Chilingaryan
Initial import
6
7
#include <stdio.h>
8
#include <string.h>
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
9
#include <strings.h>
1 by Suren A. Chilingaryan
Initial import
10
#include <stdlib.h>
11
#include <stdint.h>
12
#include <fcntl.h>
13
#include <unistd.h>
14
#include <sys/ioctl.h>
15
#include <sys/mman.h>
267 by Suren A. Chilingaryan
Provide PCIe link information in pcilib
16
#include <sys/types.h>
17
#include <sys/stat.h>
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
18
#include <arpa/inet.h>
1 by Suren A. Chilingaryan
Initial import
19
#include <errno.h>
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
20
#include <assert.h>
3 by Suren A. Chilingaryan
Print a bit more details
21
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
22
#include "pcilib.h"
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
23
#include "pci.h"
1 by Suren A. Chilingaryan
Initial import
24
#include "tools.h"
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
25
#include "error.h"
236 by Suren A. Chilingaryan
Big redign of model structures
26
#include "model.h"
242 by Suren A. Chilingaryan
Initial support for event engines
27
#include "plugin.h"
258 by Suren A. Chilingaryan
Split bar manipulation and fifo operations in stand-alone source and publish kmem and bar headers
28
#include "bar.h"
277.2.1 by zilio nicolas
registers and banks support in xml v1. pci -ll works fine, but got segfault on pci -r name and pci -r name gives 0 always. might be due to the order in pci.c ------> ask suren
29
#include "xml.h"
277.1.1 by zilio nicolas
clean version for locks
30
#include "locking.h"
236 by Suren A. Chilingaryan
Big redign of model structures
31
32
static int pcilib_detect_model(pcilib_t *ctx, const char *model) {
33
    int i, j;
34
242 by Suren A. Chilingaryan
Initial support for event engines
35
    const pcilib_model_description_t *model_info = NULL;
36
    const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
236 by Suren A. Chilingaryan
Big redign of model structures
37
242 by Suren A. Chilingaryan
Initial support for event engines
38
    model_info = pcilib_find_plugin_model(ctx, board_info->vendor_id, board_info->device_id, model);
39
    if (model_info) {
40
	memcpy(&ctx->model_info, model_info, sizeof(pcilib_model_description_t));
41
	memcpy(&ctx->dma, model_info->dma, sizeof(pcilib_dma_description_t));
243 by Suren A. Chilingaryan
Report selected model
42
	ctx->model = strdup(model_info->name);
242 by Suren A. Chilingaryan
Initial support for event engines
43
    } else if (model) {
44
	    // If not found, check for DMA models
236 by Suren A. Chilingaryan
Big redign of model structures
45
	for (i = 0; pcilib_dma[i].name; i++) {
46
	    if (!strcasecmp(model, pcilib_dma[i].name))
47
		break;
48
	}
49
50
	if (pcilib_dma[i].api) {
242 by Suren A. Chilingaryan
Initial support for event engines
51
	    model_info = &ctx->model_info;
236 by Suren A. Chilingaryan
Big redign of model structures
52
	    memcpy(&ctx->dma, &pcilib_dma[i], sizeof(pcilib_dma_description_t));
53
	    ctx->model_info.dma = &ctx->dma;
242 by Suren A. Chilingaryan
Initial support for event engines
54
	}
55
    }
56
57
	    // Precedens of register configuration: DMA/Event Initialization (top), XML, Event Description, DMA Description (least)
58
    if (model_info) {
59
	const pcilib_dma_description_t *dma = model_info->dma;
60
61
	if (dma) {
62
	    if (dma->banks)
303 by Suren A. Chilingaryan
Initial integration of XML support
63
		pcilib_add_register_banks(ctx, PCILIB_MODEL_MODIFICATON_FLAGS_DEFAULT, 0, dma->banks, NULL);
242 by Suren A. Chilingaryan
Initial support for event engines
64
65
	    if (dma->registers)
303 by Suren A. Chilingaryan
Initial integration of XML support
66
		pcilib_add_registers(ctx, PCILIB_MODEL_MODIFICATON_FLAGS_DEFAULT, 0, dma->registers, NULL);
242 by Suren A. Chilingaryan
Initial support for event engines
67
68
	    if (dma->engines) {
69
		for (j = 0; dma->engines[j].addr_bits; j++);
70
		memcpy(ctx->engines, dma->engines, j * sizeof(pcilib_dma_engine_description_t));
236 by Suren A. Chilingaryan
Big redign of model structures
71
		ctx->num_engines = j;
72
	    } else
73
		ctx->dma.engines = ctx->engines;
74
	}
75
242 by Suren A. Chilingaryan
Initial support for event engines
76
	if (model_info->protocols)
303 by Suren A. Chilingaryan
Initial integration of XML support
77
	    pcilib_add_register_protocols(ctx, PCILIB_MODEL_MODIFICATON_FLAGS_DEFAULT, 0, model_info->protocols, NULL);
242 by Suren A. Chilingaryan
Initial support for event engines
78
		
79
	if (model_info->banks)
303 by Suren A. Chilingaryan
Initial integration of XML support
80
	    pcilib_add_register_banks(ctx, PCILIB_MODEL_MODIFICATON_FLAGS_DEFAULT, 0, model_info->banks, NULL);
236 by Suren A. Chilingaryan
Big redign of model structures
81
242 by Suren A. Chilingaryan
Initial support for event engines
82
	if (model_info->registers)
303 by Suren A. Chilingaryan
Initial integration of XML support
83
	    pcilib_add_registers(ctx, PCILIB_MODEL_MODIFICATON_FLAGS_DEFAULT, 0, model_info->registers, NULL);
242 by Suren A. Chilingaryan
Initial support for event engines
84
		
85
	if (model_info->ranges)
303 by Suren A. Chilingaryan
Initial integration of XML support
86
	    pcilib_add_register_ranges(ctx, PCILIB_MODEL_MODIFICATON_FLAGS_DEFAULT, 0, model_info->ranges);
236 by Suren A. Chilingaryan
Big redign of model structures
87
    }
88
258 by Suren A. Chilingaryan
Split bar manipulation and fifo operations in stand-alone source and publish kmem and bar headers
89
    if (!model_info) {
90
	if ((model)&&(strcasecmp(model, "pci"))/*&&(no xml)*/)
91
	    return PCILIB_ERROR_NOTFOUND;
92
	
93
	ctx->model = strdup("pci");
94
    }
236 by Suren A. Chilingaryan
Big redign of model structures
95
96
    return 0;
97
}
98
99
100
101
pcilib_t *pcilib_open(const char *device, const char *model) {
303 by Suren A. Chilingaryan
Initial integration of XML support
102
    int err, xmlerr;
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
103
    pcilib_t *ctx = malloc(sizeof(pcilib_t));
379 by Suren A. Chilingaryan
Support XML configuration of device models
104
    const pcilib_board_info_t *board_info;
337 by Suren A. Chilingaryan
Driver versioning
105
    const pcilib_driver_version_t *drv_version;
277.2.1 by zilio nicolas
registers and banks support in xml v1. pci -ll works fine, but got segfault on pci -r name and pci -r name gives 0 always. might be due to the order in pci.c ------> ask suren
106
	
286 by Suren A. Chilingaryan
Read model from environmental variable if defined
107
    if (!model)
108
	model = getenv("PCILIB_MODEL");
109
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
110
    if (ctx) {
236 by Suren A. Chilingaryan
Big redign of model structures
111
	memset(ctx, 0, sizeof(pcilib_t));
267 by Suren A. Chilingaryan
Provide PCIe link information in pcilib
112
	ctx->pci_cfg_space_fd = -1;
236 by Suren A. Chilingaryan
Big redign of model structures
113
	
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
114
	ctx->handle = open(device, O_RDWR);
36 by Suren A. Chilingaryan
Some improvements in error handling
115
	if (ctx->handle < 0) {
116
	    pcilib_error("Error opening device (%s)", device);
117
	    free(ctx);
118
	    return NULL;
119
	}
120
	
337 by Suren A. Chilingaryan
Driver versioning
121
	drv_version = pcilib_get_driver_version(ctx);
122
	if (!drv_version) {
123
	    pcilib_error("Driver verification has failed (%s)", device);
124
	    free(ctx);
125
	    return NULL;
126
	}
127
	
352.1.3 by Suren A. Chilingaryan
Detect page mask before any kmem operations (locks, softregs, etc.)
128
	ctx->page_mask = pcilib_get_page_mask();
280 by Suren A. Chilingaryan
Integrate locking subsystem from Nicolas Zilio
129
	
130
	if ((model)&&(!strcasecmp(model, "maintenance"))) {
131
	    ctx->model = strdup("maintenance");
132
	    return ctx;
133
	}
134
379 by Suren A. Chilingaryan
Support XML configuration of device models
135
	board_info = pcilib_get_board_info(ctx);
136
	if (!board_info) {
137
	    pcilib_error("Failed to enumerate PCI device");
138
	    pcilib_close(ctx);
139
	    return NULL;
140
	}
141
142
	    // Check if model is specified in the XML configuration
143
	if (!model)
144
	    model = pcilib_detect_xml_model(ctx, board_info->vendor_id, board_info->device_id);
145
280 by Suren A. Chilingaryan
Integrate locking subsystem from Nicolas Zilio
146
	err = pcilib_init_locking(ctx);
147
	if (err) {
148
	    pcilib_error("Error (%i) initializing locking subsystem", err);
149
	    pcilib_close(ctx);
150
	    return NULL;
151
	}
346.1.16 by Vasilii Chernov
1. Add cmake BUILD_PYTHON_MODULES option.
152
	
153
	err = pcilib_init_py(ctx);
154
	if (err) {
369 by Suren A. Chilingaryan
Make Python problems non-fatal
155
	    pcilib_warning("Error (%i) initializing python subsystem", err);
156
	    pcilib_free_py(ctx);
346.1.16 by Vasilii Chernov
1. Add cmake BUILD_PYTHON_MODULES option.
157
	}
236 by Suren A. Chilingaryan
Big redign of model structures
158
379 by Suren A. Chilingaryan
Support XML configuration of device models
159
236 by Suren A. Chilingaryan
Big redign of model structures
160
	ctx->alloc_reg = PCILIB_DEFAULT_REGISTER_SPACE;
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
161
	ctx->alloc_views = PCILIB_DEFAULT_VIEW_SPACE;
162
	ctx->alloc_units = PCILIB_DEFAULT_UNIT_SPACE;
236 by Suren A. Chilingaryan
Big redign of model structures
163
	ctx->registers = (pcilib_register_description_t *)malloc(PCILIB_DEFAULT_REGISTER_SPACE * sizeof(pcilib_register_description_t));
249 by Suren A. Chilingaryan
Create dummy register context
164
	ctx->register_ctx = (pcilib_register_context_t *)malloc(PCILIB_DEFAULT_REGISTER_SPACE * sizeof(pcilib_register_context_t));
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
165
	ctx->views = (pcilib_view_description_t**)malloc(PCILIB_DEFAULT_VIEW_SPACE * sizeof(pcilib_view_description_t*));
166
	ctx->units = (pcilib_unit_description_t*)malloc(PCILIB_DEFAULT_UNIT_SPACE * sizeof(pcilib_unit_description_t));
236 by Suren A. Chilingaryan
Big redign of model structures
167
	
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
168
	if ((!ctx->registers)||(!ctx->register_ctx)||(!ctx->views)||(!ctx->units)) {
236 by Suren A. Chilingaryan
Big redign of model structures
169
	    pcilib_error("Error allocating memory for register model");
170
	    pcilib_close(ctx);
171
	    return NULL;
172
	}
173
	
174
	memset(ctx->registers, 0, sizeof(pcilib_register_description_t));
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
175
	memset(ctx->units, 0, sizeof(pcilib_unit_t));
309 by Suren A. Chilingaryan
Base functions for views
176
	memset(ctx->views, 0, sizeof(pcilib_view_t*));
236 by Suren A. Chilingaryan
Big redign of model structures
177
	memset(ctx->banks, 0, sizeof(pcilib_register_bank_description_t));
178
	memset(ctx->ranges, 0, sizeof(pcilib_register_range_t));
249 by Suren A. Chilingaryan
Create dummy register context
179
180
	memset(ctx->register_ctx, 0, PCILIB_DEFAULT_REGISTER_SPACE * sizeof(pcilib_register_context_t));
181
324 by Suren A. Chilingaryan
Documentation update
182
	pcilib_add_register_protocols(ctx, PCILIB_MODEL_MODIFICATON_FLAGS_DEFAULT, 0, pcilib_standard_register_protocols, NULL);
183
	pcilib_add_register_banks(ctx, PCILIB_MODEL_MODIFICATON_FLAGS_DEFAULT, 0, pcilib_standard_register_banks, NULL);
184
	pcilib_add_registers(ctx, PCILIB_MODEL_MODIFICATON_FLAGS_DEFAULT, 0, pcilib_standard_registers, NULL);
236 by Suren A. Chilingaryan
Big redign of model structures
185
186
	err = pcilib_detect_model(ctx, model);
303 by Suren A. Chilingaryan
Initial integration of XML support
187
	if ((err)&&(err != PCILIB_ERROR_NOTFOUND)) {
379 by Suren A. Chilingaryan
Support XML configuration of device models
188
	    pcilib_error("Error (%i) configuring model %s (%x:%x)", err, (model?model:""), board_info->vendor_id, board_info->device_id);
236 by Suren A. Chilingaryan
Big redign of model structures
189
	    pcilib_close(ctx);
190
	    return NULL;
191
	}
192
243 by Suren A. Chilingaryan
Report selected model
193
	if (!ctx->model)
194
	    ctx->model = strdup(model?model:"pci");
369 by Suren A. Chilingaryan
Make Python problems non-fatal
195
353 by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov
196
	err = pcilib_py_add_script_dir(ctx, NULL);
346.1.10 by Vasilii Chernov
1. Cmakelists - move copy xml folder command to root file
197
	if (err) {
369 by Suren A. Chilingaryan
Make Python problems non-fatal
198
	    pcilib_warning("Error (%i) add script path to python path", err);
199
	    pcilib_free_py(ctx);
200
	    err = 0;
346.1.10 by Vasilii Chernov
1. Cmakelists - move copy xml folder command to root file
201
	}
369 by Suren A. Chilingaryan
Make Python problems non-fatal
202
203
303 by Suren A. Chilingaryan
Initial integration of XML support
204
	xmlerr = pcilib_init_xml(ctx, ctx->model);
205
	if ((xmlerr)&&(xmlerr != PCILIB_ERROR_NOTFOUND)) {
206
	    pcilib_error("Error (%i) initializing XML subsystem for model %s", xmlerr, ctx->model);
207
	    pcilib_close(ctx);
208
	    return NULL;
209
	}
369 by Suren A. Chilingaryan
Make Python problems non-fatal
210
303 by Suren A. Chilingaryan
Initial integration of XML support
211
212
	    // We have found neither standard model nor XML
213
	if ((err)&&(xmlerr)) {
214
	    pcilib_error("The specified model (%s) is not available", model);
277.2.17 by zilio nicolas
further modifications
215
	    pcilib_close(ctx);
216
	    return NULL;
217
	}
277.2.1 by zilio nicolas
registers and banks support in xml v1. pci -ll works fine, but got segfault on pci -r name and pci -r name gives 0 always. might be due to the order in pci.c ------> ask suren
218
	
242 by Suren A. Chilingaryan
Initial support for event engines
219
	ctx->model_info.registers = ctx->registers;
220
	ctx->model_info.banks = ctx->banks;
221
	ctx->model_info.protocols = ctx->protocols;
222
	ctx->model_info.ranges = ctx->ranges;
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
223
	ctx->model_info.views = (const pcilib_view_description_t**)ctx->views;
224
	ctx->model_info.units = ctx->units;
242 by Suren A. Chilingaryan
Initial support for event engines
225
236 by Suren A. Chilingaryan
Big redign of model structures
226
	err = pcilib_init_register_banks(ctx);
227
	if (err) {
228
	    pcilib_error("Error (%i) initializing regiser banks\n", err);
229
	    pcilib_close(ctx);
230
	    return NULL;
231
	}
232
	err = pcilib_init_event_engine(ctx);
233
	if (err) {
234
	    pcilib_error("Error (%i) initializing event engine\n", err);
235
	    pcilib_close(ctx);
236
	    return NULL;
237
	}
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
238
    }
239
240
    return ctx;
241
}
242
43 by root
Enumerate DMA engines
243
337 by Suren A. Chilingaryan
Driver versioning
244
const pcilib_driver_version_t *pcilib_get_driver_version(pcilib_t *ctx) {
245
    int ret;
246
    
247
    if (!ctx->driver_version.version) {
248
	ret = ioctl( ctx->handle, PCIDRIVER_IOC_VERSION, &ctx->driver_version );
249
	if (ret) {
250
	    pcilib_error("PCIDRIVER_IOC_DRIVER_VERSION ioctl have failed");
251
	    return NULL;
252
	}
253
	
254
	if (ctx->driver_version.interface != PCIDRIVER_INTERFACE_VERSION) {
255
	    pcilib_error("Using pcilib (version: %u.%u.%u, driver interface: 0x%lx) with incompatible driver (version: %u.%u.%u, interface: 0x%lx)", 
256
		PCILIB_VERSION_GET_MAJOR(PCILIB_VERSION),
257
		PCILIB_VERSION_GET_MINOR(PCILIB_VERSION),
258
		PCILIB_VERSION_GET_MICRO(PCILIB_VERSION),
259
		PCIDRIVER_INTERFACE_VERSION,
260
		PCILIB_VERSION_GET_MAJOR(ctx->driver_version.version),
261
		PCILIB_VERSION_GET_MINOR(ctx->driver_version.version),
262
		PCILIB_VERSION_GET_MICRO(ctx->driver_version.version),
263
		ctx->driver_version.interface
264
	    );
265
	    return NULL;
266
	}
267
    }
268
269
    return &ctx->driver_version;
270
}
271
41 by root
A bit of DMA infrastructure
272
const pcilib_board_info_t *pcilib_get_board_info(pcilib_t *ctx) {
1 by Suren A. Chilingaryan
Initial import
273
    int ret;
274
    
352.1.3 by Suren A. Chilingaryan
Detect page mask before any kmem operations (locks, softregs, etc.)
275
    if (!ctx->board_info_ready) {
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
276
	ret = ioctl( ctx->handle, PCIDRIVER_IOC_PCI_INFO, &ctx->board_info );
36 by Suren A. Chilingaryan
Some improvements in error handling
277
	if (ret) {
278
	    pcilib_error("PCIDRIVER_IOC_PCI_INFO ioctl have failed");
279
	    return NULL;
280
	}
1 by Suren A. Chilingaryan
Initial import
281
	
352.1.3 by Suren A. Chilingaryan
Detect page mask before any kmem operations (locks, softregs, etc.)
282
	ctx->board_info_ready = 1;
1 by Suren A. Chilingaryan
Initial import
283
    }
337 by Suren A. Chilingaryan
Driver versioning
284
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
285
    return &ctx->board_info;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
286
}
287
45 by root
North West Logick DMA implementation
288
31 by Suren A. Chilingaryan
Introduce pcilib_context_t type instead pointer to void
289
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
290
    return ctx->event_ctx;
291
}
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
292
267 by Suren A. Chilingaryan
Provide PCIe link information in pcilib
293
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
294
void pcilib_close(pcilib_t *ctx) {
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
295
    pcilib_bar_t bar;
236 by Suren A. Chilingaryan
Big redign of model structures
296
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
297
    if (ctx) {
292 by Suren A. Chilingaryan
Protect access to the DMA engine with locks
298
	pcilib_dma_engine_t dma;
236 by Suren A. Chilingaryan
Big redign of model structures
299
	const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
300
	const pcilib_event_api_description_t *eapi = model_info->api;
240 by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines
301
	const pcilib_dma_api_description_t *dapi = ctx->dma.api;
236 by Suren A. Chilingaryan
Big redign of model structures
302
	
41 by root
A bit of DMA infrastructure
303
        if ((eapi)&&(eapi->free)) eapi->free(ctx->event_ctx);
304
        if ((dapi)&&(dapi->free)) dapi->free(ctx->dma_ctx);
236 by Suren A. Chilingaryan
Big redign of model structures
305
292 by Suren A. Chilingaryan
Protect access to the DMA engine with locks
306
	for  (dma = 0; dma < PCILIB_MAX_DMA_ENGINES; dma++) {
307
	    if (ctx->dma_rlock[dma])
308
		pcilib_return_lock(ctx, PCILIB_LOCK_FLAGS_DEFAULT, ctx->dma_rlock[dma]);
309
	    if (ctx->dma_wlock[dma])
310
		pcilib_return_lock(ctx, PCILIB_LOCK_FLAGS_DEFAULT, ctx->dma_wlock[dma]);
311
	}
312
315 by Suren A. Chilingaryan
Support properties of arbitrary type
313
	pcilib_free_register_banks(ctx, 0);
277.2.17 by zilio nicolas
further modifications
314
242 by Suren A. Chilingaryan
Initial support for event engines
315
	if (ctx->event_plugin)
316
	    pcilib_plugin_close(ctx->event_plugin);
280 by Suren A. Chilingaryan
Integrate locking subsystem from Nicolas Zilio
317
318
	if (ctx->locks.kmem)
319
	    pcilib_free_locking(ctx);
320
71 by Suren A. Chilingaryan
First iteration of work to preserve DMA state between executions
321
	if (ctx->kmem_list) {
322
	    pcilib_warning("Not all kernel buffers are properly cleaned");
323
	
324
	    while (ctx->kmem_list) {
325
		pcilib_free_kernel_memory(ctx, ctx->kmem_list, 0);
326
	    }
45 by root
North West Logick DMA implementation
327
	}
236 by Suren A. Chilingaryan
Big redign of model structures
328
	
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
329
	for (bar = 0; bar < PCILIB_MAX_BARS; bar++) {
330
	    if (ctx->bar_space[bar]) {
331
		char *ptr = ctx->bar_space[bar];
332
		ctx->bar_space[bar] = NULL;
333
		pcilib_unmap_bar(ctx, bar, ptr);
39 by root
Move to new FPGA design
334
	    }
335
	}
267 by Suren A. Chilingaryan
Provide PCIe link information in pcilib
336
	
337
	if (ctx->pci_cfg_space_fd >= 0)
338
	    close(ctx->pci_cfg_space_fd);
236 by Suren A. Chilingaryan
Big redign of model structures
339
310 by Suren A. Chilingaryan
Introduce hashes
340
341
        if (ctx->units) {
315 by Suren A. Chilingaryan
Support properties of arbitrary type
342
            pcilib_clean_units(ctx, 0);
310 by Suren A. Chilingaryan
Introduce hashes
343
            free(ctx->units);
344
        }
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
345
346
	if (ctx->views) {
315 by Suren A. Chilingaryan
Support properties of arbitrary type
347
	    pcilib_clean_views(ctx, 0);
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
348
	    free(ctx->views);
349
	}
350
315 by Suren A. Chilingaryan
Support properties of arbitrary type
351
        pcilib_clean_registers(ctx, 0);
310 by Suren A. Chilingaryan
Introduce hashes
352
353
	if (ctx->register_ctx)
354
            free(ctx->register_ctx);
355
236 by Suren A. Chilingaryan
Big redign of model structures
356
	if (ctx->registers)
357
	    free(ctx->registers);
346.1.15 by Vasilii Chernov
1. Add python thread initialization to pcilib_init_py()
358
	    
236 by Suren A. Chilingaryan
Big redign of model structures
359
	if (ctx->model)
360
	    free(ctx->model);
280 by Suren A. Chilingaryan
Integrate locking subsystem from Nicolas Zilio
361
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
362
	pcilib_free_xml(ctx);
353 by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov
363
	pcilib_free_py(ctx);
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
364
236 by Suren A. Chilingaryan
Big redign of model structures
365
	if (ctx->handle >= 0)
366
	    close(ctx->handle);
15 by Suren A. Chilingaryan
Infrastructure for event API
367
	
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
368
	free(ctx);
369
    }
370
}
371
267 by Suren A. Chilingaryan
Provide PCIe link information in pcilib
372
static int pcilib_update_pci_configuration_space(pcilib_t *ctx) {
373
    int err;
374
    int size;
375
376
    if (ctx->pci_cfg_space_fd < 0) {
377
	char fname[128];
378
379
	const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
380
	if (!board_info) {
381
	    pcilib_error("Failed to acquire board info");
382
	    return PCILIB_ERROR_FAILED;
383
	}
384
385
	sprintf(fname, "/sys/bus/pci/devices/0000:%02x:%02x.%1x/config", board_info->bus, board_info->slot, board_info->func);
386
387
	ctx->pci_cfg_space_fd = open(fname, O_RDONLY);
388
	if (ctx->pci_cfg_space_fd < 0) {
389
	    pcilib_error("Failed to open configuration space in %s", fname);
390
	    return PCILIB_ERROR_FAILED;
391
	}
392
    } else {
393
	err = lseek(ctx->pci_cfg_space_fd, SEEK_SET, 0);
394
	if (err) {
395
	    close(ctx->pci_cfg_space_fd);
396
	    ctx->pci_cfg_space_fd = -1;
397
	    return pcilib_update_pci_configuration_space(ctx);
398
	}
399
    }
400
401
    size = read(ctx->pci_cfg_space_fd, ctx->pci_cfg_space_cache, 256);
298 by Suren A. Chilingaryan
Do not fail if PCI configuration is not fully available to unprivileged user
402
    if (size < 64) {
403
	if (size <= 0)
404
	    pcilib_error("Failed to read PCI configuration from sysfs, errno: %i", errno);
405
	else
406
	    pcilib_error("Failed to read PCI configuration from sysfs, only %zu bytes read (expected at least 64)", size);
267 by Suren A. Chilingaryan
Provide PCIe link information in pcilib
407
	return PCILIB_ERROR_FAILED;
408
    }
409
298 by Suren A. Chilingaryan
Do not fail if PCI configuration is not fully available to unprivileged user
410
    ctx->pci_cfg_space_size = size;
411
267 by Suren A. Chilingaryan
Provide PCIe link information in pcilib
412
    return 0;
413
}
414
415
416
static uint32_t *pcilib_get_pci_capabilities(pcilib_t *ctx, int cap_id) {
417
    int err;
418
419
    uint32_t cap;
420
    uint8_t cap_offset;		/**< Offset of capability in the configuration space */
421
422
    if (!ctx->pci_cfg_space_fd) {
423
	err = pcilib_update_pci_configuration_space(ctx);
424
	if (err) {
425
	    pcilib_error("Error (%i) reading PCI configuration space", err);
426
	    return NULL;
427
	}
428
    }
429
430
	// This is just a pointer to the first cap
431
    cap = ctx->pci_cfg_space_cache[(0x34>>2)];
432
    cap_offset = cap&0xFC;
433
298 by Suren A. Chilingaryan
Do not fail if PCI configuration is not fully available to unprivileged user
434
    while ((cap_offset)&&(cap_offset < ctx->pci_cfg_space_size)) {
267 by Suren A. Chilingaryan
Provide PCIe link information in pcilib
435
	cap = ctx->pci_cfg_space_cache[cap_offset>>2];
436
	if ((cap&0xFF) == cap_id)
437
	    return &ctx->pci_cfg_space_cache[cap_offset>>2];
438
	cap_offset = (cap>>8)&0xFC;
439
    }
440
441
    return NULL;
442
};
443
444
445
static const uint32_t *pcilib_get_pcie_capabilities(pcilib_t *ctx) {
446
    if (ctx->pcie_capabilities)
447
	return ctx->pcie_capabilities;
448
449
    ctx->pcie_capabilities = pcilib_get_pci_capabilities(ctx, 0x10);
450
    return ctx->pcie_capabilities;
451
}
452
453
454
const pcilib_pcie_link_info_t *pcilib_get_pcie_link_info(pcilib_t *ctx) {
455
    int err;
456
    const uint32_t *cap;
457
458
    err = pcilib_update_pci_configuration_space(ctx);
459
    if (err) {
460
	pcilib_error("Error (%i) updating PCI configuration space", err);
461
	return NULL;
462
    }
463
464
    cap = pcilib_get_pcie_capabilities(ctx);
465
    if (!cap) return NULL;
466
467
	// Generally speaking this can be updated during the application life time
468
    
469
    ctx->link_info.max_payload = (cap[1] & 0x07) + 7;
470
    ctx->link_info.payload = ((cap[2] >> 5) & 0x07) + 7;
471
    ctx->link_info.link_speed = (cap[3]&0xF);
472
    ctx->link_info.link_width = (cap[3]&0x3F0) >> 4;
473
    ctx->link_info.max_link_speed = (cap[4]&0xF0000) >> 16;
474
    ctx->link_info.max_link_width = (cap[4]&0x3F00000) >> 20;
475
476
    return &ctx->link_info;
477
}
335 by Suren A. Chilingaryan
Enforce 64-bit dma mask from IPEDMA if supported
478
337 by Suren A. Chilingaryan
Driver versioning
479
int pcilib_get_device_state(pcilib_t *ctx, pcilib_device_state_t *state) {
480
    int ret = ioctl( ctx->handle, PCIDRIVER_IOC_DEVICE_STATE, state);
481
    if (ret < 0) {
482
	pcilib_error("PCIDRIVER_IOC_DEVICE_STATE ioctl have failed");
483
	return PCILIB_ERROR_FAILED;
484
    }
485
    return 0;
486
}
487
335 by Suren A. Chilingaryan
Enforce 64-bit dma mask from IPEDMA if supported
488
int pcilib_set_dma_mask(pcilib_t *ctx, int mask) {
337 by Suren A. Chilingaryan
Driver versioning
489
    if (ioctl(ctx->handle, PCIDRIVER_IOC_DMA_MASK, mask) < 0)
335 by Suren A. Chilingaryan
Enforce 64-bit dma mask from IPEDMA if supported
490
	return PCILIB_ERROR_FAILED;
491
492
    return 0;
493
}
338 by Suren A. Chilingaryan
Support setting payload size
494
495
int pcilib_set_mps(pcilib_t *ctx, int mps) {
496
    if (ioctl(ctx->handle, PCIDRIVER_IOC_MPS, mps) < 0)
497
	return PCILIB_ERROR_FAILED;
498
499
    return 0;
500
}