summaryrefslogtreecommitdiffstats
path: root/pcilib
diff options
context:
space:
mode:
authorSuren A. Chilingaryan <csa@suren.me>2015-10-09 03:11:34 +0200
committerSuren A. Chilingaryan <csa@suren.me>2015-10-09 03:11:34 +0200
commit3b8e32c9bbe0d909c34303da0ad36ef0ef5be852 (patch)
treeed22378979b2889a84615cf9f24de76359a95244 /pcilib
parent21812f8d763fac8ee9bb3fdc593642b06f405a2b (diff)
downloadpcitool-3b8e32c9bbe0d909c34303da0ad36ef0ef5be852.tar.gz
pcitool-3b8e32c9bbe0d909c34303da0ad36ef0ef5be852.tar.bz2
pcitool-3b8e32c9bbe0d909c34303da0ad36ef0ef5be852.tar.xz
pcitool-3b8e32c9bbe0d909c34303da0ad36ef0ef5be852.zip
Introduce hashes
Diffstat (limited to 'pcilib')
-rw-r--r--pcilib/bank.c14
-rw-r--r--pcilib/pci.c25
-rw-r--r--pcilib/pci.h17
-rw-r--r--pcilib/register.c37
-rw-r--r--pcilib/register.h1
-rw-r--r--pcilib/unit.c96
-rw-r--r--pcilib/unit.h3
-rw-r--r--pcilib/view.c144
-rw-r--r--pcilib/view.h20
9 files changed, 249 insertions, 108 deletions
diff --git a/pcilib/bank.c b/pcilib/bank.c
index 66ff739..24ddf1f 100644
--- a/pcilib/bank.c
+++ b/pcilib/bank.c
@@ -208,6 +208,7 @@ pcilib_register_t pcilib_find_register(pcilib_t *ctx, const char *bank, const ch
pcilib_register_t i;
pcilib_register_bank_t bank_id;
pcilib_register_bank_addr_t bank_addr = 0;
+ pcilib_register_context_t *reg_ctx;
const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
const pcilib_register_description_t *registers = model_info->registers;
@@ -220,11 +221,16 @@ pcilib_register_t pcilib_find_register(pcilib_t *ctx, const char *bank, const ch
}
bank_addr = model_info->banks[bank_id].addr;
+
+ // ToDo: we can use additionaly per-bank hashes
+ for (i = 0; registers[i].bits; i++) {
+ if ((!strcasecmp(registers[i].name, reg))&&((!bank)||(registers[i].bank == bank_addr))) return i;
+ }
+ } else {
+ HASH_FIND_STR(ctx->reg_hash, reg, reg_ctx);
+ if (reg_ctx) return reg_ctx->reg;
}
-
- for (i = 0; registers[i].bits; i++) {
- if ((!strcasecmp(registers[i].name, reg))&&((!bank)||(registers[i].bank == bank_addr))) return i;
- }
+
return PCILIB_REGISTER_INVALID;
};
diff --git a/pcilib/pci.c b/pcilib/pci.c
index 0ba5f51..4a0e79c 100644
--- a/pcilib/pci.c
+++ b/pcilib/pci.c
@@ -365,7 +365,6 @@ char *pcilib_resolve_data_space(pcilib_t *ctx, uintptr_t addr, size_t *size) {
void pcilib_close(pcilib_t *ctx) {
- int i;
pcilib_bar_t bar;
if (ctx) {
@@ -386,15 +385,6 @@ void pcilib_close(pcilib_t *ctx) {
pcilib_free_register_banks(ctx);
- if (ctx->register_ctx) {
- pcilib_register_t reg;
- for (reg = 0; reg < ctx->num_reg; reg++) {
- if (ctx->register_ctx[reg].views)
- free(ctx->register_ctx[reg].views);
- }
- free(ctx->register_ctx);
- }
-
if (ctx->event_plugin)
pcilib_plugin_close(ctx->event_plugin);
@@ -422,15 +412,22 @@ void pcilib_close(pcilib_t *ctx) {
if (ctx->pci_cfg_space_fd >= 0)
close(ctx->pci_cfg_space_fd);
- if (ctx->units);
- free(ctx->units);
+
+ if (ctx->units) {
+ pcilib_clean_units(ctx);
+ free(ctx->units);
+ }
if (ctx->views) {
- for (i = 0; ctx->views[i]; i++)
- free(ctx->views[i]);
+ pcilib_clean_views(ctx);
free(ctx->views);
}
+ pcilib_clean_registers(ctx);
+
+ if (ctx->register_ctx)
+ free(ctx->register_ctx);
+
if (ctx->registers)
free(ctx->registers);
diff --git a/pcilib/pci.h b/pcilib/pci.h
index 88327b3..ff18e52 100644
--- a/pcilib/pci.h
+++ b/pcilib/pci.h
@@ -40,22 +40,25 @@ typedef struct {
} pcilib_pcie_link_info_t;
struct pcilib_view_context_s {
- UT_hash_handle hh;
+ const char *name;
pcilib_view_t view;
-// pcilib_view_description_t desc; /**< We will allocate more memory and store actual description instance here, so it should be the last member */
-};
+ UT_hash_handle hh;
+};
struct pcilib_unit_context_s {
- UT_hash_handle hh;
+ const char *name;
pcilib_unit_t unit;
-// pcilib_unit_description_t desc;
+ UT_hash_handle hh;
};
typedef struct {
+ const char *name; /**< Register name */
+ pcilib_register_t reg; /**< Register index */
pcilib_register_bank_t bank; /**< Reference to bank containing the register */
pcilib_register_value_t min, max; /**< Minimum & maximum allowed values */
pcilib_xml_node_t *xml; /**< Additional XML properties */
pcilib_view_reference_t *views; /**< For non-static list of views, this vairables holds a copy of a NULL-terminated list from model (if present, memory should be de-allocated) */
+ UT_hash_handle hh;
} pcilib_register_context_t;
struct pcilib_s {
@@ -104,6 +107,10 @@ struct pcilib_s {
pcilib_view_description_t **views; /**< list of currently defined views */
pcilib_unit_description_t *units; /**< list of currently defined units */
+ pcilib_unit_context_t *unit_hash; /**< Hash of units */
+ pcilib_view_context_t *view_hash; /**< Hash of views */
+ pcilib_register_context_t *reg_hash; /**< Hash of registers */
+
pcilib_lock_t *dma_rlock[PCILIB_MAX_DMA_ENGINES]; /**< Per-engine locks to serialize streaming and read operations */
pcilib_lock_t *dma_wlock[PCILIB_MAX_DMA_ENGINES]; /**< Per-engine locks to serialize write operations */
diff --git a/pcilib/register.c b/pcilib/register.c
index 68e5d36..3a60800 100644
--- a/pcilib/register.c
+++ b/pcilib/register.c
@@ -23,6 +23,7 @@ int pcilib_add_registers(pcilib_t *ctx, pcilib_model_modification_flags_t flags,
// DS: Overrride existing registers
// Registers identified by addr + offset + size + type or name
+ pcilib_register_t i;
pcilib_register_description_t *regs;
pcilib_register_context_t *reg_ctx;
size_t size;
@@ -45,11 +46,26 @@ int pcilib_add_registers(pcilib_t *ctx, pcilib_model_modification_flags_t flags,
memset(reg_ctx + ctx->alloc_reg, 0, (size - ctx->alloc_reg) * sizeof(pcilib_register_context_t));
- ctx->register_ctx = reg_ctx;
+ if (ctx->register_ctx != reg_ctx) {
+ // We need to recreate cache if context is moved...
+ HASH_CLEAR(hh, ctx->reg_hash);
+ for (i = 0; i < ctx->num_reg; i++) {
+ pcilib_register_context_t *cur = &ctx->register_ctx[ctx->num_reg + i];
+ HASH_ADD_KEYPTR(hh, ctx->reg_hash, cur->name, strlen(cur->name), cur);
+ }
+ }
+ ctx->register_ctx = reg_ctx;
ctx->alloc_reg = size;
}
+ for (i = 0; i < n; i++) {
+ pcilib_register_context_t *cur = &ctx->register_ctx[ctx->num_reg + i];
+ cur->reg = ctx->num_reg + i;
+ cur->name = registers[i].name;
+ HASH_ADD_KEYPTR(hh, ctx->reg_hash, cur->name, strlen(cur->name), cur);
+ }
+
memcpy(ctx->registers + ctx->num_reg, registers, n * sizeof(pcilib_register_description_t));
memset(ctx->registers + ctx->num_reg + n, 0, sizeof(pcilib_register_description_t));
@@ -61,11 +77,28 @@ int pcilib_add_registers(pcilib_t *ctx, pcilib_model_modification_flags_t flags,
}
ctx->num_reg += n;
-
+
return 0;
}
+void pcilib_clean_registers(pcilib_t *ctx) {
+ pcilib_register_t reg;
+
+ HASH_CLEAR(hh, ctx->reg_hash);
+ for (reg = 0; reg < ctx->num_reg; reg++) {
+ if (ctx->register_ctx[reg].views)
+ free(ctx->register_ctx[reg].views);
+ }
+
+ if (ctx->registers)
+ memset(ctx->registers, 0, sizeof(pcilib_register_description_t));
+
+ if (ctx->register_ctx)
+ memset(ctx->register_ctx, 0, ctx->alloc_reg * sizeof(pcilib_register_context_t));
+
+ ctx->num_reg = 0;
+}
static int pcilib_read_register_space_internal(pcilib_t *ctx, pcilib_register_bank_t bank, pcilib_register_addr_t addr, size_t n, pcilib_register_size_t offset, pcilib_register_size_t bits, pcilib_register_value_t *buf) {
int err;
diff --git a/pcilib/register.h b/pcilib/register.h
index 74eeb12..95f52cc 100644
--- a/pcilib/register.h
+++ b/pcilib/register.h
@@ -55,6 +55,7 @@ extern "C" {
#endif
int pcilib_add_registers(pcilib_t *ctx, pcilib_model_modification_flags_t flags, size_t n, const pcilib_register_description_t *registers, pcilib_register_t *ids);
+void pcilib_clean_registers(pcilib_t *ctx);
#ifdef __cplusplus
}
diff --git a/pcilib/unit.c b/pcilib/unit.c
index 6817afc..0295120 100644
--- a/pcilib/unit.c
+++ b/pcilib/unit.c
@@ -8,16 +8,79 @@
#include "unit.h"
#include "error.h"
-
static pcilib_unit_transform_t pcilib_unit_transform_null = { NULL, NULL };
+int pcilib_add_units(pcilib_t *ctx, size_t n, const pcilib_unit_description_t *desc) {
+ size_t i;
+ int err = 0;
+
+ if (!n) {
+ for (n = 0; desc[n].name; n++);
+ }
+
+ if ((ctx->num_units + n + 1) > ctx->alloc_units) {
+ size_t size;
+ pcilib_unit_description_t *units;
+
+ for (size = ctx->alloc_units; size < 2 * (n + ctx->num_units + 1); size <<= 1);
+
+ units = (pcilib_unit_description_t*)realloc(ctx->units, size * sizeof(pcilib_unit_description_t));
+ if (!units) return PCILIB_ERROR_MEMORY;
+
+ ctx->units = units;
+ ctx->alloc_units = size;
+
+ ctx->model_info.units = units;
+ }
+
+ // ToDo: Check if exists...
+ for (i = 0; i < n; i++) {
+ pcilib_unit_context_t *unit_ctx = (pcilib_unit_context_t*)malloc(sizeof(pcilib_unit_context_t));
+ if (!unit_ctx) {
+ err = PCILIB_ERROR_MEMORY;
+ break;
+ }
+ memset(unit_ctx, 0, sizeof(pcilib_unit_context_t));
+ unit_ctx->unit = ctx->num_units + i;
+ unit_ctx->name = desc[i].name;
+
+ HASH_ADD_KEYPTR(hh, ctx->unit_hash, unit_ctx->name, strlen(unit_ctx->name), unit_ctx);
+ memcpy(ctx->units + ctx->num_units + i, &desc[i], sizeof(pcilib_unit_description_t));
+ }
+
+ memset(ctx->units + ctx->num_units + i, 0, sizeof(pcilib_unit_description_t));
+ ctx->num_units += i;
+
+ return err;
+}
+
+void pcilib_clean_units(pcilib_t *ctx) {
+ pcilib_unit_context_t *s, *tmp;
+
+ if (ctx->unit_hash) {
+ HASH_ITER(hh, ctx->unit_hash, s, tmp) {
+ HASH_DEL(ctx->unit_hash, s);
+ free(s);
+ }
+ }
+
+ memset(ctx->units, 0, sizeof(pcilib_unit_description_t));
+ ctx->num_units = 0;
+}
+
pcilib_unit_t pcilib_find_unit_by_name(pcilib_t *ctx, const char *name) {
- pcilib_unit_t i;
+ pcilib_unit_context_t *unit_ctx = NULL;
+ HASH_FIND_STR(ctx->unit_hash, name, unit_ctx);
+ if (unit_ctx) return unit_ctx->unit;
+
+/*
+ pcilib_unit_t i;
for(i = 0; ctx->units[i].name; i++) {
if (!strcasecmp(ctx->units[i].name, name))
return i;
}
+*/
return PCILIB_UNIT_INVALID;
}
@@ -42,35 +105,6 @@ pcilib_unit_transform_t *pcilib_find_transform_by_unit_names(pcilib_t *ctx, cons
return NULL;
}
-int pcilib_add_units(pcilib_t *ctx, size_t n, const pcilib_unit_description_t *desc) {
- if (!n) {
- for (n = 0; desc[n].name; n++);
- }
-
- if ((ctx->num_units + n + 1) > ctx->alloc_units) {
- size_t size;
- pcilib_unit_description_t *units;
-
- for (size = ctx->alloc_units; size < 2 * (n + ctx->num_units + 1); size <<= 1);
-
- units = (pcilib_unit_description_t*)realloc(ctx->units, size * sizeof(pcilib_unit_description_t));
- if (!units) return PCILIB_ERROR_MEMORY;
-
- ctx->units = units;
- ctx->alloc_units = size;
-
- ctx->model_info.units = units;
- }
-
- memcpy(ctx->units + ctx->num_units, desc, n * sizeof(pcilib_unit_description_t));
- memset(ctx->units + ctx->num_units + n, 0, sizeof(pcilib_unit_description_t));
-
- ctx->num_units += n;
-
- return 0;
-}
-
-
int pcilib_transform_unit(pcilib_t *ctx, pcilib_unit_transform_t *trans, pcilib_value_t *value) {
int err;
diff --git a/pcilib/unit.h b/pcilib/unit.h
index e0eeefc..dad7962 100644
--- a/pcilib/unit.h
+++ b/pcilib/unit.h
@@ -8,7 +8,7 @@
#define PCILIB_MAX_TRANSFORMS_PER_UNIT 16 /**< Limits number of supported transforms per unit */
-typedef struct pcilib_unit_context_s *pcilib_unit_context_t;
+typedef struct pcilib_unit_context_s pcilib_unit_context_t;
/**
* unit transformation routines
@@ -28,6 +28,7 @@ extern "C" {
#endif
int pcilib_add_units(pcilib_t *ctx, size_t n, const pcilib_unit_description_t *desc);
+void pcilib_clean_units(pcilib_t *ctx);
pcilib_unit_t pcilib_find_unit_by_name(pcilib_t *ctx, const char *unit);
pcilib_unit_transform_t *pcilib_find_transform_by_unit_names(pcilib_t *ctx, const char *from, const char *to);
diff --git a/pcilib/view.c b/pcilib/view.c
index d121f34..bf312e4 100644
--- a/pcilib/view.c
+++ b/pcilib/view.c
@@ -11,6 +11,7 @@
#include "value.h"
int pcilib_add_views(pcilib_t *ctx, size_t n, const pcilib_view_description_t *desc) {
+ int err = 0;
size_t i;
void *ptr;
@@ -43,88 +44,138 @@ int pcilib_add_views(pcilib_t *ctx, size_t n, const pcilib_view_description_t *d
ptr = (void*)desc;
for (i = 0; i < n; i++) {
const pcilib_view_description_t *v = (const pcilib_view_description_t*)ptr;
+ pcilib_view_context_t *view_ctx;
+
ctx->views[ctx->num_views + i] = (pcilib_view_description_t*)malloc(v->api->description_size);
if (!ctx->views[ctx->num_views + i]) {
- size_t j;
- for (j = 0; j < i; j++)
- free(ctx->views[ctx->num_views + j]);
- ctx->views[ctx->num_views] = NULL;
- pcilib_error("Error allocating %zu bytes of memory for the view description", v->api->description_size);
- return PCILIB_ERROR_MEMORY;
+ err = PCILIB_ERROR_MEMORY;
+ break;
+ }
+
+ if (v->api->init)
+ view_ctx = v->api->init(ctx);
+ else {
+ view_ctx = (pcilib_view_context_t*)malloc(sizeof(pcilib_view_context_t));
+ memset(view_ctx, 0, sizeof(pcilib_view_context_t));
}
+
+ view_ctx->view = ctx->num_views + i;
+ view_ctx->name = v->name;
+
+ if (!view_ctx) {
+ free(ctx->views[ctx->num_views + i]);
+ err = PCILIB_ERROR_MEMORY;
+ break;
+ }
+
+ HASH_ADD_KEYPTR(hh, ctx->view_hash, view_ctx->name, strlen(view_ctx->name), view_ctx);
memcpy(ctx->views[ctx->num_views + i], v, v->api->description_size);
ptr += v->api->description_size;
}
ctx->views[ctx->num_views + i] = NULL;
- ctx->num_views += n;
+ ctx->num_views += i;
- return 0;
+ return err;
}
-
-pcilib_view_t pcilib_find_view_by_name(pcilib_t *ctx, const char *name) {
+void pcilib_clean_views(pcilib_t *ctx) {
pcilib_view_t i;
+ pcilib_view_context_t *view_ctx, *tmp;
+
+ if (ctx->unit_hash) {
+ HASH_ITER(hh, ctx->view_hash, view_ctx, tmp) {
+ const pcilib_view_description_t *v = ctx->views[view_ctx->view];
+
+ HASH_DEL(ctx->view_hash, view_ctx);
+ if (v->api->free) v->api->free(ctx, view_ctx);
+ else free(view_ctx);
+ }
+ }
- for(i = 0; ctx->views[i]; i++) {
- if (!strcasecmp(ctx->views[i]->name, name))
- return i;
+ for (i = 0; ctx->views[i]; i++) {
+ if (ctx->views[i]->api->free_description) {
+ ctx->views[i]->api->free_description(ctx, ctx->views[i]);
+ } else {
+ free(ctx->views[i]);
+ }
}
+ ctx->views[0] = NULL;
+ ctx->num_views = 0;
+}
+
+pcilib_view_context_t *pcilib_find_view_context_by_name(pcilib_t *ctx, const char *name) {
+ pcilib_view_context_t *view_ctx = NULL;
+
+ HASH_FIND_STR(ctx->view_hash, name, view_ctx);
+ return view_ctx;
+}
+
+pcilib_view_t pcilib_find_view_by_name(pcilib_t *ctx, const char *name) {
+ pcilib_view_context_t *view_ctx = pcilib_find_view_context_by_name(ctx, name);
+ if (view_ctx) return view_ctx->view;
return PCILIB_VIEW_INVALID;
}
-pcilib_view_t pcilib_find_register_view_by_name(pcilib_t *ctx, pcilib_register_t reg, const char *name) {
+
+
+pcilib_view_context_t *pcilib_find_register_view_context_by_name(pcilib_t *ctx, pcilib_register_t reg, const char *name) {
pcilib_view_t i;
pcilib_register_context_t *regctx = &ctx->register_ctx[reg];
- if (!regctx->views) return PCILIB_VIEW_INVALID;
+ if (!regctx->views) return NULL;
for (i = 0; regctx->views[i].name; i++) {
if (strcasecmp(name, regctx->views[i].name)) {
- return pcilib_find_view_by_name(ctx, regctx->views[i].view);
+ return pcilib_find_view_context_by_name(ctx, regctx->views[i].view);
}
}
-
- return PCILIB_VIEW_INVALID;
+
+ return NULL;
}
// We expect symmetric units. Therefore, we don't distringuish if we read or write
-pcilib_view_t pcilib_find_register_view(pcilib_t *ctx, pcilib_register_t reg, const char *name) {
+pcilib_view_context_t *pcilib_find_register_view_context(pcilib_t *ctx, pcilib_register_t reg, const char *name) {
pcilib_view_t i;
+ pcilib_view_context_t *view_ctx;
+ pcilib_view_description_t *view_desc;
pcilib_register_context_t *regctx = &ctx->register_ctx[reg];
- if (!regctx->views) return PCILIB_VIEW_INVALID;
+ if (!regctx->views) return NULL;
// Check if view is just a name of listed view
- i = pcilib_find_register_view_by_name(ctx, reg, name);
- if (i != PCILIB_VIEW_INVALID) return i;
+ view_ctx = pcilib_find_register_view_context_by_name(ctx, reg, name);
+ if (view_ctx) return view_ctx;
// Check if view is a unit
for (i = 0; regctx->views[i].name; i++) {
pcilib_unit_transform_t *trans;
- pcilib_view_t view = pcilib_find_view_by_name(ctx, regctx->views[i].view);
- if (view == PCILIB_VIEW_INVALID) continue;
-
- if (ctx->views[view]->unit) {
- trans = pcilib_find_transform_by_unit_names(ctx, ctx->views[view]->unit, name);
- if (trans) return view;
+
+ view_ctx = pcilib_find_view_context_by_name(ctx, regctx->views[i].view);
+ if (!view_ctx) continue;
+
+ view_desc = ctx->views[view_ctx->view];
+ if (view_desc->unit) {
+ trans = pcilib_find_transform_by_unit_names(ctx, view_desc->unit, name);
+ if (trans) return pcilib_find_view_context_by_name(ctx, view_desc->name);
}
}
- return PCILIB_VIEW_INVALID;
+ return NULL;
}
typedef struct {
pcilib_register_t reg;
- pcilib_view_t view;
+ pcilib_view_context_t *view;
pcilib_unit_transform_t *trans;
} pcilib_view_configuration_t;
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) {
pcilib_view_t view;
- pcilib_register_t reg = PCILIB_REGISTER_INVALID;
+ pcilib_view_context_t *view_ctx;
pcilib_unit_transform_t *trans = NULL;
+ pcilib_register_t reg = PCILIB_REGISTER_INVALID;
char *view_name = alloca(strlen(view_cname) + 1);
char *unit_name;
@@ -147,20 +198,21 @@ static int pcilib_detect_view_configuration(pcilib_t *ctx, const char *bank, con
// get value
- if (unit_name) view = pcilib_find_register_view_by_name(ctx, reg, view_name);
- else view = pcilib_find_register_view(ctx, reg, view_name);
+ if (unit_name) view_ctx = pcilib_find_register_view_context_by_name(ctx, reg, view_name);
+ else view_ctx = pcilib_find_register_view_context(ctx, reg, view_name);
- if (view == PCILIB_VIEW_INVALID) {
+ if (!view_ctx) {
pcilib_error("Can't find the specified view %s for register %s", view_name, regname);
return PCILIB_ERROR_NOTFOUND;
}
} else {
- view = pcilib_find_view_by_name(ctx, view_name);
- if (view == PCILIB_VIEW_INVALID) {
+ view_ctx = pcilib_find_view_context_by_name(ctx, view_name);
+ if (!view_ctx) {
pcilib_error("Can't find the specified view %s", view_name);
return PCILIB_ERROR_NOTFOUND;
}
}
+ view = view_ctx->view;
if (unit_name) {
if (write_direction) trans = pcilib_find_transform_by_unit_names(ctx, unit_name, ctx->views[view]->unit);
@@ -175,7 +227,7 @@ static int pcilib_detect_view_configuration(pcilib_t *ctx, const char *bank, con
}
cfg->reg = reg;
- cfg->view = view;
+ cfg->view = view_ctx;
cfg->trans = trans;
return 0;
@@ -185,13 +237,16 @@ static int pcilib_detect_view_configuration(pcilib_t *ctx, const char *bank, con
int pcilib_read_register_view(pcilib_t *ctx, const char *bank, const char *regname, const char *view, pcilib_value_t *val) {
int err;
+ pcilib_view_description_t *v;
pcilib_view_configuration_t cfg;
pcilib_register_value_t regvalue = 0;
err = pcilib_detect_view_configuration(ctx, bank, regname, view, 0, &cfg);
if (err) return err;
- if (!ctx->views[cfg.view]->api->read_from_reg) {
+ v = ctx->views[cfg.view->view];
+
+ if (!v->api->read_from_reg) {
pcilib_error("The view (%s) does not support reading from the register", view);
return PCILIB_ERROR_NOTSUPPORTED;
}
@@ -206,7 +261,7 @@ int pcilib_read_register_view(pcilib_t *ctx, const char *bank, const char *regna
pcilib_clean_value(ctx, val);
- err = ctx->views[cfg.view]->api->read_from_reg(ctx, NULL /*???*/, &regvalue, val);
+ err = v->api->read_from_reg(ctx, cfg.view, &regvalue, val);
if (err) {
if (regname)
pcilib_error("Error (%i) computing view (%s) of register %s", err, view, regname);
@@ -228,13 +283,16 @@ int pcilib_write_register_view(pcilib_t *ctx, const char *bank, const char *regn
int err;
pcilib_value_t val;
+ pcilib_view_description_t *v;
pcilib_view_configuration_t cfg;
pcilib_register_value_t regvalue = 0;
err = pcilib_detect_view_configuration(ctx, bank, regname, view, 1, &cfg);
if (err) return err;
- if (!ctx->views[cfg.view]->api->write_to_reg) {
+ v = ctx->views[cfg.view->view];
+
+ if (!v->api->write_to_reg) {
pcilib_error("The view (%s) does not support reading from the register", view);
return PCILIB_ERROR_NOTSUPPORTED;
}
@@ -242,9 +300,9 @@ int pcilib_write_register_view(pcilib_t *ctx, const char *bank, const char *regn
err = pcilib_copy_value(ctx, &val, valarg);
if (err) return err;
- err = pcilib_convert_value_type(ctx, &val, ctx->views[cfg.view]->type);
+ err = pcilib_convert_value_type(ctx, &val, v->type);
if (err) {
- 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(ctx->views[cfg.view]->type), view);
+ 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);
return err;
}
@@ -254,7 +312,7 @@ int pcilib_write_register_view(pcilib_t *ctx, const char *bank, const char *regn
}
- err = ctx->views[cfg.view]->api->write_to_reg(ctx, NULL /*???*/, &regvalue, &val);
+ err = v->api->write_to_reg(ctx, cfg.view, &regvalue, &val);
if (err) {
if (regname)
pcilib_error("Error (%i) computing view (%s) of register %s", err, view, regname);
diff --git a/pcilib/view.h b/pcilib/view.h
index bf0ea28..4af4c00 100644
--- a/pcilib/view.h
+++ b/pcilib/view.h
@@ -6,8 +6,8 @@
#define PCILIB_VIEW_INVALID ((pcilib_view_t)-1)
-//typedef void *pcilib_view_context_t;
-typedef struct pcilib_view_context_s *pcilib_view_context_t;
+typedef struct pcilib_view_context_s pcilib_view_context_t;
+typedef struct pcilib_view_description_s pcilib_view_description_t;
typedef enum {
PCILIB_VIEW_FLAG_PROPERTY = 1 /**< Indicates that view does not depend on a value and is independent property */
@@ -16,30 +16,34 @@ typedef enum {
typedef struct {
pcilib_version_t version;
size_t description_size;
- pcilib_view_context_t (*init)(pcilib_t *ctx);
+ pcilib_view_context_t *(*init)(pcilib_t *ctx);
void (*free)(pcilib_t *ctx, pcilib_view_context_t *view);
+ void (*free_description)(pcilib_t *ctx, pcilib_view_description_t *view);
int (*read_from_reg)(pcilib_t *ctx, pcilib_view_context_t *view, const pcilib_register_value_t *regval, pcilib_value_t *val);
int (*write_to_reg)(pcilib_t *ctx, pcilib_view_context_t *view, pcilib_register_value_t *regval, const pcilib_value_t *val);
} pcilib_view_api_description_t;
-typedef struct {
+struct pcilib_view_description_s {
const pcilib_view_api_description_t *api;
pcilib_value_type_t type; /**< The default data type returned by operation, PCILIB_VIEW_TYPE_STRING is supported by all operations */
pcilib_view_flags_t flags; /**< Flags specifying type of the view */
const char *unit; /**< Returned unit (if any) */
const char *name; /**< Name of the view */
const char *description; /**< Short description */
-} pcilib_view_description_t;
+};
#ifdef __cplusplus
extern "C" {
#endif
int pcilib_add_views(pcilib_t *ctx, size_t n, const pcilib_view_description_t *desc);
+void pcilib_clean_views(pcilib_t *ctx);
+
+pcilib_view_context_t *pcilib_find_view_context_by_name(pcilib_t *ctx, const char *view);
+pcilib_view_context_t *pcilib_find_register_view_context_by_name(pcilib_t *ctx, pcilib_register_t reg, const char *name);
+pcilib_view_context_t *pcilib_find_register_view_context(pcilib_t *ctx, pcilib_register_t reg, const char *name);
-pcilib_view_t pcilib_find_view_by_name(pcilib_t *ctx, const char *view);
-pcilib_view_t pcilib_find_register_view_by_name(pcilib_t *ctx, pcilib_register_t reg, const char *name);
-pcilib_view_t pcilib_find_register_view(pcilib_t *ctx, pcilib_register_t reg, const char *name);
+pcilib_view_t pcilib_find_view_by_name(pcilib_t *ctx, const char *name);
#ifdef __cplusplus
}