depmod: use real regex matching on depmod "overrides" entries
[mit.git] / tables.c
blobc8629209e74a3ec770212762d7a5a68702e57a07
1 #include <string.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <ctype.h>
5 #include "depmod.h"
6 #include "tables.h"
7 #include "util.h"
9 /* Turn /lib/modules/2.5.49/kernel/foo.ko(.gz) => foo */
10 static void make_shortname(char *dest, const char *src)
12 char *ext;
13 const char *bname;
15 bname = my_basename(src);
16 strcpy(dest, bname);
17 ext = strchr(dest, '.');
18 if (ext)
19 *ext = '\0';
22 /* We set driver_data to zero */
23 static void output_pci_entry(struct pci_device_id *pci, char *name, FILE *out,
24 int conv)
26 fprintf(out,
27 "%-20s 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x0\n",
28 name,
29 END(pci->vendor, conv),
30 END(pci->device, conv),
31 END(pci->subvendor, conv),
32 END(pci->subdevice, conv),
33 END(pci->class, conv),
34 END(pci->class_mask, conv));
37 int output_pci_table(struct module *modules, FILE *out, char *dirname)
39 struct module *i;
41 fprintf(out, "# pci module vendor device subvendor"
42 " subdevice class class_mask driver_data\n");
44 for (i = modules; i; i = i->next) {
45 struct pci_device_id *e;
46 char shortname[strlen(i->pathname) + 1];
47 struct module_tables *t = &i->tables;
49 if (!t->pci_table)
50 continue;
52 make_shortname(shortname, i->pathname);
53 for (e = t->pci_table; e->vendor; e = (void *)e + t->pci_size)
54 output_pci_entry(e, shortname, out, i->file->conv);
56 return 1;
59 /* We set driver_info to zero */
60 static void output_usb_entry(struct usb_device_id *usb, char *name, FILE *out,
61 int conv)
63 fprintf(out, "%-20s 0x%04x 0x%04x 0x%04x 0x%04x"
64 " 0x%04x 0x%02x 0x%02x"
65 " 0x%02x 0x%02x"
66 " 0x%02x 0x%02x"
67 " 0x0\n",
68 name,
69 END(usb->match_flags, conv),
70 END(usb->idVendor, conv),
71 END(usb->idProduct, conv),
72 END(usb->bcdDevice_lo, conv),
73 END(usb->bcdDevice_hi, conv),
74 END(usb->bDeviceClass, conv),
75 END(usb->bDeviceSubClass, conv),
76 END(usb->bDeviceProtocol, conv),
77 END(usb->bInterfaceClass, conv),
78 END(usb->bInterfaceSubClass, conv),
79 END(usb->bInterfaceProtocol, conv));
82 int output_usb_table(struct module *modules, FILE *out, char *dirname)
84 struct module *i;
86 fprintf(out, "# usb module ");
87 /* Requires all users to be on kernel 2.4.0 or later */
88 fprintf(out, "match_flags ");
89 fprintf(out, "idVendor idProduct bcdDevice_lo bcdDevice_hi"
90 " bDeviceClass bDeviceSubClass bDeviceProtocol"
91 " bInterfaceClass bInterfaceSubClass"
92 " bInterfaceProtocol driver_info\n");
94 for (i = modules; i; i = i->next) {
95 struct usb_device_id *e;
96 char shortname[strlen(i->pathname) + 1];
97 struct module_tables *t = &i->tables;
99 if (!t->usb_table)
100 continue;
102 make_shortname(shortname, i->pathname);
103 for (e = t->usb_table;
104 e->idVendor || e->bDeviceClass || e->bInterfaceClass;
105 e = (void *)e + t->usb_size)
106 output_usb_entry(e, shortname, out, i->file->conv);
108 return 1;
111 static void output_ieee1394_entry(struct ieee1394_device_id *fw, char *name,
112 FILE *out, int conv)
114 fprintf(out, "%-20s 0x%08x 0x%06x 0x%06x 0x%06x 0x%06x\n",
115 name,
116 END(fw->match_flags, conv),
117 END(fw->vendor_id, conv),
118 END(fw->model_id, conv),
119 END(fw->specifier_id, conv),
120 END(fw->version, conv));
123 int output_ieee1394_table(struct module *modules, FILE *out, char *dirname)
125 struct module *i;
127 fprintf(out, "# ieee1394 module ");
128 fprintf(out, "match_flags vendor_id model_id specifier_id version\n");
130 for (i = modules; i; i = i->next) {
131 struct ieee1394_device_id *fw;
132 char shortname[strlen(i->pathname) + 1];
133 struct module_tables *t = &i->tables;
135 if (!t->ieee1394_table)
136 continue;
138 make_shortname(shortname, i->pathname);
139 for (fw = t->ieee1394_table; fw->match_flags;
140 fw = (void *) fw + t->ieee1394_size)
141 output_ieee1394_entry(fw, shortname, out, i->file->conv);
143 return 1;
147 /* We set driver_data to zero */
148 static void output_ccw_entry(struct ccw_device_id *ccw, char *name, FILE *out,
149 int conv)
151 fprintf(out, "%-20s 0x%04x 0x%04x 0x%02x 0x%04x 0x%02x\n",
152 name, END(ccw->match_flags, conv),
153 END(ccw->cu_type, conv), END(ccw->cu_model, conv),
154 END(ccw->dev_type, conv), END(ccw->dev_model, conv));
157 int output_ccw_table(struct module *modules, FILE *out, char *dirname)
159 struct module *i;
161 fprintf(out, "# ccw module ");
162 fprintf(out, "match_flags cu_type cu_model dev_type dev_model\n");
164 for (i = modules; i; i = i->next) {
165 struct ccw_device_id *e;
166 char shortname[strlen(i->pathname) + 1];
167 struct module_tables *t = &i->tables;
169 if (!t->ccw_table)
170 continue;
172 make_shortname(shortname, i->pathname);
173 for (e = t->ccw_table;
174 e->cu_type || e->cu_model || e->dev_type || e->dev_model;
175 e = (void *) e + t->ccw_size)
176 output_ccw_entry(e, shortname, out, i->file->conv);
178 return 1;
181 #define ISAPNP_VENDOR(a,b,c) (((((a)-'A'+1)&0x3f)<<2)|\
182 ((((b)-'A'+1)&0x18)>>3)|((((b)-'A'+1)&7)<<13)|\
183 ((((c)-'A'+1)&0x1f)<<8))
184 #define ISAPNP_DEVICE(x) ((((x)&0xf000)>>8)|\
185 (((x)&0x0f00)>>8)|\
186 (((x)&0x00f0)<<8)|\
187 (((x)&0x000f)<<8))
189 static void put_isapnp_id(FILE *out, const char *id)
191 unsigned short vendor, device;
193 vendor = ISAPNP_VENDOR(id[0], id[1], id[2]);
194 device = (unsigned short)strtol(&id[3], NULL, 16);
195 device = ISAPNP_DEVICE(device);
196 fprintf(out, " 0x%04x 0x%04x ", vendor, device);
199 int output_isapnp_table(struct module *modules, FILE *out, char *dirname)
201 struct module *i;
203 fprintf(out, "# isapnp module ");
204 fprintf(out, "cardvendor carddevice driver_data vendor function ...\n");
206 for (i = modules; i; i = i->next) {
207 char shortname[strlen(i->pathname) + 1];
208 struct module_tables *t = &i->tables;
210 if (t->pnp_table) {
211 struct pnp_device_id *id;
212 make_shortname(shortname, i->pathname);
213 for (id = t->pnp_table;
214 id->id[0];
215 id = (void *)id + t->pnp_size) {
216 fprintf(out, "%-20s", shortname);
217 fprintf(out, " 0xffff 0xffff ");
218 fprintf(out, " 0x00000000 "); /* driver_data */
219 put_isapnp_id(out, id->id);
220 fprintf(out, "\n");
223 if (t->pnp_card_table) {
224 void *id;
225 make_shortname(shortname, i->pathname);
226 for (id = t->pnp_card_table;
227 ((char *)id)[0];
228 id += t->pnp_card_size) {
229 int idx;
230 struct pnp_card_devid *devid
231 = id + t->pnp_card_offset;
233 fprintf(out, "%-20s", shortname);
234 put_isapnp_id(out, id);
235 fprintf(out, " 0x00000000 "); /* driver_data */
236 for (idx = 0; idx < 8; idx++) {
237 if (!devid->devid[idx][0])
238 break;
239 put_isapnp_id(out, devid->devid[idx]);
241 fprintf(out, "\n");
245 return 1;
248 #define MATCH_bustype 1
249 #define MATCH_vendor 2
250 #define MATCH_product 4
251 #define MATCH_version 8
253 #define MATCH_evbit 0x010
254 #define MATCH_keybit 0x020
255 #define MATCH_relbit 0x040
256 #define MATCH_absbit 0x080
257 #define MATCH_mscbit 0x100
258 #define MATCH_ledbit 0x200
259 #define MATCH_sndbit 0x400
260 #define MATCH_ffbit 0x800
261 #define MATCH_swbit 0x1000
263 #define MATCH(x) (END(input->match_flags, conv) & MATCH_ ## x)
264 #define PRINT_SCALAR(n) fprintf(out, " 0x%lx", MATCH(n) ? END(input->n, conv) : 0l)
265 #define PRINT_ARRAY64(n) do { \
266 fprintf(out, " "); \
267 if (MATCH(n)) \
268 output_input_bits_64(out, input->n, sizeof(input->n), conv); \
269 else \
270 fprintf(out, "%d", 0); \
271 } while (0)
273 #define PRINT_ARRAY32(n) do { \
274 fprintf(out, " "); \
275 if (MATCH(n)) \
276 output_input_bits_32(out, input->n, sizeof(input->n), conv); \
277 else \
278 fprintf(out, "%d", 0); \
279 } while (0)
281 static void output_input_bits_32(FILE *out, unsigned int *bits, int size,
282 int conv)
284 int i, j;
286 size /= sizeof(*bits);
287 for (i = size - 1; i >= 0; i--)
288 if (END(bits[i], conv))
289 break;
290 if (i < 0)
291 i = 0;
292 fprintf(out, "%x", END(bits[i], conv));
293 for (j = i - 1; j >= 0; j--)
294 fprintf(out, ":%x", END(bits[j], conv));
297 static void output_input_bits_64(FILE *out, unsigned long long *bits, int size,
298 int conv)
300 int i, j;
302 size /= sizeof(*bits);
303 for (i = size - 1; i >= 0; i--)
304 if (END(bits[i], conv))
305 break;
306 if (i < 0)
307 i = 0;
308 fprintf(out, "%llx", END(bits[i], conv));
309 for (j = i - 1; j >= 0; j--)
310 fprintf(out, ":%llx", END(bits[j], conv));
313 /* Formats are too different to */
314 static int output_input_entry_32(struct input_device_id_32 *input,
315 char *name, FILE *out, int conv)
317 if (!input->match_flags && !input->driver_info)
318 return 1;
320 fprintf(out, "%-20s0x%x", name, END(input->match_flags, conv));
322 PRINT_SCALAR(bustype);
323 PRINT_SCALAR(vendor);
324 PRINT_SCALAR(product);
325 PRINT_SCALAR(version);
327 PRINT_ARRAY32(evbit);
328 PRINT_ARRAY32(keybit);
329 PRINT_ARRAY32(relbit);
330 PRINT_ARRAY32(absbit);
331 PRINT_ARRAY32(mscbit);
332 PRINT_ARRAY32(ledbit);
333 PRINT_ARRAY32(sndbit);
334 PRINT_ARRAY32(ffbit);
335 PRINT_ARRAY32(swbit);
337 fprintf(out, " 0x%x\n", END(input->driver_info, conv));
338 return 0;
341 static int output_input_entry_32_old(struct input_device_id_old_32 *input,
342 char *name, FILE *out, int conv)
344 if (!input->match_flags && !input->driver_info)
345 return 1;
347 fprintf(out, "%-20s0x%x", name, END(input->match_flags, conv));
349 PRINT_SCALAR(bustype);
350 PRINT_SCALAR(vendor);
351 PRINT_SCALAR(product);
352 PRINT_SCALAR(version);
354 PRINT_ARRAY32(evbit);
355 PRINT_ARRAY32(keybit);
356 PRINT_ARRAY32(relbit);
357 PRINT_ARRAY32(absbit);
358 PRINT_ARRAY32(mscbit);
359 PRINT_ARRAY32(ledbit);
360 PRINT_ARRAY32(sndbit);
361 PRINT_ARRAY32(ffbit);
363 fprintf(out, " 0x%x\n", END(input->driver_info, conv));
364 return 0;
367 static int output_input_entry_64(struct input_device_id_64 *input,
368 char *name, FILE *out, int conv)
370 if (!input->match_flags && !input->driver_info)
371 return 1;
373 fprintf(out, "%-20s0x%llx", name, END(input->match_flags, conv));
375 PRINT_SCALAR(bustype);
376 PRINT_SCALAR(vendor);
377 PRINT_SCALAR(product);
378 PRINT_SCALAR(version);
380 PRINT_ARRAY64(evbit);
381 PRINT_ARRAY64(keybit);
382 PRINT_ARRAY64(relbit);
383 PRINT_ARRAY64(absbit);
384 PRINT_ARRAY64(mscbit);
385 PRINT_ARRAY64(ledbit);
386 PRINT_ARRAY64(sndbit);
387 PRINT_ARRAY64(ffbit);
388 PRINT_ARRAY64(swbit);
390 fprintf(out, " 0x%llx\n", END(input->driver_info, conv));
391 return 0;
394 static int output_input_entry_64_old(struct input_device_id_old_64 *input,
395 char *name, FILE *out, int conv)
397 if (!input->match_flags && !input->driver_info)
398 return 1;
400 fprintf(out, "%-20s0x%llx", name, END(input->match_flags, conv));
402 PRINT_SCALAR(bustype);
403 PRINT_SCALAR(vendor);
404 PRINT_SCALAR(product);
405 PRINT_SCALAR(version);
407 PRINT_ARRAY64(evbit);
408 PRINT_ARRAY64(keybit);
409 PRINT_ARRAY64(relbit);
410 PRINT_ARRAY64(absbit);
411 PRINT_ARRAY64(mscbit);
412 PRINT_ARRAY64(ledbit);
413 PRINT_ARRAY64(sndbit);
414 PRINT_ARRAY64(ffbit);
416 fprintf(out, " 0x%llx\n", END(input->driver_info, conv));
417 return 0;
420 int output_input_table(struct module *modules, FILE *out, char *dirname)
422 struct module *i;
424 fprintf(out, "# module matchBits");
425 fprintf(out, " bustype vendor product version evBits keyBits relBits");
426 fprintf(out, " absBits mscBits ledBits sndBits ffBits [swBits] driver_info\n");
428 for (i = modules; i; i = i->next) {
429 void *p;
430 char shortname[strlen(i->pathname) + 1];
431 int done = 0;
432 struct module_tables *t = &i->tables;
433 int conv = i->file->conv;
435 if (!t->input_table)
436 continue;
438 make_shortname(shortname, i->pathname);
439 /* Guess what size it really is, based on size of
440 * whole table. Table changed in 2.6.14. This is a hack. */
441 if (t->input_size == sizeof(struct input_device_id_old_64)) {
442 if ((t->input_table_size % t->input_size) != 0) {
443 t->input_size
444 = sizeof(struct input_device_id_64);
446 } else {
447 if ((t->input_table_size % t->input_size) != 0) {
448 t->input_size
449 = sizeof(struct input_device_id_32);
453 for (p = t->input_table; !done; p += t->input_size) {
454 switch (t->input_size) {
455 case sizeof(struct input_device_id_old_64):
456 done = output_input_entry_64_old(p,
457 shortname,
458 out, conv);
459 break;
460 case sizeof(struct input_device_id_64):
461 done = output_input_entry_64(p, shortname,
462 out, conv);
463 break;
464 case sizeof(struct input_device_id_old_32):
465 done = output_input_entry_32_old(p,
466 shortname,
467 out, conv);
468 break;
469 case sizeof(struct input_device_id_32):
470 done = output_input_entry_32(p, shortname,
471 out, conv);
472 break;
476 return 1;
479 static void output_serio_entry(struct serio_device_id *serio, char *name, FILE *out)
481 fprintf(out,
482 "%-20s 0x%02x 0x%02x 0x%02x 0x%02x\n",
483 name,
484 serio->type,
485 serio->extra,
486 serio->id,
487 serio->proto);
491 int output_serio_table(struct module *modules, FILE *out, char *dirname)
493 struct module *i;
495 fprintf(out, "# serio module type extra id proto\n");
497 for (i = modules; i; i = i->next) {
498 struct serio_device_id *e;
499 char shortname[strlen(i->pathname) + 1];
500 struct module_tables *t = &i->tables;
502 if (!t->serio_table)
503 continue;
505 make_shortname(shortname, i->pathname);
506 for (e = t->serio_table; e->type || e->proto; e = (void *)e + t->serio_size)
507 output_serio_entry(e, shortname, out);
509 return 1;
513 static void
514 strip_whitespace (char *str, char chr)
516 int i;
517 if (!str)
518 return;
519 for (i = strlen (str); i >= 0; --i)
520 if (isspace (*str))
521 *str = chr;
524 /* We set driver_data to zero */
525 static void output_of_entry(struct of_device_id *dev, char *name, FILE *out)
527 char *ofname = NULL, *type = NULL, *compatible = NULL;
528 if (dev->name[0]) {
529 ofname = strdup (dev->name);
530 strip_whitespace (ofname, '_');
533 if (dev->type[0]) {
534 type = strdup (dev->type);
535 strip_whitespace (type, '_');
538 if (dev->compatible[0]) {
539 compatible = strdup (dev->compatible);
540 strip_whitespace (compatible, '_');
543 fprintf (out, "%-20s %-20s %-20s %s\n",
544 name, ofname ? ofname : "*", type ? type : "*",
545 compatible ? compatible : "*");
547 free(ofname);
548 free(type);
549 free(compatible);
552 int output_of_table(struct module *modules, FILE *out, char *dirname)
554 struct module *i;
556 fprintf (out, "# of module name type compatible\n");
557 for (i = modules; i; i = i->next) {
558 struct of_device_id *e;
559 char shortname[strlen(i->pathname) + 1];
560 struct module_tables *t = &i->tables;
562 if (!t->of_table)
563 continue;
565 make_shortname(shortname, i->pathname);
566 for (e = t->of_table; e->name[0]|e->type[0]|e->compatible[0];
567 e = (void *)e + t->of_size)
568 output_of_entry(e, shortname, out);
570 return 1;