7
#include <views/register.h>
18
int pcilib_add_register_properties(pcilib_t *ctx, size_t n, const pcilib_register_bank_t *banks, const pcilib_register_description_t *registers) {
22
pcilib_view_t cur_view = ctx->num_views;
23
pcilib_view_context_t *view_ctx;
26
return PCILIB_ERROR_INVALID_ARGUMENT;
29
for (i = 0; i < n; i++) {
30
pcilib_access_mode_t mode = 0;
32
pcilib_register_view_description_t v;
33
pcilib_register_bank_description_t *b = &ctx->banks[banks[i]];
35
char *view_name = malloc(strlen(registers[i].name) + strlen(b->name) + 13);
37
pcilib_clean_views(ctx, cur_view);
38
return PCILIB_ERROR_MEMORY;
41
sprintf(view_name, "/registers/%s/%s", b->name, registers[i].name);
43
if ((registers[i].views)&&(registers[i].views[0].view)) {
44
pcilib_view_t view = pcilib_find_view_by_name(ctx, registers[i].views[0].view);
45
if (view == PCILIB_VIEW_INVALID) return PCILIB_ERROR_NOTFOUND;
47
memcpy(&v, ctx->views[view], sizeof(pcilib_view_description_t));
48
v.view = registers[i].views[0].name;
50
if (ctx->views[view]->api->read_from_reg) mode |= PCILIB_ACCESS_R;
51
if (ctx->views[view]->api->write_to_reg) mode |= PCILIB_ACCESS_W;
52
mode &= ctx->views[view]->mode;
54
v.base.type = PCILIB_TYPE_LONG;
55
mode = PCILIB_ACCESS_RW;
58
v.base.api = &pcilib_register_view_api;
59
v.base.name = view_name;
60
v.base.description = registers[i].description;
61
v.base.mode = registers[i].mode&mode;
62
v.reg = registers[i].name;
65
err = pcilib_add_views(ctx, 1, (pcilib_view_description_t*)&v);
68
pcilib_clean_views(ctx, cur_view);
72
view_ctx = pcilib_find_view_context_by_name(ctx, v.base.name);
73
view_ctx->flags |= PCILIB_VIEW_FLAG_PROPERTY;
79
pcilib_property_info_t *pcilib_get_property_list(pcilib_t *ctx, const char *branch, pcilib_list_flags_t flags) {
83
size_t name_offset = 0;
84
pcilib_view_context_t *view_ctx, *view_tmp;
85
pcilib_property_info_t *info = (pcilib_property_info_t*)malloc((ctx->num_views + 1) * sizeof(pcilib_property_info_t));
90
} *dir_hash = NULL, *dir, *dir_tmp;
93
name_offset = strlen(branch);
94
if (branch[name_offset - 1] != '/') name_offset++;
98
HASH_ITER(hh, ctx->view_hash, view_ctx, view_tmp) {
99
const pcilib_view_description_t *v = ctx->views[view_ctx->view];
100
const char *subname = v->name + name_offset;
103
if (!(view_ctx->flags&PCILIB_VIEW_FLAG_PROPERTY)) continue;
104
if ((branch)&&(strncasecmp(branch, v->name, strlen(branch)))) continue;
106
suffix = strchr(subname, '/');
108
char *name = strndup(v->name, suffix - v->name);
110
err = PCILIB_ERROR_MEMORY;
114
HASH_FIND_STR(dir_hash, name + name_offset, dir);
121
dir = (struct dir_hash_s*)malloc(sizeof(struct dir_hash_s));
123
err = PCILIB_ERROR_MEMORY;
129
HASH_ADD_KEYPTR(hh, dir_hash, dir->name + name_offset, strlen(dir->name + name_offset), dir);
133
HASH_ITER(hh, ctx->view_hash, view_ctx, view_tmp) {
134
const pcilib_view_description_t *v = ctx->views[view_ctx->view];
135
const char *subname = v->name + name_offset;
137
if (!(view_ctx->flags&PCILIB_VIEW_FLAG_PROPERTY)) continue;
138
if ((branch)&&(strncasecmp(branch, v->name, strlen(branch)))) continue;
140
if (!strchr(subname, '/')) {
141
pcilib_view_context_t *found_view;
143
char *path = strdup(v->name);
145
err = PCILIB_ERROR_MEMORY;
148
char *name = strrchr(v->name, '/');
152
HASH_FIND_STR(dir_hash, name, found_view);
154
info[pos++] = (pcilib_property_info_t) {
157
.description = v->description,
161
.flags = (found_view?PCILIB_LIST_FLAG_CHILDS:0)
164
if (found_view) HASH_DEL(dir_hash, found_view);
168
HASH_ITER(hh, dir_hash, dir, dir_tmp) {
169
char *name = strrchr(dir->name, '/');
171
else name = dir->name;
173
info[pos++] = (pcilib_property_info_t) {
176
.type = PCILIB_TYPE_INVALID,
177
.flags = PCILIB_LIST_FLAG_CHILDS
181
HASH_CLEAR(hh, dir_hash);
183
memset(&info[pos], 0, sizeof(pcilib_property_info_t));
186
pcilib_free_property_info(ctx, info);
193
void pcilib_free_property_info(pcilib_t *ctx, pcilib_property_info_t *info) {
196
for (i = 0; info[i].path; i++)
197
free((char*)info[i].path);
201
int pcilib_get_property(pcilib_t *ctx, const char *prop, pcilib_value_t *val) {
202
return pcilib_read_register_view(ctx, NULL, NULL, prop, val);
205
int pcilib_set_property(pcilib_t *ctx, const char *prop, const pcilib_value_t *val) {
206
return pcilib_write_register_view(ctx, NULL, NULL, prop, val);