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, ®value); |
|
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, ®value, &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 |
}
|