/alps/pcitool

To get this branch, use:
bzr branch http://darksoft.org/webbzr/alps/pcitool
242 by Suren A. Chilingaryan
Initial support for event engines
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <dlfcn.h>
4
#include <dirent.h>
5
#include <unistd.h>
6
#include <string.h>
7
#include <sys/types.h>
8
9
#include "model.h"
244 by Suren A. Chilingaryan
Check event interface version for plugins
10
#include "error.h"
242 by Suren A. Chilingaryan
Initial support for event engines
11
#include "pci.h"
12
#include "config.h"
13
14
void *pcilib_plugin_load(const char *name) {
15
    void *plug;
16
    char *fullname;
17
    const char *path;
18
19
    path = getenv("PCILIB_PLUGIN_DIR");
20
    if (!path) path = PCILIB_PLUGIN_DIR;
21
22
    fullname = malloc(strlen(path) + strlen(name) + 2);
23
    if (!fullname) return NULL;
24
25
    sprintf(fullname, "%s/%s", path, name);
26
27
    plug = dlopen(fullname, RTLD_LAZY|RTLD_LOCAL);
28
    free(fullname);
29
30
    return plug;
31
}
32
33
void pcilib_plugin_close(void *plug) {
34
    if (plug) 
35
	dlclose(plug);
36
37
}
38
39
void *pcilib_plugin_get_symbol(void *plug, const char *symbol) {
40
    if ((!plug)||(!symbol)) return NULL;
41
    return dlsym(plug, symbol);
42
}
43
44
const pcilib_model_description_t *pcilib_get_plugin_model(pcilib_t *pcilib, void *plug, unsigned short vendor_id, unsigned short device_id, const char *model) {
45
    void *get_model;
244 by Suren A. Chilingaryan
Check event interface version for plugins
46
    const pcilib_model_description_t *model_info;
242 by Suren A. Chilingaryan
Initial support for event engines
47
48
    if (!plug) return NULL;
49
50
    get_model = dlsym(plug, "pcilib_get_event_model");
51
    if (!get_model) return NULL;
52
244 by Suren A. Chilingaryan
Check event interface version for plugins
53
    model_info = ((const pcilib_model_description_t *(*)(pcilib_t *pcilib, unsigned short vendor_id, unsigned short device_id, const char *model))get_model)(pcilib, vendor_id, device_id, model);
54
    if (!model_info) return model_info;
55
253 by Suren A. Chilingaryan
Include version information in all API descriptions
56
    if ((PCILIB_VERSION_GET_MAJOR(model_info->interface_version) != PCILIB_VERSION_MAJOR)||(PCILIB_VERSION_GET_MINOR(model_info->interface_version) != PCILIB_VERSION_MINOR)) {
256 by Suren A. Chilingaryan
Fix typos in versioning code
57
	printf("%u %u\n", model_info->interface_version, PCILIB_EVENT_INTERFACE_VERSION);
58
	pcilib_warning("Plugin %s exposes outdated interface version (%u.%u.%u), pcilib interface version is (%u.%u.%u)", model_info->name, 
59
		PCILIB_VERSION_GET_MAJOR(model_info->interface_version),
60
		PCILIB_VERSION_GET_MINOR(model_info->interface_version),
61
		PCILIB_VERSION_GET_MICRO(model_info->interface_version),
62
		PCILIB_VERSION_GET_MAJOR(PCILIB_EVENT_INTERFACE_VERSION),
63
		PCILIB_VERSION_GET_MINOR(PCILIB_EVENT_INTERFACE_VERSION),
64
		PCILIB_VERSION_GET_MICRO(PCILIB_EVENT_INTERFACE_VERSION)
65
	);
244 by Suren A. Chilingaryan
Check event interface version for plugins
66
	return NULL;
67
    }
68
69
    return model_info;
242 by Suren A. Chilingaryan
Initial support for event engines
70
}
71
72
const pcilib_model_description_t *pcilib_find_plugin_model(pcilib_t *pcilib, unsigned short vendor_id, unsigned short device_id, const char *model) {
73
    DIR *dir;
74
    const char *path;
75
    struct dirent *entry;
76
77
    void *plugin;
78
    const pcilib_model_description_t *model_info = NULL;
79
80
81
    path = getenv("PCILIB_PLUGIN_DIR");
82
    if (!path) path = PCILIB_PLUGIN_DIR;
83
84
    if (model) {
85
	plugin = pcilib_plugin_load(model);
86
	if (plugin) {
87
	    model_info = pcilib_get_plugin_model(pcilib, plugin, vendor_id, device_id, model);
88
	    if (model_info) {
89
		pcilib->event_plugin = plugin;
90
		return model_info;
91
	    }
92
	    pcilib_plugin_close(plugin);
93
	}
94
    }
95
96
    dir = opendir(path);
97
    if (!dir) return NULL;
98
99
    while ((entry = readdir(dir))) {
100
	const char *suffix = strstr(entry->d_name, ".so");
101
	if ((!suffix)||(strlen(suffix) != 3)) continue;
102
103
	if ((model)&&(!strcmp(entry->d_name, model))) 
104
	    continue;
105
106
	plugin = pcilib_plugin_load(entry->d_name);
107
	if (plugin) {
108
	    model_info = pcilib_get_plugin_model(pcilib, plugin, vendor_id, device_id, model);
109
	    if (model_info) {
110
		pcilib->event_plugin = plugin;
111
		break;
112
	    }
113
	    pcilib_plugin_close(plugin);
114
	}
115
    }
116
117
    closedir(dir);
118
    return model_info;
119
}