/alps/pcitool

To get this branch, use:
bzr branch http://suren.me/webbzr/alps/pcitool
277.1.1 by zilio nicolas
clean version for locks
1
#define _XOPEN_SOURCE 700
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
2
#define _POSIX_C_SOURCE 200112L
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
3
#define _BSD_SOURCE
304 by Suren A. Chilingaryan
Sort registers before listing
4
#define _GNU_SOURCE
303 by Suren A. Chilingaryan
Initial integration of XML support
5
#define _DEFAULT_SOURCE
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
6
7
#include <stdio.h>
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
8
#include <stdlib.h>
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
9
#include <string.h>
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
10
#include <strings.h>
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
11
#include <stdint.h>
12
#include <stdarg.h>
13
#include <fcntl.h>
14
#include <unistd.h>
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
15
#include <sys/time.h>
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
16
#include <sys/ioctl.h>
17
#include <sys/mman.h>
18
#include <errno.h>
19
#include <alloca.h>
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
20
#include <arpa/inet.h>
80 by Suren A. Chilingaryan
List kernel buffers
21
#include <sys/types.h>
196 by Suren A. Chilingaryan
Provide access to PCI configuration space in cli
22
#include <sys/stat.h>
80 by Suren A. Chilingaryan
List kernel buffers
23
#include <dirent.h>
117 by Suren A. Chilingaryan
new event architecture, first trial
24
#include <pthread.h>
138 by Suren A. Chilingaryan
Handle SIGINT signal in pcitool
25
#include <signal.h>
242 by Suren A. Chilingaryan
Initial support for event engines
26
#include <dlfcn.h>
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
27
28
#include <getopt.h>
29
141 by Suren A. Chilingaryan
Initial support of fastwritter library
30
#include <fastwriter.h>
31
117 by Suren A. Chilingaryan
new event architecture, first trial
32
#include "pcitool/sysinfo.h"
146 by Suren A. Chilingaryan
Do event counting when rawcallback is used to stream the data
33
#include "pcitool/formaters.h"
348 by Suren A. Chilingaryan
Add build information
34
#include "pcitool/buildinfo.h"
117 by Suren A. Chilingaryan
new event architecture, first trial
35
319 by Suren A. Chilingaryan
Provide register listings in public API
36
#include "views/transform.h"
37
#include "views/enum.h"
348 by Suren A. Chilingaryan
Add build information
38
#include "pcilib/pci.h"
39
#include "pcilib/plugin.h"
40
#include "pcilib/config.h"
41
#include "pcilib/tools.h"
42
#include "pcilib/kmem.h"
43
#include "pcilib/error.h"
44
#include "pcilib/debug.h"
45
#include "pcilib/model.h"
46
#include "pcilib/locking.h"
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
47
48
/* defines */
49
#define MAX_KBUF 14
50
//#define BIGBUFSIZE (512*1024*1024)
51
#define BIGBUFSIZE (1024*1024)
52
53
54
#define DEFAULT_FPGA_DEVICE "/dev/fpga0"
55
56
#define LINE_WIDTH 80
57
#define SEPARATOR_WIDTH 2
58
#define BLOCK_SEPARATOR_WIDTH 2
59
#define BLOCK_SIZE 8
60
#define BENCHMARK_ITERATIONS 128
147 by Suren A. Chilingaryan
Store with additional header containing timestmap, sequential number, etc.
61
#define STATUS_MESSAGE_INTERVAL	5	/* seconds */
136 by Suren A. Chilingaryan
Verbose grabbing mode
62
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
63
7.1.5 by Suren A. Chilingaryan
Support for FPGA registers
64
#define isnumber pcilib_isnumber
65
#define isxnumber pcilib_isxnumber
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
66
#define isnumber_n pcilib_isnumber_n
67
#define isxnumber_n pcilib_isxnumber_n
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
68
69
typedef uint8_t access_t;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
70
71
typedef enum {
117 by Suren A. Chilingaryan
new event architecture, first trial
72
    GRAB_MODE_GRAB = 1,
73
    GRAB_MODE_TRIGGER = 2
74
} GRAB_MODE;
75
76
typedef enum {
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
77
    MODE_INVALID,
337 by Suren A. Chilingaryan
Driver versioning
78
    MODE_VERSION,
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
79
    MODE_INFO,
80
    MODE_LIST,
81
    MODE_BENCHMARK,
82
    MODE_READ,
83
    MODE_READ_REGISTER,
315 by Suren A. Chilingaryan
Support properties of arbitrary type
84
    MODE_READ_PROPERTY,
318 by Suren A. Chilingaryan
Support reading/writting register views by id
85
    MODE_READ_ATTR,
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
86
    MODE_WRITE,
15 by Suren A. Chilingaryan
Infrastructure for event API
87
    MODE_WRITE_REGISTER,
315 by Suren A. Chilingaryan
Support properties of arbitrary type
88
    MODE_WRITE_PROPERTY,
15 by Suren A. Chilingaryan
Infrastructure for event API
89
    MODE_RESET,
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
90
    MODE_GRAB,
91
    MODE_START_DMA,
92
    MODE_STOP_DMA,
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
93
    MODE_LIST_DMA,
94
    MODE_LIST_DMA_BUFFERS,
95
    MODE_READ_DMA_BUFFER,
194 by Suren A. Chilingaryan
DMA-independent IRQ functions
96
    MODE_ENABLE_IRQ,
97
    MODE_DISABLE_IRQ,
98
    MODE_ACK_IRQ,
80 by Suren A. Chilingaryan
List kernel buffers
99
    MODE_WAIT_IRQ,
337 by Suren A. Chilingaryan
Driver versioning
100
    MODE_SET_DMASK,
338 by Suren A. Chilingaryan
Support setting payload size
101
    MODE_SET_MPS,
192 by Suren A. Chilingaryan
Kernel memory allocation
102
    MODE_ALLOC_KMEM,
80 by Suren A. Chilingaryan
List kernel buffers
103
    MODE_LIST_KMEM,
100 by root
Support exporting data from kernel buffers
104
    MODE_READ_KMEM,
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
105
    MODE_FREE_KMEM,
280 by Suren A. Chilingaryan
Integrate locking subsystem from Nicolas Zilio
106
    MODE_LIST_LOCKS,
107
    MODE_FREE_LOCKS,
108
    MODE_LOCK,
109
    MODE_UNLOCK
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
110
} MODE;
111
112
typedef enum {
44 by root
DMA engine initialization and basic intrastructure for DMA read/write
113
    ACCESS_BAR,
114
    ACCESS_DMA,
196 by Suren A. Chilingaryan
Provide access to PCI configuration space in cli
115
    ACCESS_FIFO, 
116
    ACCESS_CONFIG
44 by root
DMA engine initialization and basic intrastructure for DMA read/write
117
} ACCESS_MODE;
118
119
typedef enum {
109 by Suren A. Chilingaryan
Improvements of DMA engine
120
    FLAG_MULTIPACKET = 1,
121
    FLAG_WAIT = 2
122
} FLAGS;
123
117 by Suren A. Chilingaryan
new event architecture, first trial
124
125
typedef enum {
167 by Suren A. Chilingaryan
Respect --format parameter in cli
126
    FORMAT_DEFAULT = 0,
117 by Suren A. Chilingaryan
new event architecture, first trial
127
    FORMAT_RAW,
128
    FORMAT_HEADER,
129
    FORMAT_RINGFS
130
} FORMAT;
131
132
typedef enum {
133
    PARTITION_UNKNOWN,
134
    PARTITION_RAW,
123 by Suren A. Chilingaryan
Parse required event & data_type
135
    PARTITION_EXT4,
136
    PARTITION_NULL
117 by Suren A. Chilingaryan
new event architecture, first trial
137
} PARTITION;
138
109 by Suren A. Chilingaryan
Improvements of DMA engine
139
typedef enum {
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
140
    OPT_DEVICE = 'd',
141
    OPT_MODEL = 'm',
142
    OPT_BAR = 'b',
143
    OPT_ACCESS = 'a',
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
144
    OPT_ENDIANESS = 'e',
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
145
    OPT_SIZE = 's',
15 by Suren A. Chilingaryan
Infrastructure for event API
146
    OPT_OUTPUT = 'o',
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
147
    OPT_TIMEOUT = 't',
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
148
    OPT_INFO = 'i',
100 by root
Support exporting data from kernel buffers
149
    OPT_LIST = 'l',
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
150
    OPT_READ = 'r',
151
    OPT_WRITE = 'w',
15 by Suren A. Chilingaryan
Infrastructure for event API
152
    OPT_GRAB = 'g',
25 by Suren A. Chilingaryan
Support quiete mode to suppress warnings
153
    OPT_QUIETE = 'q',
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
154
    OPT_HELP = 'h',
337 by Suren A. Chilingaryan
Driver versioning
155
    OPT_VERSION = 128,
156
    OPT_RESET,
101 by root
Remove short option for benchmark in cli
157
    OPT_BENCHMARK,
117 by Suren A. Chilingaryan
new event architecture, first trial
158
    OPT_TRIGGER,
159
    OPT_DATA_TYPE,
160
    OPT_EVENT,
161
    OPT_TRIGGER_RATE,
162
    OPT_TRIGGER_TIME,
163
    OPT_RUN_TIME,
164
    OPT_FORMAT,
165
    OPT_BUFFER,
135 by Suren A. Chilingaryan
Allow to configure the number of preprocessing threads
166
    OPT_THREADS,
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
167
    OPT_LIST_DMA,
168
    OPT_LIST_DMA_BUFFERS,
169
    OPT_READ_DMA_BUFFER,
80 by Suren A. Chilingaryan
List kernel buffers
170
    OPT_START_DMA,
171
    OPT_STOP_DMA,
194 by Suren A. Chilingaryan
DMA-independent IRQ functions
172
    OPT_ENABLE_IRQ,
173
    OPT_DISABLE_IRQ,
174
    OPT_ACK_IRQ,
80 by Suren A. Chilingaryan
List kernel buffers
175
    OPT_WAIT_IRQ,
176
    OPT_ITERATIONS,
337 by Suren A. Chilingaryan
Driver versioning
177
    OPT_SET_DMASK,
338 by Suren A. Chilingaryan
Support setting payload size
178
    OPT_SET_MPS,
192 by Suren A. Chilingaryan
Kernel memory allocation
179
    OPT_ALLOC_KMEM,
80 by Suren A. Chilingaryan
List kernel buffers
180
    OPT_LIST_KMEM,
181
    OPT_FREE_KMEM,
100 by root
Support exporting data from kernel buffers
182
    OPT_READ_KMEM,
280 by Suren A. Chilingaryan
Integrate locking subsystem from Nicolas Zilio
183
    OPT_LIST_LOCKS,
184
    OPT_FREE_LOCKS,
185
    OPT_LOCK,
186
    OPT_UNLOCK,
192 by Suren A. Chilingaryan
Kernel memory allocation
187
    OPT_BLOCK_SIZE,
188
    OPT_ALIGNMENT,
189
    OPT_TYPE,
109 by Suren A. Chilingaryan
Improvements of DMA engine
190
    OPT_FORCE,
191 by Suren A. Chilingaryan
Do not verify BAR writes by default
191
    OPT_VERIFY,
109 by Suren A. Chilingaryan
Improvements of DMA engine
192
    OPT_WAIT,
136 by Suren A. Chilingaryan
Verbose grabbing mode
193
    OPT_MULTIPACKET,
280 by Suren A. Chilingaryan
Integrate locking subsystem from Nicolas Zilio
194
    OPT_VERBOSE
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
195
} OPTIONS;
196
197
static struct option long_options[] = {
198
    {"device",			required_argument, 0, OPT_DEVICE },
199
    {"model",			required_argument, 0, OPT_MODEL },
200
    {"bar",			required_argument, 0, OPT_BAR },
201
    {"access",			required_argument, 0, OPT_ACCESS },
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
202
    {"endianess",		required_argument, 0, OPT_ENDIANESS },
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
203
    {"size",			required_argument, 0, OPT_SIZE },
16 by Suren A. Chilingaryan
Prototype of IPECamera image protocol
204
    {"output",			required_argument, 0, OPT_OUTPUT },
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
205
    {"timeout",			required_argument, 0, OPT_TIMEOUT },
68 by Suren A. Chilingaryan
Support iterations argument and fix interpretation of size argument for benchmarking
206
    {"iterations",		required_argument, 0, OPT_ITERATIONS },
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
207
    {"info",			optional_argument, 0, OPT_INFO },
315 by Suren A. Chilingaryan
Support properties of arbitrary type
208
    {"list",			optional_argument, 0, OPT_LIST },
15 by Suren A. Chilingaryan
Infrastructure for event API
209
    {"reset",			no_argument, 0, OPT_RESET },
45 by root
North West Logick DMA implementation
210
    {"benchmark",		optional_argument, 0, OPT_BENCHMARK },
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
211
    {"read",			optional_argument, 0, OPT_READ },
212
    {"write",			optional_argument, 0, OPT_WRITE },
15 by Suren A. Chilingaryan
Infrastructure for event API
213
    {"grab",			optional_argument, 0, OPT_GRAB },
117 by Suren A. Chilingaryan
new event architecture, first trial
214
    {"trigger",			optional_argument, 0, OPT_TRIGGER },
215
    {"data",			required_argument, 0, OPT_DATA_TYPE },
216
    {"event",			required_argument, 0, OPT_EVENT },
217
    {"run-time",		required_argument, 0, OPT_RUN_TIME },
218
    {"trigger-rate",		required_argument, 0, OPT_TRIGGER_RATE },
219
    {"trigger-time",		required_argument, 0, OPT_TRIGGER_TIME },
220
    {"format",			required_argument, 0, OPT_FORMAT },
221
    {"buffer",			optional_argument, 0, OPT_BUFFER },
135 by Suren A. Chilingaryan
Allow to configure the number of preprocessing threads
222
    {"threads",			optional_argument, 0, OPT_THREADS },
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
223
    {"start-dma",		required_argument, 0, OPT_START_DMA },
224
    {"stop-dma",		optional_argument, 0, OPT_STOP_DMA },
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
225
    {"list-dma-engines",	no_argument, 0, OPT_LIST_DMA },
226
    {"list-dma-buffers",	required_argument, 0, OPT_LIST_DMA_BUFFERS },
227
    {"read-dma-buffer",		required_argument, 0, OPT_READ_DMA_BUFFER },
194 by Suren A. Chilingaryan
DMA-independent IRQ functions
228
    {"enable-irq",		optional_argument, 0, OPT_ENABLE_IRQ },
229
    {"disable-irq",		optional_argument, 0, OPT_DISABLE_IRQ },
230
    {"acknowledge-irq",		optional_argument, 0, OPT_ACK_IRQ },
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
231
    {"wait-irq",		optional_argument, 0, OPT_WAIT_IRQ },
337 by Suren A. Chilingaryan
Driver versioning
232
    {"set-dma-mask",		required_argument, 0, OPT_SET_DMASK },
338 by Suren A. Chilingaryan
Support setting payload size
233
    {"set-mps",			required_argument, 0, OPT_SET_MPS },
192 by Suren A. Chilingaryan
Kernel memory allocation
234
    {"list-kernel-memory",	optional_argument, 0, OPT_LIST_KMEM },
100 by root
Support exporting data from kernel buffers
235
    {"read-kernel-memory",	required_argument, 0, OPT_READ_KMEM },
192 by Suren A. Chilingaryan
Kernel memory allocation
236
    {"alloc-kernel-memory",	required_argument, 0, OPT_ALLOC_KMEM },
81 by Suren A. Chilingaryan
Support forceful clean-up of kernel memory
237
    {"free-kernel-memory",	required_argument, 0, OPT_FREE_KMEM },
280 by Suren A. Chilingaryan
Integrate locking subsystem from Nicolas Zilio
238
    {"list-locks",		no_argument, 0, OPT_LIST_LOCKS },
239
    {"free-locks",		no_argument, 0, OPT_FREE_LOCKS },
240
    {"lock",			required_argument, 0, OPT_LOCK },
241
    {"unlock",			required_argument, 0, OPT_UNLOCK },
192 by Suren A. Chilingaryan
Kernel memory allocation
242
    {"type",			required_argument, 0, OPT_TYPE },
243
    {"block-size",		required_argument, 0, OPT_BLOCK_SIZE },
244
    {"alignment",		required_argument, 0, OPT_ALIGNMENT },
25 by Suren A. Chilingaryan
Support quiete mode to suppress warnings
245
    {"quiete",			no_argument, 0, OPT_QUIETE },
136 by Suren A. Chilingaryan
Verbose grabbing mode
246
    {"verbose",			optional_argument, 0, OPT_VERBOSE },
81 by Suren A. Chilingaryan
Support forceful clean-up of kernel memory
247
    {"force",			no_argument, 0, OPT_FORCE },
191 by Suren A. Chilingaryan
Do not verify BAR writes by default
248
    {"verify",			no_argument, 0, OPT_VERIFY },
109 by Suren A. Chilingaryan
Improvements of DMA engine
249
    {"multipacket",		no_argument, 0, OPT_MULTIPACKET },
250
    {"wait",			no_argument, 0, OPT_WAIT },
337 by Suren A. Chilingaryan
Driver versioning
251
    {"version",			no_argument, 0, OPT_VERSION },
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
252
    {"help",			no_argument, 0, OPT_HELP },
253
    { 0, 0, 0, 0 }
254
};
255
256
257
void Usage(int argc, char *argv[], const char *format, ...) {
258
    if (format) {
259
	va_list ap;
260
    
261
	va_start(ap, format);
262
	printf("Error %i: ", errno);
263
	vprintf(format, ap);
264
	printf("\n");
265
	va_end(ap);
266
    
267
        printf("\n");
268
    }
269
270
271
    printf(
272
"Usage:\n"
273
" %s <mode> [options] [hex data]\n"
274
"  Modes:\n"
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
275
"   -i [target]			- Device or Register (target) Info\n"
339 by Suren A. Chilingaryan
pcitool help formating
276
"   -l[l] [bank|/branch] 	- List (detailed) Data Banks & Registers\n"
318 by Suren A. Chilingaryan
Support reading/writting register views by id
277
"   -r <addr|dmaX|reg|prop>	- Read Data/Register/Property\n"
278
"   -w <addr|dmaX|reg|prop>	- Write Data/Register/Property\n"
101 by root
Remove short option for benchmark in cli
279
"   --benchmark <barX|dmaX>	- Performance Evaluation\n"
80 by Suren A. Chilingaryan
List kernel buffers
280
"   --reset			- Reset board\n"
337 by Suren A. Chilingaryan
Driver versioning
281
"   --version			- Version information\n"
80 by Suren A. Chilingaryan
List kernel buffers
282
"   --help			- Help message\n"
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
283
"\n"
318 by Suren A. Chilingaryan
Support reading/writting register views by id
284
"  Property/Register Modes:\n"
339 by Suren A. Chilingaryan
pcitool help formating
285
"   -r <reg>/view[:unit] 	- Read register view\n"
286
"   -w <reg>/view[:unit] 	- Write register view\n"
287
"   -r <reg>/unit		- Read register, detect view based on unit\n"
288
"   -w <reg>/unit		- Write register, detect view based on unt\n"
289
"   -r <prop>[:unit]		- Read property\n"
290
"   -w <prop>[:unit]		- Write property\n"
291
"   -r <prop|reg>@attr		- Read register/property attribute\n"
318 by Suren A. Chilingaryan
Support reading/writting register views by id
292
"\n"
117 by Suren A. Chilingaryan
new event architecture, first trial
293
"  Event Modes:\n"
294
"   --trigger [event]		- Trigger Events\n"
295
"   -g [event]			- Grab Events\n"
296
"\n"
194 by Suren A. Chilingaryan
DMA-independent IRQ functions
297
"  IRQ Modes:\n"
298
"   --enable-irq [type]		- Enable IRQs\n"
339 by Suren A. Chilingaryan
pcitool help formating
299
"   --disable-irq [type] 	- Disable IRQs\n"
194 by Suren A. Chilingaryan
DMA-independent IRQ functions
300
"   --acknowledge-irq <source>	- Clean IRQ queue\n"
301
"   --wait-irq <source>		- Wait for IRQ\n"
339 by Suren A. Chilingaryan
pcitool help formating
302
"\n"
59 by Suren A. Chilingaryan
Reorganization of NWL engine, step 1
303
"  DMA Modes:\n"
80 by Suren A. Chilingaryan
List kernel buffers
304
"   --start-dma <num>[r|w]	- Start specified DMA engine\n"
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
305
"   --stop-dma [num[r|w]]	- Stop specified engine or DMA subsystem\n"
306
"   --list-dma-engines		- List active DMA engines\n"
307
"   --list-dma-buffers <dma>	- List buffers for specified DMA engine\n"
308
"   --read-dma-buffer <dma:buf>	- Read the specified buffer\n"
80 by Suren A. Chilingaryan
List kernel buffers
309
"\n"
338 by Suren A. Chilingaryan
Support setting payload size
310
"  PCI Configuration:\n"
337 by Suren A. Chilingaryan
Driver versioning
311
"   --set-dma-mask [bits]	- Set DMA address width (DANGEROUS)\n"
338 by Suren A. Chilingaryan
Support setting payload size
312
"   --set-mps [bits]		- Set PCIe Payload Size (DANGEROUS)\n"
313
"\n"
314
"  Kernel Memory Modes:\n"
192 by Suren A. Chilingaryan
Kernel memory allocation
315
"   --list-kernel-memory [use] 	- List kernel buffers\n"
117 by Suren A. Chilingaryan
new event architecture, first trial
316
"   --read-kernel-memory <blk>	- Read the specified block of the kernel memory\n"
100 by root
Support exporting data from kernel buffers
317
"				  block is specified as: use:block_number\n"
192 by Suren A. Chilingaryan
Kernel memory allocation
318
"   --alloc-kernel-memory <use>	- Allocate kernel buffers (DANGEROUS)\n"
81 by Suren A. Chilingaryan
Support forceful clean-up of kernel memory
319
"   --free-kernel-memory <use>	- Cleans lost kernel space buffers (DANGEROUS)\n"
320
"	dma			- Remove all buffers allocated by DMA subsystem\n"
321
"	#number			- Remove all buffers with the specified use id\n"
59 by Suren A. Chilingaryan
Reorganization of NWL engine, step 1
322
"\n"
339 by Suren A. Chilingaryan
pcitool help formating
323
"   --list-locks 		- List all registered locks\n"
324
"   --free-locks 		- Destroy all locks (DANGEROUS)\n"
280 by Suren A. Chilingaryan
Integrate locking subsystem from Nicolas Zilio
325
"   --lock <lock name>		- Obtain persistent lock\n"
339 by Suren A. Chilingaryan
pcitool help formating
326
"   --unlock <lock name> 	- Release persistent lock\n"
280 by Suren A. Chilingaryan
Integrate locking subsystem from Nicolas Zilio
327
"\n"
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
328
"  Addressing:\n"
80 by Suren A. Chilingaryan
List kernel buffers
329
"   -d <device>			- FPGA device (/dev/fpga0)\n"
330
"   -m <model>			- Memory model (autodetected)\n"
331
"	pci			- Plain\n"
332
"	ipecamera		- IPE Camera\n"
333
"   -b <bank>			- PCI bar, Register bank, or DMA channel\n"
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
334
"\n"
335
"  Options:\n"
80 by Suren A. Chilingaryan
List kernel buffers
336
"   -s <size>			- Number of words (default: 1)\n"
196 by Suren A. Chilingaryan
Provide access to PCI configuration space in cli
337
"   -a [fifo|dma|config]<bits>	- Access type and bits per word (default: 32)\n"
80 by Suren A. Chilingaryan
List kernel buffers
338
"   -e <l|b>			- Endianess Little/Big (default: host)\n"
87 by Suren A. Chilingaryan
Support writting output to file
339
"   -o <file>			- Append output to file (default: stdout)\n"
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
340
"   -t <timeout|unlimited> 	- Timeout in microseconds\n"
191 by Suren A. Chilingaryan
Do not verify BAR writes by default
341
"   --check			- Verify write operations\n"
14 by Suren A. Chilingaryan
Support memset operation
342
"\n"
117 by Suren A. Chilingaryan
new event architecture, first trial
343
"  Event Options:\n"
344
"   --event <evt>		- Specifies event for trigger and grab modes\n"
345
"   --data <type>		- Data type to request for the events\n"
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
346
"   --run-time <us>		- Limit time to grab/trigger events\n"
347
"   -t <timeout|unlimited>	- Timeout to stop if no events triggered\n"
348
"   --trigger-rate <tps>		- Generate tps triggers per second\n"
349
"   --trigger-time <us>		- Specifies delay between triggers (us)\n"
117 by Suren A. Chilingaryan
new event architecture, first trial
350
"   -s <num|unlimited> 		- Number of events to grab and trigger\n"
351
"   --format [type]		- Specifies how event data should be stored\n"
352
"	raw			- Just write all events sequentially\n"
147 by Suren A. Chilingaryan
Store with additional header containing timestmap, sequential number, etc.
353
"	add_header		- Prefix events with 512 bit header:\n"
354
"				  event(64), data(64), nope(64), size(64)\n"
355
"				  seqnum(64), offset(64), timestamp(128)\n"
134 by Suren A. Chilingaryan
Handle properly more of trigger-and-grab options in pcitool
356
//"	ringfs			- Write to RingFS\n"
117 by Suren A. Chilingaryan
new event architecture, first trial
357
"   --buffer [size]		- Request data buffering, size in MB\n"
135 by Suren A. Chilingaryan
Allow to configure the number of preprocessing threads
358
"   --threads [num]		- Allow multithreaded processing\n"
117 by Suren A. Chilingaryan
new event architecture, first trial
359
"\n"
109 by Suren A. Chilingaryan
Improvements of DMA engine
360
"  DMA Options:\n"
361
"   --multipacket		- Read multiple packets\n"
362
"   --wait			- Wait until data arrives\n"
363
"\n"
194 by Suren A. Chilingaryan
DMA-independent IRQ functions
364
"  Kernel Options:\n"
365
"   --type <type>		- Type of kernel memory to allocate\n"
366
"   	consistent		- Consistent memory\n"
367
"   	s2c			- DMA S2C (write) memory\n"
368
"   	c2s			- DMA C2S (read) memory\n"
369
"   --page-size <size>		- Size of kernel buffer in bytes (default: page)\n"
370
"   -s <size>			- Number of buffers to allocate (default: 1)\n"
371
"   --allignment <alignment>	- Buffer alignment (default: page)\n"
372
"\n"
25 by Suren A. Chilingaryan
Support quiete mode to suppress warnings
373
"  Information:\n"
136 by Suren A. Chilingaryan
Verbose grabbing mode
374
"   --verbose [level]		- Announce details of ongoing operations\n"
80 by Suren A. Chilingaryan
List kernel buffers
375
"   -q				- Quiete mode (suppress warnings)\n"
25 by Suren A. Chilingaryan
Support quiete mode to suppress warnings
376
"\n"
14 by Suren A. Chilingaryan
Support memset operation
377
"  Data:\n"
378
"	Data can be specified as sequence of hexdecimal number or\n"
379
"	a single value prefixed with '*'. In this case it will be\n"
380
"	replicated the specified amount of times\n"
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
381
"\n\n",
382
argv[0]);
383
384
    exit(0);
385
}
386
138 by Suren A. Chilingaryan
Handle SIGINT signal in pcitool
387
static int StopFlag = 0;
388
389
static void signal_exit_handler(int signo) { 
390
    if (++StopFlag > 2)
391
	exit(-1);
392
}
393
247 by Suren A. Chilingaryan
New error reporting public interface
394
void LogError(void *arg, const char *file, int line, pcilib_log_priority_t prio, const char *format, va_list ap) {
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
395
    vprintf(format, ap);
247 by Suren A. Chilingaryan
New error reporting public interface
396
397
    if (prio == PCILIB_LOG_ERROR) {
398
	if (errno) printf("\nerrno: %i (%s)", errno, strerror(errno));
399
    }
400
262 by Suren A. Chilingaryan
Support gen3 DMA engine and provide work-arround for hardware mishandling last_descriptor_read register
401
    printf("\n");
247 by Suren A. Chilingaryan
New error reporting public interface
402
403
    if (prio == PCILIB_LOG_ERROR) {
404
	printf("Exiting at [%s:%u]\n\n", file, line);
405
	exit(-1);
406
    }
407
}
408
409
void ErrorInternal(void *arg, const char *file, int line, pcilib_log_priority_t prio, const char *format, ...) {
410
     va_list ap;
411
     va_start(ap, format);
412
     LogError(arg, file, line, prio, format, ap);
413
     va_end(ap);
414
}
415
416
#define Error(...) ErrorInternal(NULL, __FILE__, __LINE__, PCILIB_LOG_ERROR, __VA_ARGS__)
417
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
418
304 by Suren A. Chilingaryan
Sort registers before listing
419
int RegisterCompare(const void *aptr, const void *bptr, void *registers) {
420
    pcilib_register_description_t *a = &((pcilib_register_description_t*)registers)[*(const pcilib_register_t*)aptr];
421
    pcilib_register_description_t *b = &((pcilib_register_description_t*)registers)[*(const pcilib_register_t*)bptr];
422
423
    if (a->bank < b->bank) return -1;
424
    if (a->bank > b->bank) return 1;
425
426
    if (a->addr < b->addr) return -1;
427
    if (a->addr > b->addr) return 1;
428
429
    if ((a->type != PCILIB_REGISTER_BITS)&&(b->type == PCILIB_REGISTER_BITS)) return -1;
430
    if ((a->type == PCILIB_REGISTER_BITS)&&(b->type != PCILIB_REGISTER_BITS)) return 1;
431
432
    if (a->offset < b->offset) return -1;
433
    if (a->offset > b->offset) return 0;
434
435
    return 0;
436
}
437
315 by Suren A. Chilingaryan
Support properties of arbitrary type
438
void ListProperties(pcilib_t *handle, const char *branch, int details) {
439
    int i;
440
    pcilib_property_info_t *props;
441
442
    props = pcilib_get_property_list(handle, branch, 0);
443
    if (!props) Error("Error getting properties");
444
445
    if (props[0].path) {
446
        printf("Properties: \n");
447
448
        for (i = 0; props[i].path; i++) {
449
            const char *mode;
450
            const char *type;
451
452
            switch (props[i].type) {
453
                case PCILIB_TYPE_LONG:
454
                    type = "int    ";
455
                    break;
456
                case PCILIB_TYPE_DOUBLE:
457
                    type = "float  ";
458
                    break;
459
                case PCILIB_TYPE_STRING:
460
                    type = "string ";
461
                    break;
462
                case PCILIB_TYPE_INVALID:
463
                    type = NULL;
464
                    break;
465
                default:
466
                    type = "unknown";
467
            }
468
            
469
            switch (props[i].mode) {
470
                case PCILIB_ACCESS_RW:
471
                    mode = "RW";
472
                    break;
473
                case PCILIB_ACCESS_R:
474
                    mode = "R ";
475
                    break;
476
                case PCILIB_ACCESS_W:
477
                    mode = "W ";
478
                    break;
479
                default:
480
                    mode = "  ";
481
            }
482
483
            if (type)
484
                printf(" (%s %s) ", type, mode);
485
            else
486
                printf(" %12s", "");
487
488
            if (props[i].flags&PCILIB_LIST_FLAG_CHILDS)
489
                printf(" + ");
490
            else
491
                printf("   ");
492
493
	    if (details > 0) {
494
	        printf("%s", props[i].name);
495
	        if ((props[i].description)&&(props[i].description[0])) {
496
		    printf(": %s", props[i].description);
497
	        }
498
	    } else {
499
	        printf("%s", props[i].path);
500
	    }
501
	    printf("\n");
502
        }
503
504
        printf("\n");
505
506
        pcilib_free_property_info(handle, props);
507
    }
508
509
}
510
236 by Suren A. Chilingaryan
Big redign of model structures
511
void List(pcilib_t *handle, const pcilib_model_description_t *model_info, const char *bank, int details) {
304 by Suren A. Chilingaryan
Sort registers before listing
512
    int i, j, k;
236 by Suren A. Chilingaryan
Big redign of model structures
513
    const pcilib_register_bank_description_t *banks;
514
    const pcilib_register_description_t *registers;
515
    const pcilib_event_description_t *events;
516
    const pcilib_event_data_type_description_t *types;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
517
41 by root
A bit of DMA infrastructure
518
    const pcilib_board_info_t *board_info = pcilib_get_board_info(handle);
240 by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines
519
    const pcilib_dma_description_t *dma_info = pcilib_get_dma_description(handle);
315 by Suren A. Chilingaryan
Support properties of arbitrary type
520
236 by Suren A. Chilingaryan
Big redign of model structures
521
    for (i = 0; i < PCILIB_MAX_BARS; i++) {
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
522
	if (board_info->bar_length[i] > 0) {
523
	    printf(" BAR %d - ", i);
524
525
	    switch ( board_info->bar_flags[i]&IORESOURCE_TYPE_BITS) {
526
		case IORESOURCE_IO:  printf(" IO"); break;
527
		case IORESOURCE_MEM: printf("MEM"); break;
528
		case IORESOURCE_IRQ: printf("IRQ"); break;
529
		case IORESOURCE_DMA: printf("DMA"); break;
530
	    }
531
	    
532
	    if (board_info->bar_flags[i]&IORESOURCE_MEM_64) printf("64");
533
	    else printf("32");
534
	    
535
	    printf(", Start: 0x%08lx, Length: 0x%8lx, Flags: 0x%08lx\n", board_info->bar_start[i], board_info->bar_length[i], board_info->bar_flags[i] );
536
	}
537
    }
538
    printf("\n");
41 by root
A bit of DMA infrastructure
539
    
540
    if ((dma_info)&&(dma_info->engines)) {
541
	printf("DMA Engines: \n");
236 by Suren A. Chilingaryan
Big redign of model structures
542
	for (i = 0; dma_info->engines[i].addr_bits; i++) {
543
	    const pcilib_dma_engine_description_t *engine = &dma_info->engines[i];
41 by root
A bit of DMA infrastructure
544
	    printf(" DMA %2d ", engine->addr);
545
	    switch (engine->direction) {
546
		case PCILIB_DMA_FROM_DEVICE:
547
		    printf("C2S");
548
		break;
549
		case PCILIB_DMA_TO_DEVICE:
550
		    printf("S2C");
551
		break;
552
		case PCILIB_DMA_BIDIRECTIONAL:
553
		    printf("BI ");
554
		break;
555
	    }
556
	    printf(" - Type: ");
557
	    switch (engine->type) {
558
		case PCILIB_DMA_TYPE_BLOCK:
559
		    printf("Block");
560
		break;
561
		case PCILIB_DMA_TYPE_PACKET:
562
		    printf("Packet");
563
		break;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
564
		default:
565
		    printf("Unknown");
41 by root
A bit of DMA infrastructure
566
	    }
567
	    
43 by root
Enumerate DMA engines
568
	    printf(", Address Width: %02lu bits\n", engine->addr_bits);
41 by root
A bit of DMA infrastructure
569
	}
43 by root
Enumerate DMA engines
570
	printf("\n");
41 by root
A bit of DMA infrastructure
571
    }
7.1.2 by Suren A. Chilingaryan
Better handling of register banks
572
573
    if ((bank)&&(bank != (char*)-1)) banks = NULL;
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
574
    else banks = model_info->banks;
315 by Suren A. Chilingaryan
Support properties of arbitrary type
575
7.1.2 by Suren A. Chilingaryan
Better handling of register banks
576
    if (banks) {
577
	printf("Banks: \n");
578
	for (i = 0; banks[i].access; i++) {
579
	    printf(" 0x%02x %s", banks[i].addr, banks[i].name);
580
	    if ((banks[i].description)&&(banks[i].description[0])) {
581
		printf(": %s", banks[i].description);
582
	    }
583
	    printf("\n");
584
	}
585
	printf("\n");
586
    }
587
    
588
    if (bank == (char*)-1) registers = NULL;
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
589
    else registers = model_info->registers;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
590
    
591
    if (registers) {
304 by Suren A. Chilingaryan
Sort registers before listing
592
	pcilib_register_t regsort[handle->num_reg];
593
	
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
594
        pcilib_register_bank_addr_t bank_addr = 0;
7.1.2 by Suren A. Chilingaryan
Better handling of register banks
595
	if (bank) {
236 by Suren A. Chilingaryan
Big redign of model structures
596
	    pcilib_register_bank_t bank_id = pcilib_find_register_bank(handle, bank);
597
	    const pcilib_register_bank_description_t *b = model_info->banks + bank_id;
7.1.2 by Suren A. Chilingaryan
Better handling of register banks
598
599
	    bank_addr = b->addr;
600
	    if (b->description) printf("%s:\n", b->description);
601
	    else if (b->name) printf("Registers of bank %s:\n", b->name);
602
	    else printf("Registers of bank 0x%x:\n", b->addr);
603
	} else {
604
	    printf("Registers: \n");
605
	}
304 by Suren A. Chilingaryan
Sort registers before listing
606
607
	    // sorting
608
	for (i = 0, k = 0; registers[i].bits; i++) {
609
	    if ((bank)&&(registers[i].bank != bank_addr)) continue;
610
	    if ((registers[i].type == PCILIB_REGISTER_BITS)&&(!details)) continue;
611
	    regsort[k++] = i;
612
	}
613
614
	qsort_r(regsort, k, sizeof(pcilib_register_t), &RegisterCompare, (void*)registers);
615
	
616
	
617
	for (j = 0; j < k; j++) {
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
618
	    const char *mode;
304 by Suren A. Chilingaryan
Sort registers before listing
619
	    i = regsort[j];
620
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
621
	    if (registers[i].type == PCILIB_REGISTER_BITS) {
622
		if (!details) continue;
623
		
624
		if (registers[i].bits > 1) {
625
		    printf("    [%2u:%2u] - %s\n", registers[i].offset, registers[i].offset + registers[i].bits, registers[i].name);
626
		} else {
627
		    printf("    [   %2u] - %s\n", registers[i].offset, registers[i].name);
628
		}
629
		
630
		continue;
631
	    }
7.1.2 by Suren A. Chilingaryan
Better handling of register banks
632
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
633
	    if (registers[i].mode == PCILIB_REGISTER_RW) mode = "RW";
634
	    else if (registers[i].mode == PCILIB_REGISTER_R) mode = "R ";
635
	    else if (registers[i].mode == PCILIB_REGISTER_W) mode = " W";
636
	    else mode = "  ";
637
	    
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
638
	    printf(" 0x%02x (%2i %s) %s", registers[i].addr, registers[i].bits, mode, registers[i].name);
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
639
	    if ((details > 0)&&(registers[i].description)&&(registers[i].description[0])) {
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
640
		printf(": %s", registers[i].description);
641
	    }
642
	    printf("\n");
643
644
	}
645
	printf("\n");
646
    }
41 by root
A bit of DMA infrastructure
647
315 by Suren A. Chilingaryan
Support properties of arbitrary type
648
    ListProperties(handle, "/", details);
649
41 by root
A bit of DMA infrastructure
650
    if (bank == (char*)-1) events = NULL;
117 by Suren A. Chilingaryan
new event architecture, first trial
651
    else {
652
	events = model_info->events;
653
	types = model_info->data_types;
654
    }
41 by root
A bit of DMA infrastructure
655
656
    if (events) {
657
	printf("Events: \n");
658
	for (i = 0; events[i].name; i++) {
659
	    printf(" %s", events[i].name);
660
	    if ((events[i].description)&&(events[i].description[0])) {
661
		printf(": %s", events[i].description);
662
	    }
117 by Suren A. Chilingaryan
new event architecture, first trial
663
	    
664
	    if (types) {
665
		for (j = 0; types[j].name; j++) {
666
		    if (types[j].evid & events[i].evid) {
667
			printf("\n    %s", types[j].name);
668
			if ((types[j].description)&&(types[j].description[0])) {
669
			    printf(": %s", types[j].description);
670
			}
671
		    }
672
		}
673
	    }
41 by root
A bit of DMA infrastructure
674
	}
675
	printf("\n");
676
    }
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
677
}
678
319 by Suren A. Chilingaryan
Provide register listings in public API
679
void ViewInfo(pcilib_t *handle, pcilib_register_t reg, size_t id) {
680
    int err;
681
682
    int i;
683
    pcilib_value_t val = {0};
684
    pcilib_register_value_name_t *vnames;
685
686
    pcilib_view_t view;
687
    const pcilib_model_description_t *model_info = pcilib_get_model_description(handle);
688
    const pcilib_register_description_t *r;
689
    const pcilib_view_description_t *v;
690
691
    if (reg == PCILIB_REGISTER_INVALID) {
692
        r = NULL;
693
        view = id;
694
    } else {
695
        r = &model_info->registers[reg];
696
        view = pcilib_find_view_by_name(handle, r->views[id].view);
697
    }
698
699
    if (view == PCILIB_VIEW_INVALID) return;
700
    v = model_info->views[view];
701
702
    if (r) {
703
        printf("  View %s (", r->views[id].name);
704
    } else {
705
        printf("%s\n", v->name);
706
        printf("    Data type      : ");
707
    }
708
    switch (v->type) {
709
	case PCILIB_TYPE_STRING:
710
	    printf("char*");
711
	    break;
712
	case PCILIB_TYPE_DOUBLE:
713
	    printf("double");
714
	    break;
715
	case PCILIB_TYPE_LONG:
716
	    printf("long");
717
	    break;
718
	default:
719
	    printf("unknown");
720
    }
721
    if (r) printf(")");
722
    printf("\n");
723
321 by Suren A. Chilingaryan
Support computed (property-based) registers
724
    if (v->mode&PCILIB_ACCESS_R) {
725
        if (r) {
726
            err = pcilib_read_register_view_by_id(handle, reg, r->views[id].name, &val);
727
        } else {
728
            err = pcilib_get_property(handle, v->name, &val);
729
        }
730
        if (!err) err = pcilib_convert_value_type(handle, &val, PCILIB_TYPE_STRING);
319 by Suren A. Chilingaryan
Provide register listings in public API
731
    } else {
321 by Suren A. Chilingaryan
Support computed (property-based) registers
732
        err = PCILIB_ERROR_NOTPERMITED;
319 by Suren A. Chilingaryan
Provide register listings in public API
733
    }
734
321 by Suren A. Chilingaryan
Support computed (property-based) registers
735
    if (err) {
736
        if (err == PCILIB_ERROR_NOTPERMITED)
737
            printf("    Current value  : no read access\n");
738
        else
739
            printf("    Current value  : error %i\n", err);
740
    } else {
319 by Suren A. Chilingaryan
Provide register listings in public API
741
        printf("    Current value  : %s", val.sval);
742
        if (v->unit) printf(" (units: %s)", v->unit);
743
        printf("\n");
744
    }
745
746
    if (v->unit) {
747
	pcilib_unit_t unit = pcilib_find_unit_by_name(handle, v->unit);
748
749
	printf("    Supported units: %s", v->unit);
750
751
	if (unit != PCILIB_UNIT_INVALID) {
752
	    const pcilib_unit_description_t *u = &model_info->units[unit];
753
754
	    for (i = 0; u->transforms[i].unit; i++)
755
		printf(", %s", u->transforms[i].unit);
756
	}
757
	printf("\n");
758
    }
759
760
    printf("    Access         : ");
761
    if ((v->mode&PCILIB_REGISTER_RW) == 0) printf("-");
762
    if (v->mode&PCILIB_REGISTER_R) printf("R");
763
    if (v->mode&PCILIB_REGISTER_W) printf("W");
764
    printf("\n");
765
766
    if ((v->api == &pcilib_enum_view_static_api)||(v->api == &pcilib_enum_view_xml_api)) {
767
	vnames = ((pcilib_enum_view_description_t*)v)->names;
768
        printf("    Value aliases  :");
769
	for (i = 0; vnames[i].name; i++) {
770
	    if (i) printf(",");
330 by Suren A. Chilingaryan
Support for 64-bit registes
771
	    printf(" %s = %lu", vnames[i].name, vnames[i].value);
319 by Suren A. Chilingaryan
Provide register listings in public API
772
	    if (vnames[i].min != vnames[i].max) 
330 by Suren A. Chilingaryan
Support for 64-bit registes
773
	        printf(" (%lu - %lu)", vnames[i].min, vnames[i].max);
319 by Suren A. Chilingaryan
Provide register listings in public API
774
	}
775
	printf("\n");
776
    } else if (v->api == &pcilib_transform_view_api) {
777
	const pcilib_transform_view_description_t *tv = (const pcilib_transform_view_description_t*)v;
778
	if (tv->read_from_reg)
779
            printf("    Read function  : %s\n", tv->read_from_reg);
780
	if (tv->write_to_reg)
781
            printf("    Write function : %s\n", tv->write_to_reg);
782
    }
783
784
    if (v->description)
785
	printf("    Description    : %s\n", v->description);
786
}
787
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
788
void RegisterInfo(pcilib_t *handle, pcilib_register_t reg) {
789
    int err;
319 by Suren A. Chilingaryan
Provide register listings in public API
790
791
    int i;
311 by Suren A. Chilingaryan
Implement enum view
792
    pcilib_register_value_t regval;
319 by Suren A. Chilingaryan
Provide register listings in public API
793
    pcilib_register_info_t *info;
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
794
795
    const pcilib_model_description_t *model_info = pcilib_get_model_description(handle);
796
    const pcilib_register_description_t *r = &model_info->registers[reg];
797
    pcilib_register_bank_t bank = pcilib_find_register_bank_by_addr(handle, r->bank);
798
    const pcilib_register_bank_description_t *b = &model_info->banks[bank];
799
321 by Suren A. Chilingaryan
Support computed (property-based) registers
800
    if (r->mode&PCILIB_ACCESS_R) {
801
        err = pcilib_read_register_by_id(handle, reg, &regval);
802
    } else {
803
        err = PCILIB_ERROR_NOTPERMITED;
804
    }
319 by Suren A. Chilingaryan
Provide register listings in public API
805
806
    info = pcilib_get_register_info(handle, b->name, r->name, 0);
807
    if (!info) Error("Can't obtain register info for %s", r->name);
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
808
809
    printf("%s/%s\n", b->name, r->name);
810
    printf("  Current value: ");
321 by Suren A. Chilingaryan
Support computed (property-based) registers
811
    if (err) {
812
        if (err == PCILIB_ERROR_NOTPERMITED) printf("no read access");
813
        else printf("error %i", err);
814
    } else printf(b->format, regval);
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
815
816
    if (r->mode&PCILIB_REGISTER_W) {
817
	printf(" (default: ");
818
	printf(b->format, r->defvalue);
319 by Suren A. Chilingaryan
Provide register listings in public API
819
	if (info->range) {
820
	    printf(", range: ");
821
	    printf(b->format, info->range->min);
822
	    printf (" - ");
823
	    printf(b->format, info->range->max);
824
	}
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
825
	printf(")");
826
    }
827
    printf("\n");
828
829
    printf("  Address      : 0x%x [%u:%u]\n", r->addr, r->offset, r->offset + r->bits);
319 by Suren A. Chilingaryan
Provide register listings in public API
830
    if ((info->values)&&(info->values[0].name)) {
831
        printf("  Value aliases:");
832
        for (i = 0; info->values[i].name; i++)
833
            printf(" %s", info->values[i].name);
834
        printf("\n");
835
    }
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
836
    printf("  Access       : ");
837
    if ((r->mode&PCILIB_REGISTER_RW) == 0) printf("-");
838
    if (r->mode&PCILIB_REGISTER_R) printf("R");
839
    if (r->mode&PCILIB_REGISTER_W) printf("W");
840
    if (r->mode&PCILIB_REGISTER_W1C) printf("/reset");
841
    if (r->mode&PCILIB_REGISTER_W1I) printf("/invert");
842
    printf("\n");
843
844
845
    if (r->description)
846
	printf("  Description  : %s\n", r->description);
847
848
    if (r->views) {
849
	printf("\nSupported Views:\n");
850
	for (i = 0; r->views[i].name; i++) {
319 by Suren A. Chilingaryan
Provide register listings in public API
851
            ViewInfo(handle, reg, i);
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
852
	}
853
    }
854
319 by Suren A. Chilingaryan
Provide register listings in public API
855
    pcilib_free_register_info(handle, info);
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
856
}
857
337 by Suren A. Chilingaryan
Driver versioning
858
void Version(pcilib_t *handle, const pcilib_model_description_t *model_info) {
859
    const pcilib_driver_version_t *driver_version;
860
861
    driver_version = pcilib_get_driver_version(handle);
862
863
    printf("pcilib version: %u.%u.%u\n",
864
	PCILIB_VERSION_GET_MAJOR(PCILIB_VERSION),
865
	PCILIB_VERSION_GET_MINOR(PCILIB_VERSION),
866
	PCILIB_VERSION_GET_MICRO(PCILIB_VERSION)
867
    );
868
869
    printf("driver version: %lu.%lu.%lu, interface: 0x%lx, registered ioctls: %lu\n",
870
	PCILIB_VERSION_GET_MAJOR(driver_version->version),
871
	PCILIB_VERSION_GET_MINOR(driver_version->version),
872
	PCILIB_VERSION_GET_MICRO(driver_version->version),
873
	driver_version->interface,
874
	driver_version->ioctls
875
    );
876
877
    if (model_info) {
878
	pcilib_version_t version = model_info->interface_version;
879
	printf("Model: %s", handle->model);
880
	if (version) {
881
	    printf(", version: %u.%u.%u\n",
882
		PCILIB_VERSION_GET_MAJOR(version),
883
		PCILIB_VERSION_GET_MINOR(version),
884
		PCILIB_VERSION_GET_MICRO(version)
885
	    );
886
	} else {
887
	    printf(" (embedded)\n");
888
	}
889
    }
890
891
    if (model_info->dma) {
892
	pcilib_version_t version = model_info->dma->api->version;
893
	printf("DMA Engine: %s, version: %u.%u.%u\n", model_info->dma->name,
894
	    PCILIB_VERSION_GET_MAJOR(version),
895
	    PCILIB_VERSION_GET_MINOR(version),
896
	    PCILIB_VERSION_GET_MICRO(version)
897
	);
898
    }
348 by Suren A. Chilingaryan
Add build information
899
900
    BuildInfo();
337 by Suren A. Chilingaryan
Driver versioning
901
}
902
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
903
void Info(pcilib_t *handle, const pcilib_model_description_t *model_info, const char *target) {
242 by Suren A. Chilingaryan
Initial support for event engines
904
    int i, j;
905
    DIR *dir;
906
    void *plugin;
907
    const char *path;
908
    struct dirent *entry;
909
    const pcilib_model_description_t *info = NULL;
41 by root
A bit of DMA infrastructure
910
    const pcilib_board_info_t *board_info = pcilib_get_board_info(handle);
267 by Suren A. Chilingaryan
Provide PCIe link information in pcilib
911
    const pcilib_pcie_link_info_t *link_info = pcilib_get_pcie_link_info(handle);
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
912
337 by Suren A. Chilingaryan
Driver versioning
913
    int have_state;
914
    pcilib_device_state_t state;
915
242 by Suren A. Chilingaryan
Initial support for event engines
916
    path = getenv("PCILIB_PLUGIN_DIR");
917
    if (!path) path = PCILIB_PLUGIN_DIR;
918
337 by Suren A. Chilingaryan
Driver versioning
919
    have_state = !pcilib_get_device_state(handle, &state);
920
267 by Suren A. Chilingaryan
Provide PCIe link information in pcilib
921
    if (board_info)
922
	printf("Vendor: %x, Device: %x, Bus: %x, Slot: %x, Function: %x, Model: %s\n", board_info->vendor_id, board_info->device_id, board_info->bus, board_info->slot, board_info->func, handle->model);
923
924
    if (link_info) {
337 by Suren A. Chilingaryan
Driver versioning
925
	printf(" PCIe x%u (gen%u), DMA Payload: %u (of %u)", link_info->link_width, link_info->link_speed, 1<<link_info->payload, 1<<link_info->max_payload);
926
	if (have_state) {
927
	    int bits = 0;
928
	    unsigned long mask;
929
930
	    for (mask = state.dma_mask; mask&1; mask>>=1) bits++;
931
932
	    printf(", DMA Mask: ");
933
934
	    if (mask) printf("0x%lx", state.dma_mask);
935
	    else printf("%u bits", bits);
936
937
	    printf(", IOMMU: %s", state.iommu?"on":"off");
938
	}
939
	printf("\n");
267 by Suren A. Chilingaryan
Provide PCIe link information in pcilib
940
    }
941
942
    if (board_info)
943
	printf(" Interrupt - Pin: %i, Line: %i\n", board_info->interrupt_pin, board_info->interrupt_line);
242 by Suren A. Chilingaryan
Initial support for event engines
944
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
945
    printf("\n");
946
947
    if (target) {
319 by Suren A. Chilingaryan
Provide register listings in public API
948
	if (*target == '/') {
949
	    pcilib_view_t view;
950
	    view = pcilib_find_view_by_name(handle, target);
951
	    if (view != PCILIB_VIEW_INVALID)
952
	        return ViewInfo(handle, PCILIB_REGISTER_INVALID, view);
953
954
	    Error(" No property %s is found", target);
955
	} else {
956
	    pcilib_register_t reg;
957
	
958
	    reg = pcilib_find_register(handle, NULL, target);
959
	    if (reg != PCILIB_REGISTER_INVALID) 
960
	        return RegisterInfo(handle, reg);
961
962
	    Error(" No register %s is found", target);
963
	}
964
	
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
965
    }
966
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
967
    List(handle, model_info, (char*)-1, 0);
242 by Suren A. Chilingaryan
Initial support for event engines
968
969
    printf("Available models:\n");
970
971
    dir = opendir(path);
972
    if (dir) {
973
	while ((entry = readdir(dir))) {
974
	    const char *suffix = strstr(entry->d_name, ".so");
975
	    if ((!suffix)||(strlen(suffix) != 3)) continue;
976
977
	    plugin = pcilib_plugin_load(entry->d_name);
978
	    if (plugin) {
979
		info = pcilib_get_plugin_model(handle, plugin, 0, 0, NULL);
980
		if (info) {
245 by Suren A. Chilingaryan
Better formatting of model output
981
		    printf(" %s\n", entry->d_name);
253 by Suren A. Chilingaryan
Include version information in all API descriptions
982
		    for (j = 0; info[j].name; j++) {
983
			pcilib_version_t version = info[j].api->version;
984
			printf("   %-12s %u.%u.%u - %s\n", info[j].name, 
985
				PCILIB_VERSION_GET_MAJOR(version), 
986
				PCILIB_VERSION_GET_MINOR(version),
987
				PCILIB_VERSION_GET_MICRO(version),
988
				info[j].description?info[j].description:"");
989
		    }
242 by Suren A. Chilingaryan
Initial support for event engines
990
		}
991
		pcilib_plugin_close(plugin);
992
	    } else {
993
		const char *msg = dlerror();
994
		if (msg) 
995
		    printf(" %s: %s\n", entry->d_name, msg);
996
	    }
997
	}
998
	closedir(dir);
999
    }
1000
245 by Suren A. Chilingaryan
Better formatting of model output
1001
//    printf(" XML\n");
1002
1003
    printf(" Internal Models\n");
242 by Suren A. Chilingaryan
Initial support for event engines
1004
    for (i = 0; pcilib_dma[i].api; i++)
245 by Suren A. Chilingaryan
Better formatting of model output
1005
	printf("   %-12s - %s\n", pcilib_dma[i].name, pcilib_dma[i].description?pcilib_dma[i].description:"");
1006
    printf("   %-12s - Plain PCI-access model\n\n", "pci");
242 by Suren A. Chilingaryan
Initial support for event engines
1007
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1008
}
1009
1010
71 by Suren A. Chilingaryan
First iteration of work to preserve DMA state between executions
1011
#define BENCH_MAX_DMA_SIZE 4 * 1024 * 1024
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1012
#define BENCH_MAX_FIFO_SIZE 1024 * 1024
1013
68 by Suren A. Chilingaryan
Support iterations argument and fix interpretation of size argument for benchmarking
1014
int Benchmark(pcilib_t *handle, ACCESS_MODE mode, pcilib_dma_engine_addr_t dma, pcilib_bar_t bar, uintptr_t addr, size_t n, access_t access, size_t iterations) {
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1015
    int err;
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1016
    int i, j, errors;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1017
    void *data, *buf, *check;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
1018
    void *fifo = NULL;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1019
    struct timeval start, end;
1020
    unsigned long time;
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1021
    size_t size, min_size, max_size;
45 by root
North West Logick DMA implementation
1022
    double mbs_in, mbs_out, mbs;
55 by Suren A. Chilingaryan
IRQ support in NWL DMA engine
1023
    size_t irqs;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1024
    
41 by root
A bit of DMA infrastructure
1025
    const pcilib_board_info_t *board_info = pcilib_get_board_info(handle);
196 by Suren A. Chilingaryan
Provide access to PCI configuration space in cli
1026
    
1027
    if (mode == ACCESS_CONFIG)
1028
	Error("No benchmarking of configuration space acess is allowed");
45 by root
North West Logick DMA implementation
1029
1030
    if (mode == ACCESS_DMA) {
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1031
	if (n) {
1032
	    min_size = n * access;
1033
	    max_size = n * access;
1034
	} else {
1035
	    min_size = 1024;
1036
	    max_size = BENCH_MAX_DMA_SIZE;
1037
	}
1038
	
68 by Suren A. Chilingaryan
Support iterations argument and fix interpretation of size argument for benchmarking
1039
        for (size = min_size; size <= max_size; size *= 4) {
109 by Suren A. Chilingaryan
Improvements of DMA engine
1040
	    mbs_in = pcilib_benchmark_dma(handle, dma, addr, size, iterations, PCILIB_DMA_FROM_DEVICE);
1041
	    mbs_out = pcilib_benchmark_dma(handle, dma, addr, size, iterations, PCILIB_DMA_TO_DEVICE);
68 by Suren A. Chilingaryan
Support iterations argument and fix interpretation of size argument for benchmarking
1042
	    mbs = pcilib_benchmark_dma(handle, dma, addr, size, iterations, PCILIB_DMA_BIDIRECTIONAL);
55 by Suren A. Chilingaryan
IRQ support in NWL DMA engine
1043
	    err = pcilib_wait_irq(handle, 0, 0, &irqs);
1044
	    if (err) irqs = 0;
1045
	    
324 by Suren A. Chilingaryan
Documentation update
1046
	    printf("%8zu KiB - ", size / 1024);
45 by root
North West Logick DMA implementation
1047
	    
1048
	    printf("RW: ");
1049
	    if (mbs < 0) printf("failed ...   ");
324 by Suren A. Chilingaryan
Documentation update
1050
	    else printf("%8.2lf MiB/s", mbs);
45 by root
North West Logick DMA implementation
1051
1052
	    printf(", R: ");
1053
	    if (mbs_in < 0) printf("failed ...   ");
324 by Suren A. Chilingaryan
Documentation update
1054
	    else printf("%8.2lf MiB/s", mbs_in);
45 by root
North West Logick DMA implementation
1055
1056
	    printf(", W: ");
1057
	    if (mbs_out < 0) printf("failed ...   ");
324 by Suren A. Chilingaryan
Documentation update
1058
	    else printf("%8.2lf MiB/s", mbs_out);
55 by Suren A. Chilingaryan
IRQ support in NWL DMA engine
1059
	    
1060
	    if (irqs) {
1061
	        printf(", IRQs: %lu", irqs);
1062
	    }
45 by root
North West Logick DMA implementation
1063
1064
	    printf("\n");
1065
	}
1066
	
1067
	return 0;
1068
    }
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1069
1070
    if (bar == PCILIB_BAR_INVALID) {
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1071
	unsigned long maxlength = 0;
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1072
	
1073
236 by Suren A. Chilingaryan
Big redign of model structures
1074
	for (i = 0; i < PCILIB_MAX_REGISTER_BANKS; i++) {
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1075
	    if ((addr >= board_info->bar_start[i])&&((board_info->bar_start[i] + board_info->bar_length[i]) >= (addr + access))) {
1076
		bar = i;
1077
		break;
1078
	    }
1079
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1080
	    if (board_info->bar_length[i] > maxlength) {
1081
		maxlength = board_info->bar_length[i];
1082
		bar = i;
1083
	    }
1084
	}
1085
	
1086
	if (bar < 0) Error("Data banks are not available");
1087
    }
1088
    
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1089
    if (n) {
1090
	if ((mode == ACCESS_BAR)&&(n * access > board_info->bar_length[bar])) Error("The specified size (%i) exceeds the size of bar (%i)", n * access, board_info->bar_length[bar]);
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1091
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1092
	min_size = n * access;
1093
	max_size = n * access;
1094
    } else {
1095
	min_size = access;
1096
	if (mode == ACCESS_BAR) max_size = board_info->bar_length[bar];
1097
	else max_size = BENCH_MAX_FIFO_SIZE;
1098
    }
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1099
    
1100
    err = posix_memalign( (void**)&buf, 256, max_size );
1101
    if (!err) err = posix_memalign( (void**)&check, 256, max_size );
1102
    if ((err)||(!buf)||(!check)) Error("Allocation of %i bytes of memory have failed", max_size);
1103
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1104
    if (mode == ACCESS_FIFO) {
324 by Suren A. Chilingaryan
Documentation update
1105
	fifo = pcilib_resolve_bar_address(handle, bar, addr);
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1106
	if (!fifo) Error("Can't resolve address (%lx) in bar (%u)", addr, bar);
324 by Suren A. Chilingaryan
Documentation update
1107
    } else {
1108
	data = pcilib_resolve_bar_address(handle, bar, 0);
1109
	if (!data) Error("Can't resolve start of bar (%u)", bar);
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1110
    }
1111
1112
    if (mode == ACCESS_FIFO)
1113
	printf("Transfer time (Bank: %i, Fifo: %lx):\n", bar, addr);
1114
    else
1115
	printf("Transfer time (Bank: %i):\n", bar);
1116
	
1117
    for (size = min_size ; size < max_size; size *= 8) {
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1118
	gettimeofday(&start,NULL);
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1119
	if (mode == ACCESS_BAR) {
1120
	    for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
345 by Suren A. Chilingaryan
64-bit access to BAR memory
1121
		pcilib_memcpy(buf, data, access, size / access);
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1122
	    }
1123
	} else {
1124
	    for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
1125
		for (j = 0; j < (size/access); j++) {
345 by Suren A. Chilingaryan
64-bit access to BAR memory
1126
		    pcilib_memcpy(buf + j * access, fifo, access, 1);
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1127
		}
1128
	    }
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1129
	}
