/alps/pcitool

To get this branch, use:
bzr branch http://suren.me/webbzr/alps/pcitool

« back to all changes in this revision

Viewing changes to bank.c

  • Committer: Suren A. Chilingaryan
  • Date: 2015-04-20 20:01:04 UTC
  • Revision ID: csa@suren.me-20150420200104-b5xny65io8lvoz3w
Big redign of model structures

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <stdio.h>
 
2
#include <string.h>
 
3
#include <strings.h>
 
4
#include <stdlib.h>
 
5
#include <stdint.h>
 
6
#include <stdarg.h>
 
7
#include <fcntl.h>
 
8
#include <unistd.h>
 
9
#include <sys/ioctl.h>
 
10
#include <sys/mman.h>
 
11
#include <arpa/inet.h>
 
12
#include <errno.h>
 
13
#include <assert.h>
 
14
 
 
15
#include "pci.h"
 
16
 
 
17
#include "tools.h"
 
18
#include "error.h"
 
19
 
 
20
int pcilib_init_register_banks(pcilib_t *ctx) {
 
21
    int err; 
 
22
 
 
23
    err = pcilib_map_register_space(ctx);
 
24
    if (err) return err;
 
25
 
 
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;
 
30
 
 
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;
 
37
        }
 
38
        
 
39
        bapi = ctx->protocols[protocol].api;
 
40
 
 
41
        if (bapi->init) 
 
42
            bank_ctx = bapi->init(ctx, ctx->num_banks_init, ctx->protocols[protocol].model, ctx->protocols[protocol].args);
 
43
        else
 
44
            bank_ctx = (pcilib_register_bank_context_t*)malloc(sizeof(pcilib_register_bank_context_t));
 
45
        
 
46
        if (!bank_ctx)
 
47
            return PCILIB_ERROR_FAILED;
 
48
        
 
49
        bank_ctx->bank = ctx->banks + ctx->num_banks_init;
 
50
        bank_ctx->api = bapi;
 
51
        ctx->bank_ctx[ctx->num_banks_init] = bank_ctx;
 
52
    }
 
53
 
 
54
    return 0;
 
55
}
 
56
 
 
57
void pcilib_free_register_banks(pcilib_t *ctx) {
 
58
    size_t i;
 
59
 
 
60
    for (i = 0; i < ctx->num_banks_init; i++) {
 
61
        const pcilib_register_protocol_api_description_t *bapi = ctx->bank_ctx[i]->api;
 
62
        
 
63
        if (ctx->bank_ctx[i]) {
 
64
            if (bapi->free)
 
65
                bapi->free(ctx->bank_ctx[i]);
 
66
            else
 
67
                free(ctx->bank_ctx[i]);
 
68
                
 
69
            ctx->bank_ctx[i] = NULL;
 
70
        }
 
71
    }
 
72
 
 
73
    ctx->num_banks_init = 0;
 
74
}
 
75
 
 
76
 
 
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? 
 
79
        
 
80
    if (!n) {
 
81
        for (n = 0; banks[n].access; n++);
 
82
    }
 
83
 
 
84
    if ((ctx->num_banks + n + 1) > PCILIB_MAX_REGISTER_BANKS)
 
85
        return PCILIB_ERROR_TOOBIG;
 
86
        
 
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));
 
89
    ctx->num_banks += n;
 
90
 
 
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);
 
96
    }
 
97
    
 
98
    return 0;
 
99
}
 
100
 
 
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;
 
105
 
 
106
    for (i = 0; banks[i].access; i++)
 
107
        if (banks[i].addr == bank) return i;
 
108
 
 
109
    return PCILIB_REGISTER_BANK_INVALID;
 
110
}
 
111
 
 
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;
 
116
 
 
117
    for (i = 0; banks[i].access; i++)
 
118
        if (!strcasecmp(banks[i].name, bankname)) return i;
 
119
 
 
120
    return PCILIB_REGISTER_BANK_INVALID;
 
121
}
 
122
 
 
123
pcilib_register_bank_t pcilib_find_register_bank(pcilib_t *ctx, const char *bank) {
 
124
    pcilib_register_bank_t res;
 
125
    unsigned long addr;
 
126
    
 
127
    if (!bank) {
 
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;
 
132
    }
 
133
    
 
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;
 
137
    }
 
138
    
 
139
    return pcilib_find_register_bank_by_name(ctx, bank);
 
140
}
 
141
 
 
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) {
 
144
    pcilib_register_t i;
 
145
    pcilib_register_bank_t bank_id;
 
146
    pcilib_register_bank_addr_t bank_addr = 0;
 
147
 
 
148
    const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx);
 
149
    const pcilib_register_description_t *registers =  model_info->registers;
 
150
    
 
151
    if (bank) {
 
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;
 
156
        }
 
157
        
 
158
        bank_addr = model_info->banks[bank_id].addr;
 
159
    }
 
160
    
 
161
    for (i = 0; registers[i].bits; i++) {
 
162
        if ((!strcasecmp(registers[i].name, reg))&&((!bank)||(registers[i].bank == bank_addr))) return i;
 
163
    }
 
164
 
 
165
    return PCILIB_REGISTER_INVALID;
 
166
};
 
167
 
 
168
 
 
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;
 
173
 
 
174
    for (i = 0; protocols[i].api; i++)
 
175
        if (protocols[i].addr == protocol) return i;
 
176
 
 
177
    return PCILIB_REGISTER_PROTOCOL_INVALID;
 
178
}
 
179
 
 
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;
 
184
 
 
185
    for (i = 0; protocols[i].api; i++)
 
186
        if (!strcasecmp(protocols[i].name, name)) return i;
 
187
 
 
188
    return PCILIB_REGISTER_PROTOCOL_INVALID;
 
189
}
 
190
 
 
191
pcilib_register_protocol_t pcilib_find_register_protocol(pcilib_t *ctx, const char *protocol) {
 
192
    pcilib_register_bank_t res;
 
193
    unsigned long addr;
 
194
 
 
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;
 
198
    }
 
199
 
 
200
    return pcilib_find_register_protocol_by_name(ctx, protocol);
 
201
}