45
44
for (i = 0; i < n; i++) {
46
45
const pcilib_view_description_t *v = (const pcilib_view_description_t*)ptr;
46
pcilib_view_description_t *cur;
47
47
pcilib_view_context_t *view_ctx;
49
ctx->views[ctx->num_views + i] = (pcilib_view_description_t*)malloc(v->api->description_size);
50
if (!ctx->views[ctx->num_views + i]) {
51
err = PCILIB_ERROR_MEMORY;
49
pcilib_view_t view = pcilib_find_view_by_name(ctx, v->name);
50
if (view != PCILIB_VIEW_INVALID) {
51
pcilib_clean_views(ctx, ctx->num_views);
52
pcilib_error("View %s is already defined in the model", v->name);
53
return PCILIB_ERROR_EXIST;
56
cur = (pcilib_view_description_t*)malloc(v->api->description_size);
58
pcilib_clean_views(ctx, ctx->num_views);
59
return PCILIB_ERROR_MEMORY;
56
63
view_ctx = v->api->init(ctx);
58
65
view_ctx = (pcilib_view_context_t*)malloc(sizeof(pcilib_view_context_t));
59
memset(view_ctx, 0, sizeof(pcilib_view_context_t));
66
if (view_ctx) memset(view_ctx, 0, sizeof(pcilib_view_context_t));
71
pcilib_clean_views(ctx, ctx->num_views);
72
return PCILIB_ERROR_FAILED;
75
memcpy(cur, v, v->api->description_size);
62
76
view_ctx->view = ctx->num_views + i;
63
77
view_ctx->name = v->name;
66
free(ctx->views[ctx->num_views + i]);
67
err = PCILIB_ERROR_MEMORY;
71
79
HASH_ADD_KEYPTR(hh, ctx->view_hash, view_ctx->name, strlen(view_ctx->name), view_ctx);
72
memcpy(ctx->views[ctx->num_views + i], v, v->api->description_size);
80
ctx->views[ctx->num_views + i] = cur;
73
82
ptr += v->api->description_size;
75
ctx->views[ctx->num_views + i] = NULL;
85
ctx->views[ctx->num_views + n] = NULL;
81
void pcilib_clean_views(pcilib_t *ctx) {
91
void pcilib_clean_views(pcilib_t *ctx, pcilib_view_t start) {
83
93
pcilib_view_context_t *view_ctx, *tmp;
86
96
HASH_ITER(hh, ctx->view_hash, view_ctx, tmp) {
87
97
const pcilib_view_description_t *v = ctx->views[view_ctx->view];
89
HASH_DEL(ctx->view_hash, view_ctx);
90
if (v->api->free) v->api->free(ctx, view_ctx);
99
if (view_ctx->view >= start) {
100
HASH_DEL(ctx->view_hash, view_ctx);
101
if (v->api->free) v->api->free(ctx, view_ctx);
95
for (i = 0; ctx->views[i]; i++) {
107
for (i = start; ctx->views[i]; i++) {
96
108
if (ctx->views[i]->api->free_description) {
97
109
ctx->views[i]->api->free_description(ctx, ctx->views[i]);
191
201
pcilib_unit_transform_t *trans;
192
202
} pcilib_view_configuration_t;
194
static int pcilib_detect_view_configuration(pcilib_t *ctx, const char *bank, const char *regname, const char *view_cname, int write_direction, pcilib_view_configuration_t *cfg) {
204
static int pcilib_detect_view_configuration(pcilib_t *ctx, const char *bank, const char *regname, const char *view_cname, const char *unit_cname, int write_direction, pcilib_view_configuration_t *cfg) {
196
206
pcilib_view_t view;
197
207
pcilib_view_context_t *view_ctx;
199
209
pcilib_register_t reg = PCILIB_REGISTER_INVALID;
201
211
char *view_name = alloca(strlen(view_cname) + 1);
212
const char *unit_name;
205
215
strcpy(view_name, view_cname);
207
unit_name = strchr(view_name, ':');
217
if (unit_cname) unit_name = unit_cname;
219
unit_name = strchr(view_name, ':');
221
*(char*)unit_name = 0;
214
228
reg = pcilib_find_register(ctx, bank, regname);
215
229
if (reg == PCILIB_REGISTER_INVALID) {
261
275
pcilib_view_configuration_t cfg;
262
276
pcilib_register_value_t regvalue = 0;
264
err = pcilib_detect_view_configuration(ctx, bank, regname, view, 0, &cfg);
278
err = pcilib_detect_view_configuration(ctx, bank, regname, view, NULL, 0, &cfg);
265
279
if (err) return err;
267
281
v = ctx->views[cfg.view->view];
307
330
pcilib_view_configuration_t cfg;
308
331
pcilib_register_value_t regvalue = 0;
310
err = pcilib_detect_view_configuration(ctx, bank, regname, view, 1, &cfg);
333
err = pcilib_detect_view_configuration(ctx, bank, regname, view, valarg->unit, 1, &cfg);
311
334
if (err) return err;
313
336
v = ctx->views[cfg.view->view];
315
338
if (!v->api->write_to_reg) {
316
pcilib_error("The view (%s) does not support reading from the register", view);
339
pcilib_error("The view (%s) does not support writting to the register", view);
317
340
return PCILIB_ERROR_NOTSUPPORTED;
343
if ((v->mode & PCILIB_REGISTER_W) == 0) {
344
pcilib_error("The view (%s) does not allow writting to the register", view);
345
return PCILIB_ERROR_NOTPERMITED;
320
348
err = pcilib_copy_value(ctx, &val, valarg);
321
349
if (err) return err;