1130
	gettimeofday(&end,NULL);
1131
1132
	time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec);
324 by Suren A. Chilingaryan
Documentation update
1133
	printf("%8zu bytes - read: %8.2lf MiB/s", size, 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024. * 1024.));
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1134
	
1135
	fflush(0);
1136
1137
	gettimeofday(&start,NULL);
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1138
	if (mode == ACCESS_BAR) {
1139
	    for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
345 by Suren A. Chilingaryan
64-bit access to BAR memory
1140
		pcilib_memcpy(data, buf, access, size / access);
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1141
	    }
1142
	} else {
1143
	    for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
1144
		for (j = 0; j < (size/access); j++) {
345 by Suren A. Chilingaryan
64-bit access to BAR memory
1145
		    pcilib_memcpy(fifo, buf + j * access, access, 1);
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1146
		}
1147
	    }
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1148
	}
1149
	gettimeofday(&end,NULL);
1150
1151
	time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec);
324 by Suren A. Chilingaryan
Documentation update
1152
	printf(", write: %8.2lf MiB/s\n", 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024. * 1024.));
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1153
    }
1154
    
1155
    printf("\n\nOpen-Transfer-Close time: \n");
1156
    
1157
    for (size = 4 ; size < max_size; size *= 8) {
1158
	gettimeofday(&start,NULL);
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1159
	if (mode == ACCESS_BAR) {
1160
	    for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
345 by Suren A. Chilingaryan
64-bit access to BAR memory
1161
		pcilib_read(handle, bar, 0, access, size / access, buf);
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1162
	    }
1163
	} else {
1164
	    for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
1165
		pcilib_read_fifo(handle, bar, addr, access, size / access, buf);
1166
	    }
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1167
	}
