/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/pci.c

  • Committer: Suren A. Chilingaryan
  • Date: 2015-10-22 13:57:59 UTC
  • Revision ID: csa@suren.me-20151022135759-nqs5wowy38tvbw09
Documentation update

Show diffs side-by-side

added added

removed removed

Lines of Context:
107
107
 
108
108
pcilib_t *pcilib_open(const char *device, const char *model) {
109
109
    int err, xmlerr;
110
 
    size_t i;
111
110
    pcilib_t *ctx = malloc(sizeof(pcilib_t));
112
111
        
113
112
    if (!model)
167
166
 
168
167
        memset(ctx->register_ctx, 0, PCILIB_DEFAULT_REGISTER_SPACE * sizeof(pcilib_register_context_t));
169
168
 
170
 
        
171
 
        for (i = 0; pcilib_protocols[i].api; i++);
172
 
        memcpy(ctx->protocols, pcilib_protocols, i * sizeof(pcilib_register_protocol_description_t));
173
 
        ctx->num_protocols = i;
 
169
        pcilib_add_register_protocols(ctx, PCILIB_MODEL_MODIFICATON_FLAGS_DEFAULT, 0, pcilib_standard_register_protocols, NULL);
 
170
        pcilib_add_register_banks(ctx, PCILIB_MODEL_MODIFICATON_FLAGS_DEFAULT, 0, pcilib_standard_register_banks, NULL);
 
171
        pcilib_add_registers(ctx, PCILIB_MODEL_MODIFICATON_FLAGS_DEFAULT, 0, pcilib_standard_registers, NULL);
174
172
 
175
173
        err = pcilib_detect_model(ctx, model);
176
174
        if ((err)&&(err != PCILIB_ERROR_NOTFOUND)) {
248
246
}
249
247
 
250
248
 
251
 
int pcilib_map_data_space(pcilib_t *ctx, uintptr_t addr) {
252
 
    int err;
253
 
    pcilib_bar_t i;
254
 
    
255
 
    if (!ctx->data_bar_mapped) {
256
 
        const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx);
257
 
        if (!board_info) return PCILIB_ERROR_FAILED;
258
 
 
259
 
        err = pcilib_map_register_space(ctx);
260
 
        if (err) {
261
 
            pcilib_error("Error mapping register space");
262
 
            return err;
263
 
        }
264
 
        
265
 
        int data_bar = -1;
266
 
        
267
 
        for (i = 0; i < PCILIB_MAX_BARS; i++) {
268
 
            if ((ctx->bar_space[i])||(!board_info->bar_length[i])) continue;
269
 
            
270
 
            if (addr) {
271
 
                if (board_info->bar_start[i] == addr) {
272
 
                    data_bar = i;
273
 
                    break;
274
 
                }
275
 
            } else {
276
 
                if (data_bar >= 0) {
277
 
                    data_bar = -1;
278
 
                    break;
279
 
                }
280
 
                
281
 
                data_bar = i;
282
 
            }
283
 
        }
284
 
            
285
 
 
286
 
        if (data_bar < 0) {
287
 
            if (addr) pcilib_error("Unable to find the specified data space (%lx)", addr);
288
 
            else pcilib_error("Unable to find the data space");
289
 
            return PCILIB_ERROR_NOTFOUND;
290
 
        }
291
 
        
292
 
        ctx->data_bar = data_bar;
293
 
        
294
 
        if (!ctx->bar_space[data_bar]) {
295
 
            char *data_space = pcilib_map_bar(ctx, data_bar);
296
 
            if (data_space) ctx->bar_space[data_bar] = data_space;
297
 
            else {
298
 
                pcilib_error("Unable to map the data space");
299
 
                return PCILIB_ERROR_FAILED;
300
 
            }
301
 
        }
302
 
        
303
 
        ctx->data_bar_mapped = 0;
304
 
    }
305
 
    
306
 
    return 0;
307
 
}
308
 
        
309
 
char *pcilib_resolve_register_address(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr) {
310
 
    if (bar == PCILIB_BAR_DETECT) {
311
 
            // First checking the default register bar
312
 
        size_t offset = addr - ctx->board_info.bar_start[ctx->reg_bar];
313
 
        if ((addr > ctx->board_info.bar_start[ctx->reg_bar])&&(offset < ctx->board_info.bar_length[ctx->reg_bar])) {
314
 
            if (!ctx->bar_space[ctx->reg_bar]) {
315
 
                pcilib_error("The register bar is not mapped");
316
 
                return NULL;
317
 
            }
318
 
 
319
 
            return ctx->bar_space[ctx->reg_bar] + offset + (ctx->board_info.bar_start[ctx->reg_bar] & ctx->page_mask);
320
 
        }
321
 
            
322
 
            // Otherwise trying to detect
323
 
        bar = pcilib_detect_bar(ctx, addr, 1);
324
 
        if (bar != PCILIB_BAR_INVALID) {
325
 
            size_t offset = addr - ctx->board_info.bar_start[bar];
326
 
            if ((offset < ctx->board_info.bar_length[bar])&&(ctx->bar_space[bar])) {
327
 
                if (!ctx->bar_space[bar]) {
328
 
                    pcilib_error("The requested bar (%i) is not mapped", bar);
329
 
                    return NULL;
330
 
                }
331
 
                return ctx->bar_space[bar] + offset + (ctx->board_info.bar_start[bar] & ctx->page_mask);
332
 
            }
333
 
        }
334
 
    } else {
335
 
        if (!ctx->bar_space[bar]) {
336
 
            pcilib_error("The requested bar (%i) is not mapped", bar);
337
 
            return NULL;
338
 
        }
339
 
        
340
 
        if (addr < ctx->board_info.bar_length[bar]) {
341
 
            return ctx->bar_space[bar] + addr + (ctx->board_info.bar_start[bar] & ctx->page_mask);
342
 
        }
343
 
        
344
 
        if ((addr >= ctx->board_info.bar_start[bar])&&(addr < (ctx->board_info.bar_start[bar] + ctx->board_info.bar_length[ctx->reg_bar]))) {
345
 
            return ctx->bar_space[bar] + (addr - ctx->board_info.bar_start[bar]) + (ctx->board_info.bar_start[bar] & ctx->page_mask);
346
 
        }
347
 
    }
348
 
 
349
 
    return NULL;
350
 
}
351
 
 
352
 
char *pcilib_resolve_data_space(pcilib_t *ctx, uintptr_t addr, size_t *size) {
353
 
    int err;
354
 
    
355
 
    err = pcilib_map_data_space(ctx, addr);
356
 
    if (err) {
357
 
        pcilib_error("Failed to map the specified address space (%lx)", addr);
358
 
        return NULL;
359
 
    }
360
 
    
361
 
    if (size) *size = ctx->board_info.bar_length[ctx->data_bar];
362
 
    
363
 
    return ctx->bar_space[ctx->data_bar] + (ctx->board_info.bar_start[ctx->data_bar] & ctx->page_mask);
364
 
}
365
 
 
366
 
 
367
249
void pcilib_close(pcilib_t *ctx) {
368
250
    pcilib_bar_t bar;
369
251