~apw/module-init-tools/resync2

« back to all changes in this revision

Viewing changes to tables.c

  • Committer: Andy Whitcroft
  • Date: 2011-06-07 17:05:36 UTC
  • mfrom: (0.1.13 sid)
  • Revision ID: apw@canonical.com-20110607170536-2vwmd0km51fef9l5
Manual Resync with Debian version 3.13-1.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
}