1168
	gettimeofday(&end,NULL);
1169
1170
	time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec);
324 by Suren A. Chilingaryan
Documentation update
1171
	printf("%8zu bytes - read: %8.2lf MiB/s", size, 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024. * 1024.));
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1172
	
1173
	fflush(0);
1174
1175
	gettimeofday(&start,NULL);
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1176
	if (mode == ACCESS_BAR) {
1177
	    for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
345 by Suren A. Chilingaryan
64-bit access to BAR memory
1178
		pcilib_write(handle, bar, 0, access, size / access, buf);
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1179
	    }
1180
	} else {
1181
	    for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
1182
		pcilib_write_fifo(handle, bar, addr, access, size / access, buf);
1183
	    }
1184
	}
1185
	
1186
	gettimeofday(&end,NULL);
1187
1188
	time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec);
324 by Suren A. Chilingaryan
Documentation update
1189
	printf(", write: %8.2lf MiB/s", 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024. * 1024.));
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1190
1191
	if (mode == ACCESS_BAR) {
1192
	    gettimeofday(&start,NULL);
1193
	    for (i = 0, errors = 0; i < BENCHMARK_ITERATIONS; i++) {
345 by Suren A. Chilingaryan
64-bit access to BAR memory
1194
		pcilib_write(handle, bar, 0, access, size / access, buf);
1195
		pcilib_read(handle, bar, 0, access, size / access, check);
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1196
		if (memcmp(buf, check, size)) ++errors;
1197
	    }
1198
	    gettimeofday(&end,NULL);
1199
1200
	    time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec);
324 by Suren A. Chilingaryan
Documentation update
1201
	    printf(", write-verify: %8.2lf MiB/s", 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024. * 1024.));
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1202
	    if (errors) printf(", errors: %u of %u", errors, BENCHMARK_ITERATIONS);
1203
	}
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1204
	printf("\n");
1205
    }
1206
    
1207
    printf("\n\n");
1208
1209
    free(check);
1210
    free(buf);
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
1211
    
1212
    return 0;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1213
}
1214
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
1215
#define pci2host16(endianess, value) endianess?
1216
109 by Suren A. Chilingaryan
Improvements of DMA engine
1217
/*
1218
typedef struct {
1219
    size_t size;
1220
    void *data;
1221
    size_t pos;
1222
1223
    int multi_mode;
1224
} DMACallbackContext;
1225
1226
static int DMACallback(void *arg, pcilib_dma_flags_t flags, size_t bufsize, void *buf) {
1227
    DMACallbackContext *ctx = (DMACallbackContext*)arg;
1228
    
1229
    if ((ctx->pos + bufsize > ctx->size)||(!ctx->data)) {
1230
	ctx->size *= 2;
1231
	ctx->data = realloc(ctx->data, ctx->size);
1232
	if (!ctx->data) {
1233
	    Error("Allocation of %i bytes of memory have failed", ctx->size);
1234
	    return 0;
1235
	}
1236
    }
1237
    
1238
    memcpy(ctx->data + ctx->pos, buf, bufsize);
1239
    ctx->pos += bufsize;
1240
1241
    if (flags & PCILIB_DMA_FLAG_EOP) return 0;
1242
    return 1;
1243
}
1244
*/
1245
1246
1247
int ReadData(pcilib_t *handle, ACCESS_MODE mode, FLAGS flags, pcilib_dma_engine_addr_t dma, pcilib_bar_t bar, uintptr_t addr, size_t n, access_t access, int endianess, size_t timeout, FILE *o) {
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1248
    void *buf;
1249
    int i, err;
109 by Suren A. Chilingaryan
Improvements of DMA engine
1250
    size_t ret, bytes;
112 by Suren A. Chilingaryan
Fix allocation of big memory buffers for DMA readout in pcitool
1251
    size_t size = n * abs(access);
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1252
    int block_width, blocks_per_line;
1253
    int numbers_per_block, numbers_per_line; 
49 by Suren A. Chilingaryan
A bit of renaming
1254
    pcilib_dma_engine_t dmaid;
109 by Suren A. Chilingaryan
Improvements of DMA engine
1255
    pcilib_dma_flags_t dma_flags = 0;
196 by Suren A. Chilingaryan
Provide access to PCI configuration space in cli
1256
1257
    int fd;
1258
    char stmp[256];
1259
    struct stat st;
1260
    const pcilib_board_info_t *board_info;
1261
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1262
    numbers_per_block = BLOCK_SIZE / access;
1263
1264
    block_width = numbers_per_block * ((access * 2) +  SEPARATOR_WIDTH);
1265
    blocks_per_line = (LINE_WIDTH - 10) / (block_width +  BLOCK_SEPARATOR_WIDTH);
1266
    if ((blocks_per_line > 1)&&(blocks_per_line % 2)) --blocks_per_line;
1267
    numbers_per_line = blocks_per_line * numbers_per_block;
1268
109 by Suren A. Chilingaryan
Improvements of DMA engine
1269
    if (size) {
1270
	buf = malloc(size);
112 by Suren A. Chilingaryan
Fix allocation of big memory buffers for DMA readout in pcitool
1271
        if (!buf) Error("Allocation of %zu bytes of memory has failed", size);
109 by Suren A. Chilingaryan
Improvements of DMA engine
1272
    } else {
1273
	buf = NULL;
1274
    }
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1275
    
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1276
    switch (mode) {
1277
      case ACCESS_DMA:
109 by Suren A. Chilingaryan
Improvements of DMA engine
1278
        if (timeout == (size_t)-1) timeout = PCILIB_DMA_TIMEOUT;
1279
    
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1280
	dmaid = pcilib_find_dma_by_addr(handle, PCILIB_DMA_FROM_DEVICE, dma);
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
1281
	if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("Invalid DMA engine (%lu) is specified", dma);
109 by Suren A. Chilingaryan
Improvements of DMA engine
1282
	
1283
	if (flags&FLAG_MULTIPACKET) dma_flags |= PCILIB_DMA_FLAG_MULTIPACKET;
1284
	if (flags&FLAG_WAIT) dma_flags |= PCILIB_DMA_FLAG_WAIT;
1285
	
1286
	if (size) {
1287
	    err = pcilib_read_dma_custom(handle, dmaid, addr, size, dma_flags, timeout, buf, &bytes);
1288
	    if (err) Error("Error (%i) is reported by DMA engine", err);
1289
	} else {
1290
	    dma_flags |= PCILIB_DMA_FLAG_IGNORE_ERRORS;
1291
	    
1292
	    size = 2048; bytes = 0;
1293
	    do {
352.1.1 by Suren A. Chilingaryan
Don't increase buffer size if only read few pages and there are still space
1294
		if ((size - bytes) < 4096) {
1295
		    size *= 2;
1296
		    buf = realloc(buf, size);
1297
		    if (!buf) Error("Allocation of %zu bytes of memory has failed", size);
1298
		}
109 by Suren A. Chilingaryan
Improvements of DMA engine
1299
	        err = pcilib_read_dma_custom(handle, dmaid, addr, size - bytes, dma_flags, timeout, buf + bytes, &ret);
1300
		bytes += ret;
1301
		
1302
		if ((!err)&&(flags&FLAG_MULTIPACKET)) {
1303
		    err = PCILIB_ERROR_TOOBIG;
1304
		    if ((flags&FLAG_WAIT)==0) timeout = 0;
1305
		}
1306
	    } while (err == PCILIB_ERROR_TOOBIG);
1307
	}
189 by Suren A. Chilingaryan
Report errors during DMA read in cli
1308
1309
	if ((err)&&(err != PCILIB_ERROR_TIMEOUT)) {
1310
	    Error("Error (%i) during DMA read", err);
1311
	}
134 by Suren A. Chilingaryan
Handle properly more of trigger-and-grab options in pcitool
1312
	if (bytes <= 0) {
1313
	    pcilib_warning("No data is returned by DMA engine");
248 by Suren A. Chilingaryan
Set error in exit status if no data returned by DMA engine
1314
	    return -1;
134 by Suren A. Chilingaryan
Handle properly more of trigger-and-grab options in pcitool
1315
	}
109 by Suren A. Chilingaryan
Improvements of DMA engine
1316
	size = bytes;
1317
	n = bytes / abs(access);
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1318
	addr = 0;
1319
      break;
1320
      case ACCESS_FIFO:
1321
	pcilib_read_fifo(handle, bar, addr, access, n, buf);
1322
	addr = 0;
1323
      break;
196 by Suren A. Chilingaryan
Provide access to PCI configuration space in cli
1324
      case ACCESS_CONFIG:
1325
	board_info = pcilib_get_board_info(handle);
1326
	sprintf(stmp, "/sys/bus/pci/devices/0000:%02x:%02x.%1x/config", board_info->bus, board_info->slot, board_info->func);
1327
	fd = open(stmp, O_RDONLY);
1328
1329
	if ((!fd)||(fstat(fd, &st))) Error("Can't open %s", stmp);
1330
	
1331
        if (st.st_size < addr) 
1332
    	    Error("Access beyond the end of PCI configuration space");
1333
    	
1334
	if (st.st_size < (addr + size)) {
1335
	    n = (st.st_size - addr) / abs(access);
1336
	    size = n * abs(access);
1337
	    if (!n) Error("Access beyond the end of PCI configuration space");
1338
	}
1339
	
1340
	lseek(fd, addr, SEEK_SET);
1341
	ret = read(fd, buf, size);
1342
	if (ret == (size_t)-1) Error("Error reading %s", stmp);
1343
	
1344
	if (ret < size) {
1345
	    size = ret;
1346
	    n = ret / abs(access);
1347
	}
1348
	
1349
	close(fd);
1350
      break;
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1351
      default:
345 by Suren A. Chilingaryan
64-bit access to BAR memory
1352
	pcilib_read(handle, bar, addr, access, size / access, buf);
44 by root
DMA engine initialization and basic intrastructure for DMA read/write
1353
    }
87 by Suren A. Chilingaryan
Support writting output to file
1354
    
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
1355
    if (endianess) pcilib_swap(buf, buf, abs(access), n);
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1356
87 by Suren A. Chilingaryan
Support writting output to file
1357
    if (o) {
1358
	printf("Writting output (%zu bytes) to file (append to the end)...\n", n * abs(access));
1359
	fwrite(buf, abs(access), n, o);
1360
    } else {
1361
	for (i = 0; i < n; i++) {
1362
	    if (i) {
1363
		if (i%numbers_per_line == 0) printf("\n");
1364
		else {
1365
		    printf("%*s", SEPARATOR_WIDTH, "");
1366
		    if (i%numbers_per_block == 0) printf("%*s", BLOCK_SEPARATOR_WIDTH, "");
1367
		}
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1368
	    }
1369
	    
87 by Suren A. Chilingaryan
Support writting output to file
1370
	    if (i%numbers_per_line == 0) printf("%8lx:  ", addr + i * abs(access));
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1371
87 by Suren A. Chilingaryan
Support writting output to file
1372
	    switch (access) {
1373
		case 1: printf("%0*hhx", access * 2, ((uint8_t*)buf)[i]); break;
1374
		case 2: printf("%0*hx", access * 2, ((uint16_t*)buf)[i]); break;
1375
		case 4: printf("%0*x", access * 2, ((uint32_t*)buf)[i]); break;
1376
		case 8: printf("%0*lx", access * 2, ((uint64_t*)buf)[i]); break;
1377
	    }
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1378
	}
87 by Suren A. Chilingaryan
Support writting output to file
1379
	printf("\n\n");
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1380
    }
1381
1382
    
1383
    free(buf);
109 by Suren A. Chilingaryan
Improvements of DMA engine
1384
    return 0;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1385
}
1386
44 by root
DMA engine initialization and basic intrastructure for DMA read/write
1387
1388
1389
318 by Suren A. Chilingaryan
Support reading/writting register views by id
1390
int ReadRegister(pcilib_t *handle, const pcilib_model_description_t *model_info, const char *bank, const char *reg, const char *view, const char *unit, const char *attr) {
39 by root
Move to new FPGA design
1391
    int i;
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
1392
    int err;
39 by root
Move to new FPGA design
1393
    const char *format;
1394
1395
    pcilib_register_bank_t bank_id;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
1396
    pcilib_register_bank_addr_t bank_addr = 0;
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
1397
1398
    pcilib_register_value_t value;
313 by Suren A. Chilingaryan
Support reading of register views
1399
1400
	// Adding DMA registers
1401
    pcilib_get_dma_description(handle);
1402
318 by Suren A. Chilingaryan
Support reading/writting register views by id
1403
    if (reg||view||attr) {
1404
        pcilib_value_t val = {0};
1405
        if (attr) {
1406
            if (reg) err = pcilib_get_register_attr(handle, bank, reg, attr, &val);
1407
            else if (view) err = pcilib_get_property_attr(handle, view, attr, &val);
1408
            else if (bank) err = pcilib_get_register_bank_attr(handle, bank, attr, &val);
1409
            else err = PCILIB_ERROR_INVALID_ARGUMENT;
1410
1411
            if (err) {
1412
                if (err == PCILIB_ERROR_NOTFOUND)
1413
                    Error("Attribute %s is not found", attr);
1414
                else
1415
                    Error("Error (%i) reading attribute %s", err, attr);
1416
            }
1417
1418
            err = pcilib_convert_value_type(handle, &val, PCILIB_TYPE_STRING);
1419
            if (err) Error("Error converting attribute %s to string", attr);
1420
1421
            printf("%s = %s", attr, val.sval);
1422
            if ((val.unit)&&(strcasecmp(val.unit, "name")))
1423
                printf(" %s", val.unit);
1424
            printf(" (for %s)\n", (reg?reg:(view?view:bank)));
1425
        } else if (view) {
315 by Suren A. Chilingaryan
Support properties of arbitrary type
1426
            if (reg) {
1427
                err = pcilib_read_register_view(handle, bank, reg, view, &val);
1428
                if (err) Error("Error reading view %s of register %s", view, reg);
1429
            } else {
1430
                err = pcilib_get_property(handle, view, &val);
1431
                if (err) Error("Error reading property %s", view);
1432
            }
314 by Suren A. Chilingaryan
Support writting register views
1433
315 by Suren A. Chilingaryan
Support properties of arbitrary type
1434
            if (unit) {
1435
                err = pcilib_convert_value_unit(handle, &val, unit);
1436
                if (err) {
1437
                    if (reg) Error("Error converting view %s of register %s to unit %s", view, reg, unit);
1438
                    else Error("Error converting property %s to unit %s", view, unit);
1439
                }
1440
            }
1441
            
314 by Suren A. Chilingaryan
Support writting register views
1442
            err = pcilib_convert_value_type(handle, &val, PCILIB_TYPE_STRING);
315 by Suren A. Chilingaryan
Support properties of arbitrary type
1443
            if (err) {
1444
                if (reg) Error("Error converting view %s of register %s to string", view);
1445
                else Error("Error converting property %s to string", view);
1446
            }
314 by Suren A. Chilingaryan
Support writting register views
1447
315 by Suren A. Chilingaryan
Support properties of arbitrary type
1448
            printf("%s = %s", (reg?reg:view), val.sval);
1449
            if ((val.unit)&&(strcasecmp(val.unit, "name")))
1450
                printf(" %s", val.unit);
1451
            printf("\n");
313 by Suren A. Chilingaryan
Support reading of register views
1452
        } else {
315 by Suren A. Chilingaryan
Support properties of arbitrary type
1453
            pcilib_register_t regid = pcilib_find_register(handle, bank, reg);
313 by Suren A. Chilingaryan
Support reading of register views
1454
            bank_id = pcilib_find_register_bank_by_addr(handle, model_info->registers[regid].bank);
1455
            format = model_info->banks[bank_id].format;
1456
            if (!format) format = "%lu";
1457
            err = pcilib_read_register_by_id(handle, regid, &value);
314 by Suren A. Chilingaryan
Support writting register views
1458
            if (err) Error("Error reading register %s", reg);
1459
1460
	    printf("%s = ", reg);
1461
	    printf(format, value);
1462
	    printf("\n");
39 by root
Move to new FPGA design
1463
	}
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
1464
    } else {
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
1465
	if (model_info->registers) {
7.1.2 by Suren A. Chilingaryan
Better handling of register banks
1466
	    if (bank) {
236 by Suren A. Chilingaryan
Big redign of model structures
1467
		bank_id = pcilib_find_register_bank(handle, bank);
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
1468
		bank_addr = model_info->banks[bank_id].addr;
7.1.2 by Suren A. Chilingaryan
Better handling of register banks
1469
	    }
1470
	    
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1471
	    printf("Registers:\n");
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
1472
	    for (i = 0; model_info->registers[i].bits; i++) {
1473
		if ((model_info->registers[i].mode & PCILIB_REGISTER_R)&&((!bank)||(model_info->registers[i].bank == bank_addr))&&(model_info->registers[i].type != PCILIB_REGISTER_BITS)) { 
236 by Suren A. Chilingaryan
Big redign of model structures
1474
		    bank_id = pcilib_find_register_bank_by_addr(handle, model_info->registers[i].bank);
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
1475
		    format = model_info->banks[bank_id].format;
39 by root
Move to new FPGA design
1476
		    if (!format) format = "%lu";
1477
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
1478
		    err = pcilib_read_register_by_id(handle, i, &value);
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
1479
		    if (err) printf(" %s = error reading value", model_info->registers[i].name);
39 by root
Move to new FPGA design
1480
	    	    else {
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
1481
			printf(" %s = ", model_info->registers[i].name);
39 by root
Move to new FPGA design
1482
			printf(format, value);
1483
		    }
1484
1485
		    printf(" [");
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
1486
		    printf(format, model_info->registers[i].defvalue);
39 by root
Move to new FPGA design
1487
		    printf("]");
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
1488
		    printf("\n");
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1489
		}
1490
	    }
1491
	} else {
1492
	    printf("No registers");
1493
	}
1494
	printf("\n");
1495
    }
313 by Suren A. Chilingaryan
Support reading of register views
1496
109 by Suren A. Chilingaryan
Improvements of DMA engine
1497
    return 0;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1498
}
1499
87 by Suren A. Chilingaryan
Support writting output to file
1500
#define WRITE_REGVAL(buf, n, access, o) {\
1501
    uint##access##_t tbuf[n]; \
