/alps/pcitool

To get this branch, use:
bzr branch http://suren.me/webbzr/alps/pcitool

« back to all changes in this revision

Viewing changes to pcilib/view.c

  • Committer: Suren A. Chilingaryan
  • Date: 2015-10-18 01:47:47 UTC
  • Revision ID: csa@suren.me-20151018014747-9ji2ygdhz1l9wnt5
Support properties of arbitrary type

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
#include "value.h"
12
12
 
13
13
int pcilib_add_views(pcilib_t *ctx, size_t n, const pcilib_view_description_t *desc) {
14
 
    int err = 0;
15
14
    size_t i;
16
15
    void *ptr;
17
16
 
44
43
    ptr = (void*)desc;
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;
48
48
 
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;
52
 
            break;
 
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;
 
54
        }
 
55
 
 
56
        cur = (pcilib_view_description_t*)malloc(v->api->description_size);
 
57
        if (!cur) {
 
58
            pcilib_clean_views(ctx, ctx->num_views);
 
59
            return PCILIB_ERROR_MEMORY;
53
60
        }
54
61
 
55
62
        if (v->api->init) 
56
63
            view_ctx = v->api->init(ctx);
57
64
        else {
58
65
            view_ctx = (pcilib_view_context_t*)malloc(sizeof(pcilib_view_context_t));
59
 
            memset(view_ctx, 0, sizeof(pcilib_view_context_t));
60
 
        }
61
 
 
 
66
            if (view_ctx) memset(view_ctx, 0, sizeof(pcilib_view_context_t));
 
67
        }
 
68
 
 
69
        if (!view_ctx) {
 
70
            free(cur);
 
71
            pcilib_clean_views(ctx, ctx->num_views);
 
72
            return PCILIB_ERROR_FAILED;
 
73
        }
 
74
 
 
75
        memcpy(cur, v, v->api->description_size);
62
76
        view_ctx->view = ctx->num_views + i;
63
77
        view_ctx->name = v->name;
64
78
 
65
 
        if (!view_ctx) {
66
 
            free(ctx->views[ctx->num_views + i]);
67
 
            err = PCILIB_ERROR_MEMORY;
68
 
            break;
69
 
        }
70
 
 
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;
 
81
 
73
82
        ptr += v->api->description_size;
74
83
    }
75
 
    ctx->views[ctx->num_views + i] = NULL;
76
 
    ctx->num_views += i;
77
 
 
78
 
    return err;
 
84
 
 
85
    ctx->views[ctx->num_views + n] = NULL;
 
86
    ctx->num_views += n;
 
87
 
 
88
    return 0;
79
89
}
80
90
 
81
 
void pcilib_clean_views(pcilib_t *ctx) {
 
91
void pcilib_clean_views(pcilib_t *ctx, pcilib_view_t start) {
82
92
    pcilib_view_t i;
83
93
    pcilib_view_context_t *view_ctx, *tmp;
84
94
 
85
 
    if (ctx->unit_hash) {
 
95
    if (ctx->view_hash) {
86
96
        HASH_ITER(hh, ctx->view_hash, view_ctx, tmp) {
87
97
            const pcilib_view_description_t *v = ctx->views[view_ctx->view];
88
98
 
89
 
            HASH_DEL(ctx->view_hash, view_ctx);
90
 
            if (v->api->free) v->api->free(ctx, view_ctx);
91
 
            else free(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);
 
102
                else free(view_ctx);
 
103
            }
92
104
        }
93
105
    }
94
106
 
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]);
98
110
        } else {
100
112
        }
101
113
    }
102
114
 
103
 
    ctx->views[0] = NULL;
104
 
    ctx->num_views = 0;
 
115
    ctx->views[start] = NULL;
 
116
    ctx->num_views = start;
105
117
}
106
118
 
107
119
pcilib_view_context_t *pcilib_find_view_context_by_name(pcilib_t *ctx, const char *name) {
117
129
    return PCILIB_VIEW_INVALID;
118
130
}
119
131
 
120
 
 
121
 
 
122
132
pcilib_view_context_t *pcilib_find_register_view_context_by_name(pcilib_t *ctx, pcilib_register_t reg, const char *name) {
123
133
    pcilib_view_t i;
124
134
    pcilib_register_context_t *regctx = &ctx->register_ctx[reg];
191
201
    pcilib_unit_transform_t *trans;
192
202
} pcilib_view_configuration_t;
193
203
 
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) {
195
205
    int err = 0;
196
206
    pcilib_view_t view;
197
207
    pcilib_view_context_t *view_ctx;
199
209
    pcilib_register_t reg = PCILIB_REGISTER_INVALID;
200
210
 
201
211
    char *view_name = alloca(strlen(view_cname) + 1);
202
 
    char *unit_name;
 
212
    const char *unit_name;
203
213
 
204
214
 
205
215
    strcpy(view_name, view_cname);
206
216
 
207
 
    unit_name = strchr(view_name, ':');
208
 
    if (unit_name) {
209
 
        *unit_name = 0;
210
 
        unit_name++;
 
217
    if (unit_cname) unit_name = unit_cname;
 
218
    else {
 
219
        unit_name = strchr(view_name, ':');
 
220
        if (unit_name) {
 
221
            *(char*)unit_name = 0;
 
222
            unit_name++;
 
223
        }
211
224
    }
212
225
 
 
226
 
213
227
    if (regname) {
214
228
        reg = pcilib_find_register(ctx, bank, regname);
215
229
        if (reg == PCILIB_REGISTER_INVALID) {
244
258
    }
245
259
 
246
260
        // No transform is required
247
 
    if (!trans->transform) trans = NULL;
 
261
    if ((trans)&&(!trans->transform)) trans = NULL;
248
262
 
249
263
    cfg->reg = reg;
250
264
    cfg->view = view_ctx;
261
275
    pcilib_view_configuration_t cfg;
262
276
    pcilib_register_value_t regvalue = 0;
263
277
 
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;
266
280
 
267
281
    v = ctx->views[cfg.view->view];
271
285
        return PCILIB_ERROR_NOTSUPPORTED;
272
286
    }
273
287
 
 
288
    if ((v->mode & PCILIB_REGISTER_R) == 0) {
 
289
        pcilib_error("The view (%s) does not allow reading from the register", view);
 
290
        return PCILIB_ERROR_NOTPERMITED;
 
291
    }
 
292
 
274
293
    if (regname) {
275
294
        err = pcilib_read_register_by_id(ctx, cfg.reg, &regvalue);
276
295
        if (err) {
290
309
        return err;
291
310
    }
292
311
 
 
312
    if (v->unit) {
 
313
        val->unit = v->unit;
 
314
    }
 
315
 
293
316
    if (cfg.trans) {
294
317
        err = pcilib_transform_unit(ctx, cfg.trans, val);
295
318
        if (err) return err;
307
330
    pcilib_view_configuration_t cfg;
308
331
    pcilib_register_value_t regvalue = 0;
309
332
 
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;
312
335
 
313
336
    v = ctx->views[cfg.view->view];
314
337
 
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;
318
341
    }
319
342
 
 
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;
 
346
    }
 
347
 
320
348
    err = pcilib_copy_value(ctx, &val, valarg);
321
349
    if (err) return err;
322
350