Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 30a31
- > #include <stdbool.h>
- 40a42,96
- > /* This array collects all instances that use the generic do_table */
- > struct devtable {
- > const char *device_id; /* name of table, __mod_<name>_device_table. */
- > unsigned long id_size;
- > void *function;
- > };
- >
- > #define ___cat(a,b) a ## b
- > #define __cat(a,b) ___cat(a,b)
- >
- > /* we need some special handling for this host tool running eventually on
- > * Darwin. The Mach-O section handling is a bit different than ELF section
- > * handling. The differnces in detail are:
- > * a) we have segments which have sections
- > * b) we need a API call to get the respective section symbols */
- > #if defined(__MACH__)
- > #include <mach-o/getsect.h>
- >
- > #define INIT_SECTION(name) do { \
- > unsigned long name ## _len; \
- > char *__cat(pstart_,name) = getsectdata("__TEXT", \
- > #name, &__cat(name,_len)); \
- > char *__cat(pstop_,name) = __cat(pstart_,name) + \
- > __cat(name, _len); \
- > __cat(__start_,name) = (void *)__cat(pstart_,name); \
- > __cat(__stop_,name) = (void *)__cat(pstop_,name); \
- > } while (0)
- > #define SECTION(name) __attribute__((section("__TEXT, " #name)))
- >
- > struct devtable **__start___devtable, **__stop___devtable;
- > #else
- > #define INIT_SECTION(name) /* no-op for ELF */
- > #define SECTION(name) __attribute__((section(#name)))
- >
- > /* We construct a table of pointers in an ELF section (pointers generally
- > * go unpadded by gcc). ld creates boundary syms for us. */
- > extern struct devtable *__start___devtable[], *__stop___devtable[];
- > #endif /* __MACH__ */
- >
- > #if __GNUC__ == 3 && __GNUC_MINOR__ < 3
- > # define __used __attribute__((__unused__))
- > #else
- > # define __used __attribute__((__used__))
- > #endif
- >
- > /* Add a table entry. We test function type matches while we're here. */
- > #define ADD_TO_DEVTABLE(device_id, type, function) \
- > static struct devtable __cat(devtable,__LINE__) = { \
- > device_id + 0*sizeof((function)((const char *)NULL, \
- > (type *)NULL, \
- > (char *)NULL)), \
- > sizeof(type), (function) }; \
- > static struct devtable *SECTION(__devtable) __used \
- > __cat(devtable_ptr,__LINE__) = &__cat(devtable,__LINE__)
- >
- 291a348
- > ADD_TO_DEVTABLE("hid", struct hid_device_id, do_hid_entry);
- 315a373
- > ADD_TO_DEVTABLE("ieee1394", struct ieee1394_device_id, do_ieee1394_entry);
- 358a417
- > ADD_TO_DEVTABLE("pci", struct pci_device_id, do_pci_entry);
- 381a441
- > ADD_TO_DEVTABLE("ccw", struct ccw_device_id, do_ccw_entry);
- 389a450
- > ADD_TO_DEVTABLE("ap", struct ap_device_id, do_ap_entry);
- 397a459
- > ADD_TO_DEVTABLE("css", struct css_device_id, do_css_entry);
- 416a479
- > ADD_TO_DEVTABLE("serio", struct serio_device_id, do_serio_entry);
- 424a488
- > ADD_TO_DEVTABLE("acpi", struct acpi_device_id, do_acpi_entry);
- 547,548c611
- <
- <
- ---
- > ADD_TO_DEVTABLE("pcmcia", struct pcmcia_device_id, do_pcmcia_entry);
- 570a634
- > ADD_TO_DEVTABLE("of", struct of_device_id, do_of_entry);
- 587a652
- > ADD_TO_DEVTABLE("vio", struct vio_device_id, do_vio_entry);
- 642a708
- > ADD_TO_DEVTABLE("input", struct input_device_id, do_input_entry);
- 652a719
- > ADD_TO_DEVTABLE("eisa", struct eisa_device_id, do_eisa_entry);
- 671a739
- > ADD_TO_DEVTABLE("parisc", struct parisc_device_id, do_parisc_entry);
- 687a756
- > ADD_TO_DEVTABLE("sdio", struct sdio_device_id, do_sdio_entry);
- 703a773,792
- > ADD_TO_DEVTABLE("ssb", struct ssb_device_id, do_ssb_entry);
- >
- > /* Looks like: bcma:mNidNrevNclN. */
- > static int do_bcma_entry(const char *filename,
- > struct bcma_device_id *id, char *alias)
- > {
- > id->manuf = TO_NATIVE(id->manuf);
- > id->id = TO_NATIVE(id->id);
- > id->rev = TO_NATIVE(id->rev);
- > id->class = TO_NATIVE(id->class);
- >
- > strcpy(alias, "bcma:");
- > ADD(alias, "m", id->manuf != BCMA_ANY_MANUF, id->manuf);
- > ADD(alias, "id", id->id != BCMA_ANY_ID, id->id);
- > ADD(alias, "rev", id->rev != BCMA_ANY_REV, id->rev);
- > ADD(alias, "cl", id->class != BCMA_ANY_CLASS, id->class);
- > add_wildcard(alias);
- > return 1;
- > }
- > ADD_TO_DEVTABLE("bcma", struct bcma_device_id, do_bcma_entry);
- 718a808,830
- > ADD_TO_DEVTABLE("virtio", struct virtio_device_id, do_virtio_entry);
- >
- > /*
- > * Looks like: vmbus:guid
- > * Each byte of the guid will be represented by two hex characters
- > * in the name.
- > */
- >
- > static int do_vmbus_entry(const char *filename, struct hv_vmbus_device_id *id,
- > char *alias)
- > {
- > int i;
- > char guid_name[((sizeof(id->guid) + 1)) * 2];
- >
- > for (i = 0; i < (sizeof(id->guid) * 2); i += 2)
- > sprintf(&guid_name[i], "%02x", id->guid[i/2]);
- >
- > strcpy(alias, "vmbus:");
- > strcat(alias, guid_name);
- >
- > return 1;
- > }
- > ADD_TO_DEVTABLE("vmbus", struct hv_vmbus_device_id, do_vmbus_entry);
- 727a840
- > ADD_TO_DEVTABLE("i2c", struct i2c_device_id, do_i2c_entry);
- 736a850
- > ADD_TO_DEVTABLE("spi", struct spi_device_id, do_spi_entry);
- 790a905
- > ADD_TO_DEVTABLE("dmi", struct dmi_system_id, do_dmi_entry);
- 797a913
- > ADD_TO_DEVTABLE("platform", struct platform_device_id, do_platform_entry);
- 819a936
- > ADD_TO_DEVTABLE("mdio", struct mdio_device_id, do_mdio_entry);
- 829a947
- > ADD_TO_DEVTABLE("zorro", struct zorro_device_id, do_zorro_entry);
- 842a961
- > ADD_TO_DEVTABLE("isapnp", struct isapnp_device_id, do_isapnp_entry);
- 844,845c963,970
- < /* Ignore any prefix, eg. some architectures prepend _ */
- < static inline int sym_is(const char *symbol, const char *name)
- ---
- > /*
- > * Append a match expression for a single masked hex digit.
- > * outp points to a pointer to the character at which to append.
- > * *outp is updated on return to point just after the appended text,
- > * to facilitate further appending.
- > */
- > static void append_nibble_mask(char **outp,
- > unsigned int nibble, unsigned int mask)
- 847c972,973
- < const char *match;
- ---
- > char *p = *outp;
- > unsigned int i;
- 849,852c975,1063
- < match = strstr(symbol, name);
- < if (!match)
- < return 0;
- < return match[strlen(name)] == '\0';
- ---
- > switch (mask) {
- > case 0:
- > *p++ = '?';
- > break;
- >
- > case 0xf:
- > p += sprintf(p, "%X", nibble);
- > break;
- >
- > default:
- > /*
- > * Dumbly emit a match pattern for all possible matching
- > * digits. This could be improved in some cases using ranges,
- > * but it has the advantage of being trivially correct, and is
- > * often optimal.
- > */
- > *p++ = '[';
- > for (i = 0; i < 0x10; i++)
- > if ((i & mask) == nibble)
- > p += sprintf(p, "%X", i);
- > *p++ = ']';
- > }
- >
- > /* Ensure that the string remains NUL-terminated: */
- > *p = '\0';
- >
- > /* Advance the caller's end-of-string pointer: */
- > *outp = p;
- > }
- >
- > /*
- > * looks like: "amba:dN"
- > *
- > * N is exactly 8 digits, where each is an upper-case hex digit, or
- > * a ? or [] pattern matching exactly one digit.
- > */
- > static int do_amba_entry(const char *filename,
- > struct amba_id *id, char *alias)
- > {
- > unsigned int digit;
- > char *p = alias;
- >
- > if ((id->id & id->mask) != id->id)
- > fatal("%s: Masked-off bit(s) of AMBA device ID are non-zero: "
- > "id=0x%08X, mask=0x%08X. Please fix this driver.\n",
- > filename, id->id, id->mask);
- >
- > p += sprintf(alias, "amba:d");
- > for (digit = 0; digit < 8; digit++)
- > append_nibble_mask(&p,
- > (id->id >> (4 * (7 - digit))) & 0xf,
- > (id->mask >> (4 * (7 - digit))) & 0xf);
- >
- > return 1;
- > }
- > ADD_TO_DEVTABLE("amba", struct amba_id, do_amba_entry);
- >
- > /* LOOKS like x86cpu:vendor:VVVV:family:FFFF:model:MMMM:feature:*,FEAT,*
- > * All fields are numbers. It would be nicer to use strings for vendor
- > * and feature, but getting those out of the build system here is too
- > * complicated.
- > */
- >
- > static int do_x86cpu_entry(const char *filename, struct x86_cpu_id *id,
- > char *alias)
- > {
- > id->feature = TO_NATIVE(id->feature);
- > id->family = TO_NATIVE(id->family);
- > id->model = TO_NATIVE(id->model);
- > id->vendor = TO_NATIVE(id->vendor);
- >
- > strcpy(alias, "x86cpu:");
- > ADD(alias, "vendor:", id->vendor != X86_VENDOR_ANY, id->vendor);
- > ADD(alias, ":family:", id->family != X86_FAMILY_ANY, id->family);
- > ADD(alias, ":model:", id->model != X86_MODEL_ANY, id->model);
- > strcat(alias, ":feature:*");
- > if (id->feature != X86_FEATURE_ANY)
- > sprintf(alias + strlen(alias), "%04X*", id->feature);
- > return 1;
- > }
- > ADD_TO_DEVTABLE("x86cpu", struct x86_cpu_id, do_x86cpu_entry);
- >
- > /* Does namelen bytes of name exactly match the symbol? */
- > static bool sym_is(const char *name, unsigned namelen, const char *symbol)
- > {
- > if (namelen != strlen(symbol))
- > return false;
- >
- > return memcmp(name, symbol, namelen) == 0;
- 884a1096,1097
- > const char *name;
- > unsigned int namelen;
- 887c1100,1113
- < if (!sym->st_shndx || sym->st_shndx >= info->hdr->e_shnum)
- ---
- > if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections)
- > return;
- >
- > /* We're looking for an object */
- > if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT)
- > return;
- >
- > /* All our symbols are of form <prefix>__mod_XXX_device_table. */
- > name = strstr(symname, "__mod_");
- > if (!name)
- > return;
- > name += strlen("__mod_");
- > namelen = strlen(name);
- > if (namelen < strlen("_device_table"))
- 888a1115,1117
- > if (strcmp(name + namelen - strlen("_device_table"), "_device_table"))
- > return;
- > namelen -= strlen("_device_table");
- 891c1120
- < if (info->sechdrs[sym->st_shndx].sh_type & SHT_NOBITS) {
- ---
- > if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) {
- 896c1125
- < + info->sechdrs[sym->st_shndx].sh_offset
- ---
- > + info->sechdrs[get_secindex(info, sym)].sh_offset
- 900,905c1129,1130
- < if (sym_is(symname, "__mod_pci_device_table"))
- < do_table(symval, sym->st_size,
- < sizeof(struct pci_device_id), "pci",
- < do_pci_entry, mod);
- < else if (sym_is(symname, "__mod_usb_device_table"))
- < /* special case to handle bcdDevice ranges */
- ---
- > /* First handle the "special" cases */
- > if (sym_is(name, namelen, "usb"))
- 907,935c1132
- < else if (sym_is(symname, "__mod_hid_device_table"))
- < do_table(symval, sym->st_size,
- < sizeof(struct hid_device_id), "hid",
- < do_hid_entry, mod);
- < else if (sym_is(symname, "__mod_ieee1394_device_table"))
- < do_table(symval, sym->st_size,
- < sizeof(struct ieee1394_device_id), "ieee1394",
- < do_ieee1394_entry, mod);
- < else if (sym_is(symname, "__mod_ccw_device_table"))
- < do_table(symval, sym->st_size,
- < sizeof(struct ccw_device_id), "ccw",
- < do_ccw_entry, mod);
- < else if (sym_is(symname, "__mod_ap_device_table"))
- < do_table(symval, sym->st_size,
- < sizeof(struct ap_device_id), "ap",
- < do_ap_entry, mod);
- < else if (sym_is(symname, "__mod_css_device_table"))
- < do_table(symval, sym->st_size,
- < sizeof(struct css_device_id), "css",
- < do_css_entry, mod);
- < else if (sym_is(symname, "__mod_serio_device_table"))
- < do_table(symval, sym->st_size,
- < sizeof(struct serio_device_id), "serio",
- < do_serio_entry, mod);
- < else if (sym_is(symname, "__mod_acpi_device_table"))
- < do_table(symval, sym->st_size,
- < sizeof(struct acpi_device_id), "acpi",
- < do_acpi_entry, mod);
- < else if (sym_is(symname, "__mod_pnp_device_table"))
- ---
- > else if (sym_is(name, namelen, "pnp"))
- 937c1134
- < else if (sym_is(symname, "__mod_pnp_card_device_table"))
- ---
- > else if (sym_is(name, namelen, "pnp_card"))
- 939,1002c1136,1147
- < else if (sym_is(symname, "__mod_pcmcia_device_table"))
- < do_table(symval, sym->st_size,
- < sizeof(struct pcmcia_device_id), "pcmcia",
- < do_pcmcia_entry, mod);
- < else if (sym_is(symname, "__mod_of_device_table"))
- < do_table(symval, sym->st_size,
- < sizeof(struct of_device_id), "of",
- < do_of_entry, mod);
- < else if (sym_is(symname, "__mod_vio_device_table"))
- < do_table(symval, sym->st_size,
- < sizeof(struct vio_device_id), "vio",
- < do_vio_entry, mod);
- < else if (sym_is(symname, "__mod_input_device_table"))
- < do_table(symval, sym->st_size,
- < sizeof(struct input_device_id), "input",
- < do_input_entry, mod);
- < else if (sym_is(symname, "__mod_eisa_device_table"))
- < do_table(symval, sym->st_size,
- < sizeof(struct eisa_device_id), "eisa",
- < do_eisa_entry, mod);
- < else if (sym_is(symname, "__mod_parisc_device_table"))
- < do_table(symval, sym->st_size,
- < sizeof(struct parisc_device_id), "parisc",
- < do_parisc_entry, mod);
- < else if (sym_is(symname, "__mod_sdio_device_table"))
- < do_table(symval, sym->st_size,
- < sizeof(struct sdio_device_id), "sdio",
- < do_sdio_entry, mod);
- < else if (sym_is(symname, "__mod_ssb_device_table"))
- < do_table(symval, sym->st_size,
- < sizeof(struct ssb_device_id), "ssb",
- < do_ssb_entry, mod);
- < else if (sym_is(symname, "__mod_virtio_device_table"))
- < do_table(symval, sym->st_size,
- < sizeof(struct virtio_device_id), "virtio",
- < do_virtio_entry, mod);
- < else if (sym_is(symname, "__mod_i2c_device_table"))
- < do_table(symval, sym->st_size,
- < sizeof(struct i2c_device_id), "i2c",
- < do_i2c_entry, mod);
- < else if (sym_is(symname, "__mod_spi_device_table"))
- < do_table(symval, sym->st_size,
- < sizeof(struct spi_device_id), "spi",
- < do_spi_entry, mod);
- < else if (sym_is(symname, "__mod_dmi_device_table"))
- < do_table(symval, sym->st_size,
- < sizeof(struct dmi_system_id), "dmi",
- < do_dmi_entry, mod);
- < else if (sym_is(symname, "__mod_platform_device_table"))
- < do_table(symval, sym->st_size,
- < sizeof(struct platform_device_id), "platform",
- < do_platform_entry, mod);
- < else if (sym_is(symname, "__mod_mdio_device_table"))
- < do_table(symval, sym->st_size,
- < sizeof(struct mdio_device_id), "mdio",
- < do_mdio_entry, mod);
- < else if (sym_is(symname, "__mod_zorro_device_table"))
- < do_table(symval, sym->st_size,
- < sizeof(struct zorro_device_id), "zorro",
- < do_zorro_entry, mod);
- < else if (sym_is(symname, "__mod_isapnp_device_table"))
- < do_table(symval, sym->st_size,
- < sizeof(struct isapnp_device_id), "isa",
- < do_isapnp_entry, mod);
- ---
- > else {
- > struct devtable **p;
- > INIT_SECTION(__devtable);
- >
- > for (p = __start___devtable; p < __stop___devtable; p++) {
- > if (sym_is(name, namelen, (*p)->device_id)) {
- > do_table(symval, sym->st_size, (*p)->id_size,
- > (*p)->device_id, (*p)->function, mod);
- > break;
- > }
- > }
- > }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement