aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2012-01-12 18:02:16 -0500
committerRusty Russell <rusty@rustcorp.com.au>2012-01-12 18:02:16 -0500
commite49ce14150c64b29a8dd211df785576fa19a9858 (patch)
tree0150a0b0db79879943e31960728fb737ec8dea2b
parent626596e295d477c0fefa08cd5daa7dd011b1bb2c (diff)
modpost: use linker section to generate table.
This means (most) future busses need only have one hunk in their patch. Also took the opportunity to check that function matches the type. Again, inspired by Alessandro's patch series. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Cc: Alessandro Rubini <rubini@gnudd.com>
-rw-r--r--scripts/mod/file2alias.c106
1 files changed, 61 insertions, 45 deletions
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 395e7479bcf7..e8c969577768 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -39,6 +39,35 @@ typedef unsigned char __u8;
39 * we handle those differences explicitly below */ 39 * we handle those differences explicitly below */
40#include "../../include/linux/mod_devicetable.h" 40#include "../../include/linux/mod_devicetable.h"
41 41
42/* This array collects all instances that use the generic do_table */
43struct devtable {
44 const char *device_id; /* name of table, __mod_<name>_device_table. */
45 unsigned long id_size;
46 void *function;
47};
48
49/* We construct a table of pointers in an ELF section (pointers generally
50 * go unpadded by gcc). ld creates boundary syms for us. */
51extern struct devtable *__start___devtable[], *__stop___devtable[];
52#define ___cat(a,b) a ## b
53#define __cat(a,b) ___cat(a,b)
54
55#if __GNUC__ == 3 && __GNUC_MINOR__ < 3
56# define __used __attribute__((__unused__))
57#else
58# define __used __attribute__((__used__))
59#endif
60
61/* Add a table entry. We test function type matches while we're here. */
62#define ADD_TO_DEVTABLE(device_id, type, function) \
63 static struct devtable __cat(devtable,__LINE__) = { \
64 device_id + 0*sizeof((function)((const char *)NULL, \
65 (type *)NULL, \
66 (char *)NULL)), \
67 sizeof(type), (function) }; \
68 static struct devtable *__attribute__((section("__devtable"))) \
69 __used __cat(devtable_ptr,__LINE__) = &__cat(devtable,__LINE__)
70
42#define ADD(str, sep, cond, field) \ 71#define ADD(str, sep, cond, field) \
43do { \ 72do { \
44 strcat(str, sep); \ 73 strcat(str, sep); \
@@ -290,6 +319,7 @@ static int do_hid_entry(const char *filename,
290 319
291 return 1; 320 return 1;
292} 321}
322ADD_TO_DEVTABLE("hid", struct hid_device_id, do_hid_entry);
293 323
294/* Looks like: ieee1394:venNmoNspNverN */ 324/* Looks like: ieee1394:venNmoNspNverN */
295static int do_ieee1394_entry(const char *filename, 325static int do_ieee1394_entry(const char *filename,
@@ -314,6 +344,7 @@ static int do_ieee1394_entry(const char *filename,
314 add_wildcard(alias); 344 add_wildcard(alias);
315 return 1; 345 return 1;
316} 346}
347ADD_TO_DEVTABLE("ieee1394", struct ieee1394_device_id, do_ieee1394_entry);
317 348
318/* Looks like: pci:vNdNsvNsdNbcNscNiN. */ 349/* Looks like: pci:vNdNsvNsdNbcNscNiN. */
319static int do_pci_entry(const char *filename, 350static int do_pci_entry(const char *filename,
@@ -357,6 +388,7 @@ static int do_pci_entry(const char *filename,
357 add_wildcard(alias); 388 add_wildcard(alias);
358 return 1; 389 return 1;
359} 390}
391ADD_TO_DEVTABLE("pci", struct pci_device_id, do_pci_entry);
360 392
361/* looks like: "ccw:tNmNdtNdmN" */ 393/* looks like: "ccw:tNmNdtNdmN" */
362static int do_ccw_entry(const char *filename, 394static int do_ccw_entry(const char *filename,
@@ -380,6 +412,7 @@ static int do_ccw_entry(const char *filename,
380 add_wildcard(alias); 412 add_wildcard(alias);
381 return 1; 413 return 1;
382} 414}
415ADD_TO_DEVTABLE("ccw", struct ccw_device_id, do_ccw_entry);
383 416
384/* looks like: "ap:tN" */ 417/* looks like: "ap:tN" */
385static int do_ap_entry(const char *filename, 418static int do_ap_entry(const char *filename,
@@ -388,6 +421,7 @@ static int do_ap_entry(const char *filename,
388 sprintf(alias, "ap:t%02X*", id->dev_type); 421 sprintf(alias, "ap:t%02X*", id->dev_type);
389 return 1; 422 return 1;
390} 423}
424ADD_TO_DEVTABLE("ap", struct ap_device_id, do_ap_entry);
391 425
392/* looks like: "css:tN" */ 426/* looks like: "css:tN" */
393static int do_css_entry(const char *filename, 427static int do_css_entry(const char *filename,
@@ -396,6 +430,7 @@ static int do_css_entry(const char *filename,
396 sprintf(alias, "css:t%01X", id->type); 430 sprintf(alias, "css:t%01X", id->type);
397 return 1; 431 return 1;
398} 432}
433ADD_TO_DEVTABLE("css", struct css_device_id, do_css_entry);
399 434
400/* Looks like: "serio:tyNprNidNexN" */ 435/* Looks like: "serio:tyNprNidNexN" */
401static int do_serio_entry(const char *filename, 436static int do_serio_entry(const char *filename,
@@ -415,6 +450,7 @@ static int do_serio_entry(const char *filename,
415 add_wildcard(alias); 450 add_wildcard(alias);
416 return 1; 451 return 1;
417} 452}
453ADD_TO_DEVTABLE("serio", struct serio_device_id, do_serio_entry);
418 454
419/* looks like: "acpi:ACPI0003 or acpi:PNP0C0B" or "acpi:LNXVIDEO" */ 455/* looks like: "acpi:ACPI0003 or acpi:PNP0C0B" or "acpi:LNXVIDEO" */
420static int do_acpi_entry(const char *filename, 456static int do_acpi_entry(const char *filename,
@@ -423,6 +459,7 @@ static int do_acpi_entry(const char *filename,
423 sprintf(alias, "acpi*:%s:*", id->id); 459 sprintf(alias, "acpi*:%s:*", id->id);
424 return 1; 460 return 1;
425} 461}
462ADD_TO_DEVTABLE("acpi", struct acpi_device_id, do_acpi_entry);
426 463
427/* looks like: "pnp:dD" */ 464/* looks like: "pnp:dD" */
428static void do_pnp_device_entry(void *symval, unsigned long size, 465static void do_pnp_device_entry(void *symval, unsigned long size,
@@ -545,8 +582,7 @@ static int do_pcmcia_entry(const char *filename,
545 add_wildcard(alias); 582 add_wildcard(alias);
546 return 1; 583 return 1;
547} 584}
548 585ADD_TO_DEVTABLE("pcmcia", struct pcmcia_device_id, do_pcmcia_entry);
549
550 586
551static int do_of_entry (const char *filename, struct of_device_id *of, char *alias) 587static int do_of_entry (const char *filename, struct of_device_id *of, char *alias)
552{ 588{
@@ -569,6 +605,7 @@ static int do_of_entry (const char *filename, struct of_device_id *of, char *ali
569 add_wildcard(alias); 605 add_wildcard(alias);
570 return 1; 606 return 1;
571} 607}
608ADD_TO_DEVTABLE("of", struct of_device_id, do_of_entry);
572 609
573static int do_vio_entry(const char *filename, struct vio_device_id *vio, 610static int do_vio_entry(const char *filename, struct vio_device_id *vio,
574 char *alias) 611 char *alias)
@@ -586,6 +623,7 @@ static int do_vio_entry(const char *filename, struct vio_device_id *vio,
586 add_wildcard(alias); 623 add_wildcard(alias);
587 return 1; 624 return 1;
588} 625}
626ADD_TO_DEVTABLE("vio", struct vio_device_id, do_vio_entry);
589 627
590#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 628#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
591 629
@@ -641,6 +679,7 @@ static int do_input_entry(const char *filename, struct input_device_id *id,
641 do_input(alias, id->swbit, 0, INPUT_DEVICE_ID_SW_MAX); 679 do_input(alias, id->swbit, 0, INPUT_DEVICE_ID_SW_MAX);
642 return 1; 680 return 1;
643} 681}
682ADD_TO_DEVTABLE("input", struct input_device_id, do_input_entry);
644 683
645static int do_eisa_entry(const char *filename, struct eisa_device_id *eisa, 684static int do_eisa_entry(const char *filename, struct eisa_device_id *eisa,
646 char *alias) 685 char *alias)
@@ -651,6 +690,7 @@ static int do_eisa_entry(const char *filename, struct eisa_device_id *eisa,
651 strcat(alias, "*"); 690 strcat(alias, "*");
652 return 1; 691 return 1;
653} 692}
693ADD_TO_DEVTABLE("eisa", struct eisa_device_id, do_eisa_entry);
654 694
655/* Looks like: parisc:tNhvNrevNsvN */ 695/* Looks like: parisc:tNhvNrevNsvN */
656static int do_parisc_entry(const char *filename, struct parisc_device_id *id, 696static int do_parisc_entry(const char *filename, struct parisc_device_id *id,
@@ -670,6 +710,7 @@ static int do_parisc_entry(const char *filename, struct parisc_device_id *id,
670 add_wildcard(alias); 710 add_wildcard(alias);
671 return 1; 711 return 1;
672} 712}
713ADD_TO_DEVTABLE("parisc", struct parisc_device_id, do_parisc_entry);
673 714
674/* Looks like: sdio:cNvNdN. */ 715/* Looks like: sdio:cNvNdN. */
675static int do_sdio_entry(const char *filename, 716static int do_sdio_entry(const char *filename,
@@ -686,6 +727,7 @@ static int do_sdio_entry(const char *filename,
686 add_wildcard(alias); 727 add_wildcard(alias);
687 return 1; 728 return 1;
688} 729}
730ADD_TO_DEVTABLE("sdio", struct sdio_device_id, do_sdio_entry);
689 731
690/* Looks like: ssb:vNidNrevN. */ 732/* Looks like: ssb:vNidNrevN. */
691static int do_ssb_entry(const char *filename, 733static int do_ssb_entry(const char *filename,
@@ -702,6 +744,7 @@ static int do_ssb_entry(const char *filename,
702 add_wildcard(alias); 744 add_wildcard(alias);
703 return 1; 745 return 1;
704} 746}
747ADD_TO_DEVTABLE("ssb", struct ssb_device_id, do_ssb_entry);
705 748
706/* Looks like: bcma:mNidNrevNclN. */ 749/* Looks like: bcma:mNidNrevNclN. */
707static int do_bcma_entry(const char *filename, 750static int do_bcma_entry(const char *filename,
@@ -720,6 +763,7 @@ static int do_bcma_entry(const char *filename,
720 add_wildcard(alias); 763 add_wildcard(alias);
721 return 1; 764 return 1;
722} 765}
766ADD_TO_DEVTABLE("bcma", struct bcma_device_id, do_bcma_entry);
723 767
724/* Looks like: virtio:dNvN */ 768/* Looks like: virtio:dNvN */
725static int do_virtio_entry(const char *filename, struct virtio_device_id *id, 769static int do_virtio_entry(const char *filename, struct virtio_device_id *id,
@@ -735,6 +779,7 @@ static int do_virtio_entry(const char *filename, struct virtio_device_id *id,
735 add_wildcard(alias); 779 add_wildcard(alias);
736 return 1; 780 return 1;
737} 781}
782ADD_TO_DEVTABLE("virtio", struct virtio_device_id, do_virtio_entry);
738 783
739/* 784/*
740 * Looks like: vmbus:guid 785 * Looks like: vmbus:guid
@@ -756,6 +801,7 @@ static int do_vmbus_entry(const char *filename, struct hv_vmbus_device_id *id,
756 801
757 return 1; 802 return 1;
758} 803}
804ADD_TO_DEVTABLE("vmbus", struct hv_vmbus_device_id, do_vmbus_entry);
759 805
760/* Looks like: i2c:S */ 806/* Looks like: i2c:S */
761static int do_i2c_entry(const char *filename, struct i2c_device_id *id, 807static int do_i2c_entry(const char *filename, struct i2c_device_id *id,
@@ -765,6 +811,7 @@ static int do_i2c_entry(const char *filename, struct i2c_device_id *id,
765 811
766 return 1; 812 return 1;
767} 813}
814ADD_TO_DEVTABLE("i2c", struct i2c_device_id, do_i2c_entry);
768 815
769/* Looks like: spi:S */ 816/* Looks like: spi:S */
770static int do_spi_entry(const char *filename, struct spi_device_id *id, 817static int do_spi_entry(const char *filename, struct spi_device_id *id,
@@ -774,6 +821,7 @@ static int do_spi_entry(const char *filename, struct spi_device_id *id,
774 821
775 return 1; 822 return 1;
776} 823}
824ADD_TO_DEVTABLE("spi", struct spi_device_id, do_spi_entry);
777 825
778static const struct dmifield { 826static const struct dmifield {
779 const char *prefix; 827 const char *prefix;
@@ -828,6 +876,7 @@ static int do_dmi_entry(const char *filename, struct dmi_system_id *id,
828 strcat(alias, ":"); 876 strcat(alias, ":");
829 return 1; 877 return 1;
830} 878}
879ADD_TO_DEVTABLE("dmi", struct dmi_system_id, do_dmi_entry);
831 880
832static int do_platform_entry(const char *filename, 881static int do_platform_entry(const char *filename,
833 struct platform_device_id *id, char *alias) 882 struct platform_device_id *id, char *alias)
@@ -835,6 +884,7 @@ static int do_platform_entry(const char *filename,
835 sprintf(alias, PLATFORM_MODULE_PREFIX "%s", id->name); 884 sprintf(alias, PLATFORM_MODULE_PREFIX "%s", id->name);
836 return 1; 885 return 1;
837} 886}
887ADD_TO_DEVTABLE("platform", struct platform_device_id, do_platform_entry);
838 888
839static int do_mdio_entry(const char *filename, 889static int do_mdio_entry(const char *filename,
840 struct mdio_device_id *id, char *alias) 890 struct mdio_device_id *id, char *alias)
@@ -857,6 +907,7 @@ static int do_mdio_entry(const char *filename,
857 907
858 return 1; 908 return 1;
859} 909}
910ADD_TO_DEVTABLE("mdio", struct mdio_device_id, do_mdio_entry);
860 911
861/* Looks like: zorro:iN. */ 912/* Looks like: zorro:iN. */
862static int do_zorro_entry(const char *filename, struct zorro_device_id *id, 913static int do_zorro_entry(const char *filename, struct zorro_device_id *id,
@@ -867,6 +918,7 @@ static int do_zorro_entry(const char *filename, struct zorro_device_id *id,
867 ADD(alias, "i", id->id != ZORRO_WILDCARD, id->id); 918 ADD(alias, "i", id->id != ZORRO_WILDCARD, id->id);
868 return 1; 919 return 1;
869} 920}
921ADD_TO_DEVTABLE("zorro", struct zorro_device_id, do_zorro_entry);
870 922
871/* looks like: "pnp:dD" */ 923/* looks like: "pnp:dD" */
872static int do_isapnp_entry(const char *filename, 924static int do_isapnp_entry(const char *filename,
@@ -880,6 +932,7 @@ static int do_isapnp_entry(const char *filename,
880 (id->function >> 12) & 0x0f, (id->function >> 8) & 0x0f); 932 (id->function >> 12) & 0x0f, (id->function >> 8) & 0x0f);
881 return 1; 933 return 1;
882} 934}
935ADD_TO_DEVTABLE("isa", struct isapnp_device_id, do_isapnp_entry);
883 936
884/* 937/*
885 * Append a match expression for a single masked hex digit. 938 * Append a match expression for a single masked hex digit.
@@ -948,6 +1001,7 @@ static int do_amba_entry(const char *filename,
948 1001
949 return 1; 1002 return 1;
950} 1003}
1004ADD_TO_DEVTABLE("amba", struct amba_id, do_amba_entry);
951 1005
952/* Does namelen bytes of name exactly match the symbol? */ 1006/* Does namelen bytes of name exactly match the symbol? */
953static bool sym_is(const char *name, unsigned namelen, const char *symbol) 1007static bool sym_is(const char *name, unsigned namelen, const char *symbol)
@@ -980,43 +1034,6 @@ static void do_table(void *symval, unsigned long size,
980 } 1034 }
981} 1035}
982 1036
983/* This array collects all instances that use the generic do_table above */
984struct devtable_switch {
985 const char *device_id; /* name of table, __mod_<name>_device_table. */
986 unsigned long id_size;
987 void *function;
988};
989
990static const struct devtable_switch devtable_switch[] = {
991 { "acpi", sizeof(struct acpi_device_id), do_acpi_entry },
992 { "amba", sizeof(struct amba_id), do_amba_entry },
993 { "ap", sizeof(struct ap_device_id), do_ap_entry },
994 { "bcma", sizeof(struct bcma_device_id), do_bcma_entry },
995 { "ccw", sizeof(struct ccw_device_id), do_ccw_entry },
996 { "css", sizeof(struct css_device_id), do_css_entry },
997 { "dmi", sizeof(struct dmi_system_id), do_dmi_entry },
998 { "eisa", sizeof(struct eisa_device_id), do_eisa_entry },
999 { "hid", sizeof(struct hid_device_id), do_hid_entry },
1000 { "i2c", sizeof(struct i2c_device_id), do_i2c_entry },
1001 { "ieee1394", sizeof(struct ieee1394_device_id), do_ieee1394_entry },
1002 { "input", sizeof(struct input_device_id), do_input_entry },
1003 { "isa", sizeof(struct isapnp_device_id), do_isapnp_entry },
1004 { "mdio", sizeof(struct mdio_device_id), do_mdio_entry },
1005 { "of", sizeof(struct of_device_id), do_of_entry },
1006 { "parisc", sizeof(struct parisc_device_id), do_parisc_entry },
1007 { "pci", sizeof(struct pci_device_id), do_pci_entry },
1008 { "pcmcia", sizeof(struct pcmcia_device_id), do_pcmcia_entry },
1009 { "platform", sizeof(struct platform_device_id), do_platform_entry },
1010 { "sdio", sizeof(struct sdio_device_id), do_sdio_entry },
1011 { "serio", sizeof(struct serio_device_id), do_serio_entry },
1012 { "spi", sizeof(struct spi_device_id), do_spi_entry },
1013 { "ssb", sizeof(struct ssb_device_id), do_ssb_entry },
1014 { "vio", sizeof(struct vio_device_id), do_vio_entry },
1015 { "virtio", sizeof(struct virtio_device_id), do_virtio_entry },
1016 { "vmbus", sizeof(struct hv_vmbus_device_id), do_vmbus_entry },
1017 { "zorro", sizeof(struct zorro_device_id), do_zorro_entry },
1018};
1019
1020/* Create MODULE_ALIAS() statements. 1037/* Create MODULE_ALIAS() statements.
1021 * At this time, we cannot write the actual output C source yet, 1038 * At this time, we cannot write the actual output C source yet,
1022 * so we write into the mod->dev_table_buf buffer. */ 1039 * so we write into the mod->dev_table_buf buffer. */
@@ -1062,13 +1079,12 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
1062 else if (sym_is(name, namelen, "pnp_card")) 1079 else if (sym_is(name, namelen, "pnp_card"))
1063 do_pnp_card_entries(symval, sym->st_size, mod); 1080 do_pnp_card_entries(symval, sym->st_size, mod);
1064 else { 1081 else {
1065 const struct devtable_switch *p = devtable_switch; 1082 struct devtable **p;
1066 unsigned int i;
1067 1083
1068 for (i = 0; i < ARRAY_SIZE(devtable_switch); i++, p++) { 1084 for (p = __start___devtable; p < __stop___devtable; p++) {
1069 if (sym_is(name, namelen, p->device_id)) { 1085 if (sym_is(name, namelen, (*p)->device_id)) {
1070 do_table(symval, sym->st_size, p->id_size, 1086 do_table(symval, sym->st_size, (*p)->id_size,
1071 p->device_id, p->function, mod); 1087 (*p)->device_id, (*p)->function, mod);
1072 break; 1088 break;
1073 } 1089 }
1074 } 1090 }