bzr branch
http://suren.me/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 |
}
|