summaryrefslogtreecommitdiffstats
path: root/pcilib/bank.c
diff options
context:
space:
mode:
Diffstat (limited to 'pcilib/bank.c')
-rw-r--r--pcilib/bank.c75
1 files changed, 50 insertions, 25 deletions
diff --git a/pcilib/bank.c b/pcilib/bank.c
index 3d53db2..66ff739 100644
--- a/pcilib/bank.c
+++ b/pcilib/bank.c
@@ -51,6 +51,7 @@ int pcilib_init_register_banks(pcilib_t *ctx) {
bank_ctx->bank = ctx->banks + ctx->num_banks_init;
bank_ctx->api = bapi;
+ bank_ctx->xml = ctx->xml.bank_nodes[ctx->num_banks_init];
ctx->bank_ctx[ctx->num_banks_init] = bank_ctx;
}
@@ -76,9 +77,11 @@ void pcilib_free_register_banks(pcilib_t *ctx) {
ctx->num_banks_init = 0;
}
-
-int pcilib_add_register_banks(pcilib_t *ctx, size_t n, const pcilib_register_bank_description_t *banks) {
- // DS: Override existing banks
+int pcilib_add_register_banks(pcilib_t *ctx, pcilib_model_modification_flags_t flags, size_t n, const pcilib_register_bank_description_t *banks, pcilib_register_bank_t *ids) {
+ size_t i;
+ pcilib_register_bank_t bank;
+ size_t dyn_banks = ctx->dyn_banks;
+ size_t num_banks = ctx->num_banks;
if (!n) {
for (n = 0; banks[n].access; n++);
@@ -86,9 +89,42 @@ int pcilib_add_register_banks(pcilib_t *ctx, size_t n, const pcilib_register_ban
if ((ctx->num_banks + n + 1) > PCILIB_MAX_REGISTER_BANKS)
return PCILIB_ERROR_TOOBIG;
-
+
+/*
memcpy(ctx->banks + ctx->num_banks, banks, n * sizeof(pcilib_register_bank_description_t));
ctx->num_banks += n;
+*/
+
+ for (i = 0; i < n; i++) {
+ // Try to find if the bank is already existing...
+ bank = pcilib_find_register_bank_by_name(ctx, banks[i].name);
+ if ((bank == PCILIB_REGISTER_BANK_INVALID)&&(banks[i].addr != PCILIB_REGISTER_BANK_DYNAMIC))
+ bank = pcilib_find_register_bank_by_addr(ctx, banks[i].addr);
+
+ if (bank == PCILIB_REGISTER_BANK_INVALID) {
+ bank = num_banks++;
+ } else if (flags&PCILIB_MODEL_MODIFICATION_FLAG_SKIP_EXISTING) {
+ if (ids) ids[i] = bank;
+ continue;
+ } else if ((flags&PCILIB_MODEL_MODIFICATION_FLAG_OVERRIDE) == 0) {
+ if (pcilib_find_register_bank_by_name(ctx, banks[i].name) == PCILIB_REGISTER_BANK_INVALID)
+ pcilib_error("The bank %s is already existing and override flag is not set", banks[i].name);
+ else
+ pcilib_error("The bank with address 0x%lx is already existing and override flag is not set", banks[i].addr);
+ return PCILIB_ERROR_EXIST;
+ }
+
+ memcpy(ctx->banks + bank, banks + i, sizeof(pcilib_register_bank_description_t));
+ if (ids) ids[i] = bank;
+
+ if (banks[i].addr == PCILIB_REGISTER_BANK_DYNAMIC) {
+ ctx->banks[bank].addr = PCILIB_REGISTER_BANK_DYNAMIC + dyn_banks + 1;
+ dyn_banks++;
+ }
+ }
+
+ ctx->num_banks = num_banks;
+ ctx->dyn_banks = dyn_banks;
// If banks are already initialized, we need to re-run the initialization code
// DS: Locking is currently missing
@@ -100,7 +136,7 @@ int pcilib_add_register_banks(pcilib_t *ctx, size_t n, const pcilib_register_ban
return 0;
}
-int pcilib_add_register_protocols(pcilib_t *ctx, size_t n, const pcilib_register_protocol_description_t *protocols) {
+int pcilib_add_register_protocols(pcilib_t *ctx, pcilib_model_modification_flags_t flags, size_t n, const pcilib_register_protocol_description_t *protocols, pcilib_register_protocol_t *ids) {
// DS: Override existing banks
if (!n) {
@@ -116,10 +152,7 @@ int pcilib_add_register_protocols(pcilib_t *ctx, size_t n, const pcilib_register
return 0;
}
-
-int pcilib_add_register_ranges(pcilib_t *ctx, size_t n, const pcilib_register_range_t *ranges) {
- // DS: Override existing banks
-
+int pcilib_add_register_ranges(pcilib_t *ctx, pcilib_model_modification_flags_t flags, size_t n, const pcilib_register_range_t *ranges) {
if (!n) {
for (n = 0; ranges[n].end; n++);
}
@@ -135,22 +168,18 @@ int pcilib_add_register_ranges(pcilib_t *ctx, size_t n, const pcilib_register_ra
pcilib_register_bank_t pcilib_find_register_bank_by_addr(pcilib_t *ctx, pcilib_register_bank_addr_t bank) {
pcilib_register_bank_t i;
- const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
- const pcilib_register_bank_description_t *banks = model_info->banks;
- for (i = 0; banks[i].access; i++)
- if (banks[i].addr == bank) return i;
+ for (i = 0; ctx->banks[i].access; i++)
+ if (ctx->banks[i].addr == bank) return i;
return PCILIB_REGISTER_BANK_INVALID;
}
pcilib_register_bank_t pcilib_find_register_bank_by_name(pcilib_t *ctx, const char *bankname) {
pcilib_register_bank_t i;
- const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
- const pcilib_register_bank_description_t *banks = model_info->banks;
- for (i = 0; banks[i].access; i++)
- if (!strcasecmp(banks[i].name, bankname)) return i;
+ for (i = 0; ctx->banks[i].access; i++)
+ if (!strcasecmp(ctx->banks[i].name, bankname)) return i;
return PCILIB_REGISTER_BANK_INVALID;
}
@@ -203,22 +232,18 @@ pcilib_register_t pcilib_find_register(pcilib_t *ctx, const char *bank, const ch
pcilib_register_protocol_t pcilib_find_register_protocol_by_addr(pcilib_t *ctx, pcilib_register_protocol_addr_t protocol) {
pcilib_register_protocol_t i;
- const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
- const pcilib_register_protocol_description_t *protocols = model_info->protocols;
- for (i = 0; protocols[i].api; i++)
- if (protocols[i].addr == protocol) return i;
+ for (i = 0; ctx->protocols[i].api; i++)
+ if (ctx->protocols[i].addr == protocol) return i;
return PCILIB_REGISTER_PROTOCOL_INVALID;
}
pcilib_register_protocol_t pcilib_find_register_protocol_by_name(pcilib_t *ctx, const char *name) {
pcilib_register_protocol_t i;
- const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
- const pcilib_register_protocol_description_t *protocols = model_info->protocols;
- for (i = 0; protocols[i].api; i++)
- if (!strcasecmp(protocols[i].name, name)) return i;
+ for (i = 0; ctx->protocols[i].api; i++)
+ if (!strcasecmp(ctx->protocols[i].name, name)) return i;
return PCILIB_REGISTER_PROTOCOL_INVALID;
}