1502
    for (i = 0; i < n; i++) { \
1503
	tbuf[i] = (uint##access##_t)buf[i]; \
1504
    } \
1505
    fwrite(tbuf, access/8, n, o); \
1506
}
1507
236 by Suren A. Chilingaryan
Big redign of model structures
1508
int ReadRegisterRange(pcilib_t *handle, const pcilib_model_description_t *model_info, const char *bank, uintptr_t addr, long addr_shift, size_t n, FILE *o) {
7.1.4 by Suren A. Chilingaryan
Support writting and reading of register ranges
1509
    int err;
1510
    int i;
1511
236 by Suren A. Chilingaryan
Big redign of model structures
1512
    const pcilib_register_bank_description_t *banks = model_info->banks;
1513
    pcilib_register_bank_t bank_id = pcilib_find_register_bank(handle, bank);
7.1.4 by Suren A. Chilingaryan
Support writting and reading of register ranges
1514
1515
    if (bank_id == PCILIB_REGISTER_BANK_INVALID) {
1516
	if (bank) Error("Invalid register bank is specified (%s)", bank);
1517
	else Error("Register bank should be specified");
1518
    }
1519
1520
    int access = banks[bank_id].access / 8;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
1521
//    int size = n * abs(access);
7.1.4 by Suren A. Chilingaryan
Support writting and reading of register ranges
1522
    int block_width, blocks_per_line;
1523
    int numbers_per_block, numbers_per_line; 
7.1.2 by Suren A. Chilingaryan
Better handling of register banks
1524
    
7.1.4 by Suren A. Chilingaryan
Support writting and reading of register ranges
1525
    numbers_per_block = BLOCK_SIZE / access;
1526
1527
    block_width = numbers_per_block * ((access * 2) +  SEPARATOR_WIDTH);
1528
    blocks_per_line = (LINE_WIDTH - 6) / (block_width +  BLOCK_SEPARATOR_WIDTH);
1529
    if ((blocks_per_line > 1)&&(blocks_per_line % 2)) --blocks_per_line;
1530
    numbers_per_line = blocks_per_line * numbers_per_block;
1531
1532
7.1.2 by Suren A. Chilingaryan
Better handling of register banks
1533
    pcilib_register_value_t buf[n];
7.1.4 by Suren A. Chilingaryan
Support writting and reading of register ranges
1534
    err = pcilib_read_register_space(handle, bank, addr, n, buf);
1535
    if (err) Error("Error reading register space for bank \"%s\" at address %lx, size %lu", bank?bank:"default", addr, n);
1536
1537
87 by Suren A. Chilingaryan
Support writting output to file
1538
    if (o) {
1539
	printf("Writting output (%zu bytes) to file (append to the end)...\n", n * abs(access));
1540
	switch (access) {
1541
	    case 1: WRITE_REGVAL(buf, n, 8, o) break;
1542
	    case 2: WRITE_REGVAL(buf, n, 16, o) break;
1543
	    case 4: WRITE_REGVAL(buf, n, 32, o) break;
1544
	    case 8: WRITE_REGVAL(buf, n, 64, o) break;
1545
	}
1546
    } else {
1547
	for (i = 0; i < n; i++) {
1548
	    if (i) {
1549
		if (i%numbers_per_line == 0) printf("\n");
1550
		else {
1551
		    printf("%*s", SEPARATOR_WIDTH, "");
1552
		    if (i%numbers_per_block == 0) printf("%*s", BLOCK_SEPARATOR_WIDTH, "");
1553
		}
7.1.4 by Suren A. Chilingaryan
Support writting and reading of register ranges
1554
	    }
1555
	    
134 by Suren A. Chilingaryan
Handle properly more of trigger-and-grab options in pcitool
1556
	    if (i%numbers_per_line == 0) printf("%4lx:  ", addr + 4 * i - addr_shift);
87 by Suren A. Chilingaryan
Support writting output to file
1557
	    printf("%0*lx", access * 2, (unsigned long)buf[i]);
1558
	}
1559
	printf("\n\n");
7.1.4 by Suren A. Chilingaryan
Support writting and reading of register ranges
1560
    }
87 by Suren A. Chilingaryan
Support writting output to file
1561
    
1562
    return 0;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1563
}
1564
191 by Suren A. Chilingaryan
Do not verify BAR writes by default
1565
int WriteData(pcilib_t *handle, ACCESS_MODE mode, pcilib_dma_engine_addr_t dma, pcilib_bar_t bar, uintptr_t addr, size_t n, access_t access, int endianess, char ** data, int verify) {
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1566
    int read_back = 0;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1567
    void *buf, *check;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
1568
    int res = 0, i, err;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1569
    int size = n * abs(access);
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1570
    size_t ret;
49 by Suren A. Chilingaryan
A bit of renaming
1571
    pcilib_dma_engine_t dmaid;
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
1572
196 by Suren A. Chilingaryan
Provide access to PCI configuration space in cli
1573
    if (mode == ACCESS_CONFIG)
1574
	Error("Writting to PCI configuration space is not supported");
1575
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1576
    err = posix_memalign( (void**)&buf, 256, size );
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
1577
    if (!err) err = posix_memalign( (void**)&check, 256, size );
1578
    if ((err)||(!buf)||(!check)) Error("Allocation of %i bytes of memory have failed", size);
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1579
1580
    for (i = 0; i < n; i++) {
1581
	switch (access) {
1582
	    case 1: res = sscanf(data[i], "%hhx", ((uint8_t*)buf)+i); break;
1583
	    case 2: res = sscanf(data[i], "%hx", ((uint16_t*)buf)+i); break;
1584
	    case 4: res = sscanf(data[i], "%x", ((uint32_t*)buf)+i); break;
1585
	    case 8: res = sscanf(data[i], "%lx", ((uint64_t*)buf)+i); break;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
1586
	    default: Error("Unexpected data size (%lu)", access);
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1587
	}
7.1.5 by Suren A. Chilingaryan
Support for FPGA registers
1588
	if ((res != 1)||(!isxnumber(data[i]))) Error("Can't parse data value at poition %i, (%s) is not valid hex number", i, data[i]);
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1589
    }
1590
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
1591
    if (endianess) pcilib_swap(buf, buf, abs(access), n);
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1592
1593
    switch (mode) {
1594
      case ACCESS_DMA:
1595
	dmaid = pcilib_find_dma_by_addr(handle, PCILIB_DMA_TO_DEVICE, dma);
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
1596
	if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("Invalid DMA engine (%lu) is specified", dma);
58 by Suren A. Chilingaryan
Wait for the completion of DMA operations during writes
1597
	err = pcilib_write_dma(handle, dmaid, addr, size, buf, &ret);
1598
	if ((err)||(ret != size)) {
89 by Suren A. Chilingaryan
Few fixes for IPE Camera modification
1599
	    if (err == PCILIB_ERROR_TIMEOUT) Error("Timeout writting the data to DMA"); 
1600
	    else if (err) Error("DMA engine returned a error while writing the data");
1601
	    else if (!ret) Error("No data is written by DMA engine");
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1602
	    else Error("Only %lu bytes of %lu is written by DMA engine", ret, size);
1603
	}
1604
      break;
1605
      case ACCESS_FIFO:
1606
	pcilib_write_fifo(handle, bar, addr, access, n, buf);
1607
      break;
1608
      default:
345 by Suren A. Chilingaryan
64-bit access to BAR memory
1609
	pcilib_write(handle, bar, addr, access, size / access, buf);
191 by Suren A. Chilingaryan
Do not verify BAR writes by default
1610
	if (verify) {
345 by Suren A. Chilingaryan
64-bit access to BAR memory
1611
	    pcilib_read(handle, bar, addr, access, size / access, check);
191 by Suren A. Chilingaryan
Do not verify BAR writes by default
1612
	    read_back = 1;
1613
	}
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1614
    }
1615
1616
    if ((read_back)&&(memcmp(buf, check, size))) {
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1617
	printf("Write failed: the data written and read differ, the foolowing is read back:\n");
7.1.3 by Suren A. Chilingaryan
Fixes write verification failure if byte-swapping is in force
1618
        if (endianess) pcilib_swap(check, check, abs(access), n);
109 by Suren A. Chilingaryan
Improvements of DMA engine
1619
	ReadData(handle, mode, 0, dma, bar, addr, n, access, endianess, (size_t)-1, NULL);
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1620
	exit(-1);
1621
    }
1622
1623
    free(check);
1624
    free(buf);
109 by Suren A. Chilingaryan
Improvements of DMA engine
1625
    
1626
    return 0;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1627
}
1628
236 by Suren A. Chilingaryan
Big redign of model structures
1629
int WriteRegisterRange(pcilib_t *handle, const pcilib_model_description_t *model_info, const char *bank, uintptr_t addr, long addr_shift, size_t n, char ** data) {
7.1.4 by Suren A. Chilingaryan
Support writting and reading of register ranges
1630
    pcilib_register_value_t *buf, *check;
1631
    int res, i, err;
1632
    unsigned long value;
1633
    int size = n * sizeof(pcilib_register_value_t);
1634
1635
    err = posix_memalign( (void**)&buf, 256, size );
1636
    if (!err) err = posix_memalign( (void**)&check, 256, size );
1637
    if ((err)||(!buf)||(!check)) Error("Allocation of %i bytes of memory have failed", size);
1638
1639
    for (i = 0; i < n; i++) {
1640
	res = sscanf(data[i], "%lx", &value);
7.1.5 by Suren A. Chilingaryan
Support for FPGA registers
1641
	if ((res != 1)||(!isxnumber(data[i]))) Error("Can't parse data value at poition %i, (%s) is not valid hex number", i, data[i]);
7.1.4 by Suren A. Chilingaryan
Support writting and reading of register ranges
1642
	buf[i] = value;
1643
    }
1644
1645
    err = pcilib_write_register_space(handle, bank, addr, n, buf);
1646
    if (err) Error("Error writting register space for bank \"%s\" at address %lx, size %lu", bank?bank:"default", addr, n);
1647
    
1648
    err = pcilib_read_register_space(handle, bank, addr, n, check);
1649
    if (err) Error("Error reading register space for bank \"%s\" at address %lx, size %lu", bank?bank:"default", addr, n);
1650
1651
    if (memcmp(buf, check, size)) {
1652
	printf("Write failed: the data written and read differ, the foolowing is read back:\n");
120 by Suren A. Chilingaryan
Print proper addresses for register range read/writes
1653
	ReadRegisterRange(handle, model_info, bank, addr, addr_shift, n, NULL);
7.1.4 by Suren A. Chilingaryan
Support writting and reading of register ranges
1654
	exit(-1);
1655
    }
1656
1657
    free(check);
1658
    free(buf);
109 by Suren A. Chilingaryan
Improvements of DMA engine
1659
    
1660
    return 0;
7.1.4 by Suren A. Chilingaryan
Support writting and reading of register ranges
1661
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1662
}
1663
315 by Suren A. Chilingaryan
Support properties of arbitrary type
1664
int WriteRegister(pcilib_t *handle, const pcilib_model_description_t *model_info, const char *bank, const char *reg, const char *view, const char *unit, char **data) {
314 by Suren A. Chilingaryan
Support writting register views
1665
    int err = 0;
1666
1667
    pcilib_value_t val = {0};
1668
    pcilib_register_value_t value, verify;
305.1.12 by nicolas.zilio at hotmail
addition of other remarks, cleaning in progress
1669
82 by Suren A. Chilingaryan
Do not try to verify write-only registers
1670
1671
/*
1672
    pcilib_register_bank_t bank_id;
1673
    pcilib_register_bank_addr_t bank_addr;
1674
67 by Suren A. Chilingaryan
Report writted register in hex if it was specified in hex
1675
    bank_id = pcilib_find_bank_by_addr(handle, model_info->registers[regid].bank);
1676
    if (bank_id == PCILIB_REGISTER_BANK_INVALID) Error("Can't find bank of the register (%s)", reg);
1677
    format = model_info->banks[bank_id].format;
1678
    if (!format) format = "%lu";
1679
*/
1680
314 by Suren A. Chilingaryan
Support writting register views
1681
    err = pcilib_set_value_from_static_string(handle, &val, *data);
1682
    if (err) Error("Error (%i) setting value", err);
1683
315 by Suren A. Chilingaryan
Support properties of arbitrary type
1684
    if (view) {
1685
        if (unit)
1686
            val.unit = unit;
1687
1688
        if (reg) {
1689
            err = pcilib_write_register_view(handle, bank, reg, view, &val);
1690
            if (err) Error("Error writting view %s of register %s", view, reg);
1691
            printf("%s is written\n ", reg);
1692
        } else {
1693
            err = pcilib_set_property(handle, view, &val);
1694
            if (err) Error("Error setting property %s", view);
1695
            printf("%s is written\n ", view);
1696
        }
314 by Suren A. Chilingaryan
Support writting register views
1697
    } else {
315 by Suren A. Chilingaryan
Support properties of arbitrary type
1698
        pcilib_register_t regid = pcilib_find_register(handle, bank, reg);
1699
        if (regid == PCILIB_REGISTER_INVALID) Error("Can't find register (%s) from bank (%s)", reg, bank?bank:"autodetected");
1700
314 by Suren A. Chilingaryan
Support writting register views
1701
        value = pcilib_get_value_as_register_value(handle, &val, &err);
1702
        if (err) Error("Error (%i) parsing data value (%s)", *data);
1703
1704
        err = pcilib_write_register(handle, bank, reg, value);
1705
        if (err) Error("Error writting register %s\n", reg);
1706
353 by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov
1707
        if ((model_info->registers[regid].mode&(PCILIB_REGISTER_RW|PCILIB_REGISTER_INCONSISTENT)) == PCILIB_REGISTER_RW) {
314 by Suren A. Chilingaryan
Support writting register views
1708
            const char *format = (val.format?val.format:"%u");
1709
	    
1710
	    err = pcilib_read_register(handle, bank, reg, &verify);
1711
	    if (err) Error("Error reading back register %s for verification\n", reg);
1712
    
1713
	    if (verify != value) {
1714
	        Error("Failed to write register %s: %lu is written and %lu is read back", reg, value, verify);
1715
	    } else {
1716
	        printf("%s = ", reg);
1717
	        printf(format, verify);
1718
	        printf("\n");
1719
	    }
1720
        } else {
1721
            printf("%s is written\n ", reg);
1722
        }
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
1723
    }
314 by Suren A. Chilingaryan
Support writting register views
1724
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
1725
    return 0;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
1726
}
1727
117 by Suren A. Chilingaryan
new event architecture, first trial
1728
typedef struct {
1729
    pcilib_t *handle;
1730
    pcilib_event_t event;
1731
    pcilib_event_data_type_t data;
141 by Suren A. Chilingaryan
Initial support of fastwritter library
1732
1733
    fastwriter_t *writer;
117 by Suren A. Chilingaryan
new event architecture, first trial
1734
136 by Suren A. Chilingaryan
Verbose grabbing mode
1735
    int verbose;
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
1736
    pcilib_timeout_t timeout;
117 by Suren A. Chilingaryan
new event architecture, first trial
1737
    size_t run_time;
299 by Suren A. Chilingaryan
Improve bad events counting
1738
    size_t trigger_time;
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
1739
    size_t max_triggers;
146 by Suren A. Chilingaryan
Do event counting when rawcallback is used to stream the data
1740
    pcilib_event_flags_t flags;
147 by Suren A. Chilingaryan
Store with additional header containing timestmap, sequential number, etc.
1741
    FORMAT format;
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
1742
    
134 by Suren A. Chilingaryan
Handle properly more of trigger-and-grab options in pcitool
1743
    volatile int event_pending;			/**< Used to detect that we have read previously triggered event */
130 by Suren A. Chilingaryan
Declare volatile differently
1744
    volatile int trigger_thread_started;	/**< Indicates that trigger thread is ready and we can't procced to start event recording */
1745
    volatile int started;			/**< Indicates that recording is started */
15 by Suren A. Chilingaryan
Infrastructure for event API
1746
    
130 by Suren A. Chilingaryan
Declare volatile differently
1747
    volatile int run_flag;
141 by Suren A. Chilingaryan
Initial support of fastwritter library
1748
    volatile int writing_flag;
122 by Suren A. Chilingaryan
Gathering a bit of statistics
1749
299 by Suren A. Chilingaryan
Improve bad events counting
1750
    struct timeval first_frame;
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
1751
    struct timeval last_frame;
299 by Suren A. Chilingaryan
Improve bad events counting
1752
    size_t last_num, last_id;
1753
186 by Suren A. Chilingaryan
Provide information on failed triggers
1754
    size_t trigger_failed;
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
1755
    size_t trigger_count;
299 by Suren A. Chilingaryan
Improve bad events counting
1756
    size_t event_count;				/**< Total number of events (including bad ones, but excluding events expected, but not reported by hardware) */
1757
    size_t incomplete_count;			/**< Broken events, we even can't extract appropriate block of raw data */
1758
    size_t broken_count;			/**< Broken events, error while decoding in the requested format */
1759
    size_t empty_count;				/**< Broken events, no associated data or unknown */
1760
    size_t missing_count;			/**< Missing events, not received from the hardware */
1761
    size_t dropped_count;			/**< Missing events, dropped due slow decoding/copying performance  */
1762
    size_t storage_count;			/**< Missing events, dropped due to slowness of the storage subsystem */
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
1763
    
122 by Suren A. Chilingaryan
Gathering a bit of statistics
1764
    struct timeval start_time;
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
1765
    struct timeval stop_time;
117 by Suren A. Chilingaryan
new event architecture, first trial
1766
} GRABContext;
1767
324 by Suren A. Chilingaryan
Documentation update
1768
int GrabCallback(pcilib_event_id_t event_id, const pcilib_event_info_t *info, void *user) {
147 by Suren A. Chilingaryan
Store with additional header containing timestmap, sequential number, etc.
1769
    int err = 0;
117 by Suren A. Chilingaryan
new event architecture, first trial
1770
    void *data;
141 by Suren A. Chilingaryan
Initial support of fastwritter library
1771
    size_t size;
15 by Suren A. Chilingaryan
Infrastructure for event API
1772
    
117 by Suren A. Chilingaryan
new event architecture, first trial
1773
    GRABContext *ctx = (GRABContext*)user;
1774
    pcilib_t *handle = ctx->handle;
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
1775
1776
    gettimeofday(&ctx->last_frame, NULL);
122 by Suren A. Chilingaryan
Gathering a bit of statistics
1777
1778
    if (!ctx->event_count) {
1779
	memcpy(&ctx->first_frame, &ctx->last_frame, sizeof(struct timeval));
1780
    }
129 by Suren A. Chilingaryan
Add volatile keyword to prevent problematic optimizations
1781
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
1782
    ctx->event_pending = 0;
122 by Suren A. Chilingaryan
Gathering a bit of statistics
1783
    ctx->event_count++;
246 by Suren A. Chilingaryan
Fix counting lost frames
1784
251 by Suren A. Chilingaryan
Add code to debug missing events while recording
1785
    if (ctx->last_num) {
1786
	size_t missing_count = (info->seqnum - ctx->last_num) - 1;
1787
	ctx->missing_count += missing_count; 
1788
#ifdef PCILIB_DEBUG_MISSING_EVENTS
1789
	if (missing_count)
299 by Suren A. Chilingaryan
Improve bad events counting
1790
	    pcilib_debug(MISSING_EVENTS, "%zu missing events between %zu (hwid: %zu) and %zu (hwid: %zu)", missing_count, ctx->last_id, ctx->last_num, event_id, info->seqnum);
251 by Suren A. Chilingaryan
Add code to debug missing events while recording
1791
#endif /* PCILIB_DEBUG_MISSING_EVENTS */
1792
    }
246 by Suren A. Chilingaryan
Fix counting lost frames
1793
134 by Suren A. Chilingaryan
Handle properly more of trigger-and-grab options in pcitool
1794
    ctx->last_num = info->seqnum;
299 by Suren A. Chilingaryan
Improve bad events counting
1795
    ctx->last_id = event_id;
1796
124 by Suren A. Chilingaryan
Image frames decoding
1797
    if (info->flags&PCILIB_EVENT_INFO_FLAG_BROKEN) {
129 by Suren A. Chilingaryan
Add volatile keyword to prevent problematic optimizations
1798
	ctx->incomplete_count++;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
1799
	return PCILIB_STREAMING_CONTINUE;
124 by Suren A. Chilingaryan
Image frames decoding
1800
    }
392 by Suren A. Chilingaryan
Fix pcitool getting RAW data and returning STANDARD
1801
1802
    data = pcilib_get_data(handle, event_id, ctx->data, &size);
299 by Suren A. Chilingaryan
Improve bad events counting
1803
124 by Suren A. Chilingaryan
Image frames decoding
1804
    if (!data) {
299 by Suren A. Chilingaryan
Improve bad events counting
1805
	int err = (int)size;
1806
	switch (err) {
1807
	 case PCILIB_ERROR_OVERWRITTEN:
1808
	    ctx->dropped_count++;
1809
	    break;
1810
	 case PCILIB_ERROR_INVALID_DATA:
1811
	    ctx->broken_count++;
1812
	    break;
1813
	 default:
1814
	    ctx->empty_count++;
1815
	}
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
1816
	return PCILIB_STREAMING_CONTINUE;
124 by Suren A. Chilingaryan
Image frames decoding
1817
    }
147 by Suren A. Chilingaryan
Store with additional header containing timestmap, sequential number, etc.
1818
1819
    if (ctx->format == FORMAT_HEADER) {
1820
	uint64_t header[8];
1821
	header[0] = info->type;
1822
	header[1] = ctx->data;
1823
	header[2] = 0;
1824
	header[3] = size;
1825
	header[4] = info->seqnum;
1826
	header[5] = info->offset;
1827
	memcpy(header + 6, &info->timestamp, 16);
1828
	
1829
	err = fastwriter_push(ctx->writer, 64, header);
1830
    }
1831
1832
    if (!err) 
1833
	err = fastwriter_push(ctx->writer, size, data);
1834
141 by Suren A. Chilingaryan
Initial support of fastwritter library
1835
    if (err) {
147 by Suren A. Chilingaryan
Store with additional header containing timestmap, sequential number, etc.
1836
	fastwriter_cancel(ctx->writer);
1837
141 by Suren A. Chilingaryan
Initial support of fastwritter library
1838
	if (err != EWOULDBLOCK)
1839
	    Error("Storage error %i", err);
1840
1841
	ctx->storage_count++;
1842
	pcilib_return_data(handle, event_id, ctx->data, data);
1843
	return PCILIB_STREAMING_CONTINUE;
1844
    }
1845
1846
    err = pcilib_return_data(handle, event_id, ctx->data, data);
1847
    if (err) {
299 by Suren A. Chilingaryan
Improve bad events counting
1848
	ctx->dropped_count++;
141 by Suren A. Chilingaryan
Initial support of fastwritter library
1849
	fastwriter_cancel(ctx->writer);
1850
	return PCILIB_STREAMING_CONTINUE;
1851
    }
1852
1853
    err = fastwriter_commit(ctx->writer);
1854
    if (err) Error("Error commiting data to storage, Error: %i", err);
1855
    
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
1856
    return PCILIB_STREAMING_CONTINUE;
117 by Suren A. Chilingaryan
new event architecture, first trial
1857
}
1858
324 by Suren A. Chilingaryan
Documentation update
1859
int raw_data(pcilib_event_id_t event_id, const pcilib_event_info_t *info, pcilib_event_flags_t flags, size_t size, void *data, void *user) {
141 by Suren A. Chilingaryan
Initial support of fastwritter library
1860
    int err;
1861
1862
    GRABContext *ctx = (GRABContext*)user;
1863
//    pcilib_t *handle = ctx->handle;
142 by Suren A. Chilingaryan
fixes in pcitool
1864
146 by Suren A. Chilingaryan
Do event counting when rawcallback is used to stream the data
1865
1866
    if ((info)&&(info->seqnum != ctx->last_num)) {
1867
        gettimeofday(&ctx->last_frame, NULL);
1868
	if (!ctx->event_count) {
1869
	    memcpy(&ctx->first_frame, &ctx->last_frame, sizeof(struct timeval));
1870
	}
1871
1872
	ctx->event_count++;
251 by Suren A. Chilingaryan
Add code to debug missing events while recording
1873
	if (ctx->last_num) {
1874
	    size_t missing_count = (info->seqnum - ctx->last_num) - 1;
1875
	    ctx->missing_count += missing_count;
1876
#ifdef PCILIB_DEBUG_MISSING_EVENTS
1877
	    if (missing_count)
1878
		pcilib_debug(MISSING_EVENTS, "%zu missing events between %zu and %zu", missing_count, ctx->last_num, info->seqnum);
1879
#endif /* PCILIB_DEBUG_MISSING_EVENTS */
1880
1881
	}
146 by Suren A. Chilingaryan
Do event counting when rawcallback is used to stream the data
1882
	ctx->last_num = info->seqnum;
1883
    }
1884
141 by Suren A. Chilingaryan
Initial support of fastwritter library
1885
    err = fastwriter_push_data(ctx->writer, size, data);
1886
    if (err) {
1887
	if (err == EWOULDBLOCK) Error("Storage is not able to handle the data stream, buffer overrun");
1888
	Error("Storage error %i", err);
1889
    }
1890
    
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
1891
    return PCILIB_STREAMING_CONTINUE;
117 by Suren A. Chilingaryan
new event architecture, first trial
1892
}
1893
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
1894
117 by Suren A. Chilingaryan
new event architecture, first trial
1895
void *Trigger(void *user) {
186 by Suren A. Chilingaryan
Provide information on failed triggers
1896
    int err;
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
1897
    struct timeval start;
1898
130 by Suren A. Chilingaryan
Declare volatile differently
1899
    GRABContext *ctx = (GRABContext*)user;
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
1900
    size_t trigger_time = ctx->trigger_time;
1901
    size_t max_triggers = ctx->max_triggers;
1902
    
1903
    ctx->trigger_thread_started = 1;
1904
    ctx->event_pending = 1;
129 by Suren A. Chilingaryan
Add volatile keyword to prevent problematic optimizations
1905
1906
    while (!ctx->started) ;
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
1907
1908
    gettimeofday(&start, NULL);
1909
    do {
186 by Suren A. Chilingaryan
Provide information on failed triggers
1910
        err = pcilib_trigger(ctx->handle, ctx->event, 0, NULL);
1911
        if (err) ctx->trigger_failed++;
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
1912
	if ((++ctx->trigger_count == max_triggers)&&(max_triggers)) break;
1913
	
1914
	if (trigger_time) {
1915
	    pcilib_add_timeout(&start, trigger_time);
1916
	    if ((ctx->stop_time.tv_sec)&&(pcilib_timecmp(&start, &ctx->stop_time)>0)) break;
1917
	    pcilib_sleep_until_deadline(&start);
1918
	}  else {
1919
	    while ((ctx->event_pending)&&(ctx->run_flag)) usleep(10);
1920
	    ctx->event_pending = 1;
1921
	}
1922
    } while (ctx->run_flag);
1923
1924
    ctx->trigger_thread_started = 0;
1925
1926
    return NULL;
1927
}
1928
122 by Suren A. Chilingaryan
Gathering a bit of statistics
1929
void GrabStats(GRABContext *ctx, struct timeval *end_time) {
145 by Suren A. Chilingaryan
Print more statistics
1930
    int verbose;
122 by Suren A. Chilingaryan
Gathering a bit of statistics
1931
    pcilib_timeout_t duration, fps_duration;
1932
    struct timeval cur;
145 by Suren A. Chilingaryan
Print more statistics
1933
    double fps = 0, good_fps = 0;
146 by Suren A. Chilingaryan
Do event counting when rawcallback is used to stream the data
1934
    size_t total, good, pending = 0;
122 by Suren A. Chilingaryan
Gathering a bit of statistics
1935
145 by Suren A. Chilingaryan
Print more statistics
1936
    verbose = ctx->verbose;
1937
    
136 by Suren A. Chilingaryan
Verbose grabbing mode
1938
    if (end_time) {
145 by Suren A. Chilingaryan
Print more statistics
1939
	if (verbose++) {
136 by Suren A. Chilingaryan
Verbose grabbing mode
1940
	    printf("-------------------------------------------------------------------------------\n");
1941
	}
1942
    } else {
122 by Suren A. Chilingaryan
Gathering a bit of statistics
1943
	gettimeofday(&cur, NULL);
1944
	end_time = &cur;
1945
    }
146 by Suren A. Chilingaryan
Do event counting when rawcallback is used to stream the data
1946
176 by Suren A. Chilingaryan
print results even if no frames grabbed
1947
//    if ((ctx->event_count + ctx->missing_count) == 0) 
1948
//	return;
146 by Suren A. Chilingaryan
Do event counting when rawcallback is used to stream the data
1949
    
122 by Suren A. Chilingaryan
Gathering a bit of statistics
1950
    duration = pcilib_timediff(&ctx->start_time, end_time);
145 by Suren A. Chilingaryan
Print more statistics
1951
    fps_duration = pcilib_timediff(&ctx->first_frame, &ctx->last_frame);
1952
    
1953
    if (ctx->trigger_count) {
1954
	total = ctx->trigger_count;
186 by Suren A. Chilingaryan
Provide information on failed triggers
1955
	pending = ctx->trigger_count - ctx->event_count - ctx->missing_count - ctx->trigger_failed;
145 by Suren A. Chilingaryan
Print more statistics
1956
    } else {
1957
	total = ctx->event_count + ctx->missing_count;
1958
    }
1959
    
299 by Suren A. Chilingaryan
Improve bad events counting
1960
    good = ctx->event_count - ctx->broken_count - ctx->incomplete_count - ctx->storage_count - ctx->empty_count - ctx->dropped_count;
145 by Suren A. Chilingaryan
Print more statistics
1961
122 by Suren A. Chilingaryan
Gathering a bit of statistics
1962
    if (ctx->event_count > 1) {
1963
	fps = (ctx->event_count - 1) / (1.*fps_duration/1000000);
1964
    }
1965
    
145 by Suren A. Chilingaryan
Print more statistics
1966
    if (good > 1) {
1967
	good_fps = (good - 1) / (1.*fps_duration/1000000);
1968
    }
1969
1970
    printf("Run: ");
1971
    PrintTime(duration);    
136 by Suren A. Chilingaryan
Verbose grabbing mode
1972
    
1973
    if (ctx->trigger_count) {
145 by Suren A. Chilingaryan
Print more statistics
1974
	printf(", Triggers: ");
136 by Suren A. Chilingaryan
Verbose grabbing mode
1975
	PrintNumber(ctx->trigger_count);
1976
    }
1977
    
145 by Suren A. Chilingaryan
Print more statistics
1978
    printf(", Captured: ");
136 by Suren A. Chilingaryan
Verbose grabbing mode
1979
    PrintNumber(ctx->event_count);
145 by Suren A. Chilingaryan
Print more statistics
1980
    printf(" FPS %5.0lf", fps);
1981
146 by Suren A. Chilingaryan
Do event counting when rawcallback is used to stream the data
1982
    if ((ctx->flags&PCILIB_EVENT_FLAG_RAW_DATA_ONLY) == 0) {
1983
	printf(", Stored: ");
1984
	PrintNumber(good);
1985
	printf(" FPS %5.0lf", good_fps);
1986
    }
145 by Suren A. Chilingaryan
Print more statistics
1987
1988
    printf("\n");    
1989
1990
    if (verbose > 2) {
186 by Suren A. Chilingaryan
Provide information on failed triggers
1991
	if (ctx->trigger_count) {
1992
	    printf("Trig: ");
1993
	    PrintNumber(ctx->trigger_count);
1994
	    printf(" Issued: ");
1995
	    PrintNumber(ctx->trigger_count - ctx->trigger_failed);
1996
	    printf(" (");
1997
	    PrintPercent(ctx->trigger_count - ctx->trigger_failed, ctx->trigger_count);
1998
	    printf("%%) Failed: ");
1999
	    PrintNumber(ctx->trigger_failed);
2000
	    printf( " (");
2001
	    PrintPercent(ctx->trigger_failed, ctx->trigger_count);
2002
	    printf( "%%); Pending: ");
2003
	    PrintNumber(pending);
2004
	    printf( " (");
2005
	    PrintPercent(pending, ctx->trigger_count);
2006
	    printf( "%%)\n");
2007
	}
2008
	
146 by Suren A. Chilingaryan
Do event counting when rawcallback is used to stream the data
2009
	if (ctx->flags&PCILIB_EVENT_FLAG_RAW_DATA_ONLY) {
2010
	    printf("Captured: ");
2011
	    PrintNumber(good);
2012
	} else {
2013
	    printf("Good: ");
2014
	    PrintNumber(good);
2015
	    printf(", Dropped: ");
299 by Suren A. Chilingaryan
Improve bad events counting
2016
    	    PrintNumber(ctx->dropped_count + ctx->storage_count);
146 by Suren A. Chilingaryan
Do event counting when rawcallback is used to stream the data
2017
	    printf(", Bad: ");
299 by Suren A. Chilingaryan
Improve bad events counting
2018
	    PrintNumber(ctx->incomplete_count + ctx->broken_count);
186 by Suren A. Chilingaryan
Provide information on failed triggers
2019
	    printf(", Empty: ");
299 by Suren A. Chilingaryan
Improve bad events counting
2020
    	    PrintNumber(ctx->empty_count);
146 by Suren A. Chilingaryan
Do event counting when rawcallback is used to stream the data
2021
	}
145 by Suren A. Chilingaryan
Print more statistics
2022
	printf(", Lost: ");
2023
	PrintNumber(ctx->missing_count);
2024
	printf("\n");
2025
    }
2026
2027
    if (verbose > 1) {
146 by Suren A. Chilingaryan
Do event counting when rawcallback is used to stream the data
2028
	if (ctx->flags&PCILIB_EVENT_FLAG_RAW_DATA_ONLY) {
2029
	    printf("Captured: ");
2030
	    PrintPercent(good, total);
2031
	} else {
2032
	    printf("Good: ");
2033
	    PrintPercent(good, total);
2034
	    printf("%% Dropped: ");
299 by Suren A. Chilingaryan
Improve bad events counting
2035
	    PrintPercent(ctx->dropped_count + ctx->storage_count, total);
146 by Suren A. Chilingaryan
Do event counting when rawcallback is used to stream the data
2036
	    printf("%% Bad: ");
299 by Suren A. Chilingaryan
Improve bad events counting
2037
	    PrintPercent(ctx->incomplete_count + ctx->broken_count, total);
186 by Suren A. Chilingaryan
Provide information on failed triggers
2038
	    printf("%% Empty: ");
299 by Suren A. Chilingaryan
Improve bad events counting
2039
	    PrintPercent(ctx->empty_count, total);
146 by Suren A. Chilingaryan
Do event counting when rawcallback is used to stream the data
2040
	}
2041
2042
	printf("%% Lost: ");
145 by Suren A. Chilingaryan
Print more statistics
2043
	PrintPercent(ctx->missing_count, total);
186 by Suren A. Chilingaryan
Provide information on failed triggers
2044
        printf("%%");
145 by Suren A. Chilingaryan
Print more statistics
2045
	printf("\n");
2046
    }
2047
}
2048
2049
void StorageStats(GRABContext *ctx) {
2050
    int err;
2051
    fastwriter_stats_t st;
2052
2053
    pcilib_timeout_t duration;
2054
    struct timeval cur;
2055
2056
    gettimeofday(&cur, NULL);
2057
    duration = pcilib_timediff(&ctx->start_time, &cur);
2058
2059
    
2060
    err = fastwriter_get_stats(ctx->writer, &st);
2061
    if (err) return;
2062
2063
    printf("Wrote ");
2064
    PrintSize(st.written);
2065
    printf(" of ");
2066
    PrintSize(st.commited);
2067
    printf(" at ");
2068
    PrintSize(1000000.*st.written / duration);
2069
    printf("/s, %6.2lf%% ", 100.*st.buffer_used / st.buffer_size);
2070
    printf(" of ");
2071
    PrintSize(st.buffer_size);
2072
    printf(" buffer (%6.2lf%% max)\n", 100.*st.buffer_max / st.buffer_size);
122 by Suren A. Chilingaryan
Gathering a bit of statistics
2073
}
2074
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
2075
void *Monitor(void *user) {
2076
    struct timeval deadline;
136 by Suren A. Chilingaryan
Verbose grabbing mode
2077
    struct timeval nextinfo;
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
2078
    
130 by Suren A. Chilingaryan
Declare volatile differently
2079
    GRABContext *ctx = (GRABContext*)user;
136 by Suren A. Chilingaryan
Verbose grabbing mode
2080
    int verbose = ctx->verbose;
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
2081
    pcilib_timeout_t timeout = ctx->timeout;
2082
    
136 by Suren A. Chilingaryan
Verbose grabbing mode
2083
    
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
2084
    if (timeout == PCILIB_TIMEOUT_INFINITE) timeout = 0;
2085
2086
//    while (!ctx->started);
2087
    
2088
    if (timeout) {
130 by Suren A. Chilingaryan
Declare volatile differently
2089
	memcpy(&deadline, (struct timeval*)&ctx->last_frame, sizeof(struct timeval));
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
2090
	pcilib_add_timeout(&deadline, timeout);
2091
    }
2092
    
150 by Suren A. Chilingaryan
Quite mode
2093
    if (verbose > 0) {
136 by Suren A. Chilingaryan
Verbose grabbing mode
2094
	pcilib_calc_deadline(&nextinfo, STATUS_MESSAGE_INTERVAL*1000000);
2095
    }
2096
    
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
2097
    while (ctx->run_flag) {
138 by Suren A. Chilingaryan
Handle SIGINT signal in pcitool
2098
	if (StopFlag) {
2099
	    pcilib_stop(ctx->handle, PCILIB_EVENT_FLAG_STOP_ONLY);
2100
	    break;
2101
	}
2102
	
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
2103
	if (timeout) {
2104
	    if (pcilib_calc_time_to_deadline(&deadline) == 0) {
130 by Suren A. Chilingaryan
Declare volatile differently
2105
		memcpy(&deadline, (struct timeval*)&ctx->last_frame, sizeof(struct timeval));
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
2106
		pcilib_add_timeout(&deadline, timeout);
2107
		
2108
		if (pcilib_calc_time_to_deadline(&deadline) == 0) {
2109
		    pcilib_stop(ctx->handle, PCILIB_EVENT_FLAG_STOP_ONLY);
2110
		    break;
2111
		}
2112
	    }
2113
	}
2114
	
150 by Suren A. Chilingaryan
Quite mode
2115
	if (verbose > 0) {
136 by Suren A. Chilingaryan
Verbose grabbing mode
2116
	    if (pcilib_calc_time_to_deadline(&nextinfo) == 0) {
2117
		GrabStats(ctx, NULL);
145 by Suren A. Chilingaryan
Print more statistics
2118
		StorageStats(ctx);
136 by Suren A. Chilingaryan
Verbose grabbing mode
2119
		pcilib_calc_deadline(&nextinfo, STATUS_MESSAGE_INTERVAL*1000000);
2120
	    }
2121
	}
2122
	
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
2123
	usleep(100000);
2124
    }
2125
    
145 by Suren A. Chilingaryan
Print more statistics
2126
    pcilib_calc_deadline(&nextinfo, STATUS_MESSAGE_INTERVAL*1000000);
141 by Suren A. Chilingaryan
Initial support of fastwritter library
2127
    while (ctx->writing_flag) {
145 by Suren A. Chilingaryan
Print more statistics
2128
        if (pcilib_calc_time_to_deadline(&nextinfo) == 0) {
150 by Suren A. Chilingaryan
Quite mode
2129
	    if (verbose >= 0) StorageStats(ctx);
145 by Suren A. Chilingaryan
Print more statistics
2130
	    pcilib_calc_deadline(&nextinfo, STATUS_MESSAGE_INTERVAL*1000000);
2131
	}
2132
    
2133
	usleep(100000);
141 by Suren A. Chilingaryan
Initial support of fastwritter library
2134
    }
2135
    
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
2136
    return NULL;
2137
}
2138
141 by Suren A. Chilingaryan
Initial support of fastwritter library
2139
int TriggerAndGrab(pcilib_t *handle, GRAB_MODE grab_mode, const char *evname, const char *data_type, size_t num, size_t run_time, size_t trigger_time, pcilib_timeout_t timeout, PARTITION partition, FORMAT format, size_t buffer_size, size_t threads, int verbose, const char *output) {
117 by Suren A. Chilingaryan
new event architecture, first trial
2140
    int err;
134 by Suren A. Chilingaryan
Handle properly more of trigger-and-grab options in pcitool
2141
    GRABContext ctx;
123 by Suren A. Chilingaryan
Parse required event & data_type
2142
//    void *data = NULL;
2143
//    size_t size, written;
2144
2145
    pcilib_event_t event;
2146
    pcilib_event_t listen_events;
2147
    pcilib_event_data_type_t data;
117 by Suren A. Chilingaryan
new event architecture, first trial
2148
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
2149
    pthread_t monitor_thread;
117 by Suren A. Chilingaryan
new event architecture, first trial
2150
    pthread_t trigger_thread;
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
2151
    pthread_attr_t attr;
2152
    struct sched_param sched;
2153
122 by Suren A. Chilingaryan
Gathering a bit of statistics
2154
    struct timeval end_time;
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
2155
    pcilib_event_flags_t flags;
117 by Suren A. Chilingaryan
new event architecture, first trial
2156
123 by Suren A. Chilingaryan
Parse required event & data_type
2157
    if (evname) {
2158
	event = pcilib_find_event(handle, evname);
2159
	if (event == PCILIB_EVENT_INVALID) 
2160
	    Error("Can't find event (%s)", evname);
2161
2162
	listen_events = event;
2163
    } else {
2164
	listen_events = PCILIB_EVENTS_ALL;
2165
	event = PCILIB_EVENT0;
2166
    }
2167
    
2168
    if (data_type) {
2169
	data = pcilib_find_event_data_type(handle, event, data_type);
2170
	if (data == PCILIB_EVENT_DATA_TYPE_INVALID)
2171
	    Error("Can't find data type (%s)", data_type);
2172
    } else {
392 by Suren A. Chilingaryan
Fix pcitool getting RAW data and returning STANDARD
2173
	switch (format) {
2174
          case FORMAT_DEFAULT:
2175
	    data = PCILIB_EVENT_DATA;
2176
	    break;
2177
	  default:
2178
	    data = PCILIB_EVENT_RAW_DATA;
2179
	}
123 by Suren A. Chilingaryan
Parse required event & data_type
2180
    }
392 by Suren A. Chilingaryan
Fix pcitool getting RAW data and returning STANDARD
2181
134 by Suren A. Chilingaryan
Handle properly more of trigger-and-grab options in pcitool
2182
    memset(&ctx, 0, sizeof(GRABContext));
392 by Suren A. Chilingaryan
Fix pcitool getting RAW data and returning STANDARD
2183
117 by Suren A. Chilingaryan
new event architecture, first trial
2184
    ctx.handle = handle;
123 by Suren A. Chilingaryan
Parse required event & data_type
2185
    ctx.event = event;
2186
    ctx.data = data;
117 by Suren A. Chilingaryan
new event architecture, first trial
2187
    ctx.run_time = run_time;
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
2188
    ctx.timeout = timeout;
147 by Suren A. Chilingaryan
Store with additional header containing timestmap, sequential number, etc.
2189
    ctx.format = format;
145 by Suren A. Chilingaryan
Print more statistics
2190
2191
    if (grab_mode&GRAB_MODE_GRAB) ctx.verbose = verbose;
2192
    else ctx.verbose = 0;
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
2193
    
145 by Suren A. Chilingaryan
Print more statistics
2194
    if (grab_mode&GRAB_MODE_GRAB) {
2195
	ctx.writer =  fastwriter_init(output, 0);
2196
	if (!ctx.writer)
2197
	    Error("Can't initialize fastwritter library");
141 by Suren A. Chilingaryan
Initial support of fastwritter library
2198
145 by Suren A. Chilingaryan
Print more statistics
2199
	fastwriter_set_buffer_size(ctx.writer, buffer_size);
141 by Suren A. Chilingaryan
Initial support of fastwritter library
2200
	
145 by Suren A. Chilingaryan
Print more statistics
2201
	err = fastwriter_open(ctx.writer, output, 0);
2202
	if (err)
2203
	    Error("Error opening file (%s), Error: %i\n", output, err);
2204
2205
	ctx.writing_flag = 1;
2206
    }
141 by Suren A. Chilingaryan
Initial support of fastwritter library
2207
117 by Suren A. Chilingaryan
new event architecture, first trial
2208
    ctx.run_flag = 1;
134 by Suren A. Chilingaryan
Handle properly more of trigger-and-grab options in pcitool
2209
2210
    flags = PCILIB_EVENT_FLAGS_DEFAULT;
117 by Suren A. Chilingaryan
new event architecture, first trial
2211
    
134 by Suren A. Chilingaryan
Handle properly more of trigger-and-grab options in pcitool
2212
    if (data == PCILIB_EVENT_RAW_DATA) {
2213
	if (format == FORMAT_RAW) {
2214
	    flags |= PCILIB_EVENT_FLAG_RAW_DATA_ONLY;
2215
	}
2216
    } else {
2217
	flags |= PCILIB_EVENT_FLAG_PREPROCESS;
2218
    }
146 by Suren A. Chilingaryan
Do event counting when rawcallback is used to stream the data
2219
    
2220
    ctx.flags = flags;
123 by Suren A. Chilingaryan
Parse required event & data_type
2221
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
2222
//    printf("Limits: %lu %lu %lu\n", num, run_time, timeout);
134 by Suren A. Chilingaryan
Handle properly more of trigger-and-grab options in pcitool
2223
    pcilib_configure_autostop(handle, num, run_time);
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
2224
    
134 by Suren A. Chilingaryan
Handle properly more of trigger-and-grab options in pcitool
2225
    if (flags&PCILIB_EVENT_FLAG_RAW_DATA_ONLY) {
142 by Suren A. Chilingaryan
fixes in pcitool
2226
	pcilib_configure_rawdata_callback(handle, &raw_data, &ctx);
134 by Suren A. Chilingaryan
Handle properly more of trigger-and-grab options in pcitool
2227
    }
135 by Suren A. Chilingaryan
Allow to configure the number of preprocessing threads
2228
    
2229
    if (flags&PCILIB_EVENT_FLAG_PREPROCESS) {
324 by Suren A. Chilingaryan
Documentation update
2230
	pcilib_write_register(handle, "conf", "max_threads", threads);
135 by Suren A. Chilingaryan
Allow to configure the number of preprocessing threads
2231
    }
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
2232
    
2233
    if (grab_mode&GRAB_MODE_TRIGGER) {
134 by Suren A. Chilingaryan
Handle properly more of trigger-and-grab options in pcitool
2234
	if (trigger_time) {
2235
	    if ((timeout)&&(trigger_time * 2 > timeout)) {
2236
		timeout = 2 * trigger_time;
2237
		ctx.timeout = timeout;
2238
	    }
2239
	} else {
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
2240
		// Otherwise, we will trigger next event after previous one is read
145 by Suren A. Chilingaryan
Print more statistics
2241
	    if (((grab_mode&GRAB_MODE_GRAB) == 0)||(flags&PCILIB_EVENT_FLAG_RAW_DATA_ONLY)) trigger_time = PCILIB_TRIGGER_TIMEOUT;
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
2242
	}
2243
	
2244
	ctx.max_triggers = num;
2245
	ctx.trigger_count = 0;
2246
	ctx.trigger_time = trigger_time;
131 by Suren A. Chilingaryan
Increase event timeout for large trigger times
2247
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
2248
	    // We don't really care if RT priority is imposible
2249
	pthread_attr_init(&attr);
2250
	if (!pthread_attr_setschedpolicy(&attr, SCHED_FIFO)) {
2251
	    sched.sched_priority = sched_get_priority_min(SCHED_FIFO);
2252
	    pthread_attr_setschedparam(&attr, &sched);
2253
	}
2254
    
2255
	    // Start triggering thread and wait until it is schedulled
2256
	if (pthread_create(&trigger_thread, &attr, Trigger, (void*)&ctx))
2257
	    Error("Error spawning trigger thread");
2258
2259
	while (!ctx.trigger_thread_started) usleep(10);
2260
    }
2261
122 by Suren A. Chilingaryan
Gathering a bit of statistics
2262
    gettimeofday(&ctx.start_time, NULL);
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
2263
2264
    if (grab_mode&GRAB_MODE_GRAB) {
123 by Suren A. Chilingaryan
Parse required event & data_type
2265
	err = pcilib_start(handle, listen_events, flags);
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
2266
	if (err) Error("Failed to start event engine, error %i", err);
2267
    }
2268
    
2269
    ctx.started = 1;
2270
    
2271
    if (run_time) {
122 by Suren A. Chilingaryan
Gathering a bit of statistics
2272
	ctx.stop_time.tv_usec = ctx.start_time.tv_usec + run_time%1000000;
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
2273
	if (ctx.stop_time.tv_usec > 999999) {
2274
	    ctx.stop_time.tv_usec -= 1000000;
2275
	    __sync_synchronize();
122 by Suren A. Chilingaryan
Gathering a bit of statistics
2276
	    ctx.stop_time.tv_sec = ctx.start_time.tv_sec + 1 + run_time / 1000000;
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
2277
	} else {
2278
	    __sync_synchronize();
122 by Suren A. Chilingaryan
Gathering a bit of statistics
2279
	    ctx.stop_time.tv_sec = ctx.start_time.tv_sec + run_time / 1000000;
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
2280
	}
2281
    }
2282
    
122 by Suren A. Chilingaryan
Gathering a bit of statistics
2283
    memcpy(&ctx.last_frame, &ctx.start_time, sizeof(struct timeval));
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
2284
    if (pthread_create(&monitor_thread, NULL, Monitor, (void*)&ctx))
2285
	Error("Error spawning monitoring thread");
2286
2287
    if (grab_mode&GRAB_MODE_GRAB) {
2288
	err = pcilib_stream(handle, &GrabCallback, &ctx);
2289
	if (err) Error("Error streaming events, error %i", err);
2290
    }
2291
    
2292
    ctx.run_flag = 0;
2293
2294
    if (grab_mode&GRAB_MODE_TRIGGER) {
2295
	while (ctx.trigger_thread_started) usleep(10);
2296
    }
2297
    
2298
    if (grab_mode&GRAB_MODE_GRAB) {
2299
        pcilib_stop(handle, PCILIB_EVENT_FLAGS_DEFAULT);
2300
    }
117 by Suren A. Chilingaryan
new event architecture, first trial
2301
122 by Suren A. Chilingaryan
Gathering a bit of statistics
2302
    gettimeofday(&end_time, NULL);
2303
141 by Suren A. Chilingaryan
Initial support of fastwritter library
2304
    if (grab_mode&GRAB_MODE_TRIGGER) {
2305
	pthread_join(trigger_thread, NULL);
2306
    }
2307
    
145 by Suren A. Chilingaryan
Print more statistics
2308
2309
    if (grab_mode&GRAB_MODE_GRAB) {
150 by Suren A. Chilingaryan
Quite mode
2310
	if (verbose >= 0)
2311
	    printf("Grabbing is finished, flushing results....\n");
145 by Suren A. Chilingaryan
Print more statistics
2312
    
2313
	err = fastwriter_close(ctx.writer);
2314
	if (err) Error("Storage problems, error %i", err);
2315
    }
141 by Suren A. Chilingaryan
Initial support of fastwritter library
2316
2317
    ctx.writing_flag = 0;
2318
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
2319
    pthread_join(monitor_thread, NULL);
2320
150 by Suren A. Chilingaryan
Quite mode
2321
    if ((grab_mode&GRAB_MODE_GRAB)&&(verbose>=0)) {
145 by Suren A. Chilingaryan
Print more statistics
2322
	GrabStats(&ctx, &end_time);
2323
	StorageStats(&ctx);
2324
    }
122 by Suren A. Chilingaryan
Gathering a bit of statistics
2325
141 by Suren A. Chilingaryan
Initial support of fastwritter library
2326
    fastwriter_destroy(ctx.writer);
2327
15 by Suren A. Chilingaryan
Infrastructure for event API
2328
    return 0;
2329
}
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
2330
236 by Suren A. Chilingaryan
Big redign of model structures
2331
int StartStopDMA(pcilib_t *handle,  const pcilib_model_description_t *model_info, pcilib_dma_engine_addr_t dma, pcilib_dma_direction_t dma_direction, int start) {
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
2332
    int err;
2333
    pcilib_dma_engine_t dmaid;
2334
    
75 by Suren A. Chilingaryan
Few fixes
2335
    if (dma == PCILIB_DMA_ENGINE_ADDR_INVALID) {
240 by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines
2336
        const pcilib_dma_description_t *dma_info = pcilib_get_dma_description(handle);
75 by Suren A. Chilingaryan
Few fixes
2337
2338
        if (start) Error("DMA engine should be specified");
2339
236 by Suren A. Chilingaryan
Big redign of model structures
2340
	for (dmaid = 0; dma_info->engines[dmaid].addr_bits; dmaid++) {
343 by Suren A. Chilingaryan
Configure number of DMA buffers in IPEDMA and improve checking and reporting inconsistent kmem buffers while re-using
2341
	    err = pcilib_start_dma(handle, dmaid, PCILIB_DMA_FLAG_STOP);
236 by Suren A. Chilingaryan
Big redign of model structures
2342
	    if (err) Error("Error starting DMA Engine (%s %i)", ((dma_info->engines[dmaid].direction == PCILIB_DMA_FROM_DEVICE)?"C2S":"S2C"), dma_info->engines[dmaid].addr);
75 by Suren A. Chilingaryan
Few fixes
2343
	    err = pcilib_stop_dma(handle, dmaid, PCILIB_DMA_FLAG_PERSISTENT);
236 by Suren A. Chilingaryan
Big redign of model structures
2344
	    if (err) Error("Error stopping DMA Engine (%s %i)", ((dma_info->engines[dmaid].direction == PCILIB_DMA_FROM_DEVICE)?"C2S":"S2C"), dma_info->engines[dmaid].addr);
75 by Suren A. Chilingaryan
Few fixes
2345
	}
2346
	
2347
	return 0;
2348
    }
2349
    
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
2350
    if (dma_direction&PCILIB_DMA_FROM_DEVICE) {
75 by Suren A. Chilingaryan
Few fixes
2351
	dmaid = pcilib_find_dma_by_addr(handle, PCILIB_DMA_FROM_DEVICE, dma);
2352
	if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("Invalid DMA engine (C2S %lu) is specified", dma);
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
2353
	
2354
	if (start) {
74 by Suren A. Chilingaryan
Implement DMA access synchronization for NWL implementation
2355
	    err = pcilib_start_dma(handle, dmaid, PCILIB_DMA_FLAG_PERSISTENT);
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
2356
    	    if (err) Error("Error starting DMA engine (C2S %lu)", dma);
2357
	} else {
343 by Suren A. Chilingaryan
Configure number of DMA buffers in IPEDMA and improve checking and reporting inconsistent kmem buffers while re-using
2358
	    err = pcilib_start_dma(handle, dmaid, PCILIB_DMA_FLAG_STOP);
75 by Suren A. Chilingaryan
Few fixes
2359
    	    if (err) Error("Error starting DMA engine (C2S %lu)", dma);
74 by Suren A. Chilingaryan
Implement DMA access synchronization for NWL implementation
2360
	    err = pcilib_stop_dma(handle, dmaid, PCILIB_DMA_FLAG_PERSISTENT);
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
2361
    	    if (err) Error("Error stopping DMA engine (C2S %lu)", dma);
2362
	}
2363
    }
75 by Suren A. Chilingaryan
Few fixes
2364
    
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
2365
    if (dma_direction&PCILIB_DMA_TO_DEVICE) {
75 by Suren A. Chilingaryan
Few fixes
2366
	dmaid = pcilib_find_dma_by_addr(handle, PCILIB_DMA_TO_DEVICE, dma);
2367
	if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("Invalid DMA engine (S2C %lu) is specified", dma);
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
2368
	
2369
	if (start) {
74 by Suren A. Chilingaryan
Implement DMA access synchronization for NWL implementation
2370
	    err = pcilib_start_dma(handle, dmaid, PCILIB_DMA_FLAG_PERSISTENT);
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
2371
    	    if (err) Error("Error starting DMA engine (S2C %lu)", dma);
2372
	} else {
343 by Suren A. Chilingaryan
Configure number of DMA buffers in IPEDMA and improve checking and reporting inconsistent kmem buffers while re-using
2373
	    err = pcilib_start_dma(handle, dmaid, PCILIB_DMA_FLAG_STOP);
75 by Suren A. Chilingaryan
Few fixes
2374
    	    if (err) Error("Error starting DMA engine (S2C %lu)", dma);
74 by Suren A. Chilingaryan
Implement DMA access synchronization for NWL implementation
2375
	    err = pcilib_stop_dma(handle, dmaid, PCILIB_DMA_FLAG_PERSISTENT);
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
2376
    	    if (err) Error("Error stopping DMA engine (S2C %lu)", dma);
2377
	}
2378
    }
2379
2380
    return 0;
2381
}
2382
80 by Suren A. Chilingaryan
List kernel buffers
2383
2384
typedef struct {
197 by Suren A. Chilingaryan
Assume user kmem use
2385
    pcilib_kmem_use_t use;
80 by Suren A. Chilingaryan
List kernel buffers
2386
    
2387
    int referenced;
2388
    int hw_lock;
2389
    int reusable;
2390
    int persistent;
2391
    int open;
2392
    
2393
    size_t count;
2394
    size_t size;
2395
} kmem_use_info_t;
2396
2397
#define MAX_USES 64
2398
197 by Suren A. Chilingaryan
Assume user kmem use
2399
pcilib_kmem_use_t ParseUse(const char *use) {
2400
    unsigned long utmp;
2401
2402
    if (use) {
2403
        if ((!isxnumber(use))||(sscanf(use, "%lx", &utmp) != 1)) Error("Invalid use (%s) is specified", use);
2404
2405
	if (strlen(use) < 5)
2406
	    return PCILIB_KMEM_USE(PCILIB_KMEM_USE_USER,utmp);
2407
	else
2408
	    return utmp;
2409
    }
2410
2411
    Error("Kernel memory use is not specified");
2412
    return 0;
2413
}
2414
2415
size_t FindUse(size_t *n_uses, kmem_use_info_t *uses, pcilib_kmem_use_t use) {
80 by Suren A. Chilingaryan
List kernel buffers
2416
    size_t i, n = *n_uses;
2417
    
2418
    if (uses[n - 1].use == use) return n - 1;
2419
2420
    for (i = 1; i < (n - 1); i++) {
2421
	if (uses[i].use == use) return i;
2422
    }
2423
    
2424
    if (n == MAX_USES) return 0;
2425
280 by Suren A. Chilingaryan
Integrate locking subsystem from Nicolas Zilio
2426
    memset(&uses[n], 0, sizeof(kmem_use_info_t));
80 by Suren A. Chilingaryan
List kernel buffers
2427
    uses[n].use = use;
2428
    return (*n_uses)++;
2429
}
2430
197 by Suren A. Chilingaryan
Assume user kmem use
2431
2432
kmem_use_info_t *GetUse(size_t n_uses, kmem_use_info_t *uses, pcilib_kmem_use_t use) {
192 by Suren A. Chilingaryan
Kernel memory allocation
2433
    size_t i;
2434
    for (i = 0; i < n_uses; i++) {
2435
	if (uses[i].use == use) {
2436
	    if (uses[i].count) return uses + i;
2437
	    else return NULL;
2438
	}
2439
    }
2440
    return NULL;
2441
}
2442
2443
2444
int ParseKMEM(pcilib_t *handle, const char *device, size_t *uses_number, kmem_use_info_t *uses) {
80 by Suren A. Chilingaryan
List kernel buffers
2445
    DIR *dir;
2446
    struct dirent *entry;
2447
    const char *pos;
2448
    char sysdir[256];
2449
    char fname[256];
2450
    char info[256];
192 by Suren A. Chilingaryan
Kernel memory allocation
2451
2452
    size_t useid, n_uses = 1;	// Use 0 is for others
80 by Suren A. Chilingaryan
List kernel buffers
2453
236 by Suren A. Chilingaryan
Big redign of model structures
2454
    memset(uses, 0, sizeof(kmem_use_info_t));
80 by Suren A. Chilingaryan
List kernel buffers
2455
    
2456
    pos = strrchr(device, '/');
2457
    if (pos) ++pos;
2458
    else pos = device;
2459
    
2460
    snprintf(sysdir, 255, "/sys/class/fpga/%s", pos);
2461
2462
    dir = opendir(sysdir);
2463
    if (!dir) Error("Can't open directory (%s)", sysdir);
2464
    
2465
    while ((entry = readdir(dir)) != NULL) {
2466
	FILE *f;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
2467
	unsigned long use = 0;
2468
	unsigned long size = 0;
2469
	unsigned long refs = 0;
2470
	unsigned long mode = 0;
2471
	unsigned long hwref = 0;
80 by Suren A. Chilingaryan
List kernel buffers
2472
	
2473
	if (strncmp(entry->d_name, "kbuf", 4)) continue;
2474
	if (!isnumber(entry->d_name+4)) continue;
2475
	
2476
	snprintf(fname, 255, "%s/%s", sysdir, entry->d_name);
2477
	f = fopen(fname, "r");
2478
	if (!f) Error("Can't access file (%s)", fname);
2479
2480
	while(!feof(f)) {
236 by Suren A. Chilingaryan
Big redign of model structures
2481
	    if (!fgets(info, 256, f))
2482
		break;
2483
80 by Suren A. Chilingaryan
List kernel buffers
2484
	    if (!strncmp(info, "use:", 4)) use = strtoul(info+4, NULL, 16);
2485
	    if (!strncmp(info, "size:", 5)) size = strtoul(info+5, NULL, 10);
2486
	    if (!strncmp(info, "refs:", 5)) refs = strtoul(info+5, NULL, 10);
2487
	    if (!strncmp(info, "mode:", 5)) mode = strtoul(info+5, NULL, 16);
2488
	    if (!strncmp(info, "hw ref:", 7)) hwref = strtoul(info+7, NULL, 10);
236 by Suren A. Chilingaryan
Big redign of model structures
2489
80 by Suren A. Chilingaryan
List kernel buffers
2490
	}
2491
	fclose(f);
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
2492
80 by Suren A. Chilingaryan
List kernel buffers
2493
	useid = FindUse(&n_uses, uses, use);
2494
	uses[useid].count++;
2495
	uses[useid].size += size;
2496
	if (refs) uses[useid].referenced = 1;
2497
	if (hwref) uses[useid].hw_lock = 1;
2498
	if (mode&KMEM_MODE_REUSABLE) uses[useid].reusable = 1;
2499
	if (mode&KMEM_MODE_PERSISTENT) uses[useid].persistent = 1;
2500
	if (mode&KMEM_MODE_COUNT) uses[useid].open = 1;
2501
    }
2502
    closedir(dir);
2503
192 by Suren A. Chilingaryan
Kernel memory allocation
2504
    *uses_number = n_uses;
2505
2506
    return 0;
2507
}
2508
2509
int ListKMEM(pcilib_t *handle, const char *device) {
2510
    int err;
2511
    char stmp[256];
197 by Suren A. Chilingaryan
Assume user kmem use
2512
192 by Suren A. Chilingaryan
Kernel memory allocation
2513
    size_t i, useid, n_uses;	
2514
    kmem_use_info_t uses[MAX_USES];
2515
280 by Suren A. Chilingaryan
Integrate locking subsystem from Nicolas Zilio
2516
    const pcilib_model_description_t *model_info = pcilib_get_model_description(handle);
2517
192 by Suren A. Chilingaryan
Kernel memory allocation
2518
    err = ParseKMEM(handle, device, &n_uses, uses);
2519
    if (err) Error("Failed to parse kernel memory information provided through sysfs");
2520
88 by Suren A. Chilingaryan
IRQ acknowledgement support in the engine API
2521
    if ((n_uses == 1)&&(uses[0].count == 0)) {
2522
	printf("No kernel memory is allocated\n");
2523
	return 0;
2524
    }
280 by Suren A. Chilingaryan
Integrate locking subsystem from Nicolas Zilio
2525
100 by root
Support exporting data from kernel buffers
2526
    printf("Use      Type                  Count      Total Size       REF       Mode \n");
80 by Suren A. Chilingaryan
List kernel buffers
2527
    printf("--------------------------------------------------------------------------------\n");
2528
    for (useid = 0; useid < n_uses; useid++) {
2529
	if (useid + 1 == n_uses) {
2530
	    if (!uses[0].count) continue;
2531
	    i = 0;
2532
	} else i = useid + 1;
2533
	
197 by Suren A. Chilingaryan
Assume user kmem use
2534
	printf("%08x  ", uses[i].use);
280 by Suren A. Chilingaryan
Integrate locking subsystem from Nicolas Zilio
2535
	if (i) {
2536
	    switch(PCILIB_KMEM_USE_TYPE(uses[i].use)) {
2537
	      case PCILIB_KMEM_USE_DMA_RING:
2538
	        printf("DMA%u %s Ring      ", uses[i].use&0x7F, ((uses[i].use&0x80)?"S2C":"C2S"));
2539
	        break;
2540
	      case PCILIB_KMEM_USE_DMA_PAGES:
2541
	        printf("DMA%u %s Pages     ", uses[i].use&0x7F, ((uses[i].use&0x80)?"S2C":"C2S"));
2542
	        break;
2543
	      case PCILIB_KMEM_USE_SOFTWARE_REGISTERS: {
2544
		pcilib_register_bank_t bank = pcilib_find_register_bank_by_addr(handle, PCILIB_KMEM_USE_SUBTYPE(uses[i].use));
2545
		if (bank == PCILIB_REGISTER_BANK_INVALID)
2546
		    printf("SoftRegs (%8u)", PCILIB_KMEM_USE_SUBTYPE(uses[i].use));
2547
		else 
2548
		    printf("SoftRegs (%8s)", model_info->banks[bank].name);
2549
		break;
2550
	      }
2551
	      case PCILIB_KMEM_USE_LOCKS:
2552
		printf("Locks              ");
2553
		break;
2554
	      case PCILIB_KMEM_USE_USER:
346 by Suren A. Chilingaryan
Fix reading non DMA-able kernel pages using pcitool
2555
	        printf("User %04x          ", uses[i].use&0xFFFF);
280 by Suren A. Chilingaryan
Integrate locking subsystem from Nicolas Zilio
2556
	        break;
2557
	      default:
2558
		printf ("                   ");
2559
	    }
2560
	} else printf("All Others         ");
2561
	
100 by root
Support exporting data from kernel buffers
2562
	printf("  ");
236 by Suren A. Chilingaryan
Big redign of model structures
2563
	printf("%6zu", uses[i].count);
80 by Suren A. Chilingaryan
List kernel buffers
2564
	printf("     ");
236 by Suren A. Chilingaryan
Big redign of model structures
2565
	printf("%10s", GetPrintSize(stmp, uses[i].size));
100 by root
Support exporting data from kernel buffers
2566
	printf("      ");
280 by Suren A. Chilingaryan
Integrate locking subsystem from Nicolas Zilio
2567
	if ((uses[i].referenced)&&(uses[i].hw_lock)) printf("HW+SW");
80 by Suren A. Chilingaryan
List kernel buffers
2568
	else if (uses[i].referenced) printf("   SW");
2569
	else if (uses[i].hw_lock) printf("HW   ");
2570
	else printf("  -  ");
100 by root
Support exporting data from kernel buffers
2571
	printf("      ");
80 by Suren A. Chilingaryan
List kernel buffers
2572
	if (uses[i].persistent) printf("Persistent");
2573
	else if (uses[i].open) printf("Open      ");
2574
	else if (uses[i].reusable) printf("Reusable  ");
2575
	else printf("Closed    ");
2576
	printf("\n");
2577
    }
2578
    printf("--------------------------------------------------------------------------------\n");
2579
    printf("REF - Software/Hardware Reference, MODE - Reusable/Persistent/Open\n");
2580
2581
2582
    return 0;
2583
}
2584
197 by Suren A. Chilingaryan
Assume user kmem use
2585
int DetailKMEM(pcilib_t *handle, const char *device, const char *use, size_t block) {
192 by Suren A. Chilingaryan
Kernel memory allocation
2586
    int err;
2587
    size_t i, n;
2588
    pcilib_kmem_handle_t *kbuf;
197 by Suren A. Chilingaryan
Assume user kmem use
2589
    pcilib_kmem_use_t useid = ParseUse(use); 
192 by Suren A. Chilingaryan
Kernel memory allocation
2590
2591
    size_t n_uses;	
2592
    kmem_use_info_t uses[MAX_USES];
2593
    kmem_use_info_t *use_info;
2594
    
2595
    if (block == (size_t)-1) {
2596
        err = ParseKMEM(handle, device, &n_uses, uses);
2597
	if (err) Error("Failed to parse kernel memory information provided through sysfs");
197 by Suren A. Chilingaryan
Assume user kmem use
2598
	use_info = GetUse(n_uses, uses, useid);
2599
	if (!use_info) Error("No kernel buffers is allocated for the specified use (%lx)", useid);
192 by Suren A. Chilingaryan
Kernel memory allocation
2600
2601
	i = 0;    
2602
	n = use_info->count;
2603
    } else {
2604
	i = block;
2605
	n = block + 1;
2606
    }
2607
    
197 by Suren A. Chilingaryan
Assume user kmem use
2608
    kbuf = pcilib_alloc_kernel_memory(handle, 0, n, 0, 0, useid, PCILIB_KMEM_FLAG_REUSE|PCILIB_KMEM_FLAG_TRY);
192 by Suren A. Chilingaryan
Kernel memory allocation
2609
    if (!kbuf) {
197 by Suren A. Chilingaryan
Assume user kmem use
2610
	Error("Allocation of kernel buffer (use %lx, count %lu) is failed\n", useid, n);
192 by Suren A. Chilingaryan
Kernel memory allocation
2611
	return 0;
2612
    }
2613
2614
    printf("Buffer         Address          Hardware Address          Bus Address\n");
2615
    printf("--------------------------------------------------------------------------------\n");
2616
    for (; i < n; i++) {
370 by Suren A. Chilingaryan
RPM generation
2617
	volatile void *data = pcilib_kmem_get_block_ua(handle, kbuf, i);
192 by Suren A. Chilingaryan
Kernel memory allocation
2618
	uintptr_t pa = pcilib_kmem_get_block_pa(handle, kbuf, i);
2619
	uintptr_t ba = pcilib_kmem_get_block_ba(handle, kbuf, i);
2620
	printf("%6lu     %16p     %16lx       %16lx\n", i, data, pa, ba);
2621
    }
2622
    printf("\n");
2623
2624
    pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE);
