1 /* Simple code to turn various tables in an ELF file into alias definitions.
2 * This deals with kernel datastructures where they should be
3 * dealt with: in the kernel source.
5 * Copyright 2002-2003 Rusty Russell, IBM Corporation
6 * 2003 Kai Germaschewski
9 * This software may be used and distributed according to the terms
10 * of the GNU General Public License, incorporated herein by reference.
15 /* We use the ELF typedefs for kernel_ulong_t but bite the bullet and
16 * use either stdint.h or inttypes.h for the rest. */
17 #if KERNEL_ELFCLASS == ELFCLASS32
18 typedef Elf32_Addr kernel_ulong_t
;
19 #define BITS_PER_LONG 32
21 typedef Elf64_Addr kernel_ulong_t
;
22 #define BITS_PER_LONG 64
33 typedef uint32_t __u32
;
34 typedef uint16_t __u16
;
35 typedef unsigned char __u8
;
37 /* Big exception to the "don't include kernel headers into userspace, which
38 * even potentially has different endianness and word sizes, since
39 * we handle those differences explicitly below */
40 #include "../../include/linux/mod_devicetable.h"
42 /* This array collects all instances that use the generic do_table */
44 const char *device_id
; /* name of table, __mod_<name>_device_table. */
45 unsigned long id_size
;
49 #define ___cat(a,b) a ## b
50 #define __cat(a,b) ___cat(a,b)
52 /* we need some special handling for this host tool running eventually on
53 * Darwin. The Mach-O section handling is a bit different than ELF section
54 * handling. The differnces in detail are:
55 * a) we have segments which have sections
56 * b) we need a API call to get the respective section symbols */
58 #include <mach-o/getsect.h>
60 #define INIT_SECTION(name) do { \
61 unsigned long name ## _len; \
62 char *__cat(pstart_,name) = getsectdata("__TEXT", \
63 #name, &__cat(name,_len)); \
64 char *__cat(pstop_,name) = __cat(pstart_,name) + \
66 __cat(__start_,name) = (void *)__cat(pstart_,name); \
67 __cat(__stop_,name) = (void *)__cat(pstop_,name); \
69 #define SECTION(name) __attribute__((section("__TEXT, " #name)))
71 struct devtable
**__start___devtable
, **__stop___devtable
;
73 #define INIT_SECTION(name) /* no-op for ELF */
74 #define SECTION(name) __attribute__((section(#name)))
76 /* We construct a table of pointers in an ELF section (pointers generally
77 * go unpadded by gcc). ld creates boundary syms for us. */
78 extern struct devtable
*__start___devtable
[], *__stop___devtable
[];
81 #if __GNUC__ == 3 && __GNUC_MINOR__ < 3
82 # define __used __attribute__((__unused__))
84 # define __used __attribute__((__used__))
87 /* Add a table entry. We test function type matches while we're here. */
88 #define ADD_TO_DEVTABLE(device_id, type, function) \
89 static struct devtable __cat(devtable,__LINE__) = { \
90 device_id + 0*sizeof((function)((const char *)NULL, \
93 sizeof(type), (function) }; \
94 static struct devtable *SECTION(__devtable) __used \
95 __cat(devtable_ptr,__LINE__) = &__cat(devtable,__LINE__)
97 #define ADD(str, sep, cond, field) \
101 sprintf(str + strlen(str), \
102 sizeof(field) == 1 ? "%02X" : \
103 sizeof(field) == 2 ? "%04X" : \
104 sizeof(field) == 4 ? "%08X" : "", \
107 sprintf(str + strlen(str), "*"); \
110 /* Always end in a wildcard, for future extension */
111 static inline void add_wildcard(char *str
)
113 int len
= strlen(str
);
115 if (str
[len
- 1] != '*')
116 strcat(str
+ len
, "*");
119 unsigned int cross_build
= 0;
121 * Check that sizeof(device_id type) are consistent with size of section
122 * in .o file. If in-consistent then userspace and kernel does not agree
123 * on actual size which is a bug.
124 * Also verify that the final entry in the table is all zeros.
125 * Ignore both checks if build host differ from target host and size differs.
127 static void device_id_check(const char *modname
, const char *device_id
,
128 unsigned long size
, unsigned long id_size
,
133 if (size
% id_size
|| size
< id_size
) {
134 if (cross_build
!= 0)
136 fatal("%s: sizeof(struct %s_device_id)=%lu is not a modulo "
137 "of the size of section __mod_%s_device_table=%lu.\n"
138 "Fix definition of struct %s_device_id "
139 "in mod_devicetable.h\n",
140 modname
, device_id
, id_size
, device_id
, size
, device_id
);
142 /* Verify last one is a terminator */
143 for (i
= 0; i
< id_size
; i
++ ) {
144 if (*(uint8_t*)(symval
+size
-id_size
+i
)) {
145 fprintf(stderr
,"%s: struct %s_device_id is %lu bytes. "
146 "The last of %lu is:\n",
147 modname
, device_id
, id_size
, size
/ id_size
);
148 for (i
= 0; i
< id_size
; i
++ )
149 fprintf(stderr
,"0x%02x ",
150 *(uint8_t*)(symval
+size
-id_size
+i
) );
151 fprintf(stderr
,"\n");
152 fatal("%s: struct %s_device_id is not terminated "
153 "with a NULL entry!\n", modname
, device_id
);
158 /* USB is special because the bcdDevice can be matched against a numeric range */
159 /* Looks like "usb:vNpNdNdcNdscNdpNicNiscNipNinN" */
160 static void do_usb_entry(struct usb_device_id
*id
,
161 unsigned int bcdDevice_initial
, int bcdDevice_initial_digits
,
162 unsigned char range_lo
, unsigned char range_hi
,
163 unsigned char max
, struct module
*mod
)
166 strcpy(alias
, "usb:");
167 ADD(alias
, "v", id
->match_flags
&USB_DEVICE_ID_MATCH_VENDOR
,
169 ADD(alias
, "p", id
->match_flags
&USB_DEVICE_ID_MATCH_PRODUCT
,
173 if (bcdDevice_initial_digits
)
174 sprintf(alias
+ strlen(alias
), "%0*X",
175 bcdDevice_initial_digits
, bcdDevice_initial
);
176 if (range_lo
== range_hi
)
177 sprintf(alias
+ strlen(alias
), "%X", range_lo
);
178 else if (range_lo
> 0 || range_hi
< max
) {
179 if (range_lo
> 0x9 || range_hi
< 0xA)
180 sprintf(alias
+ strlen(alias
),
185 sprintf(alias
+ strlen(alias
),
186 range_lo
< 0x9 ? "[%X-9" : "[%X",
188 sprintf(alias
+ strlen(alias
),
189 range_hi
> 0xA ? "a-%X]" : "%X]",
193 if (bcdDevice_initial_digits
< (sizeof(id
->bcdDevice_lo
) * 2 - 1))
196 ADD(alias
, "dc", id
->match_flags
&USB_DEVICE_ID_MATCH_DEV_CLASS
,
199 id
->match_flags
&USB_DEVICE_ID_MATCH_DEV_SUBCLASS
,
200 id
->bDeviceSubClass
);
202 id
->match_flags
&USB_DEVICE_ID_MATCH_DEV_PROTOCOL
,
203 id
->bDeviceProtocol
);
205 id
->match_flags
&USB_DEVICE_ID_MATCH_INT_CLASS
,
206 id
->bInterfaceClass
);
208 id
->match_flags
&USB_DEVICE_ID_MATCH_INT_SUBCLASS
,
209 id
->bInterfaceSubClass
);
211 id
->match_flags
&USB_DEVICE_ID_MATCH_INT_PROTOCOL
,
212 id
->bInterfaceProtocol
);
214 id
->match_flags
&USB_DEVICE_ID_MATCH_INT_NUMBER
,
215 id
->bInterfaceNumber
);
218 buf_printf(&mod
->dev_table_buf
,
219 "MODULE_ALIAS(\"%s\");\n", alias
);
222 /* Handles increment/decrement of BCD formatted integers */
223 /* Returns the previous value, so it works like i++ or i-- */
224 static unsigned int incbcd(unsigned int *bcd
,
229 unsigned int init
= *bcd
, i
, j
;
230 unsigned long long c
, dec
= 0;
232 /* If bcd is not in BCD format, just increment */
238 /* Convert BCD to Decimal */
239 for (i
=0 ; i
< chars
; i
++) {
240 c
= (*bcd
>> (i
<< 2)) & 0xf;
241 c
= c
> 9 ? 9 : c
; /* force to bcd just in case */
242 for (j
=0 ; j
< i
; j
++)
247 /* Do our increment/decrement */
251 /* Convert back to BCD */
252 for (i
=0 ; i
< chars
; i
++) {
253 for (c
=1,j
=0 ; j
< i
; j
++)
256 *bcd
+= c
<< (i
<< 2);
261 static void do_usb_entry_multi(struct usb_device_id
*id
, struct module
*mod
)
263 unsigned int devlo
, devhi
;
264 unsigned char chi
, clo
, max
;
267 id
->match_flags
= TO_NATIVE(id
->match_flags
);
268 id
->idVendor
= TO_NATIVE(id
->idVendor
);
269 id
->idProduct
= TO_NATIVE(id
->idProduct
);
271 devlo
= id
->match_flags
& USB_DEVICE_ID_MATCH_DEV_LO
?
272 TO_NATIVE(id
->bcdDevice_lo
) : 0x0U
;
273 devhi
= id
->match_flags
& USB_DEVICE_ID_MATCH_DEV_HI
?
274 TO_NATIVE(id
->bcdDevice_hi
) : ~0x0U
;
276 /* Figure out if this entry is in bcd or hex format */
277 max
= 0x9; /* Default to decimal format */
278 for (ndigits
= 0 ; ndigits
< sizeof(id
->bcdDevice_lo
) * 2 ; ndigits
++) {
279 clo
= (devlo
>> (ndigits
<< 2)) & 0xf;
280 chi
= ((devhi
> 0x9999 ? 0x9999 : devhi
) >> (ndigits
<< 2)) & 0xf;
281 if (clo
> max
|| chi
> max
) {
288 * Some modules (visor) have empty slots as placeholder for
289 * run-time specification that results in catch-all alias
291 if (!(id
->idVendor
| id
->idProduct
| id
->bDeviceClass
| id
->bInterfaceClass
))
294 /* Convert numeric bcdDevice range into fnmatch-able pattern(s) */
295 for (ndigits
= sizeof(id
->bcdDevice_lo
) * 2 - 1; devlo
<= devhi
; ndigits
--) {
298 if (chi
> max
) /* If we are in bcd mode, truncate if necessary */
303 if (devlo
== devhi
|| !ndigits
) {
304 do_usb_entry(id
, devlo
, ndigits
, clo
, chi
, max
, mod
);
310 incbcd(&devlo
, 1, max
,
311 sizeof(id
->bcdDevice_lo
) * 2),
312 ndigits
, clo
, max
, max
, mod
);
316 incbcd(&devhi
, -1, max
,
317 sizeof(id
->bcdDevice_lo
) * 2),
318 ndigits
, 0x0, chi
, max
, mod
);
322 static void do_usb_table(void *symval
, unsigned long size
,
326 const unsigned long id_size
= sizeof(struct usb_device_id
);
328 device_id_check(mod
->name
, "usb", size
, id_size
, symval
);
330 /* Leave last one: it's the terminator. */
333 for (i
= 0; i
< size
; i
+= id_size
)
334 do_usb_entry_multi(symval
+ i
, mod
);
337 /* Looks like: hid:bNvNpN */
338 static int do_hid_entry(const char *filename
,
339 struct hid_device_id
*id
, char *alias
)
341 id
->bus
= TO_NATIVE(id
->bus
);
342 id
->group
= TO_NATIVE(id
->group
);
343 id
->vendor
= TO_NATIVE(id
->vendor
);
344 id
->product
= TO_NATIVE(id
->product
);
346 sprintf(alias
, "hid:");
347 ADD(alias
, "b", id
->bus
!= HID_BUS_ANY
, id
->bus
);
348 ADD(alias
, "g", id
->group
!= HID_GROUP_ANY
, id
->group
);
349 ADD(alias
, "v", id
->vendor
!= HID_ANY_ID
, id
->vendor
);
350 ADD(alias
, "p", id
->product
!= HID_ANY_ID
, id
->product
);
354 ADD_TO_DEVTABLE("hid", struct hid_device_id
, do_hid_entry
);
356 /* Looks like: ieee1394:venNmoNspNverN */
357 static int do_ieee1394_entry(const char *filename
,
358 struct ieee1394_device_id
*id
, char *alias
)
360 id
->match_flags
= TO_NATIVE(id
->match_flags
);
361 id
->vendor_id
= TO_NATIVE(id
->vendor_id
);
362 id
->model_id
= TO_NATIVE(id
->model_id
);
363 id
->specifier_id
= TO_NATIVE(id
->specifier_id
);
364 id
->version
= TO_NATIVE(id
->version
);
366 strcpy(alias
, "ieee1394:");
367 ADD(alias
, "ven", id
->match_flags
& IEEE1394_MATCH_VENDOR_ID
,
369 ADD(alias
, "mo", id
->match_flags
& IEEE1394_MATCH_MODEL_ID
,
371 ADD(alias
, "sp", id
->match_flags
& IEEE1394_MATCH_SPECIFIER_ID
,
373 ADD(alias
, "ver", id
->match_flags
& IEEE1394_MATCH_VERSION
,
379 ADD_TO_DEVTABLE("ieee1394", struct ieee1394_device_id
, do_ieee1394_entry
);
381 /* Looks like: pci:vNdNsvNsdNbcNscNiN. */
382 static int do_pci_entry(const char *filename
,
383 struct pci_device_id
*id
, char *alias
)
385 /* Class field can be divided into these three. */
386 unsigned char baseclass
, subclass
, interface
,
387 baseclass_mask
, subclass_mask
, interface_mask
;
389 id
->vendor
= TO_NATIVE(id
->vendor
);
390 id
->device
= TO_NATIVE(id
->device
);
391 id
->subvendor
= TO_NATIVE(id
->subvendor
);
392 id
->subdevice
= TO_NATIVE(id
->subdevice
);
393 id
->class = TO_NATIVE(id
->class);
394 id
->class_mask
= TO_NATIVE(id
->class_mask
);
396 strcpy(alias
, "pci:");
397 ADD(alias
, "v", id
->vendor
!= PCI_ANY_ID
, id
->vendor
);
398 ADD(alias
, "d", id
->device
!= PCI_ANY_ID
, id
->device
);
399 ADD(alias
, "sv", id
->subvendor
!= PCI_ANY_ID
, id
->subvendor
);
400 ADD(alias
, "sd", id
->subdevice
!= PCI_ANY_ID
, id
->subdevice
);
402 baseclass
= (id
->class) >> 16;
403 baseclass_mask
= (id
->class_mask
) >> 16;
404 subclass
= (id
->class) >> 8;
405 subclass_mask
= (id
->class_mask
) >> 8;
406 interface
= id
->class;
407 interface_mask
= id
->class_mask
;
409 if ((baseclass_mask
!= 0 && baseclass_mask
!= 0xFF)
410 || (subclass_mask
!= 0 && subclass_mask
!= 0xFF)
411 || (interface_mask
!= 0 && interface_mask
!= 0xFF)) {
412 warn("Can't handle masks in %s:%04X\n",
413 filename
, id
->class_mask
);
417 ADD(alias
, "bc", baseclass_mask
== 0xFF, baseclass
);
418 ADD(alias
, "sc", subclass_mask
== 0xFF, subclass
);
419 ADD(alias
, "i", interface_mask
== 0xFF, interface
);
423 ADD_TO_DEVTABLE("pci", struct pci_device_id
, do_pci_entry
);
425 /* looks like: "ccw:tNmNdtNdmN" */
426 static int do_ccw_entry(const char *filename
,
427 struct ccw_device_id
*id
, char *alias
)
429 id
->match_flags
= TO_NATIVE(id
->match_flags
);
430 id
->cu_type
= TO_NATIVE(id
->cu_type
);
431 id
->cu_model
= TO_NATIVE(id
->cu_model
);
432 id
->dev_type
= TO_NATIVE(id
->dev_type
);
433 id
->dev_model
= TO_NATIVE(id
->dev_model
);
435 strcpy(alias
, "ccw:");
436 ADD(alias
, "t", id
->match_flags
&CCW_DEVICE_ID_MATCH_CU_TYPE
,
438 ADD(alias
, "m", id
->match_flags
&CCW_DEVICE_ID_MATCH_CU_MODEL
,
440 ADD(alias
, "dt", id
->match_flags
&CCW_DEVICE_ID_MATCH_DEVICE_TYPE
,
442 ADD(alias
, "dm", id
->match_flags
&CCW_DEVICE_ID_MATCH_DEVICE_MODEL
,
447 ADD_TO_DEVTABLE("ccw", struct ccw_device_id
, do_ccw_entry
);
449 /* looks like: "ap:tN" */
450 static int do_ap_entry(const char *filename
,
451 struct ap_device_id
*id
, char *alias
)
453 sprintf(alias
, "ap:t%02X*", id
->dev_type
);
456 ADD_TO_DEVTABLE("ap", struct ap_device_id
, do_ap_entry
);
458 /* looks like: "css:tN" */
459 static int do_css_entry(const char *filename
,
460 struct css_device_id
*id
, char *alias
)
462 sprintf(alias
, "css:t%01X", id
->type
);
465 ADD_TO_DEVTABLE("css", struct css_device_id
, do_css_entry
);
467 /* Looks like: "serio:tyNprNidNexN" */
468 static int do_serio_entry(const char *filename
,
469 struct serio_device_id
*id
, char *alias
)
471 id
->type
= TO_NATIVE(id
->type
);
472 id
->proto
= TO_NATIVE(id
->proto
);
473 id
->id
= TO_NATIVE(id
->id
);
474 id
->extra
= TO_NATIVE(id
->extra
);
476 strcpy(alias
, "serio:");
477 ADD(alias
, "ty", id
->type
!= SERIO_ANY
, id
->type
);
478 ADD(alias
, "pr", id
->proto
!= SERIO_ANY
, id
->proto
);
479 ADD(alias
, "id", id
->id
!= SERIO_ANY
, id
->id
);
480 ADD(alias
, "ex", id
->extra
!= SERIO_ANY
, id
->extra
);
485 ADD_TO_DEVTABLE("serio", struct serio_device_id
, do_serio_entry
);
487 /* looks like: "acpi:ACPI0003 or acpi:PNP0C0B" or "acpi:LNXVIDEO" */
488 static int do_acpi_entry(const char *filename
,
489 struct acpi_device_id
*id
, char *alias
)
491 sprintf(alias
, "acpi*:%s:*", id
->id
);
494 ADD_TO_DEVTABLE("acpi", struct acpi_device_id
, do_acpi_entry
);
496 /* looks like: "pnp:dD" */
497 static void do_pnp_device_entry(void *symval
, unsigned long size
,
500 const unsigned long id_size
= sizeof(struct pnp_device_id
);
501 const unsigned int count
= (size
/ id_size
)-1;
502 const struct pnp_device_id
*devs
= symval
;
505 device_id_check(mod
->name
, "pnp", size
, id_size
, symval
);
507 for (i
= 0; i
< count
; i
++) {
508 const char *id
= (char *)devs
[i
].id
;
509 char acpi_id
[sizeof(devs
[0].id
)];
512 buf_printf(&mod
->dev_table_buf
,
513 "MODULE_ALIAS(\"pnp:d%s*\");\n", id
);
515 /* fix broken pnp bus lowercasing */
516 for (j
= 0; j
< sizeof(acpi_id
); j
++)
517 acpi_id
[j
] = toupper(id
[j
]);
518 buf_printf(&mod
->dev_table_buf
,
519 "MODULE_ALIAS(\"acpi*:%s:*\");\n", acpi_id
);
523 /* looks like: "pnp:dD" for every device of the card */
524 static void do_pnp_card_entries(void *symval
, unsigned long size
,
527 const unsigned long id_size
= sizeof(struct pnp_card_device_id
);
528 const unsigned int count
= (size
/ id_size
)-1;
529 const struct pnp_card_device_id
*cards
= symval
;
532 device_id_check(mod
->name
, "pnp", size
, id_size
, symval
);
534 for (i
= 0; i
< count
; i
++) {
536 const struct pnp_card_device_id
*card
= &cards
[i
];
538 for (j
= 0; j
< PNP_MAX_DEVICES
; j
++) {
539 const char *id
= (char *)card
->devs
[j
].id
;
546 /* find duplicate, already added value */
547 for (i2
= 0; i2
< i
&& !dup
; i2
++) {
548 const struct pnp_card_device_id
*card2
= &cards
[i2
];
550 for (j2
= 0; j2
< PNP_MAX_DEVICES
; j2
++) {
551 const char *id2
= (char *)card2
->devs
[j2
].id
;
556 if (!strcmp(id
, id2
)) {
563 /* add an individual alias for every device entry */
565 char acpi_id
[sizeof(card
->devs
[0].id
)];
568 buf_printf(&mod
->dev_table_buf
,
569 "MODULE_ALIAS(\"pnp:d%s*\");\n", id
);
571 /* fix broken pnp bus lowercasing */
572 for (k
= 0; k
< sizeof(acpi_id
); k
++)
573 acpi_id
[k
] = toupper(id
[k
]);
574 buf_printf(&mod
->dev_table_buf
,
575 "MODULE_ALIAS(\"acpi*:%s:*\");\n", acpi_id
);
581 /* Looks like: pcmcia:mNcNfNfnNpfnNvaNvbNvcNvdN. */
582 static int do_pcmcia_entry(const char *filename
,
583 struct pcmcia_device_id
*id
, char *alias
)
587 id
->match_flags
= TO_NATIVE(id
->match_flags
);
588 id
->manf_id
= TO_NATIVE(id
->manf_id
);
589 id
->card_id
= TO_NATIVE(id
->card_id
);
590 id
->func_id
= TO_NATIVE(id
->func_id
);
591 id
->function
= TO_NATIVE(id
->function
);
592 id
->device_no
= TO_NATIVE(id
->device_no
);
594 for (i
=0; i
<4; i
++) {
595 id
->prod_id_hash
[i
] = TO_NATIVE(id
->prod_id_hash
[i
]);
598 strcpy(alias
, "pcmcia:");
599 ADD(alias
, "m", id
->match_flags
& PCMCIA_DEV_ID_MATCH_MANF_ID
,
601 ADD(alias
, "c", id
->match_flags
& PCMCIA_DEV_ID_MATCH_CARD_ID
,
603 ADD(alias
, "f", id
->match_flags
& PCMCIA_DEV_ID_MATCH_FUNC_ID
,
605 ADD(alias
, "fn", id
->match_flags
& PCMCIA_DEV_ID_MATCH_FUNCTION
,
607 ADD(alias
, "pfn", id
->match_flags
& PCMCIA_DEV_ID_MATCH_DEVICE_NO
,
609 ADD(alias
, "pa", id
->match_flags
& PCMCIA_DEV_ID_MATCH_PROD_ID1
, id
->prod_id_hash
[0]);
610 ADD(alias
, "pb", id
->match_flags
& PCMCIA_DEV_ID_MATCH_PROD_ID2
, id
->prod_id_hash
[1]);
611 ADD(alias
, "pc", id
->match_flags
& PCMCIA_DEV_ID_MATCH_PROD_ID3
, id
->prod_id_hash
[2]);
612 ADD(alias
, "pd", id
->match_flags
& PCMCIA_DEV_ID_MATCH_PROD_ID4
, id
->prod_id_hash
[3]);
617 ADD_TO_DEVTABLE("pcmcia", struct pcmcia_device_id
, do_pcmcia_entry
);
619 static int do_of_entry (const char *filename
, struct of_device_id
*of
, char *alias
)
623 len
= sprintf (alias
, "of:N%sT%s",
624 of
->name
[0] ? of
->name
: "*",
625 of
->type
[0] ? of
->type
: "*");
627 if (of
->compatible
[0])
628 sprintf (&alias
[len
], "%sC%s",
629 of
->type
[0] ? "*" : "",
632 /* Replace all whitespace with underscores */
633 for (tmp
= alias
; tmp
&& *tmp
; tmp
++)
640 ADD_TO_DEVTABLE("of", struct of_device_id
, do_of_entry
);
642 static int do_vio_entry(const char *filename
, struct vio_device_id
*vio
,
647 sprintf(alias
, "vio:T%sS%s", vio
->type
[0] ? vio
->type
: "*",
648 vio
->compat
[0] ? vio
->compat
: "*");
650 /* Replace all whitespace with underscores */
651 for (tmp
= alias
; tmp
&& *tmp
; tmp
++)
658 ADD_TO_DEVTABLE("vio", struct vio_device_id
, do_vio_entry
);
660 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
662 static void do_input(char *alias
,
663 kernel_ulong_t
*arr
, unsigned int min
, unsigned int max
)
667 for (i
= min
; i
< max
; i
++)
668 if (arr
[i
/ BITS_PER_LONG
] & (1L << (i
%BITS_PER_LONG
)))
669 sprintf(alias
+ strlen(alias
), "%X,*", i
);
672 /* input:b0v0p0e0-eXkXrXaXmXlXsXfXwX where X is comma-separated %02X. */
673 static int do_input_entry(const char *filename
, struct input_device_id
*id
,
676 sprintf(alias
, "input:");
678 ADD(alias
, "b", id
->flags
& INPUT_DEVICE_ID_MATCH_BUS
, id
->bustype
);
679 ADD(alias
, "v", id
->flags
& INPUT_DEVICE_ID_MATCH_VENDOR
, id
->vendor
);
680 ADD(alias
, "p", id
->flags
& INPUT_DEVICE_ID_MATCH_PRODUCT
, id
->product
);
681 ADD(alias
, "e", id
->flags
& INPUT_DEVICE_ID_MATCH_VERSION
, id
->version
);
683 sprintf(alias
+ strlen(alias
), "-e*");
684 if (id
->flags
& INPUT_DEVICE_ID_MATCH_EVBIT
)
685 do_input(alias
, id
->evbit
, 0, INPUT_DEVICE_ID_EV_MAX
);
686 sprintf(alias
+ strlen(alias
), "k*");
687 if (id
->flags
& INPUT_DEVICE_ID_MATCH_KEYBIT
)
688 do_input(alias
, id
->keybit
,
689 INPUT_DEVICE_ID_KEY_MIN_INTERESTING
,
690 INPUT_DEVICE_ID_KEY_MAX
);
691 sprintf(alias
+ strlen(alias
), "r*");
692 if (id
->flags
& INPUT_DEVICE_ID_MATCH_RELBIT
)
693 do_input(alias
, id
->relbit
, 0, INPUT_DEVICE_ID_REL_MAX
);
694 sprintf(alias
+ strlen(alias
), "a*");
695 if (id
->flags
& INPUT_DEVICE_ID_MATCH_ABSBIT
)
696 do_input(alias
, id
->absbit
, 0, INPUT_DEVICE_ID_ABS_MAX
);
697 sprintf(alias
+ strlen(alias
), "m*");
698 if (id
->flags
& INPUT_DEVICE_ID_MATCH_MSCIT
)
699 do_input(alias
, id
->mscbit
, 0, INPUT_DEVICE_ID_MSC_MAX
);
700 sprintf(alias
+ strlen(alias
), "l*");
701 if (id
->flags
& INPUT_DEVICE_ID_MATCH_LEDBIT
)
702 do_input(alias
, id
->ledbit
, 0, INPUT_DEVICE_ID_LED_MAX
);
703 sprintf(alias
+ strlen(alias
), "s*");
704 if (id
->flags
& INPUT_DEVICE_ID_MATCH_SNDBIT
)
705 do_input(alias
, id
->sndbit
, 0, INPUT_DEVICE_ID_SND_MAX
);
706 sprintf(alias
+ strlen(alias
), "f*");
707 if (id
->flags
& INPUT_DEVICE_ID_MATCH_FFBIT
)
708 do_input(alias
, id
->ffbit
, 0, INPUT_DEVICE_ID_FF_MAX
);
709 sprintf(alias
+ strlen(alias
), "w*");
710 if (id
->flags
& INPUT_DEVICE_ID_MATCH_SWBIT
)
711 do_input(alias
, id
->swbit
, 0, INPUT_DEVICE_ID_SW_MAX
);
714 ADD_TO_DEVTABLE("input", struct input_device_id
, do_input_entry
);
716 static int do_eisa_entry(const char *filename
, struct eisa_device_id
*eisa
,
720 sprintf(alias
, EISA_DEVICE_MODALIAS_FMT
"*", eisa
->sig
);
725 ADD_TO_DEVTABLE("eisa", struct eisa_device_id
, do_eisa_entry
);
727 /* Looks like: parisc:tNhvNrevNsvN */
728 static int do_parisc_entry(const char *filename
, struct parisc_device_id
*id
,
731 id
->hw_type
= TO_NATIVE(id
->hw_type
);
732 id
->hversion
= TO_NATIVE(id
->hversion
);
733 id
->hversion_rev
= TO_NATIVE(id
->hversion_rev
);
734 id
->sversion
= TO_NATIVE(id
->sversion
);
736 strcpy(alias
, "parisc:");
737 ADD(alias
, "t", id
->hw_type
!= PA_HWTYPE_ANY_ID
, id
->hw_type
);
738 ADD(alias
, "hv", id
->hversion
!= PA_HVERSION_ANY_ID
, id
->hversion
);
739 ADD(alias
, "rev", id
->hversion_rev
!= PA_HVERSION_REV_ANY_ID
, id
->hversion_rev
);
740 ADD(alias
, "sv", id
->sversion
!= PA_SVERSION_ANY_ID
, id
->sversion
);
745 ADD_TO_DEVTABLE("parisc", struct parisc_device_id
, do_parisc_entry
);
747 /* Looks like: sdio:cNvNdN. */
748 static int do_sdio_entry(const char *filename
,
749 struct sdio_device_id
*id
, char *alias
)
751 id
->class = TO_NATIVE(id
->class);
752 id
->vendor
= TO_NATIVE(id
->vendor
);
753 id
->device
= TO_NATIVE(id
->device
);
755 strcpy(alias
, "sdio:");
756 ADD(alias
, "c", id
->class != (__u8
)SDIO_ANY_ID
, id
->class);
757 ADD(alias
, "v", id
->vendor
!= (__u16
)SDIO_ANY_ID
, id
->vendor
);
758 ADD(alias
, "d", id
->device
!= (__u16
)SDIO_ANY_ID
, id
->device
);
762 ADD_TO_DEVTABLE("sdio", struct sdio_device_id
, do_sdio_entry
);
764 /* Looks like: ssb:vNidNrevN. */
765 static int do_ssb_entry(const char *filename
,
766 struct ssb_device_id
*id
, char *alias
)
768 id
->vendor
= TO_NATIVE(id
->vendor
);
769 id
->coreid
= TO_NATIVE(id
->coreid
);
770 id
->revision
= TO_NATIVE(id
->revision
);
772 strcpy(alias
, "ssb:");
773 ADD(alias
, "v", id
->vendor
!= SSB_ANY_VENDOR
, id
->vendor
);
774 ADD(alias
, "id", id
->coreid
!= SSB_ANY_ID
, id
->coreid
);
775 ADD(alias
, "rev", id
->revision
!= SSB_ANY_REV
, id
->revision
);
779 ADD_TO_DEVTABLE("ssb", struct ssb_device_id
, do_ssb_entry
);
781 /* Looks like: bcma:mNidNrevNclN. */
782 static int do_bcma_entry(const char *filename
,
783 struct bcma_device_id
*id
, char *alias
)
785 id
->manuf
= TO_NATIVE(id
->manuf
);
786 id
->id
= TO_NATIVE(id
->id
);
787 id
->rev
= TO_NATIVE(id
->rev
);
788 id
->class = TO_NATIVE(id
->class);
790 strcpy(alias
, "bcma:");
791 ADD(alias
, "m", id
->manuf
!= BCMA_ANY_MANUF
, id
->manuf
);
792 ADD(alias
, "id", id
->id
!= BCMA_ANY_ID
, id
->id
);
793 ADD(alias
, "rev", id
->rev
!= BCMA_ANY_REV
, id
->rev
);
794 ADD(alias
, "cl", id
->class != BCMA_ANY_CLASS
, id
->class);
798 ADD_TO_DEVTABLE("bcma", struct bcma_device_id
, do_bcma_entry
);
800 /* Looks like: virtio:dNvN */
801 static int do_virtio_entry(const char *filename
, struct virtio_device_id
*id
,
804 id
->device
= TO_NATIVE(id
->device
);
805 id
->vendor
= TO_NATIVE(id
->vendor
);
807 strcpy(alias
, "virtio:");
808 ADD(alias
, "d", id
->device
!= VIRTIO_DEV_ANY_ID
, id
->device
);
809 ADD(alias
, "v", id
->vendor
!= VIRTIO_DEV_ANY_ID
, id
->vendor
);
814 ADD_TO_DEVTABLE("virtio", struct virtio_device_id
, do_virtio_entry
);
817 * Looks like: vmbus:guid
818 * Each byte of the guid will be represented by two hex characters
822 static int do_vmbus_entry(const char *filename
, struct hv_vmbus_device_id
*id
,
826 char guid_name
[((sizeof(id
->guid
) + 1)) * 2];
828 for (i
= 0; i
< (sizeof(id
->guid
) * 2); i
+= 2)
829 sprintf(&guid_name
[i
], "%02x", id
->guid
[i
/2]);
831 strcpy(alias
, "vmbus:");
832 strcat(alias
, guid_name
);
836 ADD_TO_DEVTABLE("vmbus", struct hv_vmbus_device_id
, do_vmbus_entry
);
838 /* Looks like: i2c:S */
839 static int do_i2c_entry(const char *filename
, struct i2c_device_id
*id
,
842 sprintf(alias
, I2C_MODULE_PREFIX
"%s", id
->name
);
846 ADD_TO_DEVTABLE("i2c", struct i2c_device_id
, do_i2c_entry
);
848 /* Looks like: spi:S */
849 static int do_spi_entry(const char *filename
, struct spi_device_id
*id
,
852 sprintf(alias
, SPI_MODULE_PREFIX
"%s", id
->name
);
856 ADD_TO_DEVTABLE("spi", struct spi_device_id
, do_spi_entry
);
858 static const struct dmifield
{
862 { "bvn", DMI_BIOS_VENDOR
},
863 { "bvr", DMI_BIOS_VERSION
},
864 { "bd", DMI_BIOS_DATE
},
865 { "svn", DMI_SYS_VENDOR
},
866 { "pn", DMI_PRODUCT_NAME
},
867 { "pvr", DMI_PRODUCT_VERSION
},
868 { "rvn", DMI_BOARD_VENDOR
},
869 { "rn", DMI_BOARD_NAME
},
870 { "rvr", DMI_BOARD_VERSION
},
871 { "cvn", DMI_CHASSIS_VENDOR
},
872 { "ct", DMI_CHASSIS_TYPE
},
873 { "cvr", DMI_CHASSIS_VERSION
},
877 static void dmi_ascii_filter(char *d
, const char *s
)
879 /* Filter out characters we don't want to see in the modalias string */
881 if (*s
> ' ' && *s
< 127 && *s
!= ':')
888 static int do_dmi_entry(const char *filename
, struct dmi_system_id
*id
,
893 sprintf(alias
, "dmi*");
895 for (i
= 0; i
< ARRAY_SIZE(dmi_fields
); i
++) {
896 for (j
= 0; j
< 4; j
++) {
897 if (id
->matches
[j
].slot
&&
898 id
->matches
[j
].slot
== dmi_fields
[i
].field
) {
899 sprintf(alias
+ strlen(alias
), ":%s*",
900 dmi_fields
[i
].prefix
);
901 dmi_ascii_filter(alias
+ strlen(alias
),
902 id
->matches
[j
].substr
);
911 ADD_TO_DEVTABLE("dmi", struct dmi_system_id
, do_dmi_entry
);
913 static int do_platform_entry(const char *filename
,
914 struct platform_device_id
*id
, char *alias
)
916 sprintf(alias
, PLATFORM_MODULE_PREFIX
"%s", id
->name
);
919 ADD_TO_DEVTABLE("platform", struct platform_device_id
, do_platform_entry
);
921 static int do_mdio_entry(const char *filename
,
922 struct mdio_device_id
*id
, char *alias
)
926 alias
+= sprintf(alias
, MDIO_MODULE_PREFIX
);
928 for (i
= 0; i
< 32; i
++) {
929 if (!((id
->phy_id_mask
>> (31-i
)) & 1))
931 else if ((id
->phy_id
>> (31-i
)) & 1)
937 /* Terminate the string */
942 ADD_TO_DEVTABLE("mdio", struct mdio_device_id
, do_mdio_entry
);
944 /* Looks like: zorro:iN. */
945 static int do_zorro_entry(const char *filename
, struct zorro_device_id
*id
,
948 id
->id
= TO_NATIVE(id
->id
);
949 strcpy(alias
, "zorro:");
950 ADD(alias
, "i", id
->id
!= ZORRO_WILDCARD
, id
->id
);
953 ADD_TO_DEVTABLE("zorro", struct zorro_device_id
, do_zorro_entry
);
955 /* looks like: "pnp:dD" */
956 static int do_isapnp_entry(const char *filename
,
957 struct isapnp_device_id
*id
, char *alias
)
959 sprintf(alias
, "pnp:d%c%c%c%x%x%x%x*",
960 'A' + ((id
->vendor
>> 2) & 0x3f) - 1,
961 'A' + (((id
->vendor
& 3) << 3) | ((id
->vendor
>> 13) & 7)) - 1,
962 'A' + ((id
->vendor
>> 8) & 0x1f) - 1,
963 (id
->function
>> 4) & 0x0f, id
->function
& 0x0f,
964 (id
->function
>> 12) & 0x0f, (id
->function
>> 8) & 0x0f);
967 ADD_TO_DEVTABLE("isapnp", struct isapnp_device_id
, do_isapnp_entry
);
970 * Append a match expression for a single masked hex digit.
971 * outp points to a pointer to the character at which to append.
972 * *outp is updated on return to point just after the appended text,
973 * to facilitate further appending.
975 static void append_nibble_mask(char **outp
,
976 unsigned int nibble
, unsigned int mask
)
987 p
+= sprintf(p
, "%X", nibble
);
992 * Dumbly emit a match pattern for all possible matching
993 * digits. This could be improved in some cases using ranges,
994 * but it has the advantage of being trivially correct, and is
998 for (i
= 0; i
< 0x10; i
++)
999 if ((i
& mask
) == nibble
)
1000 p
+= sprintf(p
, "%X", i
);
1004 /* Ensure that the string remains NUL-terminated: */
1007 /* Advance the caller's end-of-string pointer: */
1012 * looks like: "amba:dN"
1014 * N is exactly 8 digits, where each is an upper-case hex digit, or
1015 * a ? or [] pattern matching exactly one digit.
1017 static int do_amba_entry(const char *filename
,
1018 struct amba_id
*id
, char *alias
)
1023 if ((id
->id
& id
->mask
) != id
->id
)
1024 fatal("%s: Masked-off bit(s) of AMBA device ID are non-zero: "
1025 "id=0x%08X, mask=0x%08X. Please fix this driver.\n",
1026 filename
, id
->id
, id
->mask
);
1028 p
+= sprintf(alias
, "amba:d");
1029 for (digit
= 0; digit
< 8; digit
++)
1030 append_nibble_mask(&p
,
1031 (id
->id
>> (4 * (7 - digit
))) & 0xf,
1032 (id
->mask
>> (4 * (7 - digit
))) & 0xf);
1036 ADD_TO_DEVTABLE("amba", struct amba_id
, do_amba_entry
);
1038 /* LOOKS like x86cpu:vendor:VVVV:family:FFFF:model:MMMM:feature:*,FEAT,*
1039 * All fields are numbers. It would be nicer to use strings for vendor
1040 * and feature, but getting those out of the build system here is too
1044 static int do_x86cpu_entry(const char *filename
, struct x86_cpu_id
*id
,
1047 id
->feature
= TO_NATIVE(id
->feature
);
1048 id
->family
= TO_NATIVE(id
->family
);
1049 id
->model
= TO_NATIVE(id
->model
);
1050 id
->vendor
= TO_NATIVE(id
->vendor
);
1052 strcpy(alias
, "x86cpu:");
1053 ADD(alias
, "vendor:", id
->vendor
!= X86_VENDOR_ANY
, id
->vendor
);
1054 ADD(alias
, ":family:", id
->family
!= X86_FAMILY_ANY
, id
->family
);
1055 ADD(alias
, ":model:", id
->model
!= X86_MODEL_ANY
, id
->model
);
1056 strcat(alias
, ":feature:*");
1057 if (id
->feature
!= X86_FEATURE_ANY
)
1058 sprintf(alias
+ strlen(alias
), "%04X*", id
->feature
);
1061 ADD_TO_DEVTABLE("x86cpu", struct x86_cpu_id
, do_x86cpu_entry
);
1063 /* Does namelen bytes of name exactly match the symbol? */
1064 static bool sym_is(const char *name
, unsigned namelen
, const char *symbol
)
1066 if (namelen
!= strlen(symbol
))
1069 return memcmp(name
, symbol
, namelen
) == 0;
1072 static void do_table(void *symval
, unsigned long size
,
1073 unsigned long id_size
,
1074 const char *device_id
,
1080 int (*do_entry
)(const char *, void *entry
, char *alias
) = function
;
1082 device_id_check(mod
->name
, device_id
, size
, id_size
, symval
);
1083 /* Leave last one: it's the terminator. */
1086 for (i
= 0; i
< size
; i
+= id_size
) {
1087 if (do_entry(mod
->name
, symval
+i
, alias
)) {
1088 buf_printf(&mod
->dev_table_buf
,
1089 "MODULE_ALIAS(\"%s\");\n", alias
);
1094 /* Create MODULE_ALIAS() statements.
1095 * At this time, we cannot write the actual output C source yet,
1096 * so we write into the mod->dev_table_buf buffer. */
1097 void handle_moddevtable(struct module
*mod
, struct elf_info
*info
,
1098 Elf_Sym
*sym
, const char *symname
)
1103 unsigned int namelen
;
1105 /* We're looking for a section relative symbol */
1106 if (!sym
->st_shndx
|| get_secindex(info
, sym
) >= info
->num_sections
)
1109 /* We're looking for an object */
1110 if (ELF_ST_TYPE(sym
->st_info
) != STT_OBJECT
)
1113 /* All our symbols are of form <prefix>__mod_XXX_device_table. */
1114 name
= strstr(symname
, "__mod_");
1117 name
+= strlen("__mod_");
1118 namelen
= strlen(name
);
1119 if (namelen
< strlen("_device_table"))
1121 if (strcmp(name
+ namelen
- strlen("_device_table"), "_device_table"))
1123 namelen
-= strlen("_device_table");
1125 /* Handle all-NULL symbols allocated into .bss */
1126 if (info
->sechdrs
[get_secindex(info
, sym
)].sh_type
& SHT_NOBITS
) {
1127 zeros
= calloc(1, sym
->st_size
);
1130 symval
= (void *)info
->hdr
1131 + info
->sechdrs
[get_secindex(info
, sym
)].sh_offset
1135 /* First handle the "special" cases */
1136 if (sym_is(name
, namelen
, "usb"))
1137 do_usb_table(symval
, sym
->st_size
, mod
);
1138 else if (sym_is(name
, namelen
, "pnp"))
1139 do_pnp_device_entry(symval
, sym
->st_size
, mod
);
1140 else if (sym_is(name
, namelen
, "pnp_card"))
1141 do_pnp_card_entries(symval
, sym
->st_size
, mod
);
1143 struct devtable
**p
;
1144 INIT_SECTION(__devtable
);
1146 for (p
= __start___devtable
; p
< __stop___devtable
; p
++) {
1147 if (sym_is(name
, namelen
, (*p
)->device_id
)) {
1148 do_table(symval
, sym
->st_size
, (*p
)->id_size
,
1149 (*p
)->device_id
, (*p
)->function
, mod
);
1157 /* Now add out buffered information to the generated C source */
1158 void add_moddevtable(struct buffer
*buf
, struct module
*mod
)
1160 buf_printf(buf
, "\n");
1161 buf_write(buf
, mod
->dev_table_buf
.p
, mod
->dev_table_buf
.pos
);
1162 free(mod
->dev_table_buf
.p
);