/alps/pcitool

To get this branch, use:
bzr branch http://suren.me/webbzr/alps/pcitool
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
1
#include <stdio.h>
2
#include <stdlib.h>
305.1.3 by zilio nicolas
compilation ok
3
#include <string.h>
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
4
#include <strings.h>
309 by Suren A. Chilingaryan
Base functions for views
5
#include <alloca.h>
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
6
305.1.3 by zilio nicolas
compilation ok
7
#include "pci.h"
8
#include "pcilib.h"
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
9
#include "view.h"
305.1.3 by zilio nicolas
compilation ok
10
#include "error.h"
309 by Suren A. Chilingaryan
Base functions for views
11
#include "value.h"
321 by Suren A. Chilingaryan
Support computed (property-based) registers
12
#include "property.h"
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
13
318 by Suren A. Chilingaryan
Support reading/writting register views by id
14
int pcilib_add_views_custom(pcilib_t *ctx, size_t n, const pcilib_view_description_t *desc, pcilib_view_context_t **refs) {
321 by Suren A. Chilingaryan
Support computed (property-based) registers
15
    int err;
16
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
17
    size_t i;
18
    void *ptr;
305.1.9 by nicolas.zilio at hotmail
first try with pcilib_operation_t
19
20
    if (!n) {
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
21
            // No padding between array elements
22
        ptr = (void*)desc;
23
        while (1) {
24
            const pcilib_view_description_t *v = (const pcilib_view_description_t*)ptr;
25
            if (v->name) n++;
26
            else break;
27
            ptr += v->api->description_size;
28
        }
305.1.9 by nicolas.zilio at hotmail
first try with pcilib_operation_t
29
    }
30
321 by Suren A. Chilingaryan
Support computed (property-based) registers
31
    if (!refs) {
32
        refs = (pcilib_view_context_t**)alloca(n * sizeof(pcilib_view_context_t*));
33
        if (!refs) return PCILIB_ERROR_MEMORY;
34
    }
35
305.1.9 by nicolas.zilio at hotmail
first try with pcilib_operation_t
36
    if ((ctx->num_views + n + 1) > ctx->alloc_views) {
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
37
        size_t size;
38
	pcilib_view_description_t **views;
39
        for (size = ctx->alloc_views; size < 2 * (n + ctx->num_views + 1); size<<=1);
40
41
        views = (pcilib_view_description_t**)realloc(ctx->views, size * sizeof(pcilib_view_description_t*));
42
        if (!views) return PCILIB_ERROR_MEMORY;
43
44
        ctx->views = views;
45
        ctx->alloc_views = size;
46
47
        ctx->model_info.views = (const pcilib_view_description_t**)views;
48
    }
49
50
        // No padding between array elements
51
    ptr = (void*)desc;
52
    for (i = 0; i < n; i++) {
53
        const pcilib_view_description_t *v = (const pcilib_view_description_t*)ptr;
315 by Suren A. Chilingaryan
Support properties of arbitrary type
54
        pcilib_view_description_t *cur;
310 by Suren A. Chilingaryan
Introduce hashes
55
        pcilib_view_context_t *view_ctx;
56
315 by Suren A. Chilingaryan
Support properties of arbitrary type
57
        pcilib_view_t view = pcilib_find_view_by_name(ctx, v->name);
58
        if (view != PCILIB_VIEW_INVALID) {
321 by Suren A. Chilingaryan
Support computed (property-based) registers
59
            ctx->views[ctx->num_views + i] = NULL;
315 by Suren A. Chilingaryan
Support properties of arbitrary type
60
            pcilib_clean_views(ctx, ctx->num_views);
61
            pcilib_error("View %s is already defined in the model", v->name);
62
            return PCILIB_ERROR_EXIST;
63
        }
64
65
        cur = (pcilib_view_description_t*)malloc(v->api->description_size);
66
        if (!cur) {
321 by Suren A. Chilingaryan
Support computed (property-based) registers
67
            ctx->views[ctx->num_views + i] = NULL;
315 by Suren A. Chilingaryan
Support properties of arbitrary type
68
            pcilib_clean_views(ctx, ctx->num_views);
69
            return PCILIB_ERROR_MEMORY;
310 by Suren A. Chilingaryan
Introduce hashes
70
        }
71
353 by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov
72
        memcpy(cur, v, v->api->description_size);
73
        ctx->views[ctx->num_views + i] = cur;
74
310 by Suren A. Chilingaryan
Introduce hashes
75
        if (v->api->init) 
353 by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov
76
            view_ctx = v->api->init(ctx, ctx->num_views + i);
310 by Suren A. Chilingaryan
Introduce hashes
77
        else {
78
            view_ctx = (pcilib_view_context_t*)malloc(sizeof(pcilib_view_context_t));
315 by Suren A. Chilingaryan
Support properties of arbitrary type
79
            if (view_ctx) memset(view_ctx, 0, sizeof(pcilib_view_context_t));
80
        }
81
82
        if (!view_ctx) {
83
            free(cur);
321 by Suren A. Chilingaryan
Support computed (property-based) registers
84
            ctx->views[ctx->num_views + i] = NULL;
315 by Suren A. Chilingaryan
Support properties of arbitrary type
85
            pcilib_clean_views(ctx, ctx->num_views);
86
            return PCILIB_ERROR_FAILED;
87
        }
88
353 by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov
89
	view_ctx->view = ctx->num_views + i;
310 by Suren A. Chilingaryan
Introduce hashes
90
        view_ctx->name = v->name;
91
353 by Suren A. Chilingaryan
Merge Python scripting support from Vasiliy Chernov
92
        HASH_ADD_KEYPTR(hh, ctx->view_hash, view_ctx->name, strlen(view_ctx->name), view_ctx);
93
318 by Suren A. Chilingaryan
Support reading/writting register views by id
94
        if (refs) refs[i] = view_ctx;
95
307 by Suren A. Chilingaryan
Finalyze XML support and provide initial support for views (only descriptions so far)
96
        ptr += v->api->description_size;
97
    }
315 by Suren A. Chilingaryan
Support properties of arbitrary type
98
99
    ctx->views[ctx->num_views + n] = NULL;
321 by Suren A. Chilingaryan
Support computed (property-based) registers
100
101
    err = pcilib_add_registers_from_properties(ctx, n, refs, ctx->views + ctx->num_views);
102
    if (err) {
103
        pcilib_clean_views(ctx, ctx->num_views);
104
        return err;
105
    }
106
315 by Suren A. Chilingaryan
Support properties of arbitrary type
107
    ctx->num_views += n;
108
109
    return 0;
310 by Suren A. Chilingaryan
Introduce hashes
110
}
111
318 by Suren A. Chilingaryan
Support reading/writting register views by id
112
int pcilib_add_views(pcilib_t *ctx, size_t n, const pcilib_view_description_t *desc) {
113
    return pcilib_add_views_custom(ctx, n, desc, NULL);
114
}
115
116
315 by Suren A. Chilingaryan
Support properties of arbitrary type
117
void pcilib_clean_views(pcilib_t *ctx, pcilib_view_t start) {
310 by Suren A. Chilingaryan
Introduce hashes
118
    pcilib_view_t i;
119
    pcilib_view_context_t *view_ctx, *tmp;
120
315 by Suren A. Chilingaryan
Support properties of arbitrary type
121
    if (ctx->view_hash) {
310 by Suren A. Chilingaryan
Introduce hashes
122
        HASH_ITER(hh, ctx->view_hash, view_ctx, tmp) {
123
            const pcilib_view_description_t *v = ctx->views[view_ctx->view];
124
315 by Suren A. Chilingaryan
Support properties of arbitrary type
125
            if (view_ctx->view >= start) {
126
                HASH_DEL(ctx->view_hash, view_ctx);
127
                if (v->api->free) v->api->free(ctx, view_ctx);
128
                else free(view_ctx);
129
            }
310 by Suren A. Chilingaryan
Introduce hashes
130
        }
131
    }
132
315 by Suren A. Chilingaryan
Support properties of arbitrary type
133
    for (i = start; ctx->views[i]; i++) {
310 by Suren A. Chilingaryan
Introduce hashes
134
	if (ctx->views[i]->api->free_description) {
135
	    ctx->views[i]->api->free_description(ctx, ctx->views[i]);
136
	} else {
137
	    free(ctx->views[i]);
138
	}
139
    }
140
315 by Suren A. Chilingaryan
Support properties of arbitrary type
141
    ctx->views[start] = NULL;
142
    ctx->num_views = start;
310 by Suren A. Chilingaryan
Introduce hashes
143
}
144
145
pcilib_view_context_t *pcilib_find_view_context_by_name(pcilib_t *ctx, const char *name) {
146
    pcilib_view_context_t *view_ctx = NULL;
147
148
    HASH_FIND_STR(ctx->view_hash, name, view_ctx);
149
    return view_ctx;
150
}
309 by Suren A. Chilingaryan
Base functions for views
151
152
pcilib_view_t pcilib_find_view_by_name(pcilib_t *ctx, const char *name) {
310 by Suren A. Chilingaryan
Introduce hashes
153
    pcilib_view_context_t *view_ctx = pcilib_find_view_context_by_name(ctx, name);
154
    if (view_ctx) return view_ctx->view;
309 by Suren A. Chilingaryan
Base functions for views
155
    return PCILIB_VIEW_INVALID;
156
}
157
310 by Suren A. Chilingaryan
Introduce hashes
158
pcilib_view_context_t *pcilib_find_register_view_context_by_name(pcilib_t *ctx, pcilib_register_t reg, const char *name) {
309 by Suren A. Chilingaryan
Base functions for views
159
    pcilib_view_t i;
160
    pcilib_register_context_t *regctx = &ctx->register_ctx[reg];
161
310 by Suren A. Chilingaryan
Introduce hashes
162
    if (!regctx->views) return NULL;
309 by Suren A. Chilingaryan
Base functions for views
163
164
    for (i = 0; regctx->views[i].name; i++) {
311 by Suren A. Chilingaryan
Implement enum view
165
	if (!strcasecmp(name, regctx->views[i].name)) {
310 by Suren A. Chilingaryan
Introduce hashes
166
	    return pcilib_find_view_context_by_name(ctx, regctx->views[i].view);
309 by Suren A. Chilingaryan
Base functions for views
167
	}
168
    }
310 by Suren A. Chilingaryan
Introduce hashes
169
170
    return NULL;
309 by Suren A. Chilingaryan
Base functions for views
171
}
172
173
    // We expect symmetric units. Therefore, we don't distringuish if we read or write
