/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 pcilib/bank.c

  • Committer: Suren A. Chilingaryan
  • Date: 2015-10-18 01:47:47 UTC
  • Revision ID: csa@suren.me-20151018014747-9ji2ygdhz1l9wnt5
Support properties of arbitrary type

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
 
20
20
int pcilib_init_register_banks(pcilib_t *ctx) {
21
21
    int err; 
 
22
    size_t start = ctx->num_banks_init;
22
23
 
23
24
    err = pcilib_map_register_space(ctx);
24
25
    if (err) return err;
33
34
            const char *name = ctx->banks[ctx->num_banks_init].name;
34
35
            if (!name) name = "unnamed";
35
36
            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);
 
37
            pcilib_free_register_banks(ctx, start);
36
38
            return PCILIB_ERROR_INVALID_BANK;
37
39
        }
38
40
        
46
48
        } else
47
49
            bank_ctx = (pcilib_register_bank_context_t*)malloc(sizeof(pcilib_register_bank_context_t));
48
50
        
49
 
        if (!bank_ctx)
 
51
        if (!bank_ctx) {
 
52
            pcilib_free_register_banks(ctx, start);
50
53
            return PCILIB_ERROR_FAILED;
 
54
        }
51
55
        
52
56
        bank_ctx->bank = ctx->banks + ctx->num_banks_init;
53
57
        bank_ctx->api = bapi;
58
62
    return 0;
59
63
}
60
64
 
61
 
void pcilib_free_register_banks(pcilib_t *ctx) {
 
65
void pcilib_free_register_banks(pcilib_t *ctx, pcilib_register_bank_t start) {
62
66
    size_t i;
63
67
 
64
 
    for (i = 0; i < ctx->num_banks_init; i++) {
 
68
    for (i = start; i < ctx->num_banks_init; i++) {
65
69
        const pcilib_register_protocol_api_description_t *bapi = ctx->bank_ctx[i]->api;
66
70
        
67
71
        if (ctx->bank_ctx[i]) {
74
78
        }
75
79
    }
76
80
 
77
 
    ctx->num_banks_init = 0;
 
81
    ctx->num_banks_init = start;
78
82
}
79
83
 
80
84
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) {
 
85
    int err;
81
86
    size_t i;
82
87
    pcilib_register_bank_t bank;
83
88
    size_t dyn_banks = ctx->dyn_banks;
84
89
    size_t num_banks = ctx->num_banks;
 
90
    size_t cur_banks = num_banks;
85
91
        
86
92
    if (!n) {
87
93
        for (n = 0; banks[n].access; n++);
90
96
    if ((ctx->num_banks + n + 1) > PCILIB_MAX_REGISTER_BANKS)
91
97
        return PCILIB_ERROR_TOOBIG;
92
98
 
93
 
/*
94
 
    memcpy(ctx->banks + ctx->num_banks, banks, n * sizeof(pcilib_register_bank_description_t));
95
 
    ctx->num_banks += n;
96
 
*/
97
 
 
98
99
    for (i = 0; i < n; i++) {
99
100
            // Try to find if the bank is already existing...
100
101
        bank = pcilib_find_register_bank_by_name(ctx, banks[i].name);
111
112
                pcilib_error("The bank %s is already existing and override flag is not set", banks[i].name);
112
113
            else
113
114
                pcilib_error("The bank with address 0x%lx is already existing and override flag is not set", banks[i].addr);
 
115
            memset(ctx->banks + ctx->num_banks, 0, sizeof(pcilib_register_bank_description_t));
114
116
            return PCILIB_ERROR_EXIST;
115
117
        }
116
118
        
122
124
            dyn_banks++;
123
125
        }
124
126
    }
125
 
    
 
127
 
126
128
    ctx->num_banks = num_banks;
127
 
    ctx->dyn_banks = dyn_banks;
128
129
 
129
130
        // If banks are already initialized, we need to re-run the initialization code
130
 
        // DS: Locking is currently missing
131
131
    if (ctx->reg_bar_mapped) {
132
132
        ctx->reg_bar_mapped = 0;
133
 
        return pcilib_init_register_banks(ctx);
 
133
        err = pcilib_init_register_banks(ctx);
 
134
        if (err) {
 
135
            ctx->num_banks = cur_banks;
 
136
            memset(ctx->banks + ctx->num_banks, 0, sizeof(pcilib_register_bank_description_t));
 
137
            return err;
 
138
        }
134
139
    }
135
 
    
 
140
 
 
141
    ctx->dyn_banks = dyn_banks;
 
142
 
136
143
    return 0;
137
144
}
138
145