2625
2626
    return 0;
2627
}
2628
2629
197 by Suren A. Chilingaryan
Assume user kmem use
2630
int ReadKMEM(pcilib_t *handle, const char *device, pcilib_kmem_use_t useid, size_t block, size_t max_size, FILE *o) {
148 by Suren A. Chilingaryan
Synchronize kernel buffers during the read-kernel-memory and while accessing via sysfs
2631
    int err;
100 by root
Support exporting data from kernel buffers
2632
    void *data;
2633
    size_t size;
2634
    pcilib_kmem_handle_t *kbuf;
197 by Suren A. Chilingaryan
Assume user kmem use
2635
192 by Suren A. Chilingaryan
Kernel memory allocation
2636
    if (block == (size_t)-1) block = 0;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
2637
197 by Suren A. Chilingaryan
Assume user kmem use
2638
    kbuf = pcilib_alloc_kernel_memory(handle, 0, block + 1, 0, 0, useid, PCILIB_KMEM_FLAG_REUSE|PCILIB_KMEM_FLAG_TRY);
100 by root
Support exporting data from kernel buffers
2639
    if (!kbuf) {
148 by Suren A. Chilingaryan
Synchronize kernel buffers during the read-kernel-memory and while accessing via sysfs
2640
	Error("The specified kernel buffer is not allocated\n");
2641
	return 0;
2642
    }
2643
2644
    err = pcilib_kmem_sync_block(handle, kbuf, PCILIB_KMEM_SYNC_FROMDEVICE, block);
2645
    if (err) {
2646
	pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE);
2647
	Error("The synchronization of kernel buffer has failed\n");
100 by root
Support exporting data from kernel buffers
2648
	return 0;
2649
    }
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
2650
370 by Suren A. Chilingaryan
RPM generation
2651
    data = (void*)pcilib_kmem_get_block_ua(handle, kbuf, block);
