From 3b8e32c9bbe0d909c34303da0ad36ef0ef5be852 Mon Sep 17 00:00:00 2001 From: "Suren A. Chilingaryan" Date: Fri, 9 Oct 2015 03:11:34 +0200 Subject: Introduce hashes --- pcilib/bank.c | 14 ++++-- pcilib/pci.c | 25 +++++----- pcilib/pci.h | 17 +++++-- pcilib/register.c | 37 +++++++++++++- pcilib/register.h | 1 + pcilib/unit.c | 96 ++++++++++++++++++++++++------------ pcilib/unit.h | 3 +- pcilib/view.c | 144 ++++++++++++++++++++++++++++++++++++++---------------- pcilib/view.h | 20 +++++--- 9 files changed, 249 insertions(+), 108 deletions(-) (limited to 'pcilib') 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 /*???*/, ®value, val); + err = v->api->read_from_reg(ctx, cfg.view, ®value, 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 /*???*/, ®value, &val); + err = v->api->write_to_reg(ctx, cfg.view, ®value, &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 } -- cgit v1.2.3