314 by Suren A. Chilingaryan
Support writting register views
174
static int pcilib_detect_register_view_and_unit(pcilib_t *ctx, pcilib_register_t reg, const char *name, int write_direction, pcilib_view_context_t **ret_view, pcilib_unit_transform_t **ret_trans) {
309 by Suren A. Chilingaryan
Base functions for views
175
    pcilib_view_t i;
310 by Suren A. Chilingaryan
Introduce hashes
176
    pcilib_view_context_t *view_ctx;
177
    pcilib_view_description_t *view_desc;
309 by Suren A. Chilingaryan
Base functions for views
178
    pcilib_register_context_t *regctx = &ctx->register_ctx[reg];
179
312 by Suren A. Chilingaryan
Support transform views
180
    if (!regctx->views) return PCILIB_ERROR_NOTFOUND;
309 by Suren A. Chilingaryan
Base functions for views
181
182
	// Check if view is just a name of listed view
310 by Suren A. Chilingaryan
Introduce hashes
183
    view_ctx = pcilib_find_register_view_context_by_name(ctx, reg, name);
312 by Suren A. Chilingaryan
Support transform views
184
    if (view_ctx) {
185
        if (ret_view) *ret_view = view_ctx;
186
        if (ret_trans) *ret_trans = NULL;
187
        return 0;
188
    }
309 by Suren A. Chilingaryan
Base functions for views
189
190
	// Check if view is a unit
191
    for (i = 0; regctx->views[i].name; i++) {
192
	pcilib_unit_transform_t *trans;
310 by Suren A. Chilingaryan
Introduce hashes
193
194
	view_ctx = pcilib_find_view_context_by_name(ctx, regctx->views[i].view);
195
	if (!view_ctx) continue;
196
197
        view_desc = ctx->views[view_ctx->view];
198
        if (view_desc->unit) {
314 by Suren A. Chilingaryan
Support writting register views
199
            if (write_direction)
200
	        trans = pcilib_find_transform_by_unit_names(ctx, name, view_desc->unit);
201
            else
202
	        trans = pcilib_find_transform_by_unit_names(ctx, view_desc->unit, name);
312 by Suren A. Chilingaryan
Support transform views
203
	    if (trans) {
204
	        if (ret_trans) *ret_trans = trans;
205
	        if (ret_view) *ret_view = pcilib_find_view_context_by_name(ctx, view_desc->name);
206
	        return 0;
207
	    }
309 by Suren A. Chilingaryan
Base functions for views
208
	}
209
    }
210
312 by Suren A. Chilingaryan
Support transform views
211
    return PCILIB_ERROR_NOTFOUND;
212
}
213
214
pcilib_view_context_t *pcilib_find_register_view_context(pcilib_t *ctx, pcilib_register_t reg, const char *name) {
215
    int err;
216
    pcilib_view_context_t *view;
217
314 by Suren A. Chilingaryan
Support writting register views
218
    err = pcilib_detect_register_view_and_unit(ctx, reg, name, 0, &view, NULL);
312 by Suren A. Chilingaryan
Support transform views
219
    if (err) return NULL;
220
221
    return view;
222
}
309 by Suren A. Chilingaryan
Base functions for views
223
224
typedef struct {
225
    pcilib_register_t reg;
310 by Suren A. Chilingaryan
Introduce hashes
226
    pcilib_view_context_t *view;
309 by Suren A. Chilingaryan
Base functions for views
227
    pcilib_unit_transform_t *trans;
228
} pcilib_view_configuration_t;
229
318 by Suren A. Chilingaryan
Support reading/writting register views by id
230
static int pcilib_detect_view_configuration(pcilib_t *ctx, pcilib_register_t reg, const char *view_cname, const char *unit_cname, int write_direction, pcilib_view_configuration_t *cfg) {
312 by Suren A. Chilingaryan
Support transform views
231
    int err = 0;
309 by Suren A. Chilingaryan
Base functions for views
232
    pcilib_view_t view;
318 by Suren A. Chilingaryan
Support reading/writting register views by id
233
    const char *regname;
310 by Suren A. Chilingaryan
Introduce hashes
234
    pcilib_view_context_t *view_ctx;
235
    pcilib_unit_transform_t *trans = NULL;
309 by Suren A. Chilingaryan
Base functions for views
236
237
    char *view_name = alloca(strlen(view_cname) + 1);
315 by Suren A. Chilingaryan
Support properties of arbitrary type
238
    const char *unit_name;
309 by Suren A. Chilingaryan
Base functions for views
239
240
    strcpy(view_name, view_cname);
241
315 by Suren A. Chilingaryan
Support properties of arbitrary type
242
    if (unit_cname) unit_name = unit_cname;
243
    else {
244
        unit_name = strchr(view_name, ':');
245
        if (unit_name) {
246
	    *(char*)unit_name = 0;
247
	    unit_name++;
248
        }
309 by Suren A. Chilingaryan
Base functions for views
249
    }
250
318 by Suren A. Chilingaryan
Support reading/writting register views by id
251
    if (reg == PCILIB_REGISTER_INVALID) regname = NULL;
252
    else regname = ctx->registers[reg].name;
315 by Suren A. Chilingaryan
Support properties of arbitrary type
253
309 by Suren A. Chilingaryan
Base functions for views
254
    if (regname) {
310 by Suren A. Chilingaryan
Introduce hashes
255
	if (unit_name) view_ctx = pcilib_find_register_view_context_by_name(ctx, reg, view_name);
314 by Suren A. Chilingaryan
Support writting register views
256
	else err = pcilib_detect_register_view_and_unit(ctx, reg, view_name, write_direction, &view_ctx, &trans);
309 by Suren A. Chilingaryan
Base functions for views
257
312 by Suren A. Chilingaryan
Support transform views
258
	if ((err)||(!view_ctx)) {
309 by Suren A. Chilingaryan
Base functions for views
259
	    pcilib_error("Can't find the specified view %s for register %s", view_name, regname);
260
	    return PCILIB_ERROR_NOTFOUND;
261
	}
262
    } else {
310 by Suren A. Chilingaryan
Introduce hashes
263
        view_ctx = pcilib_find_view_context_by_name(ctx, view_name);
264
	if (!view_ctx) {
309 by Suren A. Chilingaryan
Base functions for views
265
	    pcilib_error("Can't find the specified view %s", view_name);
266
	    return PCILIB_ERROR_NOTFOUND;
267
	}
268
    }
310 by Suren A. Chilingaryan
Introduce hashes
269
    view = view_ctx->view;
309 by Suren A. Chilingaryan
Base functions for views
270
271
    if (unit_name) {
272
        if (write_direction) trans = pcilib_find_transform_by_unit_names(ctx, unit_name, ctx->views[view]->unit);
273
        else trans = pcilib_find_transform_by_unit_names(ctx, ctx->views[view]->unit, unit_name);
274
275
        if (!trans) {
276
            pcilib_error("Don't know how to get the requested unit %s for view %s", unit_name, ctx->views[view]->name);
277
            return PCILIB_ERROR_NOTFOUND;
278
        }
279
    }
280
312 by Suren A. Chilingaryan
Support transform views
281
        // No transform is required
315 by Suren A. Chilingaryan
Support properties of arbitrary type
282
    if ((trans)&&(!trans->transform)) trans = NULL;
312 by Suren A. Chilingaryan
Support transform views
283
309 by Suren A. Chilingaryan
Base functions for views
284
    cfg->reg = reg;
310 by Suren A. Chilingaryan
Introduce hashes
285
    cfg->view = view_ctx;
309 by Suren A. Chilingaryan
Base functions for views
286
    cfg->trans = trans;
287
288
    return 0;
289
}
290
318 by Suren A. Chilingaryan
Support reading/writting register views by id
291
int pcilib_read_register_view_by_id(pcilib_t *ctx, pcilib_register_t reg, const char *view, pcilib_value_t *val) {
309 by Suren A. Chilingaryan
Base functions for views
292
    int err;
293
318 by Suren A. Chilingaryan
Support reading/writting register views by id
294
    const char *regname;
295
310 by Suren A. Chilingaryan
Introduce hashes
296
    pcilib_view_description_t *v;
309 by Suren A. Chilingaryan
Base functions for views
297
    pcilib_view_configuration_t cfg;
298
    pcilib_register_value_t regvalue = 0;
299
318 by Suren A. Chilingaryan
Support reading/writting register views by id
300
    if (reg == PCILIB_REGISTER_INVALID) regname = NULL;
301
    else regname = ctx->registers[reg].name;
302
303
    err = pcilib_detect_view_configuration(ctx, reg, view, NULL, 0, &cfg);
309 by Suren A. Chilingaryan
Base functions for views
304
    if (err) return err;
305
310 by Suren A. Chilingaryan
Introduce hashes
306
    v = ctx->views[cfg.view->view];
307
308
    if (!v->api->read_from_reg) {
309 by Suren A. Chilingaryan
Base functions for views
309
        pcilib_error("The view (%s) does not support reading from the register", view);
310
        return PCILIB_ERROR_NOTSUPPORTED;
311
    }
312
315 by Suren A. Chilingaryan
Support properties of arbitrary type
313
    if ((v->mode & PCILIB_REGISTER_R) == 0) {
314
        pcilib_error("The view (%s) does not allow reading from the register", view);
315
        return PCILIB_ERROR_NOTPERMITED;
316
    }
317
309 by Suren A. Chilingaryan
Base functions for views
318
    if (regname) {
319
        err = pcilib_read_register_by_id(ctx, cfg.reg, &regvalue);
320
        if (err) {
321
            pcilib_error("Error (%i) reading register %s", err, regname);
322
            return err;
323
        }
324
    }
325
326
    pcilib_clean_value(ctx, val);
327
311 by Suren A. Chilingaryan
Implement enum view
328
    err = v->api->read_from_reg(ctx, cfg.view, regvalue, val);
309 by Suren A. Chilingaryan
Base functions for views
329
    if (err) {
330
        if (regname) 
331
            pcilib_error("Error (%i) computing view (%s) of register %s", err, view, regname);
332
        else
333
            pcilib_error("Error (%i) computing view %s", err, view);
334
        return err;
335
    }
336
315 by Suren A. Chilingaryan
Support properties of arbitrary type
337
    if (v->unit) {
338
        val->unit = v->unit;
339
    }
340
309 by Suren A. Chilingaryan
Base functions for views
341
    if (cfg.trans) {
342
        err = pcilib_transform_unit(ctx, cfg.trans, val);
343
        if (err) return err;
344
    }
345
346
    return 0;
347
}
348
318 by Suren A. Chilingaryan
Support reading/writting register views by id
349
int pcilib_read_register_view(pcilib_t *ctx, const char *bank, const char *regname, const char *view, pcilib_value_t *val) {
350
    pcilib_register_t reg;
351
352
    if (regname) {
353
	reg = pcilib_find_register(ctx, bank, regname);
354
	if (reg == PCILIB_REGISTER_INVALID) {
355
	    pcilib_error("Register (%s) is not found", regname);
356
	    return PCILIB_ERROR_NOTFOUND;
357
	}
358
    } else {
359
        reg = PCILIB_REGISTER_INVALID;
360
    }
361
362
    return pcilib_read_register_view_by_id(ctx, reg, view, val);
363
}
364
365
366
int pcilib_write_register_view_by_id(pcilib_t *ctx, pcilib_register_t reg, const char *view, const pcilib_value_t *valarg) {
309 by Suren A. Chilingaryan
Base functions for views
367
    int err;
311 by Suren A. Chilingaryan
Implement enum view
368
    pcilib_value_t val = {0};
309 by Suren A. Chilingaryan
Base functions for views
369
318 by Suren A. Chilingaryan
Support reading/writting register views by id
370
    const char *regname;
371
310 by Suren A. Chilingaryan
Introduce hashes
372
    pcilib_view_description_t *v;
309 by Suren A. Chilingaryan
Base functions for views
373
    pcilib_view_configuration_t cfg;
374
    pcilib_register_value_t regvalue = 0;
375
318 by Suren A. Chilingaryan
Support reading/writting register views by id
376
    if (reg == PCILIB_REGISTER_INVALID) regname = NULL;
377
    else regname = ctx->registers[reg].name;
378
379
    err = pcilib_detect_view_configuration(ctx, reg, view, valarg->unit, 1, &cfg);
309 by Suren A. Chilingaryan
Base functions for views
380
    if (err) return err;
381
310 by Suren A. Chilingaryan
Introduce hashes
382
    v = ctx->views[cfg.view->view];
383
384
    if (!v->api->write_to_reg) {
315 by Suren A. Chilingaryan
Support properties of arbitrary type
385
        pcilib_error("The view (%s) does not support writting to the register", view);
309 by Suren A. Chilingaryan
Base functions for views
386
        return PCILIB_ERROR_NOTSUPPORTED;
387
    }
388
315 by Suren A. Chilingaryan
Support properties of arbitrary type
389
    if ((v->mode & PCILIB_REGISTER_W) == 0) {
390
        pcilib_error("The view (%s) does not allow writting to the register", view);
391
        return PCILIB_ERROR_NOTPERMITED;
392
    }
393
309 by Suren A. Chilingaryan
Base functions for views
394
    err = pcilib_copy_value(ctx, &val, valarg);
395
    if (err) return err;
396
310 by Suren A. Chilingaryan
Introduce hashes
397
    err = pcilib_convert_value_type(ctx, &val, v->type);
309 by Suren A. Chilingaryan
Base functions for views
398
    if (err) {
310 by Suren A. Chilingaryan
Introduce hashes
399
        pcilib_error("Error (%i) converting the value of type (%s) to type (%s) used by view (%s)", pcilib_get_type_name(val.type), pcilib_get_type_name(v->type), view);
309 by Suren A. Chilingaryan
Base functions for views
400
        return err;
401
    }
402
403
    if (cfg.trans) {
404
        err = pcilib_transform_unit(ctx, cfg.trans, &val);
405
        if (err) return err;
406
    }
407
310 by Suren A. Chilingaryan
Introduce hashes
408
    err = v->api->write_to_reg(ctx, cfg.view, &regvalue, &val);
309 by Suren A. Chilingaryan
Base functions for views
409
    if (err) {
410
        if (regname) 
411
            pcilib_error("Error (%i) computing view (%s) of register %s", err, view, regname);
412
        else
413
            pcilib_error("Error (%i) computing view %s", err, view);
414
        return err;
415
    }
416
417
    if (regname) {
418
        err = pcilib_write_register_by_id(ctx, cfg.reg, regvalue);
419
        if (err) {
420
            pcilib_error("Error (%i) reading register %s", err, regname);
421
            return err;
422
        }
423
    }
424
425
    return 0;
426
}
318 by Suren A. Chilingaryan
Support reading/writting register views by id
427
428
int pcilib_write_register_view(pcilib_t *ctx, const char *bank, const char *regname, const char *view, const pcilib_value_t *val) {
429
    pcilib_register_t reg;
430
431
    if (regname) {
432
	reg = pcilib_find_register(ctx, bank, regname);
433
	if (reg == PCILIB_REGISTER_INVALID) {
434
	    pcilib_error("Register (%s) is not found", regname);
435
	    return PCILIB_ERROR_NOTFOUND;
436
	}
437
    } else {
438
        reg = PCILIB_REGISTER_INVALID;
439
    }
440
441
    return pcilib_write_register_view_by_id(ctx, reg, view, val);
442
}