100 by root
Support exporting data from kernel buffers
2652
    if (data) {
2653
	size = pcilib_kmem_get_block_size(handle, kbuf, block);
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
2654
	if ((max_size)&&(size > max_size)) size = max_size;
148 by Suren A. Chilingaryan
Synchronize kernel buffers during the read-kernel-memory and while accessing via sysfs
2655
	
100 by root
Support exporting data from kernel buffers
2656
	fwrite(data, 1, size, o?o:stdout);
2657
    } else {
148 by Suren A. Chilingaryan
Synchronize kernel buffers during the read-kernel-memory and while accessing via sysfs
2658
	pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE);
2659
	Error("The specified block is not existing\n");
2660
	return 0;
100 by root
Support exporting data from kernel buffers
2661
    }
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
2662
100 by root
Support exporting data from kernel buffers
2663
    pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE);
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
2664
2665
    return 0;
100 by root
Support exporting data from kernel buffers
2666
}
2667
192 by Suren A. Chilingaryan
Kernel memory allocation
2668
int AllocKMEM(pcilib_t *handle, const char *device, const char *use, const char *type, size_t size, size_t block_size, size_t alignment) {
2669
    pcilib_kmem_type_t ktype = PCILIB_KMEM_TYPE_PAGE;
2670
    pcilib_kmem_flags_t flags = KMEM_FLAG_REUSE;
2671
    pcilib_kmem_handle_t *kbuf;
197 by Suren A. Chilingaryan
Assume user kmem use
2672
    pcilib_kmem_use_t useid = ParseUse(use);
192 by Suren A. Chilingaryan
Kernel memory allocation
2673
2674
    long page_size = sysconf(_SC_PAGESIZE);
197 by Suren A. Chilingaryan
Assume user kmem use
2675
192 by Suren A. Chilingaryan
Kernel memory allocation
2676
    if (type) {
2677
	if (!strcmp(type, "consistent")) ktype = PCILIB_KMEM_TYPE_CONSISTENT;
2678
	else if (!strcmp(type, "c2s")) ktype = PCILIB_KMEM_TYPE_DMA_C2S_PAGE;
2679
	else if (!strcmp(type, "s2c")) ktype = PCILIB_KMEM_TYPE_DMA_S2C_PAGE;
2680
	else Error("Invalid memory type (%s) is specified", type);
2681
    } 
2682
    
2683
    if ((block_size)&&(ktype != PCILIB_KMEM_TYPE_CONSISTENT))
2684
	Error("Selected memory type does not allow custom size");
2685
    
2686
    kbuf = pcilib_alloc_kernel_memory(handle, ktype, size, (block_size?block_size:page_size), (alignment?alignment:page_size), useid, flags|KMEM_FLAG_PERSISTENT);
2687
    if (!kbuf) Error("Allocation of kernel memory has failed");
2688
2689
    pcilib_free_kernel_memory(handle, kbuf, flags);
2690
2691
    return 0;
2692
}
2693
81 by Suren A. Chilingaryan
Support forceful clean-up of kernel memory
2694
int FreeKMEM(pcilib_t *handle, const char *device, const char *use, int force) {
2695
    int err;
2696
    int i;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
2697
197 by Suren A. Chilingaryan
Assume user kmem use
2698
    pcilib_kmem_use_t useid;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
2699
81 by Suren A. Chilingaryan
Support forceful clean-up of kernel memory
2700
    pcilib_kmem_flags_t flags = PCILIB_KMEM_FLAG_HARDWARE|PCILIB_KMEM_FLAG_PERSISTENT|PCILIB_KMEM_FLAG_EXCLUSIVE; 
2701
    if (force) flags |= PCILIB_KMEM_FLAG_FORCE; // this will ignore mmap locks as well.
2702
2703
    if (!strcasecmp(use, "dma")) {
2704
	for (i = 0; i < PCILIB_MAX_DMA_ENGINES; i++) {
2705
	    err = pcilib_clean_kernel_memory(handle, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_RING, i), flags);
2706
	    if (err) Error("Error cleaning DMA%i C2S Ring buffer", i);
2707
	    err = pcilib_clean_kernel_memory(handle, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_RING, 0x80|i), flags);
2708
	    if (err) Error("Error cleaning DMA%i S2C Ring buffer", i);
2709
	    err = pcilib_clean_kernel_memory(handle, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_PAGES, i), flags);
2710
	    if (err) Error("Error cleaning DMA%i C2S Page buffers", i);
2711
	    err = pcilib_clean_kernel_memory(handle, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_PAGES, 0x80|i), flags);
2712
	    if (err) Error("Error cleaning DMA%i S2C Page buffers", i);
2713
	}
2714
	
2715
	return 0;
2716
    }
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
2717
197 by Suren A. Chilingaryan
Assume user kmem use
2718
    useid = ParseUse(use);
81 by Suren A. Chilingaryan
Support forceful clean-up of kernel memory
2719
    err = pcilib_clean_kernel_memory(handle, useid, flags);
2720
    if (err) Error("Error cleaning kernel buffers for use (0x%lx)", useid);
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
2721
81 by Suren A. Chilingaryan
Support forceful clean-up of kernel memory
2722
    return 0;
