/alps/pcitool

To get this branch, use:
bzr branch http://suren.me/webbzr/alps/pcitool
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
1
#define _POSIX_C_SOURCE 199309L
2
#include <stdio.h>
3
#include <string.h>
4
#include <strings.h>
5
#include <stdlib.h>
6
#include <stdint.h>
7
#include <stdarg.h>
8
#include <fcntl.h>
9
#include <unistd.h>
10
#include <sys/ioctl.h>
11
#include <sys/mman.h>
12
#include <arpa/inet.h>
13
#include <errno.h>
14
#include <assert.h>
86 by Suren A. Chilingaryan
Change timeout definition in Events API from struct timespec to pcilib_timeout_t
15
#include <time.h>
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
16
17
#include "pci.h"
18
19
#include "tools.h"
20
#include "error.h"
21
86 by Suren A. Chilingaryan
Change timeout definition in Events API from struct timespec to pcilib_timeout_t
22
#ifndef __timespec_defined
23
struct timespec {
24
    time_t tv_sec;
25
    long tv_nsec;
26
};
27
#endif /* __timespec_defined */
28
29
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
30
pcilib_event_t pcilib_find_event(pcilib_t *ctx, const char *event) {
31
    int i;
32
    pcilib_register_bank_t res;
33
    unsigned long addr;
34
    
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
35
    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
36
    pcilib_event_description_t *events = model_info->events;
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
37
    
38
    for (i = 0; events[i].name; i++) {
117 by Suren A. Chilingaryan
new event architecture, first trial
39
	if (!strcasecmp(events[i].name, event)) return events[i].evid;
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
40
    }
41
42
    return (pcilib_event_t)-1;
43
}
44
117 by Suren A. Chilingaryan
new event architecture, first trial
45
pcilib_event_data_type_t pcilib_find_event_data_type(pcilib_t *ctx, pcilib_event_t event, const char *data_type) {
46
    int i;
47
    pcilib_register_bank_t res;
48
    unsigned long addr;
49
    
50
    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
51
    pcilib_event_data_type_description_t *data_types = model_info->data_types;
52
    
53
    for (i = 0; data_types[i].name; i++) {
54
	if ((data_types[i].evid&event)&&(!strcasecmp(data_types[i].name, data_type))) return data_types[i].data_type;
55
    }
56
57
    return (pcilib_event_data_type_t)-1;
58
}
59
60
int pcilib_init_event_engine(pcilib_t *ctx) {
61
    pcilib_event_api_description_t *api;
62
    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
63
64
    api = model_info->event_api;
65
66
//    api = pcilib_model[model].event_api;
67
    if ((api)&&(api->init)) {
68
	ctx->event_ctx = api->init(ctx);
69
	if (ctx->event_ctx) {
70
	    ctx->event_ctx->pcilib = ctx;
71
	}
72
    }
73
    
74
    return 0;
75
}
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
76
77
int pcilib_reset(pcilib_t *ctx) {
78
    pcilib_event_api_description_t *api;
79
    
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
80
    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
81
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
82
    api = model_info->event_api;
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
83
    if (!api) {
84
	pcilib_error("Event API is not supported by the selected model");
85
	return PCILIB_ERROR_NOTSUPPORTED;
86
    }
87
    
88
    if (api->reset) 
89
	return api->reset(ctx->event_ctx);
90
	
91
    return 0;
92
}
93
117 by Suren A. Chilingaryan
new event architecture, first trial
94
int pcilib_configure_rawdata_callback(pcilib_t *ctx, pcilib_event_rawdata_callback_t callback, void *user) {
95
    pcilib_event_api_description_t *api;
96
    
97
    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
98
99
    api = model_info->event_api;
100
    if (!api) {
101
	pcilib_error("Event API is not supported by the selected model");
102
	return PCILIB_ERROR_NOTSUPPORTED;
103
    }
104
105
    ctx->event_ctx->params.rawdata.callback = callback;
106
    ctx->event_ctx->params.rawdata.user = user;
107
    
108
    return 0;    
109
}
110
111
int pcilib_configure_autostop(pcilib_t *ctx, size_t max_events, pcilib_timeout_t duration) {
112
    pcilib_event_api_description_t *api;
113
    
114
    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
115
116
    api = model_info->event_api;
117
    if (!api) {
118
	pcilib_error("Event API is not supported by the selected model");
119
	return PCILIB_ERROR_NOTSUPPORTED;
120
    }
121
122
    ctx->event_ctx->params.autostop.max_events = max_events;
123
    ctx->event_ctx->params.autostop.duration = duration;
124
    
125
    return 0;    
126
}
127
128
int pcilib_start(pcilib_t *ctx, pcilib_event_t event_mask, pcilib_event_flags_t flags) {
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
129
    pcilib_event_api_description_t *api;
130
    
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
131
    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
132
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
133
    api = model_info->event_api;
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
134
    if (!api) {
135
	pcilib_error("Event API is not supported by the selected model");
136
	return PCILIB_ERROR_NOTSUPPORTED;
137
    }
138
139
    if (api->start) 
117 by Suren A. Chilingaryan
new event architecture, first trial
140
	return api->start(ctx->event_ctx, event_mask, flags);
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
141
142
    return 0;
143
}
144
117 by Suren A. Chilingaryan
new event architecture, first trial
145
int pcilib_stop(pcilib_t *ctx, pcilib_event_flags_t flags) {
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
146
    pcilib_event_api_description_t *api;
147
    
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
148
    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
149
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
150
    api = model_info->event_api;
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
151
    if (!api) {
152
	pcilib_error("Event API is not supported by the selected model");
153
	return PCILIB_ERROR_NOTSUPPORTED;
154
    }
155
156
    if (api->stop) 
117 by Suren A. Chilingaryan
new event architecture, first trial
157
	return api->stop(ctx->event_ctx, flags);
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
158
159
    return 0;
160
}
161
117 by Suren A. Chilingaryan
new event architecture, first trial
162
int pcilib_stream(pcilib_t *ctx, pcilib_event_callback_t callback, void *user) {
163
    pcilib_event_api_description_t *api;
164
    
165
    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
166
167
    api = model_info->event_api;
168
    if (!api) {
169
	pcilib_error("Event API is not supported by the selected model");
170
	return PCILIB_ERROR_NOTSUPPORTED;
171
    }
172
173
    if (api->stream)
174
	return api->stream(ctx->event_ctx, callback, user);
175
176
    if (api->next_event) {
177
	pcilib_error("Streaming using next_event API is not implemented yet");
178
    }
179
180
    pcilib_error("Event enumeration is not suppored by API");
181
    return PCILIB_ERROR_NOTSUPPORTED;
182
}
183
/*
184
typedef struct {
185
    pcilib_event_id_t event_id;
186
    pcilib_event_info_t *info;
187
} pcilib_return_event_callback_context_t;
188
189
static int pcilib_return_event_callback(pcilib_event_id_t event_id, pcilib_event_info_t *info, void *user) {
190
    pcilib_return_event_callback_context_t *ctx = (pcilib_return_event_callback_context_t*)user;
191
    ctx->event_id = event_id;
192
    ctx->info = info;
193
}
194
*/
195
196
int pcilib_get_next_event(pcilib_t *ctx, pcilib_timeout_t timeout, pcilib_event_id_t *evid, pcilib_event_info_t **info) {
197
    int err;
198
    pcilib_event_api_description_t *api;
199
//    pcilib_return_event_callback_context_t user;
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
200
    
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
201
    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
202
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
203
    api = model_info->event_api;
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
204
    if (!api) {
205
	pcilib_error("Event API is not supported by the selected model");
206
	return PCILIB_ERROR_NOTSUPPORTED;
207
    }
208
209
    if (api->next_event) 
117 by Suren A. Chilingaryan
new event architecture, first trial
210
	return api->next_event(ctx->event_ctx, timeout, evid, info);
211
212
/*	
213
    if (api->stream) {
214
	err = api->stream(ctx->event_ctx, 1, timeout, pcilib_return_event_callback, &user);
215
	if (err) return err;
216
	
217
	if (evid) *evid = user->event_id;
218
	if (info) *info = user->info;
219
220
	return 0;
221
    }
222
*/
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
223
224
    pcilib_error("Event enumeration is not suppored by API");
117 by Suren A. Chilingaryan
new event architecture, first trial
225
    return PCILIB_ERROR_NOTSUPPORTED;
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
226
}
227
228
int pcilib_trigger(pcilib_t *ctx, pcilib_event_t event, size_t trigger_size, void *trigger_data) {
229
    pcilib_event_api_description_t *api;
230
    
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
231
    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
232
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
233
    api = model_info->event_api;
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
234
    if (!api) {
235
	pcilib_error("Event API is not supported by the selected model");
236
	return PCILIB_ERROR_NOTSUPPORTED;
237
    }
238
239
    if (api->trigger) 
240
	return api->trigger(ctx->event_ctx, event, trigger_size, trigger_data);
241
242
    pcilib_error("Self triggering is not supported by the selected model");
243
    return PCILIB_ERROR_NOTSUPPORTED;
244
}
245
246
247
void *pcilib_get_data_with_argument(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t arg_size, void *arg, size_t *size) {
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
248
    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
249
250
    pcilib_event_api_description_t *api = model_info->event_api;
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
251
    if (!api) {
252
	pcilib_error("Event API is not supported by the selected model");
253
	return NULL;
254
    }
255
256
    if (api->get_data) 
117 by Suren A. Chilingaryan
new event architecture, first trial
257
	return api->get_data(ctx->event_ctx, event_id, data_type, arg_size, arg, size, NULL);
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
258
259
    return NULL;
260
}
261
117 by Suren A. Chilingaryan
new event architecture, first trial
262
int pcilib_copy_data_with_argument(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t arg_size, void *arg, size_t size, void *buf, size_t *retsize) {
263
    void *res;
264
    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
265
266
    pcilib_event_api_description_t *api = model_info->event_api;
267
    if (!api) {
268
	pcilib_error("Event API is not supported by the selected model");
269
	return PCILIB_ERROR_NOTSUPPORTED;
270
    }
271
272
    if (api->get_data) {
273
	res = api->get_data(ctx->event_ctx, event_id, data_type, arg_size, arg, &size, buf);
274
	if (!res) return PCILIB_ERROR_FAILED;
275
	
276
	if (retsize) *retsize = size;
277
	return 0;
278
    }	
279
280
    return PCILIB_ERROR_NOTSUPPORTED;
281
}
282
283
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
284
void *pcilib_get_data(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t *size) {
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
285
    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
286
287
    pcilib_event_api_description_t *api = model_info->event_api;
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
288
    if (!api) {
289
	pcilib_error("Event API is not supported by the selected model");
290
	return NULL;
291
    }
292
293
    if (api->get_data) 
117 by Suren A. Chilingaryan
new event architecture, first trial
294
	return api->get_data(ctx->event_ctx, event_id, data_type, 0, NULL, size, NULL);
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
295
296
    return NULL;
297
}
298
117 by Suren A. Chilingaryan
new event architecture, first trial
299
int pcilib_copy_data(pcilib_t *ctx, pcilib_event_id_t event_id, pcilib_event_data_type_t data_type, size_t size, void *buf, size_t *ret_size) {
300
    void *res;
301
    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
302
303
    pcilib_event_api_description_t *api = model_info->event_api;
304
    if (!api) {
305
	pcilib_error("Event API is not supported by the selected model");
306
	return PCILIB_ERROR_NOTSUPPORTED;
307
    }
308
309
    if (api->get_data) {
310
	res = api->get_data(ctx->event_ctx, event_id, data_type, 0, NULL, &size, buf);
311
	if (!res) return PCILIB_ERROR_FAILED;
312
	
313
	if (ret_size) *ret_size = size;
314
	return 0;
315
    }
316
317
    return PCILIB_ERROR_NOTSUPPORTED;
318
}
319
320
int pcilib_return_data(pcilib_t *ctx, pcilib_event_id_t event_id, void *data) {
54 by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers
321
    pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
322
    
323
    pcilib_event_api_description_t *api = model_info->event_api;
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
324
    if (!api) {
325
	pcilib_error("Event API is not supported by the selected model");
326
	return PCILIB_ERROR_NOTSUPPORTED;
327
    }
328
329
    if (api->return_data) 
117 by Suren A. Chilingaryan
new event architecture, first trial
330
	return api->return_data(ctx->event_ctx, event_id, data);
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
331
332
    return 0;
333
}
334
335
336
typedef struct {
337
    pcilib_t *ctx;
338
    
339
    size_t *size;
340
    void **data;
341
} pcilib_grab_callback_user_data_t;
342
117 by Suren A. Chilingaryan
new event architecture, first trial
343
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
344
static int pcilib_grab_callback(pcilib_event_t event, pcilib_event_id_t event_id, void *vuser) {
345
    int err;
346
    void *data;
347
    size_t size;
348
    int allocated = 0;
349
350
    pcilib_grab_callback_user_data_t *user = (pcilib_grab_callback_user_data_t*)vuser;
351
352
    data = pcilib_get_data(user->ctx, event_id, PCILIB_EVENT_DATA, &size);
353
    if (!data) {
354
	pcilib_error("Error getting event data");
355
	return PCILIB_ERROR_FAILED;
356
    }
357
    
358
    if (*(user->data)) {
359
	if ((user->size)&&(*(user->size) < size)) {
360
	    pcilib_error("The supplied buffer does not have enough space to hold the event data. Buffer size is %z, but %z is required", user->size, size);
361
	    return PCILIB_ERROR_MEMORY;
362
	}
363
364
	*(user->size) = size;
365
    } else {
366
	*(user->data) = malloc(size);
367
	if (!*(user->data)) {
368
	    pcilib_error("Memory allocation (%i bytes) for event data is failed");
369
	    return PCILIB_ERROR_MEMORY;
370
	}
371
	if (*(user->size)) *(user->size) = size;
372
	allocated = 1;
373
    }
374
    
375
    memcpy(*(user->data), data, size);
376
    
117 by Suren A. Chilingaryan
new event architecture, first trial
377
    err = pcilib_return_data(user->ctx, event_id, data);
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
378
    if (err) {
379
	if (allocated) {
380
	    free(*(user->data));
381
	    *(user->data) = NULL;
382
	}
383
	pcilib_error("The event data had been overwritten before it was returned, data corruption may occur");
384
	return err;
385
    }
386
    
387
    return 0;
388
}
389
86 by Suren A. Chilingaryan
Change timeout definition in Events API from struct timespec to pcilib_timeout_t
390
int pcilib_grab(pcilib_t *ctx, pcilib_event_t event_mask, size_t *size, void **data, pcilib_timeout_t timeout) {
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
391
    int err;
86 by Suren A. Chilingaryan
Change timeout definition in Events API from struct timespec to pcilib_timeout_t
392
    struct timespec ts;
117 by Suren A. Chilingaryan
new event architecture, first trial
393
    pcilib_event_id_t eid;
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
394
    
395
    pcilib_grab_callback_user_data_t user = {ctx, size, data};
396
    
117 by Suren A. Chilingaryan
new event architecture, first trial
397
    err = pcilib_start(ctx, event_mask, PCILIB_EVENT_FLAGS_DEFAULT);
398
    if (!err) err = pcilib_trigger(ctx, event_mask, 0, NULL);
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
399
    if (!err) {
117 by Suren A. Chilingaryan
new event architecture, first trial
400
	err = pcilib_get_next_event(ctx, timeout, &eid, NULL);
401
	if (!err) pcilib_grab_callback(event_mask, eid, &user);
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
402
    }
117 by Suren A. Chilingaryan
new event architecture, first trial
403
    pcilib_stop(ctx, PCILIB_EVENT_FLAGS_DEFAULT);
92 by root
Report errors during event grabbing
404
    return err;
47 by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes
405
}