tizen 2.0
[external/module-init-tools.git] / tables.c
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"
8
9 /* Turn /lib/modules/2.5.49/kernel/foo.ko(.gz) => foo */
10 static void make_shortname(char *dest, const char *src)
11 {
12         char *ext;
13         const char *bname;
14
15         bname = my_basename(src);
16         strcpy(dest, bname);
17         ext = strchr(dest, '.');
18         if (ext)
19                 *ext = '\0';
20 }
21
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)
25 {
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));
35 }
36
37 int output_pci_table(struct module *modules, FILE *out, char *dirname)
38 {
39         struct module *i;
40
41         fprintf(out, "# pci module         vendor     device     subvendor"
42                 "  subdevice  class      class_mask driver_data\n");
43
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;
48
49                 if (!t->pci_table)
50                         continue;
51
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);
55         }
56         return 1;
57 }
58
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)
62 {
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));
80 }
81
82 int output_usb_table(struct module *modules, FILE *out, char *dirname)
83 {
84         struct module *i;
85
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");
93
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;
98
99                 if (!t->usb_table)
100                         continue;
101
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);
107         }
108         return 1;
109 }
110
111 static void output_ieee1394_entry(struct ieee1394_device_id *fw, char *name,
112                                   FILE *out, int conv)
113 {
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));
121 }
122
123 int output_ieee1394_table(struct module *modules, FILE *out, char *dirname)
124 {
125         struct module *i;
126
127         fprintf(out, "# ieee1394 module    ");
128         fprintf(out, "match_flags vendor_id model_id specifier_id version\n");
129
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;
134
135                 if (!t->ieee1394_table)
136                         continue;
137
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);
142         }
143         return 1;
144 }
145
146
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)
150 {
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));
155 }
156
157 int output_ccw_table(struct module *modules, FILE *out, char *dirname)
158 {
159         struct module *i;
160
161         fprintf(out, "# ccw module         ");
162         fprintf(out, "match_flags cu_type cu_model dev_type dev_model\n");
163
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;
168
169                 if (!t->ccw_table)
170                         continue;
171
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);
177         }
178         return 1;
179 }
180
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))
188
189 static void put_isapnp_id(FILE *out, const char *id)
190 {
191         unsigned short vendor, device;
192
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);
197 }
198
199 int output_isapnp_table(struct module *modules, FILE *out, char *dirname)
200 {
201         struct module *i;
202
203         fprintf(out, "# isapnp module      ");
204         fprintf(out, "cardvendor carddevice driver_data vendor     function   ...\n");
205
206         for (i = modules; i; i = i->next) {
207                 char shortname[strlen(i->pathname) + 1];
208                 struct module_tables *t = &i->tables;
209
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");
221                         }
222                 }
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;
232
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]);
240                                 }
241                                 fprintf(out, "\n");
242                         }
243                 }
244         }
245         return 1;
246 }
247
248 #define MATCH_bustype   1
249 #define MATCH_vendor    2
250 #define MATCH_product   4
251 #define MATCH_version   8
252
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
262
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)
272
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)
280
281 static void output_input_bits_32(FILE *out, unsigned int *bits, int size,
282                                  int conv)
283 {
284         int i, j;
285
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));
295 }
296
297 static void output_input_bits_64(FILE *out, unsigned long long *bits, int size,
298                                  int conv)
299 {
300         int i, j;
301
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));
311 }
312
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)
316 {
317         if (!input->match_flags && !input->driver_info)
318                 return 1;
319
320         fprintf(out, "%-20s0x%x", name, END(input->match_flags, conv));
321
322         PRINT_SCALAR(bustype);
323         PRINT_SCALAR(vendor);
324         PRINT_SCALAR(product);
325         PRINT_SCALAR(version);
326
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);
336
337         fprintf(out, "  0x%x\n", END(input->driver_info, conv));
338         return 0;
339 }
340
341 static int output_input_entry_32_old(struct input_device_id_old_32 *input,
342                                      char *name, FILE *out, int conv)
343 {
344         if (!input->match_flags && !input->driver_info)
345                 return 1;
346
347         fprintf(out, "%-20s0x%x", name, END(input->match_flags, conv));
348
349         PRINT_SCALAR(bustype);
350         PRINT_SCALAR(vendor);
351         PRINT_SCALAR(product);
352         PRINT_SCALAR(version);
353
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);
362
363         fprintf(out, "  0x%x\n", END(input->driver_info, conv));
364         return 0;
365 }
366
367 static int output_input_entry_64(struct input_device_id_64 *input,
368                                  char *name, FILE *out, int conv)
369 {
370         if (!input->match_flags && !input->driver_info)
371                 return 1;
372
373         fprintf(out, "%-20s0x%llx", name, END(input->match_flags, conv));
374
375         PRINT_SCALAR(bustype);
376         PRINT_SCALAR(vendor);
377         PRINT_SCALAR(product);
378         PRINT_SCALAR(version);
379
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);
389
390         fprintf(out, "  0x%llx\n", END(input->driver_info, conv));
391         return 0;
392 }
393
394 static int output_input_entry_64_old(struct input_device_id_old_64 *input,
395                                      char *name, FILE *out, int conv)
396 {
397         if (!input->match_flags && !input->driver_info)
398                 return 1;
399
400         fprintf(out, "%-20s0x%llx", name, END(input->match_flags, conv));
401
402         PRINT_SCALAR(bustype);
403         PRINT_SCALAR(vendor);
404         PRINT_SCALAR(product);
405         PRINT_SCALAR(version);
406
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);
415
416         fprintf(out, "  0x%llx\n", END(input->driver_info, conv));
417         return 0;
418 }
419
420 int output_input_table(struct module *modules, FILE *out, char *dirname)
421 {
422         struct module *i;
423
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");
427
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;
434
435                 if (!t->input_table)
436                         continue;
437
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);
445                         }
446                 } else {
447                         if ((t->input_table_size % t->input_size) != 0) {
448                                 t->input_size
449                                         = sizeof(struct input_device_id_32);
450                         }
451                 }
452
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;
473                         }
474                 }                               
475         }
476         return 1;
477 }
478
479 static void output_serio_entry(struct serio_device_id *serio, char *name, FILE *out)
480 {
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);
488 }
489
490
491 int output_serio_table(struct module *modules, FILE *out, char *dirname)
492 {
493         struct module *i;
494
495         fprintf(out, "# serio module       type extra id   proto\n");
496
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;
501
502                 if (!t->serio_table)
503                         continue;
504
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);
508         }
509         return 1;
510 }
511
512
513 static void
514 strip_whitespace (char *str, char chr)
515 {
516         int i;
517         if (!str)
518                 return;
519         for (i = strlen (str); i >= 0; --i)
520                 if (isspace (*str))
521                         *str = chr;
522 }
523
524 /* We set driver_data to zero */
525 static void output_of_entry(struct of_device_id *dev, char *name, FILE *out)
526 {
527         char *ofname = NULL, *type = NULL, *compatible = NULL;
528         if (dev->name[0]) {
529                 ofname = strdup (dev->name);
530                 strip_whitespace (ofname, '_');
531         }
532
533         if (dev->type[0]) {
534                 type = strdup (dev->type);
535                 strip_whitespace (type, '_');
536        }
537
538         if (dev->compatible[0]) {
539                 compatible = strdup (dev->compatible);
540                 strip_whitespace (compatible, '_');
541         }
542
543         fprintf (out, "%-20s %-20s %-20s %s\n",
544                 name, ofname ? ofname : "*", type ? type : "*",
545                 compatible ? compatible : "*");
546         
547         free(ofname);
548         free(type);
549         free(compatible);
550 }
551
552 int output_of_table(struct module *modules, FILE *out, char *dirname)
553 {
554         struct module *i;
555
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;
561
562                 if (!t->of_table)
563                         continue;
564
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);
569         }
570         return 1;
571 }