[PATCH 2/2] Fix (improve) deadlock condition on module removal netfilter socket optio...
[mit.git] / tables.c
blob6dfd16569ff1d1bafebb07837418018e8cdcd2e6
1 #include <string.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <ctype.h>
5 #include "depmod.h"
6 #include "tables.h"
8 /* Turn /lib/modules/2.5.49/kernel/foo.ko(.gz) => foo */
9 static void make_shortname(char *dest, const char *src)
11 char *ext;
12 const char *slash;
14 slash = strrchr(src, '/') ?: src-1;
15 strcpy(dest, slash + 1);
16 ext = strchr(dest, '.');
17 if (ext)
18 *ext = '\0';
21 /* We set driver_data to zero */
22 static void output_pci_entry(struct pci_device_id *pci, char *name, FILE *out,
23 int conv)
25 fprintf(out,
26 "%-20s 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x0\n",
27 name,
28 END(pci->vendor, conv),
29 END(pci->device, conv),
30 END(pci->subvendor, conv),
31 END(pci->subdevice, conv),
32 END(pci->class, conv),
33 END(pci->class_mask, conv));
36 void output_pci_table(struct module *modules, FILE *out)
38 struct module *i;
40 fprintf(out, "# pci module vendor device subvendor"
41 " subdevice class class_mask driver_data\n");
43 for (i = modules; i; i = i->next) {
44 struct pci_device_id *e;
45 char shortname[strlen(i->pathname) + 1];
47 if (!i->pci_table)
48 continue;
50 make_shortname(shortname, i->pathname);
51 for (e = i->pci_table; e->vendor; e = (void *)e + i->pci_size)
52 output_pci_entry(e, shortname, out, i->conv);
56 /* We set driver_info to zero */
57 static void output_usb_entry(struct usb_device_id *usb, char *name, FILE *out,
58 int conv)
60 fprintf(out, "%-20s 0x%04x 0x%04x 0x%04x 0x%04x"
61 " 0x%04x 0x%02x 0x%02x"
62 " 0x%02x 0x%02x"
63 " 0x%02x 0x%02x"
64 " 0x0\n",
65 name,
66 END(usb->match_flags, conv),
67 END(usb->idVendor, conv),
68 END(usb->idProduct, conv),
69 END(usb->bcdDevice_lo, conv),
70 END(usb->bcdDevice_hi, conv),
71 END(usb->bDeviceClass, conv),
72 END(usb->bDeviceSubClass, conv),
73 END(usb->bDeviceProtocol, conv),
74 END(usb->bInterfaceClass, conv),
75 END(usb->bInterfaceSubClass, conv),
76 END(usb->bInterfaceProtocol, conv));
79 void output_usb_table(struct module *modules, FILE *out)
81 struct module *i;
83 fprintf(out, "# usb module ");
84 /* Requires all users to be on kernel 2.4.0 or later */
85 fprintf(out, "match_flags ");
86 fprintf(out, "idVendor idProduct bcdDevice_lo bcdDevice_hi"
87 " bDeviceClass bDeviceSubClass bDeviceProtocol"
88 " bInterfaceClass bInterfaceSubClass"
89 " bInterfaceProtocol driver_info\n");
91 for (i = modules; i; i = i->next) {
92 struct usb_device_id *e;
93 char shortname[strlen(i->pathname) + 1];
95 if (!i->usb_table)
96 continue;
98 make_shortname(shortname, i->pathname);
99 for (e = i->usb_table;
100 e->idVendor || e->bDeviceClass || e->bInterfaceClass;
101 e = (void *)e + i->usb_size)
102 output_usb_entry(e, shortname, out, i->conv);
106 static void output_ieee1394_entry(struct ieee1394_device_id *fw, char *name,
107 FILE *out, int conv)
109 fprintf(out, "%-20s 0x%08x 0x%06x 0x%06x 0x%06x 0x%06x\n",
110 name,
111 END(fw->match_flags, conv),
112 END(fw->vendor_id, conv),
113 END(fw->model_id, conv),
114 END(fw->specifier_id, conv),
115 END(fw->version, conv));
118 void output_ieee1394_table(struct module *modules, FILE *out)
120 struct module *i;
122 fprintf(out, "# ieee1394 module ");
123 fprintf(out, "match_flags vendor_id model_id specifier_id version\n");
125 for (i = modules; i; i = i->next) {
126 struct ieee1394_device_id *fw;
127 char shortname[strlen(i->pathname) + 1];
129 if (!i->ieee1394_table)
130 continue;
132 make_shortname(shortname, i->pathname);
133 for (fw = i->ieee1394_table; fw->match_flags;
134 fw = (void *) fw + i->ieee1394_size)
135 output_ieee1394_entry(fw, shortname, out, i->conv);
140 /* We set driver_data to zero */
141 static void output_ccw_entry(struct ccw_device_id *ccw, char *name, FILE *out,
142 int conv)
144 fprintf(out, "%-20s 0x%04x 0x%04x 0x%02x 0x%04x 0x%02x\n",
145 name, END(ccw->match_flags, conv),
146 END(ccw->cu_type, conv), END(ccw->cu_model, conv),
147 END(ccw->dev_type, conv), END(ccw->dev_model, conv));
150 void output_ccw_table(struct module *modules, FILE *out)
152 struct module *i;
154 fprintf(out, "# ccw module ");
155 fprintf(out, "match_flags cu_type cu_model dev_type dev_model\n");
157 for (i = modules; i; i = i->next) {
158 struct ccw_device_id *e;
159 char shortname[strlen(i->pathname) + 1];
161 if (!i->ccw_table)
162 continue;
164 make_shortname(shortname, i->pathname);
165 for (e = i->ccw_table;
166 e->cu_type || e->cu_model || e->dev_type || e->dev_model;
167 e = (void *) e + i->ccw_size)
168 output_ccw_entry(e, shortname, out, i->conv);
172 #define ISAPNP_VENDOR(a,b,c) (((((a)-'A'+1)&0x3f)<<2)|\
173 ((((b)-'A'+1)&0x18)>>3)|((((b)-'A'+1)&7)<<13)|\
174 ((((c)-'A'+1)&0x1f)<<8))
175 #define ISAPNP_DEVICE(x) ((((x)&0xf000)>>8)|\
176 (((x)&0x0f00)>>8)|\
177 (((x)&0x00f0)<<8)|\
178 (((x)&0x000f)<<8))
180 static void put_isapnp_id(FILE *out, const char *id)
182 unsigned short vendor, device;
184 vendor = ISAPNP_VENDOR(id[0], id[1], id[2]);
185 device = (unsigned short)strtol(&id[3], NULL, 16);
186 device = ISAPNP_DEVICE(device);
187 fprintf(out, " 0x%04x 0x%04x ", vendor, device);
190 void output_isapnp_table(struct module *modules, FILE *out)
192 struct module *i;
194 fprintf(out, "# isapnp module ");
195 fprintf(out, "cardvendor carddevice driver_data vendor function ...\n");
197 for (i = modules; i; i = i->next) {
198 char shortname[strlen(i->pathname) + 1];
200 if (i->pnp_table) {
201 struct pnp_device_id *id;
202 make_shortname(shortname, i->pathname);
203 for (id = i->pnp_table;
204 id->id[0];
205 id = (void *)id + i->pnp_size) {
206 fprintf(out, "%-20s", shortname);
207 fprintf(out, " 0xffff 0xffff ");
208 fprintf(out, " 0x00000000 "); /* driver_data */
209 put_isapnp_id(out, id->id);
210 fprintf(out, "\n");
213 if (i->pnp_card_table) {
214 void *id;
215 make_shortname(shortname, i->pathname);
216 for (id = i->pnp_card_table;
217 ((char *)id)[0];
218 id += i->pnp_card_size) {
219 int idx;
220 struct pnp_card_devid *devid
221 = id + i->pnp_card_offset;
223 fprintf(out, "%-20s", shortname);
224 put_isapnp_id(out, id);
225 fprintf(out, " 0x00000000 "); /* driver_data */
226 for (idx = 0; idx < 8; idx++) {
227 if (!devid->devid[idx][0])
228 break;
229 put_isapnp_id(out, devid->devid[idx]);
231 fprintf(out, "\n");
237 #define MATCH_bustype 1
238 #define MATCH_vendor 2
239 #define MATCH_product 4
240 #define MATCH_version 8
242 #define MATCH_evbit 0x010
243 #define MATCH_keybit 0x020
244 #define MATCH_relbit 0x040
245 #define MATCH_absbit 0x080
246 #define MATCH_mscbit 0x100
247 #define MATCH_ledbit 0x200
248 #define MATCH_sndbit 0x400
249 #define MATCH_ffbit 0x800
250 #define MATCH_swbit 0x1000
252 #define MATCH(x) (END(input->match_flags, conv) & MATCH_ ## x)
253 #define PRINT_SCALAR(n) fprintf(out, " 0x%lx", MATCH(n) ? END(input->n, conv) : 0l)
254 #define PRINT_ARRAY64(n) do { \
255 fprintf(out, " "); \
256 if (MATCH(n)) \
257 output_input_bits_64(out, input->n, sizeof(input->n), conv); \
258 else \
259 fprintf(out, "%d", 0); \
260 } while (0)
262 #define PRINT_ARRAY32(n) do { \
263 fprintf(out, " "); \
264 if (MATCH(n)) \
265 output_input_bits_32(out, input->n, sizeof(input->n), conv); \
266 else \
267 fprintf(out, "%d", 0); \
268 } while (0)
270 static void output_input_bits_32(FILE *out, unsigned int *bits, int size,
271 int conv)
273 int i, j;
275 size /= sizeof(*bits);
276 for (i = size - 1; i >= 0; i--)
277 if (END(bits[i], conv))
278 break;
279 if (i < 0)
280 i = 0;
281 fprintf(out, "%x", END(bits[i], conv));
282 for (j = i - 1; j >= 0; j--)
283 fprintf(out, ":%x", END(bits[j], conv));
286 static void output_input_bits_64(FILE *out, unsigned long long *bits, int size,
287 int conv)
289 int i, j;
291 size /= sizeof(*bits);
292 for (i = size - 1; i >= 0; i--)
293 if (END(bits[i], conv))
294 break;
295 if (i < 0)
296 i = 0;
297 fprintf(out, "%llx", END(bits[i], conv));
298 for (j = i - 1; j >= 0; j--)
299 fprintf(out, ":%llx", END(bits[j], conv));
302 /* Formats are too different to */
303 static int output_input_entry_32(struct input_device_id_32 *input,
304 char *name, FILE *out, int conv)
306 if (!input->match_flags && !input->driver_info)
307 return 1;
309 fprintf(out, "%-20s0x%x", name, END(input->match_flags, conv));
311 PRINT_SCALAR(bustype);
312 PRINT_SCALAR(vendor);
313 PRINT_SCALAR(product);
314 PRINT_SCALAR(version);
316 PRINT_ARRAY32(evbit);
317 PRINT_ARRAY32(keybit);
318 PRINT_ARRAY32(relbit);
319 PRINT_ARRAY32(absbit);
320 PRINT_ARRAY32(mscbit);
321 PRINT_ARRAY32(ledbit);
322 PRINT_ARRAY32(sndbit);
323 PRINT_ARRAY32(ffbit);
324 PRINT_ARRAY32(swbit);
326 fprintf(out, " 0x%x\n", END(input->driver_info, conv));
327 return 0;
330 static int output_input_entry_32_old(struct input_device_id_old_32 *input,
331 char *name, FILE *out, int conv)
333 if (!input->match_flags && !input->driver_info)
334 return 1;
336 fprintf(out, "%-20s0x%x", name, END(input->match_flags, conv));
338 PRINT_SCALAR(bustype);
339 PRINT_SCALAR(vendor);
340 PRINT_SCALAR(product);
341 PRINT_SCALAR(version);
343 PRINT_ARRAY32(evbit);
344 PRINT_ARRAY32(keybit);
345 PRINT_ARRAY32(relbit);
346 PRINT_ARRAY32(absbit);
347 PRINT_ARRAY32(mscbit);
348 PRINT_ARRAY32(ledbit);
349 PRINT_ARRAY32(sndbit);
350 PRINT_ARRAY32(ffbit);
352 fprintf(out, " 0x%x\n", END(input->driver_info, conv));
353 return 0;
356 static int output_input_entry_64(struct input_device_id_64 *input,
357 char *name, FILE *out, int conv)
359 if (!input->match_flags && !input->driver_info)
360 return 1;
362 fprintf(out, "%-20s0x%llx", name, END(input->match_flags, conv));
364 PRINT_SCALAR(bustype);
365 PRINT_SCALAR(vendor);
366 PRINT_SCALAR(product);
367 PRINT_SCALAR(version);
369 PRINT_ARRAY64(evbit);
370 PRINT_ARRAY64(keybit);
371 PRINT_ARRAY64(relbit);
372 PRINT_ARRAY64(absbit);
373 PRINT_ARRAY64(mscbit);
374 PRINT_ARRAY64(ledbit);
375 PRINT_ARRAY64(sndbit);
376 PRINT_ARRAY64(ffbit);
377 PRINT_ARRAY64(swbit);
379 fprintf(out, " 0x%llx\n", END(input->driver_info, conv));
380 return 0;
383 static int output_input_entry_64_old(struct input_device_id_old_64 *input,
384 char *name, FILE *out, int conv)
386 if (!input->match_flags && !input->driver_info)
387 return 1;
389 fprintf(out, "%-20s0x%llx", name, END(input->match_flags, conv));
391 PRINT_SCALAR(bustype);
392 PRINT_SCALAR(vendor);
393 PRINT_SCALAR(product);
394 PRINT_SCALAR(version);
396 PRINT_ARRAY64(evbit);
397 PRINT_ARRAY64(keybit);
398 PRINT_ARRAY64(relbit);
399 PRINT_ARRAY64(absbit);
400 PRINT_ARRAY64(mscbit);
401 PRINT_ARRAY64(ledbit);
402 PRINT_ARRAY64(sndbit);
403 PRINT_ARRAY64(ffbit);
405 fprintf(out, " 0x%llx\n", END(input->driver_info, conv));
406 return 0;
409 void output_input_table(struct module *modules, FILE *out)
411 struct module *i;
413 fprintf(out, "# module matchBits");
414 fprintf(out, " bustype vendor product version evBits keyBits relBits");
415 fprintf(out, " absBits mscBits ledBits sndBits ffBits [swBits] driver_info\n");
417 for (i = modules; i; i = i->next) {
418 void *p;
419 char shortname[strlen(i->pathname) + 1];
420 int done = 0;
422 if (!i->input_table)
423 continue;
425 make_shortname(shortname, i->pathname);
426 /* Guess what size it really is, based on size of
427 * whole table. Table changed in 2.6.14. This is a hack. */
428 if (i->input_size == sizeof(struct input_device_id_old_64)) {
429 if ((i->input_table_size % i->input_size) != 0) {
430 i->input_size
431 = sizeof(struct input_device_id_64);
433 } else {
434 if ((i->input_table_size % i->input_size) != 0) {
435 i->input_size
436 = sizeof(struct input_device_id_32);
440 for (p = i->input_table; !done; p += i->input_size) {
441 switch (i->input_size) {
442 case sizeof(struct input_device_id_old_64):
443 done = output_input_entry_64_old(p,
444 shortname,
445 out,
446 i->conv);
447 break;
448 case sizeof(struct input_device_id_64):
449 done = output_input_entry_64(p, shortname,
450 out, i->conv);
451 break;
452 case sizeof(struct input_device_id_old_32):
453 done = output_input_entry_32_old(p,
454 shortname,
455 out,
456 i->conv);
457 break;
458 case sizeof(struct input_device_id_32):
459 done = output_input_entry_32(p, shortname,
460 out, i->conv);
461 break;
467 static void output_serio_entry(struct serio_device_id *serio, char *name, FILE *out)
469 fprintf(out,
470 "%-20s 0x%02x 0x%02x 0x%02x 0x%02x\n",
471 name,
472 serio->type,
473 serio->extra,
474 serio->id,
475 serio->proto);
479 void output_serio_table(struct module *modules, FILE *out)
481 struct module *i;
483 fprintf(out, "# serio module type extra id proto\n");
485 for (i = modules; i; i = i->next) {
486 struct serio_device_id *e;
487 char shortname[strlen(i->pathname) + 1];
489 if (!i->serio_table)
490 continue;
492 make_shortname(shortname, i->pathname);
493 for (e = i->serio_table; e->type || e->proto; e = (void *)e + i->serio_size)
494 output_serio_entry(e, shortname, out);
499 static void
500 strip_whitespace (char *str, char chr)
502 int i;
503 if (!str)
504 return;
505 for (i = strlen (str); i >= 0; --i)
506 if (isspace (*str))
507 *str = chr;
510 /* We set driver_data to zero */
511 static void output_of_entry(struct of_device_id *dev, char *name, FILE *out)
513 char *ofname = NULL, *type = NULL, *compatible = NULL;
514 if (dev->name[0]) {
515 ofname = strdup (dev->name);
516 strip_whitespace (ofname, '_');
519 if (dev->type[0]) {
520 type = strdup (dev->type);
521 strip_whitespace (type, '_');
524 if (dev->compatible[0]) {
525 compatible = strdup (dev->compatible);
526 strip_whitespace (compatible, '_');
529 fprintf (out, "%-20s %-20s %-20s %s\n",
530 name, ofname ? ofname : "*", type ? type : "*",
531 compatible ? compatible : "*");
534 void output_of_table(struct module *modules, FILE *out)
536 struct module *i;
538 fprintf (out, "# of module name type compatible\n");
539 for (i = modules; i; i = i->next) {
540 struct of_device_id *e;
541 char shortname[strlen(i->pathname) + 1];
543 if (!i->of_table)
544 continue;
546 make_shortname(shortname, i->pathname);
547 for (e = i->of_table; e->name[0]|e->type[0]|e->compatible[0];
548 e = (void *)e + i->of_size)
549 output_of_entry(e, shortname, out);