/[soft]/ldetect/trunk/hid.c
ViewVC logotype

Contents of /ldetect/trunk/hid.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5820 - (show annotations) (download)
Wed Sep 12 10:37:40 2012 UTC (11 years, 7 months ago) by tv
File MIME type: text/plain
File size: 3634 byte(s)
make ldetect 3x faster (and even faster on machines quite quite a lot
of devices such as servers)

(modalias_init) split it out of modalias_resolve_module()

(modalias_cleanup) move libkmod related cleanups here

(hid_probe,find_modules_through_aliases) only initialize libkmod once
(which reduces user time from 0.26 to 0.08s & elapsed time from 0.28 to
0.9s)
1 #include <sys/types.h>
2 #include <dirent.h>
3 #include <fnmatch.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <libkmod.h>
8
9 #include "libsysfs.h"
10 #include "libldetect.h"
11 #include "common.h"
12
13
14 #define HID_BUS_NAME "hid"
15 const char *sysfs_hid_path = "/sys/bus/"HID_BUS_NAME"/devices";
16 #if 0
17 #define DEBUG(args...) printf(args)
18 #else
19 #define DEBUG(args...)
20 #endif
21
22 #if 0
23 struct module_alias {
24 const char *modalias;
25 const char *module;
26 };
27
28 static struct module_alias aliasdb[] = { {NULL, NULL} };
29 static const char *resolve_modalias(const struct module_alias *aliasdb,
30 const char *alias_name)
31 {
32 const struct module_alias *alias = aliasdb;
33
34 while (alias->modalias != NULL) {
35 if (fnmatch(alias->modalias, alias_name, 0) == 0)
36 return alias->module;
37
38 alias++;
39 }
40 return NULL;
41 }
42 #endif
43
44 static char *get_field_value(const char *fields, const char *field_name)
45 {
46 char *modalias;
47 char *end;
48
49 modalias = strstr(fields, field_name);
50 if (modalias == NULL)
51 return NULL;
52 end = strchr(modalias, '\n');
53 if (end == NULL)
54 end = modalias + strlen(modalias);
55
56 return strndup(modalias+strlen(field_name), end - (modalias+strlen(field_name)));
57 }
58
59 static char *parse_modalias(char *fields)
60 {
61 return get_field_value(fields, "MODALIAS=");
62 }
63
64 static char *parse_name(char *fields)
65 {
66 return get_field_value(fields, "HID_NAME=");
67 }
68
69 static void add_entry(struct hid_entries *entry_list, char *name, char *module)
70 {
71
72 struct hid_entry *new_entries;
73
74 new_entries = realloc(entry_list->entries, (entry_list->nb+1)*sizeof(*(entry_list->entries)));
75 if (new_entries != NULL) {
76 new_entries[entry_list->nb].module = module;
77 new_entries[entry_list->nb].text = name;
78 entry_list->entries = new_entries;
79 entry_list->nb++;
80 }
81 }
82
83 static void parse_device(struct kmod_ctx *ctx, struct hid_entries *entries, const char *dev)
84 {
85 char keyfile[SYSFS_PATH_MAX];
86 char *modalias;
87 char *modname;
88 char *device_name;
89 struct sysfs_attribute *sysfs_attr;
90
91 snprintf(keyfile, sizeof(keyfile)-1, "%s/%s/uevent",
92 sysfs_hid_path, dev);
93 sysfs_attr = sysfs_open_attribute(keyfile);
94 if (!sysfs_attr)
95 return;
96 if (sysfs_read_attribute(sysfs_attr) != 0 || !sysfs_attr->value) {
97 sysfs_close_attribute(sysfs_attr);
98 return;
99 }
100
101 DEBUG("%s: read %s\n", HID_BUS_NAME, sysfs_attr->value);
102
103 modalias = parse_modalias(sysfs_attr->value);
104 if (modalias == NULL)
105 return;
106 DEBUG("%s: modalias is [%s]\n", HID_BUS_NAME, modalias);
107
108 device_name = parse_name(sysfs_attr->value);
109 sysfs_close_attribute(sysfs_attr);
110 if (device_name != NULL)
111 DEBUG("%s: device name is [%s]\n", HID_BUS_NAME, device_name);
112 else
113 device_name = strdup("HID Device");
114
115 modname = modalias_resolve_module(ctx, modalias);
116 free(modalias);
117 DEBUG("%s: module name is [%s]\n", HID_BUS_NAME, modname);
118 if (modname != NULL)
119 add_entry(entries, device_name, modname);
120 }
121
122
123 struct hid_entries hid_probe(void)
124 {
125 DIR *dir;
126 struct dirent *dent;
127 struct hid_entries entry_list = {NULL, 0};
128 struct kmod_ctx *ctx = modalias_init();
129
130 dir = opendir(sysfs_hid_path);
131 if (dir == NULL)
132 goto end_probe;
133
134 for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
135 if (dent->d_name[0] == '.')
136 continue;
137 DEBUG("%s: device found %s\n", HID_BUS_NAME, dent->d_name);
138 parse_device(ctx, &entry_list, dent->d_name);
139 }
140
141 end_probe:
142 modalias_cleanup(ctx);
143 if (dir)
144 closedir(dir);
145
146 return entry_list;
147 }
148
149 void hid_entries_free(struct hid_entries *entries)
150 {
151 unsigned int i;
152 for (i = 0; i < entries->nb; i++) {
153 free(entries->entries[i].module);
154 free(entries->entries[i].text);
155 }
156 free(entries->entries);
157 }

Properties

Name Value
svn:eol-style native

  ViewVC Help
Powered by ViewVC 1.1.30