aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/mod
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/mod')
-rw-r--r--scripts/mod/file2alias.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index e8c7eb16c0ea..296f17ff751b 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -889,6 +889,74 @@ static int do_isapnp_entry(const char *filename,
889 return 1; 889 return 1;
890} 890}
891 891
892/*
893 * Append a match expression for a single masked hex digit.
894 * outp points to a pointer to the character at which to append.
895 * *outp is updated on return to point just after the appended text,
896 * to facilitate further appending.
897 */
898static void append_nibble_mask(char **outp,
899 unsigned int nibble, unsigned int mask)
900{
901 char *p = *outp;
902 unsigned int i;
903
904 switch (mask) {
905 case 0:
906 *p++ = '?';
907 break;
908
909 case 0xf:
910 p += sprintf(p, "%X", nibble);
911 break;
912
913 default:
914 /*
915 * Dumbly emit a match pattern for all possible matching
916 * digits. This could be improved in some cases using ranges,
917 * but it has the advantage of being trivially correct, and is
918 * often optimal.
919 */
920 *p++ = '[';
921 for (i = 0; i < 0x10; i++)
922 if ((i & mask) == nibble)
923 p += sprintf(p, "%X", i);
924 *p++ = ']';
925 }
926
927 /* Ensure that the string remains NUL-terminated: */
928 *p = '\0';
929
930 /* Advance the caller's end-of-string pointer: */
931 *outp = p;
932}
933
934/*
935 * looks like: "amba:dN"
936 *
937 * N is exactly 8 digits, where each is an upper-case hex digit, or
938 * a ? or [] pattern matching exactly one digit.
939 */
940static int do_amba_entry(const char *filename,
941 struct amba_id *id, char *alias)
942{
943 unsigned int digit;
944 char *p = alias;
945
946 if ((id->id & id->mask) != id->id)
947 fatal("%s: Masked-off bit(s) of AMBA device ID are non-zero: "
948 "id=0x%08X, mask=0x%08X. Please fix this driver.\n",
949 filename, id->id, id->mask);
950
951 p += sprintf(alias, "amba:d");
952 for (digit = 0; digit < 8; digit++)
953 append_nibble_mask(&p,
954 (id->id >> (4 * (7 - digit))) & 0xf,
955 (id->mask >> (4 * (7 - digit))) & 0xf);
956
957 return 1;
958}
959
892/* Ignore any prefix, eg. some architectures prepend _ */ 960/* Ignore any prefix, eg. some architectures prepend _ */
893static inline int sym_is(const char *symbol, const char *name) 961static inline int sym_is(const char *symbol, const char *name)
894{ 962{
@@ -1060,6 +1128,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
1060 do_table(symval, sym->st_size, 1128 do_table(symval, sym->st_size,
1061 sizeof(struct isapnp_device_id), "isa", 1129 sizeof(struct isapnp_device_id), "isa",
1062 do_isapnp_entry, mod); 1130 do_isapnp_entry, mod);
1131 else if (sym_is(symname, "__mod_amba_device_table"))
1132 do_table(symval, sym->st_size,
1133 sizeof(struct amba_id), "amba",
1134 do_amba_entry, mod);
1063 free(zeros); 1135 free(zeros);
1064} 1136}
1065 1137