@@ -39,6 +39,35 @@ typedef unsigned char __u8;
39
39
* we handle those differences explicitly below */
40
40
#include "../../include/linux/mod_devicetable.h"
41
41
42
+ /* This array collects all instances that use the generic do_table */
43
+ struct 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. */
51
+ extern 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
71
#define ADD (str , sep , cond , field ) \
43
72
do { \
44
73
strcat(str, sep); \
@@ -290,6 +319,7 @@ static int do_hid_entry(const char *filename,
290
319
291
320
return 1 ;
292
321
}
322
+ ADD_TO_DEVTABLE ("hid" , struct hid_device_id , do_hid_entry );
293
323
294
324
/* Looks like: ieee1394:venNmoNspNverN */
295
325
static int do_ieee1394_entry (const char * filename ,
@@ -314,6 +344,7 @@ static int do_ieee1394_entry(const char *filename,
314
344
add_wildcard (alias );
315
345
return 1 ;
316
346
}
347
+ ADD_TO_DEVTABLE ("ieee1394" , struct ieee1394_device_id , do_ieee1394_entry );
317
348
318
349
/* Looks like: pci:vNdNsvNsdNbcNscNiN. */
319
350
static int do_pci_entry (const char * filename ,
@@ -357,6 +388,7 @@ static int do_pci_entry(const char *filename,
357
388
add_wildcard (alias );
358
389
return 1 ;
359
390
}
391
+ ADD_TO_DEVTABLE ("pci" , struct pci_device_id , do_pci_entry );
360
392
361
393
/* looks like: "ccw:tNmNdtNdmN" */
362
394
static int do_ccw_entry (const char * filename ,
@@ -380,6 +412,7 @@ static int do_ccw_entry(const char *filename,
380
412
add_wildcard (alias );
381
413
return 1 ;
382
414
}
415
+ ADD_TO_DEVTABLE ("ccw" , struct ccw_device_id , do_ccw_entry );
383
416
384
417
/* looks like: "ap:tN" */
385
418
static int do_ap_entry (const char * filename ,
@@ -388,6 +421,7 @@ static int do_ap_entry(const char *filename,
388
421
sprintf (alias , "ap:t%02X*" , id -> dev_type );
389
422
return 1 ;
390
423
}
424
+ ADD_TO_DEVTABLE ("ap" , struct ap_device_id , do_ap_entry );
391
425
392
426
/* looks like: "css:tN" */
393
427
static int do_css_entry (const char * filename ,
@@ -396,6 +430,7 @@ static int do_css_entry(const char *filename,
396
430
sprintf (alias , "css:t%01X" , id -> type );
397
431
return 1 ;
398
432
}
433
+ ADD_TO_DEVTABLE ("css" , struct css_device_id , do_css_entry );
399
434
400
435
/* Looks like: "serio:tyNprNidNexN" */
401
436
static int do_serio_entry (const char * filename ,
@@ -415,6 +450,7 @@ static int do_serio_entry(const char *filename,
415
450
add_wildcard (alias );
416
451
return 1 ;
417
452
}
453
+ ADD_TO_DEVTABLE ("serio" , struct serio_device_id , do_serio_entry );
418
454
419
455
/* looks like: "acpi:ACPI0003 or acpi:PNP0C0B" or "acpi:LNXVIDEO" */
420
456
static int do_acpi_entry (const char * filename ,
@@ -423,6 +459,7 @@ static int do_acpi_entry(const char *filename,
423
459
sprintf (alias , "acpi*:%s:*" , id -> id );
424
460
return 1 ;
425
461
}
462
+ ADD_TO_DEVTABLE ("acpi" , struct acpi_device_id , do_acpi_entry );
426
463
427
464
/* looks like: "pnp:dD" */
428
465
static void do_pnp_device_entry (void * symval , unsigned long size ,
@@ -545,8 +582,7 @@ static int do_pcmcia_entry(const char *filename,
545
582
add_wildcard (alias );
546
583
return 1 ;
547
584
}
548
-
549
-
585
+ ADD_TO_DEVTABLE ("pcmcia" , struct pcmcia_device_id , do_pcmcia_entry );
550
586
551
587
static 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
605
add_wildcard (alias );
570
606
return 1 ;
571
607
}
608
+ ADD_TO_DEVTABLE ("of" , struct of_device_id , do_of_entry );
572
609
573
610
static int do_vio_entry (const char * filename , struct vio_device_id * vio ,
574
611
char * alias )
@@ -586,6 +623,7 @@ static int do_vio_entry(const char *filename, struct vio_device_id *vio,
586
623
add_wildcard (alias );
587
624
return 1 ;
588
625
}
626
+ ADD_TO_DEVTABLE ("vio" , struct vio_device_id , do_vio_entry );
589
627
590
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
679
do_input (alias , id -> swbit , 0 , INPUT_DEVICE_ID_SW_MAX );
642
680
return 1 ;
643
681
}
682
+ ADD_TO_DEVTABLE ("input" , struct input_device_id , do_input_entry );
644
683
645
684
static int do_eisa_entry (const char * filename , struct eisa_device_id * eisa ,
646
685
char * alias )
@@ -651,6 +690,7 @@ static int do_eisa_entry(const char *filename, struct eisa_device_id *eisa,
651
690
strcat (alias , "*" );
652
691
return 1 ;
653
692
}
693
+ ADD_TO_DEVTABLE ("eisa" , struct eisa_device_id , do_eisa_entry );
654
694
655
695
/* Looks like: parisc:tNhvNrevNsvN */
656
696
static 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
710
add_wildcard (alias );
671
711
return 1 ;
672
712
}
713
+ ADD_TO_DEVTABLE ("parisc" , struct parisc_device_id , do_parisc_entry );
673
714
674
715
/* Looks like: sdio:cNvNdN. */
675
716
static int do_sdio_entry (const char * filename ,
@@ -686,6 +727,7 @@ static int do_sdio_entry(const char *filename,
686
727
add_wildcard (alias );
687
728
return 1 ;
688
729
}
730
+ ADD_TO_DEVTABLE ("sdio" , struct sdio_device_id , do_sdio_entry );
689
731
690
732
/* Looks like: ssb:vNidNrevN. */
691
733
static int do_ssb_entry (const char * filename ,
@@ -702,6 +744,7 @@ static int do_ssb_entry(const char *filename,
702
744
add_wildcard (alias );
703
745
return 1 ;
704
746
}
747
+ ADD_TO_DEVTABLE ("ssb" , struct ssb_device_id , do_ssb_entry );
705
748
706
749
/* Looks like: bcma:mNidNrevNclN. */
707
750
static int do_bcma_entry (const char * filename ,
@@ -720,6 +763,7 @@ static int do_bcma_entry(const char *filename,
720
763
add_wildcard (alias );
721
764
return 1 ;
722
765
}
766
+ ADD_TO_DEVTABLE ("bcma" , struct bcma_device_id , do_bcma_entry );
723
767
724
768
/* Looks like: virtio:dNvN */
725
769
static 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
779
add_wildcard (alias );
736
780
return 1 ;
737
781
}
782
+ ADD_TO_DEVTABLE ("virtio" , struct virtio_device_id , do_virtio_entry );
738
783
739
784
/*
740
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
802
return 1 ;
758
803
}
804
+ ADD_TO_DEVTABLE ("vmbus" , struct hv_vmbus_device_id , do_vmbus_entry );
759
805
760
806
/* Looks like: i2c:S */
761
807
static 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
812
return 1 ;
767
813
}
814
+ ADD_TO_DEVTABLE ("i2c" , struct i2c_device_id , do_i2c_entry );
768
815
769
816
/* Looks like: spi:S */
770
817
static 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
822
return 1 ;
776
823
}
824
+ ADD_TO_DEVTABLE ("spi" , struct spi_device_id , do_spi_entry );
777
825
778
826
static const struct dmifield {
779
827
const char * prefix ;
@@ -828,13 +876,15 @@ static int do_dmi_entry(const char *filename, struct dmi_system_id *id,
828
876
strcat (alias , ":" );
829
877
return 1 ;
830
878
}
879
+ ADD_TO_DEVTABLE ("dmi" , struct dmi_system_id , do_dmi_entry );
831
880
832
881
static int do_platform_entry (const char * filename ,
833
882
struct platform_device_id * id , char * alias )
834
883
{
835
884
sprintf (alias , PLATFORM_MODULE_PREFIX "%s" , id -> name );
836
885
return 1 ;
837
886
}
887
+ ADD_TO_DEVTABLE ("platform" , struct platform_device_id , do_platform_entry );
838
888
839
889
static int do_mdio_entry (const char * filename ,
840
890
struct mdio_device_id * id , char * alias )
@@ -857,6 +907,7 @@ static int do_mdio_entry(const char *filename,
857
907
858
908
return 1 ;
859
909
}
910
+ ADD_TO_DEVTABLE ("mdio" , struct mdio_device_id , do_mdio_entry );
860
911
861
912
/* Looks like: zorro:iN. */
862
913
static 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
918
ADD (alias , "i" , id -> id != ZORRO_WILDCARD , id -> id );
868
919
return 1 ;
869
920
}
921
+ ADD_TO_DEVTABLE ("zorro" , struct zorro_device_id , do_zorro_entry );
870
922
871
923
/* looks like: "pnp:dD" */
872
924
static int do_isapnp_entry (const char * filename ,
@@ -880,6 +932,7 @@ static int do_isapnp_entry(const char *filename,
880
932
(id -> function >> 12 ) & 0x0f , (id -> function >> 8 ) & 0x0f );
881
933
return 1 ;
882
934
}
935
+ ADD_TO_DEVTABLE ("isa" , struct isapnp_device_id , do_isapnp_entry );
883
936
884
937
/*
885
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
1002
return 1 ;
950
1003
}
1004
+ ADD_TO_DEVTABLE ("amba" , struct amba_id , do_amba_entry );
951
1005
952
1006
/* Does namelen bytes of name exactly match the symbol? */
953
1007
static 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 */
984
- struct devtable_switch {
985
- const char * device_id ; /* name of table, __mod_<name>_device_table. */
986
- unsigned long id_size ;
987
- void * function ;
988
- };
989
-
990
- static 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
1037
/* Create MODULE_ALIAS() statements.
1021
1038
* At this time, we cannot write the actual output C source yet,
1022
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
1079
else if (sym_is (name , namelen , "pnp_card" ))
1063
1080
do_pnp_card_entries (symval , sym -> st_size , mod );
1064
1081
else {
1065
- const struct devtable_switch * p = devtable_switch ;
1066
- unsigned int i ;
1082
+ struct devtable * * p ;
1067
1083
1068
- for (i = 0 ; i < ARRAY_SIZE ( devtable_switch ); i ++ , p ++ ) {
1069
- if (sym_is (name , namelen , p -> device_id )) {
1070
- do_table (symval , sym -> st_size , p -> id_size ,
1071
- p -> device_id , p -> function , mod );
1084
+ for (p = __start___devtable ; p < __stop___devtable ; p ++ ) {
1085
+ if (sym_is (name , namelen , ( * p ) -> device_id )) {
1086
+ do_table (symval , sym -> st_size , ( * p ) -> id_size ,
1087
+ ( * p ) -> device_id , ( * p ) -> function , mod );
1072
1088
break ;
1073
1089
}
1074
1090
}
0 commit comments