2723
}
2724
236 by Suren A. Chilingaryan
Big redign of model structures
2725
int ListDMA(pcilib_t *handle, const char *device, const pcilib_model_description_t *model_info) {
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
2726
    int err;
2727
    
2728
    DIR *dir;
2729
    struct dirent *entry;
2730
    const char *pos;
2731
    char sysdir[256];
2732
    char fname[256];
2733
    char info[256];
2734
    char stmp[256];
2735
2736
    pcilib_dma_engine_t dmaid;
2737
    pcilib_dma_engine_status_t status;
2738
    
2739
    pos = strrchr(device, '/');
2740
    if (pos) ++pos;
2741
    else pos = device;
2742
    
2743
    snprintf(sysdir, 255, "/sys/class/fpga/%s", pos);
2744
2745
    dir = opendir(sysdir);
2746
    if (!dir) Error("Can't open directory (%s)", sysdir);
2747
    
104 by Suren A. Chilingaryan
Precisely estimate used buffers for C2S engines
2748
    printf("DMA Engine     Status      Total Size         Buffer Ring (1st used - 1st free)\n");
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
2749
    printf("--------------------------------------------------------------------------------\n");
2750
    while ((entry = readdir(dir)) != NULL) {
2751
	FILE *f;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
2752
	unsigned long use = 0;
197 by Suren A. Chilingaryan
Assume user kmem use
2753
//	unsigned long size = 0;
2754
//	unsigned long refs = 0;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
2755
	unsigned long mode = 0;
197 by Suren A. Chilingaryan
Assume user kmem use
2756
//	unsigned long hwref = 0;
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
2757
	
2758
	if (strncmp(entry->d_name, "kbuf", 4)) continue;
2759
	if (!isnumber(entry->d_name+4)) continue;
2760
	
2761
	snprintf(fname, 255, "%s/%s", sysdir, entry->d_name);
2762
	f = fopen(fname, "r");
2763
	if (!f) Error("Can't access file (%s)", fname);
2764
2765
	while(!feof(f)) {
236 by Suren A. Chilingaryan
Big redign of model structures
2766
	    if (!fgets(info, 256, f))
2767
		break;
2768
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
2769
	    if (!strncmp(info, "use:", 4)) use = strtoul(info+4, NULL, 16);
197 by Suren A. Chilingaryan
Assume user kmem use
2770
//	    if (!strncmp(info, "size:", 5)) size = strtoul(info+5, NULL, 10);
2771
//	    if (!strncmp(info, "refs:", 5)) refs = strtoul(info+5, NULL, 10);
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
2772
	    if (!strncmp(info, "mode:", 5)) mode = strtoul(info+5, NULL, 16);
197 by Suren A. Chilingaryan
Assume user kmem use
2773
//	    if (!strncmp(info, "hw ref:", 7)) hwref = strtoul(info+7, NULL, 10);
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
2774
	}
2775
	fclose(f);
2776
	
2777
	if ((mode&(KMEM_MODE_REUSABLE|KMEM_MODE_PERSISTENT|KMEM_MODE_COUNT)) == 0) continue;	// closed
2778
	if ((use >> 16) != PCILIB_KMEM_USE_DMA_RING) continue;
2779
2780
	if (use&0x80) {
2781
	    dmaid = pcilib_find_dma_by_addr(handle, PCILIB_DMA_TO_DEVICE, use&0x7F);
2782
	} else {
2783
	    dmaid = pcilib_find_dma_by_addr(handle, PCILIB_DMA_FROM_DEVICE, use&0x7F);
2784
	}
2785
	
2786
	if (dmaid == PCILIB_DMA_ENGINE_INVALID) continue;
2787
	
2788
	
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
2789
	printf("DMA%lu %s         ", use&0x7F, (use&0x80)?"S2C":"C2S");
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
2790
        err = pcilib_start_dma(handle, dmaid, 0);
2791
        if (err) {
2792
    	    printf("-- Wrong state, start is failed\n");
2793
	    continue;
2794
	}
2795
	
2796
	err = pcilib_get_dma_status(handle, dmaid, &status, 0, NULL);
2797
	if (err) {
2798
	    printf("-- Wrong state, failed to obtain status\n");
2799
	    pcilib_stop_dma(handle, dmaid, 0);
2800
	    continue;
2801
	}
2802
2803
	pcilib_stop_dma(handle, dmaid, 0);
2804
	
2805
	if (status.started) printf("S");
2806
	else printf(" ");
2807
	
2808
	if (status.ring_head == status.ring_tail) printf(" ");
2809
	else printf("D");
2810
2811
	printf("        ");
236 by Suren A. Chilingaryan
Big redign of model structures
2812
	printf("%10s", GetPrintSize(stmp, status.ring_size * status.buffer_size));
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
2813
	
2814
	printf("         ");
2815
	printf("%zu - %zu (of %zu)", status.ring_tail, status.ring_head, status.ring_size);
2816
2817
	printf("\n");
2818
	
2819
    }
2820
    closedir(dir);
2821
2822
    printf("--------------------------------------------------------------------------------\n");
2823
    printf("S - Started, D - Data in buffers\n");
2824
2825
    return 0;
2826
}
2827
236 by Suren A. Chilingaryan
Big redign of model structures
2828
int ListBuffers(pcilib_t *handle, const char *device, const pcilib_model_description_t *model_info, pcilib_dma_engine_addr_t dma, pcilib_dma_direction_t dma_direction) {
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
2829
    int err;
2830
    size_t i;
2831
    pcilib_dma_engine_t dmaid;
2832
    pcilib_dma_engine_status_t status;
2833
    pcilib_dma_buffer_status_t *buffer;
2834
    char stmp[256];
2835
2836
    dmaid = pcilib_find_dma_by_addr(handle, dma_direction, dma);
2837
    if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("The specified DMA engine is not found");
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
2838
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
2839
    err = pcilib_start_dma(handle, dmaid, 0);
2840
    if (err) Error("Error starting the specified DMA engine");
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
2841
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
2842
    err = pcilib_get_dma_status(handle, dmaid, &status, 0, NULL);
2843
    if (err) Error("Failed to obtain status of the specified DMA engine");
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
2844
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
2845
    buffer = (pcilib_dma_buffer_status_t*)malloc(status.ring_size*sizeof(pcilib_dma_buffer_status_t));
2846
    if (!buffer) Error("Failed to allocate memory for status buffer");
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
2847
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
2848
    err = pcilib_get_dma_status(handle, dmaid, &status, status.ring_size, buffer);
2849
    if (err) Error("Failed to obtain extended status of the specified DMA engine");
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
2850
2851
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
2852
    printf("Buffer      Status      Total Size         \n");
2853
    printf("--------------------------------------------------------------------------------\n");
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
2854
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
2855
    for (i = 0; i < status.ring_size; i++) {
2856
	printf("%8zu    ", i);
2857
        printf("%c%c %c%c ", buffer[i].used?'U':' ',  buffer[i].error?'E':' ', buffer[i].first?'F':' ', buffer[i].last?'L':' ');
236 by Suren A. Chilingaryan
Big redign of model structures
2858
	printf("%10s", GetPrintSize(stmp, buffer[i].size));
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
2859
	printf("\n");
2860
    }
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
2861
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
2862
    printf("--------------------------------------------------------------------------------\n");
2863
    printf("U - Used, E - Error, F - First block, L - Last Block\n");
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
2864
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
2865
    free(buffer);
2866
2867
    pcilib_stop_dma(handle, dmaid, 0);
2868
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
2869
    return 0;
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
2870
}
2871
236 by Suren A. Chilingaryan
Big redign of model structures
2872
int ReadBuffer(pcilib_t *handle, const char *device, const pcilib_model_description_t *model_info, pcilib_dma_engine_addr_t dma, pcilib_dma_direction_t dma_direction, size_t block, FILE *o) {
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
2873
    int err;
2874
    pcilib_dma_engine_t dmaid;
2875
    pcilib_dma_engine_status_t status;
2876
    pcilib_dma_buffer_status_t *buffer;
2877
    size_t size;
2878
2879
    dmaid = pcilib_find_dma_by_addr(handle, dma_direction, dma);
2880
    if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("The specified DMA engine is not found");
2881
2882
    err = pcilib_start_dma(handle, dmaid, 0);
2883
    if (err) Error("Error starting the specified DMA engine");
2884
    
2885
    err = pcilib_get_dma_status(handle, dmaid, &status, 0, NULL);
2886
    if (err) Error("Failed to obtain status of the specified DMA engine");
2887
    
2888
    buffer = (pcilib_dma_buffer_status_t*)malloc(status.ring_size*sizeof(pcilib_dma_buffer_status_t));
2889
    if (!buffer) Error("Failed to allocate memory for status buffer");
2890
2891
    err = pcilib_get_dma_status(handle, dmaid, &status, status.ring_size, buffer);
2892
    if (err) Error("Failed to obtain extended status of the specified DMA engine");
2893
2894
    if (block == (size_t)-1) {
2895
	// get current 
2896
    }
2897
2898
    size = buffer[block].size;
2899
2900
    free(buffer);
2901
2902
    pcilib_stop_dma(handle, dmaid, 0);
2903
2904
    return ReadKMEM(handle, device, ((dma&0x7F)|((dma_direction == PCILIB_DMA_TO_DEVICE)?0x80:0x00))|(PCILIB_KMEM_USE_DMA_PAGES<<16), block, size, o);
2905
}
2906
280 by Suren A. Chilingaryan
Integrate locking subsystem from Nicolas Zilio
2907
int ListLocks(pcilib_t *ctx, int verbose) {
2908
    int err;
2909
    pcilib_lock_id_t i;
2910
2911
    if (verbose)
290 by Suren A. Chilingaryan
In case of problematic locks report the error
2912
	printf("ID      Refs    Flags   Locked    Name\n");
280 by Suren A. Chilingaryan
Integrate locking subsystem from Nicolas Zilio
2913
    else
290 by Suren A. Chilingaryan
In case of problematic locks report the error
2914
	printf("ID      Refs    Flags    Name\n");
280 by Suren A. Chilingaryan
Integrate locking subsystem from Nicolas Zilio
2915
    printf("--------------------------------------------------------------------------------\n");
2916
2917
    for (i = 0; i < PCILIB_MAX_LOCKS; i++) {
2918
	pcilib_lock_t *lock = pcilib_get_lock_by_id(ctx, i);
2919
	const char *name = pcilib_lock_get_name(lock);
2920
	if (!name) break;
2921
	
2922
	pcilib_lock_flags_t flags = pcilib_lock_get_flags(lock);
2923
	size_t refs = pcilib_lock_get_refs(lock);
2924
	
2925
	printf("%4u    %4zu    ", i, refs);
2926
2927
	if (flags&PCILIB_LOCK_FLAG_PERSISTENT) printf("P");
2928
	else printf(" ");
2929
	printf("       ");
2930
	
2931
	if (verbose) {
2932
	    err = pcilib_lock_custom(lock, PCILIB_LOCK_FLAGS_DEFAULT, PCILIB_TIMEOUT_IMMEDIATE);
2933
	    switch (err) {
2934
	     case 0:
2935
	        pcilib_unlock(lock);
290 by Suren A. Chilingaryan
In case of problematic locks report the error
2936
	        printf("No        ");
280 by Suren A. Chilingaryan
Integrate locking subsystem from Nicolas Zilio
2937
	        break;
2938
	     case PCILIB_ERROR_TIMEOUT:
290 by Suren A. Chilingaryan
In case of problematic locks report the error
2939
	        printf("Yes       ");
280 by Suren A. Chilingaryan
Integrate locking subsystem from Nicolas Zilio
2940
	        break;
2941
	     default:
290 by Suren A. Chilingaryan
In case of problematic locks report the error
2942
	        printf("Err: %3i  ", err);
280 by Suren A. Chilingaryan
Integrate locking subsystem from Nicolas Zilio
2943
	    }
2944
	}
2945
	printf("%s\n", name);
2946
    }
2947
    printf("--------------------------------------------------------------------------------\n");
2948
    printf("P - Persistent\n");
2949
2950
    return 0;
2951
}
2952
2953
int FreeLocks(pcilib_t *handle, int force) {
2954
    return pcilib_destroy_all_locks(handle, force);
2955
}
2956
2957
int LockUnlock(pcilib_t *handle, const char *name, int do_lock, pcilib_timeout_t timeout) {
2958
    int err =  0;
2959
2960
    pcilib_lock_t *lock = pcilib_get_lock(handle, PCILIB_LOCK_FLAG_PERSISTENT, name);
2961
    if (!lock) Error("Error getting persistent lock %s", name);
2962
2963
    if (do_lock)
2964
	err = pcilib_lock_custom(lock, PCILIB_LOCK_FLAGS_DEFAULT, timeout);
2965
    else 
2966
	pcilib_unlock(lock);
2967
	
2968
    if (err) {
2969
	pcilib_return_lock(handle, PCILIB_LOCK_FLAGS_DEFAULT, lock);
2970
	switch (err) {
2971
	 case PCILIB_ERROR_TIMEOUT:
2972
	    printf("Timeout locking %s\n", name);
2973
	    break;
2974
	 default:
2975
	    Error("Error (%i) locking %s", err, name);
2976
	}
2977
    } else if (do_lock) {
2978
	pcilib_lock_ref(lock);
2979
	pcilib_return_lock(handle, PCILIB_LOCK_FLAGS_DEFAULT, lock);
2980
	printf("%s is locked\n", name);
2981
    } else {
2982
	pcilib_lock_unref(lock);
2983
	pcilib_return_lock(handle, PCILIB_LOCK_FLAGS_DEFAULT, lock);
2984
    }
2985
2986
    return err;
2987
}
2988
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
2989
236 by Suren A. Chilingaryan
Big redign of model structures
2990
int EnableIRQ(pcilib_t *handle, const pcilib_model_description_t *model_info, pcilib_irq_type_t irq_type) {
194 by Suren A. Chilingaryan
DMA-independent IRQ functions
2991
    int err;
2992
2993
    err = pcilib_enable_irq(handle, irq_type, 0);
2994
    if (err) {
2995
	if ((err != PCILIB_ERROR_NOTSUPPORTED)&&(err != PCILIB_ERROR_NOTAVAILABLE))
2996
	    Error("Error enabling IRQs");
2997
    }
2998
    
2999
    return err;
3000
}
3001
236 by Suren A. Chilingaryan
Big redign of model structures
3002
int DisableIRQ(pcilib_t *handle, const pcilib_model_description_t *model_info, pcilib_irq_type_t irq_type) {
194 by Suren A. Chilingaryan
DMA-independent IRQ functions
3003
    int err;
3004
    
3005
    err = pcilib_disable_irq(handle, 0);
3006
    if (err) {
3007
	if ((err != PCILIB_ERROR_NOTSUPPORTED)&&(err != PCILIB_ERROR_NOTAVAILABLE))
3008
	    Error("Error disabling IRQs");
3009
    }
3010
    
3011
    return err;
3012
}
3013
236 by Suren A. Chilingaryan
Big redign of model structures
3014
int AckIRQ(pcilib_t *handle, const pcilib_model_description_t *model_info, pcilib_irq_hw_source_t irq_source) {
194 by Suren A. Chilingaryan
DMA-independent IRQ functions
3015
    pcilib_clear_irq(handle, irq_source);
3016
    return 0;
3017
}
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
3018
236 by Suren A. Chilingaryan
Big redign of model structures
3019
int WaitIRQ(pcilib_t *handle, const pcilib_model_description_t *model_info, pcilib_irq_hw_source_t irq_source, pcilib_timeout_t timeout) {
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
3020
    int err;
3021
    size_t count;
3022
3023
    err = pcilib_wait_irq(handle, irq_source, timeout, &count);
3024
    if (err) {
3025
	if (err == PCILIB_ERROR_TIMEOUT) Error("Timeout waiting for IRQ");
3026
	else Error("Error waiting for IRQ");
3027
    }
3028
3029
    return 0;
3030
}
3031
3032
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3033
int main(int argc, char **argv) {
248 by Suren A. Chilingaryan
Set error in exit status if no data returned by DMA engine
3034
    int err = 0;
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
3035
    int i;
3036
    long itmp;
117 by Suren A. Chilingaryan
new event architecture, first trial
3037
    size_t ztmp;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3038
    unsigned char c;
3039
117 by Suren A. Chilingaryan
new event architecture, first trial
3040
    const char *stmp;
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
3041
    const char *num_offset;
56 by Suren A. Chilingaryan
Change cli parameters (reserve -t parameter for future use as timeout)
3042
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
3043
    int details = 0;
136 by Suren A. Chilingaryan
Verbose grabbing mode
3044
    int verbose = 0;
25 by Suren A. Chilingaryan
Support quiete mode to suppress warnings
3045
    int quiete = 0;
81 by Suren A. Chilingaryan
Support forceful clean-up of kernel memory
3046
    int force = 0;
191 by Suren A. Chilingaryan
Do not verify BAR writes by default
3047
    int verify = 0;
25 by Suren A. Chilingaryan
Support quiete mode to suppress warnings
3048
    
247 by Suren A. Chilingaryan
New error reporting public interface
3049
    pcilib_log_priority_t log_priority;
3050
    
236 by Suren A. Chilingaryan
Big redign of model structures
3051
    const char *model = NULL;
3052
    const pcilib_model_description_t *model_info;
240 by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines
3053
    const pcilib_dma_description_t *dma_info;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3054
    MODE mode = MODE_INVALID;
117 by Suren A. Chilingaryan
new event architecture, first trial
3055
    GRAB_MODE grab_mode = 0;
3056
    size_t trigger_time = 0;
3057
    size_t run_time = 0;
3058
    size_t buffer = 0;
135 by Suren A. Chilingaryan
Allow to configure the number of preprocessing threads
3059
    size_t threads = 1;
167 by Suren A. Chilingaryan
Respect --format parameter in cli
3060
    FORMAT format = FORMAT_DEFAULT;
117 by Suren A. Chilingaryan
new event architecture, first trial
3061
    PARTITION partition = PARTITION_UNKNOWN;
109 by Suren A. Chilingaryan
Improvements of DMA engine
3062
    FLAGS flags = 0;
196 by Suren A. Chilingaryan
Provide access to PCI configuration space in cli
3063
    const char *atype = NULL;
60 by Suren A. Chilingaryan
Fix compilation issues
3064
    const char *type = NULL;
44 by root
DMA engine initialization and basic intrastructure for DMA read/write
3065
    ACCESS_MODE amode = ACCESS_BAR;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3066
    const char *fpga_device = DEFAULT_FPGA_DEVICE;
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
3067
    pcilib_bar_t bar = PCILIB_BAR_DETECT;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3068
    const char *addr = NULL;
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
3069
    const char *reg = NULL;
315 by Suren A. Chilingaryan
Support properties of arbitrary type
3070
    const char *view = NULL;
313 by Suren A. Chilingaryan
Support reading of register views
3071
    const char *unit = NULL;
318 by Suren A. Chilingaryan
Support reading/writting register views by id
3072
    const char *attr = NULL;
7.1.2 by Suren A. Chilingaryan
Better handling of register banks
3073
    const char *bank = NULL;
14 by Suren A. Chilingaryan
Support memset operation
3074
    char **data = NULL;
15 by Suren A. Chilingaryan
Infrastructure for event API
3075
    const char *event = NULL;
117 by Suren A. Chilingaryan
new event architecture, first trial
3076
    const char *data_type = NULL;
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
3077
    const char *dma_channel = NULL;
80 by Suren A. Chilingaryan
List kernel buffers
3078
    const char *use = NULL;
280 by Suren A. Chilingaryan
Integrate locking subsystem from Nicolas Zilio
3079
    const char *lock = NULL;
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
3080
    const char *info_target = NULL;
315 by Suren A. Chilingaryan
Support properties of arbitrary type
3081
    const char *list_target = NULL;
192 by Suren A. Chilingaryan
Kernel memory allocation
3082
    size_t block = (size_t)-1;
194 by Suren A. Chilingaryan
DMA-independent IRQ functions
3083
    pcilib_irq_type_t irq_type = PCILIB_IRQ_TYPE_ALL;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
3084
    pcilib_irq_hw_source_t irq_source =  PCILIB_IRQ_SOURCE_DEFAULT;
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
3085
    pcilib_dma_direction_t dma_direction = PCILIB_DMA_BIDIRECTIONAL;
197 by Suren A. Chilingaryan
Assume user kmem use
3086
    pcilib_kmem_use_t useid = 0;
14 by Suren A. Chilingaryan
Support memset operation
3087
    
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
3088
    pcilib_dma_engine_addr_t dma = PCILIB_DMA_ENGINE_ADDR_INVALID;
120 by Suren A. Chilingaryan
Print proper addresses for register range read/writes
3089
    long addr_shift = 0;
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
3090
    uintptr_t start = -1;
192 by Suren A. Chilingaryan
Kernel memory allocation
3091
    size_t block_size = 0;
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
3092
    size_t size = 1;
3093
    access_t access = 4;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
3094
//    int skip = 0;
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
3095
    int endianess = 0;
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
3096
    size_t timeout = 0;
192 by Suren A. Chilingaryan
Kernel memory allocation
3097
    size_t alignment = 0;
15 by Suren A. Chilingaryan
Infrastructure for event API
3098
    const char *output = NULL;
87 by Suren A. Chilingaryan
Support writting output to file
3099
    FILE *ofile = NULL;
68 by Suren A. Chilingaryan
Support iterations argument and fix interpretation of size argument for benchmarking
3100
    size_t iterations = BENCHMARK_ITERATIONS;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3101
337 by Suren A. Chilingaryan
Driver versioning
3102
    unsigned long dma_mask = 0;
338 by Suren A. Chilingaryan
Support setting payload size
3103
    unsigned long pcie_mps = 0;
337 by Suren A. Chilingaryan
Driver versioning
3104
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
3105
    pcilib_t *handle;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
3106
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
3107
    int size_set = 0;
109 by Suren A. Chilingaryan
Improvements of DMA engine
3108
    int timeout_set = 0;
197 by Suren A. Chilingaryan
Assume user kmem use
3109
//    int run_time_set = 0;
3110
264 by Suren A. Chilingaryan
In pcitool try tocquire real-time performance for DMA and grabbing operations
3111
    struct sched_param sched_param = {0};
3112
101 by root
Remove short option for benchmark in cli
3113
    while ((c = getopt_long(argc, argv, "hqilr::w::g::d:m:t:b:a:s:e:o:", long_options, NULL)) != (unsigned char)-1) {
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3114
	extern int optind;
3115
	switch (c) {
3116
	    case OPT_HELP:
3117
		Usage(argc, argv, NULL);
3118
	    break;
337 by Suren A. Chilingaryan
Driver versioning
3119
	    case OPT_VERSION:
3120
		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
3121
		mode = MODE_VERSION;
3122
	    break;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3123
	    case OPT_INFO:
3124
		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
3125
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
3126
		if (optarg) info_target = optarg;
3127
		else if ((optind < argc)&&(argv[optind][0] != '-')) info_target = argv[optind++];
3128
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3129
		mode = MODE_INFO;
3130
	    break;
3131
	    case OPT_LIST:
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
3132
		if (mode == MODE_LIST) details++;
3133
		else if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3134
315 by Suren A. Chilingaryan
Support properties of arbitrary type
3135
		if (optarg) list_target = optarg;
3136
		else if ((optind < argc)&&(argv[optind][0] != '-')) list_target = argv[optind++];
3137
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3138
		mode = MODE_LIST;
3139
	    break;
15 by Suren A. Chilingaryan
Infrastructure for event API
3140
	    case OPT_RESET:
3141
		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
3142
3143
		mode = MODE_RESET;
3144
	    break;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3145
	    case OPT_BENCHMARK:
3146
		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
3147
3148
		mode = MODE_BENCHMARK;
45 by root
North West Logick DMA implementation
3149
3150
		if (optarg) addr = optarg;
3151
		else if ((optind < argc)&&(argv[optind][0] != '-')) addr = argv[optind++];
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3152
	    break;
3153
	    case OPT_READ:
3154
		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
3155
		
3156
		mode = MODE_READ;
3157
		if (optarg) addr = optarg;
3158
		else if ((optind < argc)&&(argv[optind][0] != '-')) addr = argv[optind++];
3159
	    break;
3160
	    case OPT_WRITE:
3161
		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
3162
3163
		mode = MODE_WRITE;
3164
		if (optarg) addr = optarg;
3165
		else if ((optind < argc)&&(argv[optind][0] != '-')) addr = argv[optind++];
3166
	    break;
15 by Suren A. Chilingaryan
Infrastructure for event API
3167
	    case OPT_GRAB:
117 by Suren A. Chilingaryan
new event architecture, first trial
3168
		if ((mode != MODE_INVALID)&&((mode != MODE_GRAB)||(grab_mode&GRAB_MODE_GRAB))) Usage(argc, argv, "Multiple operations are not supported");
3169
3170
		mode = MODE_GRAB;
3171
		grab_mode |= GRAB_MODE_GRAB;
3172
		
3173
		stmp = NULL;
3174
		if (optarg) stmp = optarg;
3175
		else if ((optind < argc)&&(argv[optind][0] != '-')) stmp = argv[optind++];
3176
3177
		if (stmp) {
3178
		    if ((event)&&(strcasecmp(stmp,event))) Usage(argc, argv, "Redefinition of considered event");
3179
		    event = stmp;
3180
		}
3181
	    break;
3182
	    case OPT_TRIGGER:
3183
		if ((mode != MODE_INVALID)&&((mode != MODE_GRAB)||(grab_mode&GRAB_MODE_TRIGGER))) Usage(argc, argv, "Multiple operations are not supported");
3184
3185
		mode = MODE_GRAB;
3186
		grab_mode |= GRAB_MODE_TRIGGER;
3187
		
3188
		stmp = NULL;
3189
		if (optarg) stmp = optarg;
3190
		else if ((optind < argc)&&(argv[optind][0] != '-')) stmp = argv[optind++];
3191
3192
		if (stmp) {
3193
		    if ((event)&&(strcasecmp(stmp,event))) Usage(argc, argv, "Redefinition of considered event");
3194
		    event = stmp;
3195
		}
15 by Suren A. Chilingaryan
Infrastructure for event API
3196
	    break;
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
3197
	    case OPT_LIST_DMA:
3198
		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
3199
		
3200
		mode = MODE_LIST_DMA;
3201
	    break;
3202
	    case OPT_LIST_DMA_BUFFERS:
3203
		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
3204
		
3205
		mode = MODE_LIST_DMA_BUFFERS;
3206
		dma_channel = optarg;
3207
	    break;
3208
	    case OPT_READ_DMA_BUFFER:
3209
		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
3210
		
3211
		mode = MODE_READ_DMA_BUFFER;
3212
3213
		num_offset = strchr(optarg, ':');
3214
3215
		if (num_offset) {
3216
		    if (sscanf(num_offset + 1, "%zu", &block) != 1)
3217
			Usage(argc, argv, "Invalid buffer is specified (%s)", num_offset + 1);
3218
3219
		    *(char*)num_offset = 0;
3220
		} else block = (size_t)-1;
3221
		
3222
		dma_channel = optarg;
3223
	    break;
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
3224
	    case OPT_START_DMA:
3225
		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
3226
		
3227
		mode = MODE_START_DMA;
3228
		if (optarg) dma_channel = optarg;
3229
		else if ((optind < argc)&&(argv[optind][0] != '-')) dma_channel = argv[optind++];
3230
	    break;
3231
	    case OPT_STOP_DMA:
3232
		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
3233
		
3234
		mode = MODE_STOP_DMA;
3235
		if (optarg) dma_channel = optarg;
3236
		else if ((optind < argc)&&(argv[optind][0] != '-')) dma_channel = argv[optind++];
3237
	    break;
194 by Suren A. Chilingaryan
DMA-independent IRQ functions
3238
	    case OPT_ENABLE_IRQ:
3239
		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
3240
		
3241
		mode = MODE_ENABLE_IRQ;
3242
		if (optarg) num_offset = optarg;
3243
		else if ((optind < argc)&&(argv[optind][0] != '-'))  num_offset = argv[optind++];
3244
		else num_offset = NULL;
3245
		
3246
		if (num_offset) {
3247
		    if ((!isnumber(num_offset))||(sscanf(num_offset, "%li", &itmp) != 1))
3248
			Usage(argc, argv, "Invalid IRQ source is specified (%s)", num_offset);
3249
3250
		    irq_type = itmp;
3251
		}
3252
	    break;
3253
	    case OPT_DISABLE_IRQ:
3254
		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
3255
		
3256
		mode = MODE_DISABLE_IRQ;
3257
		if (optarg) num_offset = optarg;
3258
		else if ((optind < argc)&&(argv[optind][0] != '-'))  num_offset = argv[optind++];
3259
		else num_offset = NULL;
3260
		
3261
		if (num_offset) {
3262
		    if ((!isnumber(num_offset))||(sscanf(num_offset, "%li", &itmp) != 1))
3263
			Usage(argc, argv, "Invalid IRQ source is specified (%s)", num_offset);
3264
3265
		    irq_type = itmp;
3266
		}
3267
	    break;
3268
	    case OPT_ACK_IRQ:
3269
		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
3270
		
3271
		mode = MODE_ACK_IRQ;
3272
		if (optarg) num_offset = optarg;
3273
		else if ((optind < argc)&&(argv[optind][0] != '-'))  num_offset = argv[optind++];
3274
		else num_offset = NULL;
3275
		
3276
		if (num_offset) {
3277
		    if ((!isnumber(num_offset))||(sscanf(num_offset, "%li", &itmp) != 1))
3278
			Usage(argc, argv, "Invalid IRQ source is specified (%s)", num_offset);
3279
3280
		    irq_source = itmp;
3281
		}
3282
	    break;
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
3283
	    case OPT_WAIT_IRQ:
3284
		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
3285
		
3286
		mode = MODE_WAIT_IRQ;
3287
		if (optarg) num_offset = optarg;
3288
		else if ((optind < argc)&&(argv[optind][0] != '-'))  num_offset = argv[optind++];
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
3289
		else num_offset = NULL;
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
3290
		
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
3291
		if (num_offset) {
3292
		    if ((!isnumber(num_offset))||(sscanf(num_offset, "%li", &itmp) != 1))
3293
			Usage(argc, argv, "Invalid IRQ source is specified (%s)", num_offset);
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
3294
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
3295
		    irq_source = itmp;
3296
		}
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
3297
	    break;
337 by Suren A. Chilingaryan
Driver versioning
3298
	    case OPT_SET_DMASK:
3299
		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
3300
		mode = MODE_SET_DMASK;
3301
3302
		if ((!isnumber(optarg))||(sscanf(optarg, "%lu", &dma_mask) != 1)||(dma_mask<24)||(dma_mask>64))
3303
			Usage(argc, argv, "Invalid DMA mask is specified (%s)", optarg);
3304
	    break;
338 by Suren A. Chilingaryan
Support setting payload size
3305
	    case OPT_SET_MPS:
3306
		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
3307
		mode = MODE_SET_MPS;
3308
3309
		if ((!isnumber(optarg))||(sscanf(optarg, "%lu", &pcie_mps) != 1)||(pcie_mps<128)||(pcie_mps>2048))
3310
			Usage(argc, argv, "Invalid payload size is specified (%s)", optarg);
3311
	    break;
80 by Suren A. Chilingaryan
List kernel buffers
3312
	    case OPT_LIST_KMEM:
3313
		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
3314
		mode = MODE_LIST_KMEM;
192 by Suren A. Chilingaryan
Kernel memory allocation
3315
		
3316
		if (optarg) use = optarg;
3317
		else if ((optind < argc)&&(argv[optind][0] != '-'))  use = argv[optind++];
194 by Suren A. Chilingaryan
DMA-independent IRQ functions
3318
		else use = NULL;
192 by Suren A. Chilingaryan
Kernel memory allocation
3319
		
3320
		if (use) {
3321
		    num_offset = strchr(use, ':');
3322
3323
		    if (num_offset) {
3324
			if (sscanf(num_offset + 1, "%zu", &block) != 1)
3325
			    Usage(argc, argv, "Invalid block number is specified (%s)", num_offset + 1);
3326
3327
			*(char*)num_offset = 0;
3328
		    }
3329
		}
80 by Suren A. Chilingaryan
List kernel buffers
3330
	    break;
100 by root
Support exporting data from kernel buffers
3331
	    case OPT_READ_KMEM:
3332
		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
3333
		mode = MODE_READ_KMEM;
276 by Suren A. Chilingaryan
Execute all operations on kernel_memory using plain pci model to avoid extra references
3334
		if (!model) model = "pci";
100 by root
Support exporting data from kernel buffers
3335
3336
		num_offset = strchr(optarg, ':');
3337
3338
		if (num_offset) {
3339
		    if (sscanf(num_offset + 1, "%zu", &block) != 1)
3340
			Usage(argc, argv, "Invalid block number is specified (%s)", num_offset + 1);
3341
3342
		    *(char*)num_offset = 0;
3343
		}
3344
		
197 by Suren A. Chilingaryan
Assume user kmem use
3345
		use = optarg;
3346
		useid = ParseUse(use);
3347
    	    break;
192 by Suren A. Chilingaryan
Kernel memory allocation
3348
	    case OPT_ALLOC_KMEM:
3349
		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
3350
		mode = MODE_ALLOC_KMEM;
276 by Suren A. Chilingaryan
Execute all operations on kernel_memory using plain pci model to avoid extra references
3351
		model = "pci";
192 by Suren A. Chilingaryan
Kernel memory allocation
3352
3353
		if (optarg) use = optarg;
3354
		else if ((optind < argc)&&(argv[optind][0] != '-')) use = argv[optind++];
3355
	    break;
80 by Suren A. Chilingaryan
List kernel buffers
3356
	    case OPT_FREE_KMEM:
3357
		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
3358
		mode = MODE_FREE_KMEM;
276 by Suren A. Chilingaryan
Execute all operations on kernel_memory using plain pci model to avoid extra references
3359
		if (!model) model = "pci";
80 by Suren A. Chilingaryan
List kernel buffers
3360
3361
		if (optarg) use = optarg;
3362
		else if ((optind < argc)&&(argv[optind][0] != '-')) use = argv[optind++];
3363
	    break;
280 by Suren A. Chilingaryan
Integrate locking subsystem from Nicolas Zilio
3364
	    case OPT_LIST_LOCKS:
3365
		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
3366
		mode = MODE_LIST_LOCKS;
3367
	    break;
3368
	    case OPT_FREE_LOCKS:
3369
		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
3370
		mode = MODE_FREE_LOCKS;
3371
		model = "maintenance";
3372
	    break;
3373
	    case OPT_LOCK:
3374
		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
3375
		mode = MODE_LOCK;
3376
		lock = optarg;
3377
	    break;
3378
	    case OPT_UNLOCK:
3379
		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
3380
		mode = MODE_UNLOCK;
3381
		lock = optarg;
3382
	    break;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3383
	    case OPT_DEVICE:
3384
		fpga_device = optarg;
3385
	    break;
3386
	    case OPT_MODEL:
236 by Suren A. Chilingaryan
Big redign of model structures
3387
		model = optarg;
3388
/*		if (!strcasecmp(optarg, "pci")) model = PCILIB_MODEL_PCI;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3389
		else if (!strcasecmp(optarg, "ipecamera")) model = PCILIB_MODEL_IPECAMERA;
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
3390
		else if (!strcasecmp(optarg, "kapture")) model = PCILIB_MODEL_KAPTURE;
236 by Suren A. Chilingaryan
Big redign of model structures
3391
		else Usage(argc, argv, "Invalid memory model (%s) is specified", optarg);*/
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
3392
	    break;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3393
	    case OPT_BAR:
7.1.2 by Suren A. Chilingaryan
Better handling of register banks
3394
		bank = optarg;
3395
//		if ((sscanf(optarg,"%li", &itmp) != 1)||(itmp < 0)||(itmp >= PCILIB_MAX_BANKS)) Usage(argc, argv, "Invalid data bank (%s) is specified", optarg);
3396
//		else bar = itmp;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3397
	    break;
192 by Suren A. Chilingaryan
Kernel memory allocation
3398
	    case OPT_ALIGNMENT:
3399
		if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &alignment) != 1)) {
3400
		    Usage(argc, argv, "Invalid alignment is specified (%s)", optarg);
3401
		}
3402
	    break;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3403
	    case OPT_ACCESS:
56 by Suren A. Chilingaryan
Change cli parameters (reserve -t parameter for future use as timeout)
3404
		if (!strncasecmp(optarg, "fifo", 4)) {
196 by Suren A. Chilingaryan
Provide access to PCI configuration space in cli
3405
		    atype = "fifo";
56 by Suren A. Chilingaryan
Change cli parameters (reserve -t parameter for future use as timeout)
3406
		    num_offset = optarg + 4;
3407
		    amode = ACCESS_FIFO;
3408
		} else if (!strncasecmp(optarg, "dma", 3)) {
196 by Suren A. Chilingaryan
Provide access to PCI configuration space in cli
3409
		    atype = "dma";
56 by Suren A. Chilingaryan
Change cli parameters (reserve -t parameter for future use as timeout)
3410
		    num_offset = optarg + 3;
3411
		    amode = ACCESS_DMA;
3412
		} else if (!strncasecmp(optarg, "bar", 3)) {
196 by Suren A. Chilingaryan
Provide access to PCI configuration space in cli
3413
		    atype = "plain";
56 by Suren A. Chilingaryan
Change cli parameters (reserve -t parameter for future use as timeout)
3414
		    num_offset = optarg + 3;
3415
		    amode = ACCESS_BAR;
196 by Suren A. Chilingaryan
Provide access to PCI configuration space in cli
3416
		} else if (!strncasecmp(optarg, "config", 6)) {
3417
		    atype = "config";
3418
		    num_offset = optarg + 6;
3419
		    amode = ACCESS_CONFIG;
56 by Suren A. Chilingaryan
Change cli parameters (reserve -t parameter for future use as timeout)
3420
		} else if (!strncasecmp(optarg, "plain", 5)) {
196 by Suren A. Chilingaryan
Provide access to PCI configuration space in cli
3421
		    atype = "plain";
56 by Suren A. Chilingaryan
Change cli parameters (reserve -t parameter for future use as timeout)
3422
		    num_offset = optarg + 5;
3423
		    amode = ACCESS_BAR;
3424
		} else {
3425
		    num_offset = optarg;
3426
		}
3427
3428
		if (*num_offset) {
3429
		    if ((!isnumber(num_offset))||(sscanf(num_offset, "%li", &itmp) != 1))
3430
			Usage(argc, argv, "Invalid access type (%s) is specified", optarg);
3431
3432
	    	    switch (itmp) {
3433
			case 8: access = 1; break;
3434
			case 16: access = 2; break;
3435
			case 32: access = 4; break;
3436
			case 64: access = 8; break;
3437
			default: Usage(argc, argv, "Invalid data width (%s) is specified", num_offset);
3438
		    }	
3439
		}
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3440
	    break;
3441
	    case OPT_SIZE:
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
3442
		if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &size) != 1)) {
117 by Suren A. Chilingaryan
new event architecture, first trial
3443
		    if (strcasecmp(optarg, "unlimited"))
3444
			Usage(argc, argv, "Invalid size is specified (%s)", optarg);
3445
		    else
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
3446
			size = 0;//(size_t)-1;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
3447
		}
117 by Suren A. Chilingaryan
new event architecture, first trial
3448
			
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
3449
		size_set = 1;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3450
	    break;
192 by Suren A. Chilingaryan
Kernel memory allocation
3451
	    case OPT_BLOCK_SIZE:
3452
		if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &block_size) != 1)) {
3453
		    Usage(argc, argv, "Invalid size is specified (%s)", optarg);
3454
		}
3455
	    break;
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
3456
	    case OPT_ENDIANESS:
3457
		if ((*optarg == 'b')||(*optarg == 'B')) {
3458
		    if (ntohs(1) == 1) endianess = 0;
3459
		    else endianess = 1;
3460
		} else if ((*optarg == 'l')||(*optarg == 'L')) {
3461
		    if (ntohs(1) == 1) endianess = 1;
3462
		    else endianess = 0;
3463
		} else Usage(argc, argv, "Invalid endianess is specified (%s)", optarg);
3464
		
3465
	    break;
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
3466
	    case OPT_TIMEOUT:
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
3467
		if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &timeout) != 1)) {
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
3468
		    if (strcasecmp(optarg, "unlimited"))
3469
			Usage(argc, argv, "Invalid timeout is specified (%s)", optarg);
3470
		    else
3471
			timeout = PCILIB_TIMEOUT_INFINITE;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
3472
		}
109 by Suren A. Chilingaryan
Improvements of DMA engine
3473
		timeout_set = 1;
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
3474
	    break;
15 by Suren A. Chilingaryan
Infrastructure for event API
3475
	    case OPT_OUTPUT:
3476
		output = optarg;
3477
	    break;
68 by Suren A. Chilingaryan
Support iterations argument and fix interpretation of size argument for benchmarking
3478
	    case OPT_ITERATIONS:
3479
		if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &iterations) != 1))
3480
		    Usage(argc, argv, "Invalid number of iterations is specified (%s)", optarg);
3481
	    break;
117 by Suren A. Chilingaryan
new event architecture, first trial
3482
	    case OPT_EVENT:
3483
		event = optarg;
3484
	    break;
192 by Suren A. Chilingaryan
Kernel memory allocation
3485
	    case OPT_TYPE:
3486
		type = optarg;
3487
	    break;
117 by Suren A. Chilingaryan
new event architecture, first trial
3488
	    case OPT_DATA_TYPE:
3489
		data_type = optarg;
3490
	    break;
3491
	    case OPT_RUN_TIME:
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
3492
		if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &run_time) != 1)) {
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
3493
		    if (strcasecmp(optarg, "unlimited"))
3494
			Usage(argc, argv, "Invalid run-time is specified (%s)", optarg);
3495
		    else
3496
			run_time = 0;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
3497
		}
197 by Suren A. Chilingaryan
Assume user kmem use
3498
//		run_time_set = 1;
117 by Suren A. Chilingaryan
new event architecture, first trial
3499
	    break;
