11
#include <arpa/inet.h>
20
int pcilib_init_register_banks(pcilib_t *ctx) {
23
err = pcilib_map_register_space(ctx);
26
for (; ctx->num_banks_init < ctx->num_banks; ctx->num_banks_init++) {
27
pcilib_register_bank_context_t *bank_ctx;
28
pcilib_register_protocol_t protocol;
29
const pcilib_register_protocol_api_description_t *bapi;
31
protocol = pcilib_find_register_protocol_by_addr(ctx, ctx->banks[ctx->num_banks_init].protocol);
32
if (protocol == PCILIB_REGISTER_PROTOCOL_INVALID) {
33
const char *name = ctx->banks[ctx->num_banks_init].name;
34
if (!name) name = "unnamed";
35
pcilib_error("Invalid register protocol address (%u) is specified for bank %i (%s)", ctx->banks[ctx->num_banks_init].protocol, ctx->banks[ctx->num_banks_init].addr, name);
36
return PCILIB_ERROR_INVALID_BANK;
39
bapi = ctx->protocols[protocol].api;
42
bank_ctx = bapi->init(ctx, ctx->num_banks_init, ctx->protocols[protocol].model, ctx->protocols[protocol].args);
44
bank_ctx = (pcilib_register_bank_context_t*)malloc(sizeof(pcilib_register_bank_context_t));
47
return PCILIB_ERROR_FAILED;
49
bank_ctx->bank = ctx->banks + ctx->num_banks_init;
51
ctx->bank_ctx[ctx->num_banks_init] = bank_ctx;
57
void pcilib_free_register_banks(pcilib_t *ctx) {
60
for (i = 0; i < ctx->num_banks_init; i++) {
61
const pcilib_register_protocol_api_description_t *bapi = ctx->bank_ctx[i]->api;
63
if (ctx->bank_ctx[i]) {
65
bapi->free(ctx->bank_ctx[i]);
67
free(ctx->bank_ctx[i]);
69
ctx->bank_ctx[i] = NULL;
73
ctx->num_banks_init = 0;
77
int pcilib_add_register_banks(pcilib_t *ctx, size_t n, const pcilib_register_bank_description_t *banks) {
78
// DS: What we are doing if bank exists?
81
for (n = 0; banks[n].access; n++);
84
if ((ctx->num_banks + n + 1) > PCILIB_MAX_REGISTER_BANKS)
85
return PCILIB_ERROR_TOOBIG;
87
memset(ctx->banks + ctx->num_banks + n, 0, sizeof(pcilib_register_bank_description_t));
88
memcpy(ctx->banks + ctx->num_banks, banks, n * sizeof(pcilib_register_bank_description_t));
91
// If banks are already initialized, we need to re-run the initialization code
92
// DS: Locking is currently missing
93
if (ctx->reg_bar_mapped) {
94
ctx->reg_bar_mapped = 0;
95
return pcilib_init_register_banks(ctx);
101
pcilib_register_bank_t pcilib_find_register_bank_by_addr(pcilib_t *ctx, pcilib_register_bank_addr_t bank) {
102
pcilib_register_bank_t i;
103
const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
104
const pcilib_register_bank_description_t *banks = model_info->banks;
106
for (i = 0; banks[i].access; i++)
107
if (banks[i].addr == bank) return i;
109
return PCILIB_REGISTER_BANK_INVALID;
112
pcilib_register_bank_t pcilib_find_register_bank_by_name(pcilib_t *ctx, const char *bankname) {
113
pcilib_register_bank_t i;
114
const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
115
const pcilib_register_bank_description_t *banks = model_info->banks;
117
for (i = 0; banks[i].access; i++)
118
if (!strcasecmp(banks[i].name, bankname)) return i;
120
return PCILIB_REGISTER_BANK_INVALID;
123
pcilib_register_bank_t pcilib_find_register_bank(pcilib_t *ctx, const char *bank) {
124
pcilib_register_bank_t res;
128
const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
129
const pcilib_register_bank_description_t *banks = model_info->banks;
130
if ((banks)&&(banks[0].access)) return (pcilib_register_bank_t)0;
131
return PCILIB_REGISTER_BANK_INVALID;
134
if (pcilib_isxnumber(bank)&&(sscanf(bank,"%lx", &addr) == 1)) {
135
res = pcilib_find_register_bank_by_addr(ctx, addr);
136
if (res != PCILIB_REGISTER_BANK_INVALID) return res;
139
return pcilib_find_register_bank_by_name(ctx, bank);
142
// DS: FIXME create hash during map_register space
143
pcilib_register_t pcilib_find_register(pcilib_t *ctx, const char *bank, const char *reg) {
145
pcilib_register_bank_t bank_id;
146
pcilib_register_bank_addr_t bank_addr = 0;
148
const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
149
const pcilib_register_description_t *registers = model_info->registers;
152
bank_id = pcilib_find_register_bank(ctx, bank);
153
if (bank_id == PCILIB_REGISTER_BANK_INVALID) {
154
pcilib_error("Invalid bank (%s) is specified", bank);
155
return PCILIB_REGISTER_INVALID;
158
bank_addr = model_info->banks[bank_id].addr;
161
for (i = 0; registers[i].bits; i++) {
162
if ((!strcasecmp(registers[i].name, reg))&&((!bank)||(registers[i].bank == bank_addr))) return i;
165
return PCILIB_REGISTER_INVALID;
169
pcilib_register_protocol_t pcilib_find_register_protocol_by_addr(pcilib_t *ctx, pcilib_register_protocol_addr_t protocol) {
170
pcilib_register_protocol_t i;
171
const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
172
const pcilib_register_protocol_description_t *protocols = model_info->protocols;
174
for (i = 0; protocols[i].api; i++)
175
if (protocols[i].addr == protocol) return i;
177
return PCILIB_REGISTER_PROTOCOL_INVALID;
180
pcilib_register_protocol_t pcilib_find_register_protocol_by_name(pcilib_t *ctx, const char *name) {
181
pcilib_register_protocol_t i;
182
const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
183
const pcilib_register_protocol_description_t *protocols = model_info->protocols;
185
for (i = 0; protocols[i].api; i++)
186
if (!strcasecmp(protocols[i].name, name)) return i;
188
return PCILIB_REGISTER_PROTOCOL_INVALID;
191
pcilib_register_protocol_t pcilib_find_register_protocol(pcilib_t *ctx, const char *protocol) {
192
pcilib_register_bank_t res;
195
if (pcilib_isxnumber(protocol)&&(sscanf(protocol,"%lx", &addr) == 1)) {
196
res = pcilib_find_register_protocol_by_addr(ctx, addr);
197
if (res != PCILIB_REGISTER_BANK_INVALID) return res;
200
return pcilib_find_register_protocol_by_name(ctx, protocol);