3500
	    case OPT_TRIGGER_TIME:
3501
		if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &trigger_time) != 1))
3502
		    Usage(argc, argv, "Invalid trigger-time is specified (%s)", optarg);
3503
	    break;	    
3504
	    case OPT_TRIGGER_RATE:
3505
		if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &ztmp) != 1))
3506
		    Usage(argc, argv, "Invalid trigger-rate is specified (%s)", optarg);
3507
		    
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
3508
		    trigger_time = (1000000 / ztmp) + ((1000000 % ztmp)?1:0);
117 by Suren A. Chilingaryan
new event architecture, first trial
3509
	    break;
3510
	    case OPT_BUFFER:
3511
		if (optarg) num_offset = optarg;
3512
		else if ((optind < argc)&&(argv[optind][0] != '-')) num_offset = argv[optind++];
3513
		else num_offset = NULL;
3514
		
3515
		if (num_offset) {
3516
		    if ((!isnumber(num_offset))||(sscanf(num_offset, "%zu", &buffer) != 1))
3517
			Usage(argc, argv, "Invalid buffer size is specified (%s)", num_offset);
3518
		    buffer *= 1024 * 1024;
3519
		} else {
3520
		    buffer = get_free_memory();
324 by Suren A. Chilingaryan
Documentation update
3521
		    if (buffer < 256) Error("Not enough free memory (%lz MiB) for buffering", buffer / 1024 / 1024);
117 by Suren A. Chilingaryan
new event architecture, first trial
3522
		    
3523
		    buffer -= 128 + buffer/16;
3524
		}
3525
	    break;	   
135 by Suren A. Chilingaryan
Allow to configure the number of preprocessing threads
3526
	    case OPT_THREADS:
3527
		if (optarg) num_offset = optarg;
3528
		else if ((optind < argc)&&(argv[optind][0] != '-')) num_offset = argv[optind++];
3529
		else num_offset = NULL;
3530
		
3531
		if (num_offset) {
3532
		    if ((!isnumber(num_offset))||(sscanf(num_offset, "%zu", &threads) != 1))
3533
			Usage(argc, argv, "Invalid threads number is specified (%s)", num_offset);
3534
		} else {
3535
		    threads = 0;
3536
		}
3537
	    break;	   
117 by Suren A. Chilingaryan
new event architecture, first trial
3538
	    case OPT_FORMAT:
167 by Suren A. Chilingaryan
Respect --format parameter in cli
3539
		if (!strcasecmp(optarg, "raw")) format =  FORMAT_RAW;
3540
		else if (!strcasecmp(optarg, "add_header")) format =  FORMAT_HEADER;
136 by Suren A. Chilingaryan
Verbose grabbing mode
3541
//		else if (!strcasecmp(optarg, "ringfs")) format =  FORMAT_RINGFS;
167 by Suren A. Chilingaryan
Respect --format parameter in cli
3542
		else if (strcasecmp(optarg, "default")) Error("Invalid format (%s) is specified", optarg);
117 by Suren A. Chilingaryan
new event architecture, first trial
3543
	    break; 
25 by Suren A. Chilingaryan
Support quiete mode to suppress warnings
3544
	    case OPT_QUIETE:
3545
		quiete = 1;
150 by Suren A. Chilingaryan
Quite mode
3546
		verbose = -1;
25 by Suren A. Chilingaryan
Support quiete mode to suppress warnings
3547
	    break;
136 by Suren A. Chilingaryan
Verbose grabbing mode
3548
	    case OPT_VERBOSE:
3549
		if (optarg) num_offset = optarg;
3550
		else if ((optind < argc)&&(argv[optind][0] != '-'))  num_offset = argv[optind++];
3551
		else num_offset = NULL;
3552
		
3553
		if (num_offset) {
3554
		    if ((!isnumber(num_offset))||(sscanf(num_offset, "%i", &verbose) != 1))
3555
			Usage(argc, argv, "Invalid verbosity level is specified (%s)", num_offset);
3556
		} else {
3557
		    verbose = 1;
3558
		}
3559
	    break;
81 by Suren A. Chilingaryan
Support forceful clean-up of kernel memory
3560
	    case OPT_FORCE:
3561
		force = 1;
3562
	    break;
191 by Suren A. Chilingaryan
Do not verify BAR writes by default
3563
	    case OPT_VERIFY:
3564
		verify = 1;
3565
	    break;
109 by Suren A. Chilingaryan
Improvements of DMA engine
3566
	    case OPT_MULTIPACKET:
3567
		flags |= FLAG_MULTIPACKET;
3568
	    break;
3569
	    case OPT_WAIT:
3570
		flags |= FLAG_WAIT;
3571
	    break;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3572
	    default:
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
3573
		Usage(argc, argv, "Unknown option (%s) with argument (%s)", optarg?argv[optind-2]:argv[optind-1], optarg?optarg:"(null)");
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3574
	}
3575
    }
3576
3577
    if (mode == MODE_INVALID) {
3578
	if (argc > 1) Usage(argc, argv, "Operation is not specified");
3579
	else Usage(argc, argv, NULL);
3580
    }
3581
247 by Suren A. Chilingaryan
New error reporting public interface
3582
    if (verbose) log_priority = PCILIB_LOG_INFO;
3583
    else if (quiete) log_priority = PCILIB_LOG_ERROR;
3584
    else log_priority = PCILIB_LOG_WARNING;
3585
3586
    pcilib_set_logger(log_priority, &LogError, NULL);
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3587
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
3588
    handle = pcilib_open(fpga_device, model);
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3589
    if (handle < 0) Error("Failed to open FPGA device: %s", fpga_device);
3590
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
3591
    model_info = pcilib_get_model_description(handle);
240 by Suren A. Chilingaryan
More structural changes to get ready for stand-alone event engines
3592
    dma_info = pcilib_get_dma_description(handle);
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3593
    switch (mode) {
3594
     case MODE_WRITE:
14 by Suren A. Chilingaryan
Support memset operation
3595
        if (((argc - optind) == 1)&&(*argv[optind] == '*')) {
3596
    	    int vallen = strlen(argv[optind]);
15 by Suren A. Chilingaryan
Infrastructure for event API
3597
    	    if (vallen > 1) {
3598
		data = (char**)malloc(size * (vallen + sizeof(char*)));
3599
		if (!data) Error("Error allocating memory for data array");
3600
3601
		for (i = 0; i < size; i++) {
3602
		    data[i] = ((char*)data) + size * sizeof(char*) + i * vallen;
3603
		    strcpy(data[i], argv[optind] + 1);
3604
		}
3605
	    } else {
3606
		data = (char**)malloc(size * (9 + sizeof(char*)));
3607
		if (!data) Error("Error allocating memory for data array");
3608
		
3609
		for (i = 0; i < size; i++) {
3610
		    data[i] = ((char*)data) + size * sizeof(char*) + i * 9;
3611
		    sprintf(data[i], "%x", i);
3612
		}
14 by Suren A. Chilingaryan
Support memset operation
3613
	    }
3614
        } else if ((argc - optind) == size) data = argv + optind;
3615
        else Usage(argc, argv, "The %i data values is specified, but %i required", argc - optind, size);
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3616
     case MODE_READ:
3617
        if (!addr) {
303 by Suren A. Chilingaryan
Initial integration of XML support
3618
	    if (((!dma_info)||(!dma_info->api))&&(!model_info->api)&&(!handle->num_reg)) {
236 by Suren A. Chilingaryan
Big redign of model structures
3619
//	    if (model == PCILIB_MODEL_PCI) {
196 by Suren A. Chilingaryan
Provide access to PCI configuration space in cli
3620
		if ((amode != ACCESS_DMA)&&(amode != ACCESS_CONFIG)) 
3621
		    Usage(argc, argv, "The address is not specified");
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3622
	    } else ++mode;
3623
	}
3624
     break;
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
3625
     case MODE_START_DMA:
3626
     case MODE_STOP_DMA:
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
3627
     case MODE_LIST_DMA_BUFFERS:
3628
     case MODE_READ_DMA_BUFFER:
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
3629
        if ((dma_channel)&&(*dma_channel)) {
3630
	    itmp = strlen(dma_channel) - 1;
3631
	    if (dma_channel[itmp] == 'r') dma_direction = PCILIB_DMA_FROM_DEVICE;
3632
	    else if (dma_channel[itmp] == 'w') dma_direction = PCILIB_DMA_TO_DEVICE;
3633
3634
	    if (dma_direction != PCILIB_DMA_BIDIRECTIONAL) itmp--;
3635
	    
3636
	    if (strncmp(dma_channel, "dma", 3)) num_offset = dma_channel;
3637
	    else {
3638
		num_offset = dma_channel + 3;
3639
		itmp -= 3;
3640
	    }
315 by Suren A. Chilingaryan
Support properties of arbitrary type
3641
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
3642
	    if (bank) {
3643
		if (strncmp(num_offset, bank, itmp)) Usage(argc, argv, "Conflicting DMA channels are specified in mode parameter (%s) and bank parameter (%s)", dma_channel, bank);
3644
	    }
315 by Suren A. Chilingaryan
Support properties of arbitrary type
3645
 
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
3646
	    if (!isnumber_n(num_offset, itmp))
3647
		 Usage(argc, argv, "Invalid DMA channel (%s) is specified", dma_channel);
3648
3649
	    dma = atoi(num_offset);
3650
	}
3651
     break;
315 by Suren A. Chilingaryan
Support properties of arbitrary type
3652
     case MODE_LIST:
3653
	if (bank&&list_target) {
3654
	    if (strcmp(list_target, bank)) 
3655
		Usage(argc, argv, "Conflicting banks are specified in list parameter (%s) and bank parameter (%s)", list_target, bank);
3656
	} else if (bank) {
3657
	    list_target = bank;
3658
	}
3659
     break;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3660
     default:
3661
        if (argc > optind) Usage(argc, argv, "Invalid non-option parameters are supplied");
3662
    }
3663
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
3664
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3665
    if (addr) {
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
3666
	if ((!strncmp(addr, "dma", 3))&&((addr[3]==0)||isnumber(addr+3))) {
196 by Suren A. Chilingaryan
Provide access to PCI configuration space in cli
3667
	    if ((atype)&&(amode != ACCESS_DMA)) Usage(argc, argv, "Conflicting access modes, the DMA read is requested, but access type is (%s)", type);
51 by Suren A. Chilingaryan
Fix segmentation failure in DMA access mode
3668
	    if (bank) {
3669
		if ((addr[3] != 0)&&(strcmp(addr + 3, bank))) Usage(argc, argv, "Conflicting DMA channels are specified in read parameter (%s) and bank parameter (%s)", addr + 3, bank);
3670
	    } else {
3671
		if (addr[3] == 0) Usage(argc, argv, "The DMA channel is not specified");
3672
	    }
44 by root
DMA engine initialization and basic intrastructure for DMA read/write
3673
	    dma = atoi(addr + 3);
3674
	    amode = ACCESS_DMA;
196 by Suren A. Chilingaryan
Provide access to PCI configuration space in cli
3675
	    addr = NULL;
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
3676
	} else if ((!strncmp(addr, "bar", 3))&&((addr[3]==0)||isnumber(addr+3))) {
196 by Suren A. Chilingaryan
Provide access to PCI configuration space in cli
3677
	    if ((atype)&&(amode != ACCESS_BAR)) Usage(argc, argv, "Conflicting access modes, the plain PCI read is requested, but access type is (%s)", type);
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
3678
	    if ((addr[3] != 0)&&(strcmp(addr + 3, bank))) Usage(argc, argv, "Conflicting PCI bars are specified in read parameter (%s) and bank parameter (%s)", addr + 3, bank);
45 by root
North West Logick DMA implementation
3679
	    bar = atoi(addr + 3);
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
3680
	    amode = ACCESS_BAR;
196 by Suren A. Chilingaryan
Provide access to PCI configuration space in cli
3681
	    addr = NULL;
3682
	} else if (!strcmp(addr, "config")) {
3683
	    if ((atype)&&(amode != ACCESS_CONFIG)) Usage(argc, argv, "Conflicting access modes, the read of PCI configurataion space is requested, but access type is (%s)", type);
3684
	    amode = ACCESS_CONFIG;
3685
	    addr = NULL;
44 by root
DMA engine initialization and basic intrastructure for DMA read/write
3686
	} else if ((isxnumber(addr))&&(sscanf(addr, "%lx", &start) == 1)) {
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3687
		// check if the address in the register range
236 by Suren A. Chilingaryan
Big redign of model structures
3688
	    const pcilib_register_range_t *ranges =  model_info->ranges;
37 by Suren A. Chilingaryan
Do not crash if model is not defined
3689
	    
3690
	    if (ranges) {
3691
		for (i = 0; ranges[i].start != ranges[i].end; i++) 
3692
		    if ((start >= ranges[i].start)&&(start <= ranges[i].end)) break;
3693
	    		
3694
		    // register access in plain mode
102 by Suren A. Chilingaryan
Accept short addresses for IPECamera FPGA registers
3695
		if (ranges[i].start != ranges[i].end) {
236 by Suren A. Chilingaryan
Big redign of model structures
3696
		    pcilib_register_bank_t regbank = pcilib_find_register_bank_by_addr(handle, ranges[i].bank);
102 by Suren A. Chilingaryan
Accept short addresses for IPECamera FPGA registers
3697
		    if (regbank == PCILIB_REGISTER_BANK_INVALID) Error("Configuration error: register bank specified in the address range is not found");
3698
		    
3699
		    bank = model_info->banks[regbank].name;
3700
		    start += ranges[i].addr_shift;
120 by Suren A. Chilingaryan
Print proper addresses for register range read/writes
3701
		    addr_shift = ranges[i].addr_shift;
102 by Suren A. Chilingaryan
Accept short addresses for IPECamera FPGA registers
3702
		    ++mode;
3703
		}
37 by Suren A. Chilingaryan
Do not crash if model is not defined
3704
	    }
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
3705
	} else {
318 by Suren A. Chilingaryan
Support reading/writting register views by id
3706
	    const char *spec;
3707
3708
            attr = strchr(addr, '@');
3709
            if (attr) {
3710
                size_t spec_size = strlen(addr) - strlen(attr);
3711
                spec = strndupa(addr, spec_size);
3712
                attr++;
3713
            } else {
3714
                spec = addr;
3715
            }
3716
3717
            view = strchr(spec, '/');
3718
            unit = strchr((view?view:spec), ':');
315 by Suren A. Chilingaryan
Support properties of arbitrary type
3719
3720
            if (view||unit) {
318 by Suren A. Chilingaryan
Support reading/writting register views by id
3721
                size_t reg_size = strlen(spec) - strlen(view?view:unit);
3722
                if (reg_size) reg = strndupa(spec, reg_size);
315 by Suren A. Chilingaryan
Support properties of arbitrary type
3723
                else reg = NULL;
3724
3725
                if ((reg)&&(view)) view++;
3726
                if (unit) unit++;
3727
3728
                if (view&&unit) {
3729
                    view = strndupa(view, strlen(view) - strlen(unit) - 1);
3730
                } else if ((reg)&&(unit)) {
3731
                    view = unit;
3732
                    unit = NULL;
3733
                }
313 by Suren A. Chilingaryan
Support reading of register views
3734
            } else {
318 by Suren A. Chilingaryan
Support reading/writting register views by id
3735
                if (*spec) reg = spec;
3736
                else reg = NULL;
313 by Suren A. Chilingaryan
Support reading of register views
3737
            }
3738
315 by Suren A. Chilingaryan
Support properties of arbitrary type
3739
            if (reg) {
3740
	        if (pcilib_find_register(handle, bank, reg) == PCILIB_REGISTER_INVALID) {
3741
	            Usage(argc, argv, "Invalid address (%s) is specified", addr);
3742
	        }
318 by Suren A. Chilingaryan
Support reading/writting register views by id
3743
	    }
3744
3745
            if (attr) {
3746
                if (mode == MODE_WRITE)
3747
                    Error("Writting of attributes is not supported");
3748
                mode += 3;
3749
            } else if (reg) {
3750
		mode += 1;
7.1.1 by Suren A. Chilingaryan
Initial support of IPECamera protocol
3751
	    } else {
315 by Suren A. Chilingaryan
Support properties of arbitrary type
3752
	        mode += 2;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3753
	    }
3754
	} 
3755
    }
117 by Suren A. Chilingaryan
new event architecture, first trial
3756
	
3757
    if (mode == MODE_GRAB) {
3758
	if (output) {
3759
	    char fsname[128];
3760
	    if (!get_file_fs(output, 127, fsname)) {
3761
		if (!strcmp(fsname, "ext4")) partition = PARTITION_EXT4;
3762
		else if (!strcmp(fsname, "raw")) partition = PARTITION_RAW;
3763
	    }
123 by Suren A. Chilingaryan
Parse required event & data_type
3764
	} else {
3765
	    output = "/dev/null";
3766
	    partition = PARTITION_NULL;
117 by Suren A. Chilingaryan
new event architecture, first trial
3767
	}
119 by Suren A. Chilingaryan
Initial support of event streaming in cli
3768
3769
	if (!timeout_set) {
3770
	    if (run_time) timeout = PCILIB_TIMEOUT_INFINITE;
3771
	    else timeout = PCILIB_EVENT_TIMEOUT;
3772
	}
139 by Suren A. Chilingaryan
Fix errors preventing time-limited grabbing
3773
	
3774
	if (!size_set) {
3775
	    if (run_time) size = 0;
3776
	}
117 by Suren A. Chilingaryan
new event architecture, first trial
3777
    }
3778
    
3779
    if (mode != MODE_GRAB) {
3780
	if (size == (size_t)-1)
3781
	    Usage(argc, argv, "Unlimited size is not supported in selected operation mode");
3782
    }
7.1.2 by Suren A. Chilingaryan
Better handling of register banks
3783
    
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
3784
3785
    if ((bank)&&(amode == ACCESS_DMA)) {
3786
	if ((!isnumber(bank))||(sscanf(bank,"%li", &itmp) != 1)||(itmp < 0)) 
3787
	    Usage(argc, argv, "Invalid DMA channel (%s) is specified", bank);
3788
	else dma = itmp;
3789
    } else if (bank) {
7.1.2 by Suren A. Chilingaryan
Better handling of register banks
3790
	switch (mode) {
3791
	    case MODE_BENCHMARK:
3792
	    case MODE_READ:
3793
	    case MODE_WRITE:
236 by Suren A. Chilingaryan
Big redign of model structures
3794
		if ((!isnumber(bank))||(sscanf(bank,"%li", &itmp) != 1)||(itmp < 0)||(itmp >= PCILIB_MAX_REGISTER_BANKS)) 
7.1.2 by Suren A. Chilingaryan
Better handling of register banks
3795
		    Usage(argc, argv, "Invalid data bank (%s) is specified", bank);
3796
		else bar = itmp;
3797
	    break;
3798
	    default:
236 by Suren A. Chilingaryan
Big redign of model structures
3799
		if (pcilib_find_register_bank(handle, bank) == PCILIB_REGISTER_BANK_INVALID)
7.1.2 by Suren A. Chilingaryan
Better handling of register banks
3800
		    Usage(argc, argv, "Invalid data bank (%s) is specified", bank);
3801
	}
3802
    }
87 by Suren A. Chilingaryan
Support writting output to file
3803
138 by Suren A. Chilingaryan
Handle SIGINT signal in pcitool
3804
    signal(SIGINT, signal_exit_handler);
3805
141 by Suren A. Chilingaryan
Initial support of fastwritter library
3806
    if ((mode != MODE_GRAB)&&(output)) {
87 by Suren A. Chilingaryan
Support writting output to file
3807
	ofile = fopen(output, "a+");
3808
	if (!ofile) {
3809
	    Error("Failed to open file \"%s\"", output);
3810
	}
264 by Suren A. Chilingaryan
In pcitool try tocquire real-time performance for DMA and grabbing operations
3811
    }
3812
3813
	// Requesting real-time priority when needed
3814
    switch (mode) {
3815
     case MODE_READ:
3816
     case MODE_WRITE:
3817
        if (amode != ACCESS_DMA)
3818
	    break;
3819
     case MODE_BENCHMARK:
329 by Suren A. Chilingaryan
IPEDMA Update
3820
        sched_param.sched_priority = sched_get_priority_max(SCHED_FIFO);
3821
        err = sched_setscheduler(0, SCHED_FIFO, &sched_param);
3822
        if (err) pcilib_info("Failed to acquire real-time priority (errno: %i)", errno);
3823
     break;
264 by Suren A. Chilingaryan
In pcitool try tocquire real-time performance for DMA and grabbing operations
3824
     case MODE_GRAB:
3825
        sched_param.sched_priority = sched_get_priority_min(SCHED_FIFO);
3826
        err = sched_setscheduler(0, SCHED_FIFO, &sched_param);
3827
        if (err) pcilib_info("Failed to acquire real-time priority (errno: %i)", errno);
3828
     break;
3829
     default:
3830
        ;
3831
    }
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3832
3833
    switch (mode) {
337 by Suren A. Chilingaryan
Driver versioning
3834
     case MODE_VERSION:
3835
        Version(handle, model_info);
3836
    break;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3837
     case MODE_INFO:
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
3838
        Info(handle, model_info, info_target);
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3839
     break;
3840
     case MODE_LIST:
315 by Suren A. Chilingaryan
Support properties of arbitrary type
3841
        if ((list_target)&&(*list_target == '/'))
3842
            ListProperties(handle, list_target, details);
3843
        else
3844
            List(handle, model_info, list_target, details);
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3845
     break;
3846
     case MODE_BENCHMARK:
68 by Suren A. Chilingaryan
Support iterations argument and fix interpretation of size argument for benchmarking
3847
        Benchmark(handle, amode, dma, bar, start, size_set?size:0, access, iterations);
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3848
     break;
3849
     case MODE_READ:
109 by Suren A. Chilingaryan
Improvements of DMA engine
3850
	if (amode == ACCESS_DMA) {
248 by Suren A. Chilingaryan
Set error in exit status if no data returned by DMA engine
3851
	    err = ReadData(handle, amode, flags, dma, bar, start, size_set?size:0, access, endianess, timeout_set?timeout:(size_t)-1, ofile);
196 by Suren A. Chilingaryan
Provide access to PCI configuration space in cli
3852
	} else if (amode == ACCESS_CONFIG) {
248 by Suren A. Chilingaryan
Set error in exit status if no data returned by DMA engine
3853
	    err = ReadData(handle, amode, flags, dma, bar, addr?start:0, (addr||size_set)?size:(256/abs(access)), access, endianess, (size_t)-1, ofile);
109 by Suren A. Chilingaryan
Improvements of DMA engine
3854
	} else if (addr) {
248 by Suren A. Chilingaryan
Set error in exit status if no data returned by DMA engine
3855
	    err = ReadData(handle, amode, flags, dma, bar, start, size, access, endianess, (size_t)-1, ofile);
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3856
	} else {
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
3857
	    Error("Address to read is not specified");
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3858
	}
3859
     break;
3860
     case MODE_READ_REGISTER:
315 by Suren A. Chilingaryan
Support properties of arbitrary type
3861
     case MODE_READ_PROPERTY:
318 by Suren A. Chilingaryan
Support reading/writting register views by id
3862
     case MODE_READ_ATTR:
3863
        if ((reg)||(view)||(attr)||(!addr)) ReadRegister(handle, model_info, bank, reg, view, unit, attr);
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
3864
	else ReadRegisterRange(handle, model_info, bank, start, addr_shift, size, ofile);
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3865
     break;
3866
     case MODE_WRITE:
191 by Suren A. Chilingaryan
Do not verify BAR writes by default
3867
	WriteData(handle, amode, dma, bar, start, size, access, endianess, data, verify);
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3868
     break;
3869
     case MODE_WRITE_REGISTER:
315 by Suren A. Chilingaryan
Support properties of arbitrary type
3870
     case MODE_WRITE_PROPERTY:
3871
        if (reg||view) WriteRegister(handle, model_info, bank, reg, view, unit, data);
120 by Suren A. Chilingaryan
Print proper addresses for register range read/writes
3872
	else WriteRegisterRange(handle, model_info, bank, start, addr_shift, size, data);
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3873
     break;
15 by Suren A. Chilingaryan
Infrastructure for event API
3874
     case MODE_RESET:
3875
        pcilib_reset(handle);
3876
     break;
3877
     case MODE_GRAB:
141 by Suren A. Chilingaryan
Initial support of fastwritter library
3878
        TriggerAndGrab(handle, grab_mode, event, data_type, size, run_time, trigger_time, timeout, partition, format, buffer, threads, verbose, output);
15 by Suren A. Chilingaryan
Infrastructure for event API
3879
     break;
103 by Suren A. Chilingaryan
Provide information about active DMA engines & buffers
3880
     case MODE_LIST_DMA:
3881
        ListDMA(handle, fpga_device, model_info);
3882
     break;
3883
     case MODE_LIST_DMA_BUFFERS:
3884
        ListBuffers(handle, fpga_device, model_info, dma, dma_direction);
3885
     break;
3886
     case MODE_READ_DMA_BUFFER:
3887
        ReadBuffer(handle, fpga_device, model_info, dma, dma_direction, block, ofile);
3888
     break;
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
3889
     case MODE_START_DMA:
3890
        StartStopDMA(handle, model_info, dma, dma_direction, 1);
3891
     break;
3892
     case MODE_STOP_DMA:
3893
        StartStopDMA(handle, model_info, dma, dma_direction, 0);
3894
     break;
194 by Suren A. Chilingaryan
DMA-independent IRQ functions
3895
     case MODE_ENABLE_IRQ:
3896
        EnableIRQ(handle, model_info, irq_type);
3897
     break;
3898
     case MODE_DISABLE_IRQ:
3899
        DisableIRQ(handle, model_info, irq_type);
3900
     break;
3901
     case MODE_ACK_IRQ:
3902
        AckIRQ(handle, model_info, irq_source);
3903
     break;
62 by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet)
3904
     case MODE_WAIT_IRQ:
3905
        WaitIRQ(handle, model_info, irq_source, timeout);
3906
     break;
337 by Suren A. Chilingaryan
Driver versioning
3907
     case MODE_SET_DMASK:
3908
        pcilib_set_dma_mask(handle, dma_mask);
3909
     break;
338 by Suren A. Chilingaryan
Support setting payload size
3910
     case MODE_SET_MPS:
3911
        pcilib_set_mps(handle, pcie_mps);
3912
     break;
80 by Suren A. Chilingaryan
List kernel buffers
3913
     case MODE_LIST_KMEM:
197 by Suren A. Chilingaryan
Assume user kmem use
3914
        if (use) DetailKMEM(handle, fpga_device, use, block);
192 by Suren A. Chilingaryan
Kernel memory allocation
3915
        else ListKMEM(handle, fpga_device);
80 by Suren A. Chilingaryan
List kernel buffers
3916
     break;
100 by root
Support exporting data from kernel buffers
3917
     case MODE_READ_KMEM:
197 by Suren A. Chilingaryan
Assume user kmem use
3918
        ReadKMEM(handle, fpga_device, useid, block, 0, ofile);
100 by root
Support exporting data from kernel buffers
3919
     break;
192 by Suren A. Chilingaryan
Kernel memory allocation
3920
     case MODE_ALLOC_KMEM:
3921
        AllocKMEM(handle, fpga_device, use, type, size, block_size, alignment);
3922
     break;
81 by Suren A. Chilingaryan
Support forceful clean-up of kernel memory
3923
     case MODE_FREE_KMEM:
3924
        FreeKMEM(handle, fpga_device, use, force);
3925
     break;
280 by Suren A. Chilingaryan
Integrate locking subsystem from Nicolas Zilio
3926
     case MODE_LIST_LOCKS:
3927
        ListLocks(handle, verbose);
3928
     break;
3929
    case MODE_FREE_LOCKS:
3930
	FreeLocks(handle, force);
3931
    break;
3932
    case MODE_LOCK:
3933
	LockUnlock(handle, lock, 1, timeout_set?timeout:PCILIB_TIMEOUT_INFINITE);
3934
    break;
3935
    case MODE_UNLOCK:
3936
	LockUnlock(handle, lock, 0, timeout_set?timeout:PCILIB_TIMEOUT_INFINITE);
3937
    break;
126 by Suren A. Chilingaryan
multithread preprocessing of ipecamera frames and code reorganization
3938
     case MODE_INVALID:
3939
        break;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3940
    }
3941
87 by Suren A. Chilingaryan
Support writting output to file
3942
    if (ofile) fclose(ofile);
3943
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3944
    pcilib_close(handle);
14 by Suren A. Chilingaryan
Support memset operation
3945
    
3946
    if (data != argv + optind) free(data);
303 by Suren A. Chilingaryan
Initial integration of XML support
3947
248 by Suren A. Chilingaryan
Set error in exit status if no data returned by DMA engine
3948
    return err;
6 by Suren A. Chilingaryan
Initial support for registers, infrastructure only
3949
}