11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Simple code to turn various tables in an ELF file into alias definitions.
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This deals with kernel datastructures where they should be
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * dealt with: in the kernel source.
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright 2002-2003  Rusty Russell, IBM Corporation
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *           2003       Kai Germaschewski
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This software may be used and distributed according to the terms
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * of the GNU General Public License, incorporated herein by reference.
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "modpost.h"
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* We use the ELF typedefs for kernel_ulong_t but bite the bullet and
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * use either stdint.h or inttypes.h for the rest. */
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if KERNEL_ELFCLASS == ELFCLASS32
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstypedef Elf32_Addr	kernel_ulong_t;
191d8f430c15b3a345db990e285742c67c2f52f9a6Rusty Russell#define BITS_PER_LONG 32
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstypedef Elf64_Addr	kernel_ulong_t;
221d8f430c15b3a345db990e285742c67c2f52f9a6Rusty Russell#define BITS_PER_LONG 64
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef __sun__
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <inttypes.h>
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <stdint.h>
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
305e6557722e69840506eb8bc5a1edcdb4e447a917Jeff Mahoney#include <ctype.h>
315e6557722e69840506eb8bc5a1edcdb4e447a917Jeff Mahoney
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstypedef uint32_t	__u32;
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstypedef uint16_t	__u16;
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstypedef unsigned char	__u8;
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Big exception to the "don't include kernel headers into userspace, which
3762070fa42c4ac23d1d71146a4c14702302b80245Sam Ravnborg * even potentially has different endianness and word sizes, since
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * we handle those differences explicitly below */
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "../../include/linux/mod_devicetable.h"
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ADD(str, sep, cond, field)                              \
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsdo {                                                            \
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds        strcat(str, sep);                                       \
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds        if (cond)                                               \
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds                sprintf(str + strlen(str),                      \
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds                        sizeof(field) == 1 ? "%02X" :           \
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds                        sizeof(field) == 2 ? "%04X" :           \
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds                        sizeof(field) == 4 ? "%08X" : "",       \
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds                        field);                                 \
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds        else                                                    \
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds                sprintf(str + strlen(str), "*");                \
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} while(0)
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
54ac551828993eecb8499ef9cc3c828fceb49bcf7aJean Delvare/* Always end in a wildcard, for future extension */
55ac551828993eecb8499ef9cc3c828fceb49bcf7aJean Delvarestatic inline void add_wildcard(char *str)
56ac551828993eecb8499ef9cc3c828fceb49bcf7aJean Delvare{
57ac551828993eecb8499ef9cc3c828fceb49bcf7aJean Delvare	int len = strlen(str);
58ac551828993eecb8499ef9cc3c828fceb49bcf7aJean Delvare
59ac551828993eecb8499ef9cc3c828fceb49bcf7aJean Delvare	if (str[len - 1] != '*')
60ac551828993eecb8499ef9cc3c828fceb49bcf7aJean Delvare		strcat(str + len, "*");
61ac551828993eecb8499ef9cc3c828fceb49bcf7aJean Delvare}
62ac551828993eecb8499ef9cc3c828fceb49bcf7aJean Delvare
634ce6efed48d736e3384c39ff87bda723e1f8e041Sam Ravnborgunsigned int cross_build = 0;
64fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg/**
65fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg * Check that sizeof(device_id type) are consistent with size of section
66fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg * in .o file. If in-consistent then userspace and kernel does not agree
67fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg * on actual size which is a bug.
68e00498258c215b46bd24f12ab3a2ed1bcb4772feKees Cook * Also verify that the final entry in the table is all zeros.
694ce6efed48d736e3384c39ff87bda723e1f8e041Sam Ravnborg * Ignore both checks if build host differ from target host and size differs.
70fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg **/
71e00498258c215b46bd24f12ab3a2ed1bcb4772feKees Cookstatic void device_id_check(const char *modname, const char *device_id,
72e00498258c215b46bd24f12ab3a2ed1bcb4772feKees Cook			    unsigned long size, unsigned long id_size,
73e00498258c215b46bd24f12ab3a2ed1bcb4772feKees Cook			    void *symval)
74fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg{
75e00498258c215b46bd24f12ab3a2ed1bcb4772feKees Cook	int i;
76e00498258c215b46bd24f12ab3a2ed1bcb4772feKees Cook
77fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg	if (size % id_size || size < id_size) {
784ce6efed48d736e3384c39ff87bda723e1f8e041Sam Ravnborg		if (cross_build != 0)
794ce6efed48d736e3384c39ff87bda723e1f8e041Sam Ravnborg			return;
80fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg		fatal("%s: sizeof(struct %s_device_id)=%lu is not a modulo "
81fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg		      "of the size of section __mod_%s_device_table=%lu.\n"
82fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg		      "Fix definition of struct %s_device_id "
83fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg		      "in mod_devicetable.h\n",
84fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg		      modname, device_id, id_size, device_id, size, device_id);
85fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg	}
86e00498258c215b46bd24f12ab3a2ed1bcb4772feKees Cook	/* Verify last one is a terminator */
87e00498258c215b46bd24f12ab3a2ed1bcb4772feKees Cook	for (i = 0; i < id_size; i++ ) {
88e00498258c215b46bd24f12ab3a2ed1bcb4772feKees Cook		if (*(uint8_t*)(symval+size-id_size+i)) {
89e00498258c215b46bd24f12ab3a2ed1bcb4772feKees Cook			fprintf(stderr,"%s: struct %s_device_id is %lu bytes.  "
90e00498258c215b46bd24f12ab3a2ed1bcb4772feKees Cook				"The last of %lu is:\n",
91e00498258c215b46bd24f12ab3a2ed1bcb4772feKees Cook				modname, device_id, id_size, size / id_size);
92e00498258c215b46bd24f12ab3a2ed1bcb4772feKees Cook			for (i = 0; i < id_size; i++ )
93e00498258c215b46bd24f12ab3a2ed1bcb4772feKees Cook				fprintf(stderr,"0x%02x ",
94e00498258c215b46bd24f12ab3a2ed1bcb4772feKees Cook					*(uint8_t*)(symval+size-id_size+i) );
95e00498258c215b46bd24f12ab3a2ed1bcb4772feKees Cook			fprintf(stderr,"\n");
96e00498258c215b46bd24f12ab3a2ed1bcb4772feKees Cook			fatal("%s: struct %s_device_id is not terminated "
97e00498258c215b46bd24f12ab3a2ed1bcb4772feKees Cook				"with a NULL entry!\n", modname, device_id);
98e00498258c215b46bd24f12ab3a2ed1bcb4772feKees Cook		}
99e00498258c215b46bd24f12ab3a2ed1bcb4772feKees Cook	}
100fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg}
101fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg
102b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan/* USB is special because the bcdDevice can be matched against a numeric range */
103b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan/* Looks like "usb:vNpNdNdcNdscNdpNicNiscNipN" */
104b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kaganstatic void do_usb_entry(struct usb_device_id *id,
105b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan			 unsigned int bcdDevice_initial, int bcdDevice_initial_digits,
106b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan			 unsigned char range_lo, unsigned char range_hi,
107afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum			 unsigned char max, struct module *mod)
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
109b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan	char alias[500];
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	strcpy(alias, "usb:");
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ADD(alias, "v", id->match_flags&USB_DEVICE_ID_MATCH_VENDOR,
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    id->idVendor);
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ADD(alias, "p", id->match_flags&USB_DEVICE_ID_MATCH_PRODUCT,
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    id->idProduct);
115b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan
116b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan	strcat(alias, "d");
117b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan	if (bcdDevice_initial_digits)
118b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan		sprintf(alias + strlen(alias), "%0*X",
119b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan			bcdDevice_initial_digits, bcdDevice_initial);
120b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan	if (range_lo == range_hi)
121afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum		sprintf(alias + strlen(alias), "%X", range_lo);
122afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum	else if (range_lo > 0 || range_hi < max) {
123afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum		if (range_lo > 0x9 || range_hi < 0xA)
124afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum			sprintf(alias + strlen(alias),
125afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum				"[%X-%X]",
126afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum				range_lo,
127afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum				range_hi);
128afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum		else {
129afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum			sprintf(alias + strlen(alias),
130afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum				range_lo < 0x9 ? "[%X-9" : "[%X",
131afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum				range_lo);
132afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum			sprintf(alias + strlen(alias),
133afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum				range_hi > 0xA ? "a-%X]" : "%X]",
134afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum				range_lo);
135afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum		}
136afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum	}
137b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan	if (bcdDevice_initial_digits < (sizeof(id->bcdDevice_lo) * 2 - 1))
138b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan		strcat(alias, "*");
139b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ADD(alias, "dc", id->match_flags&USB_DEVICE_ID_MATCH_DEV_CLASS,
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    id->bDeviceClass);
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ADD(alias, "dsc",
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    id->match_flags&USB_DEVICE_ID_MATCH_DEV_SUBCLASS,
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    id->bDeviceSubClass);
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ADD(alias, "dp",
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    id->match_flags&USB_DEVICE_ID_MATCH_DEV_PROTOCOL,
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    id->bDeviceProtocol);
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ADD(alias, "ic",
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    id->match_flags&USB_DEVICE_ID_MATCH_INT_CLASS,
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    id->bInterfaceClass);
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ADD(alias, "isc",
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    id->match_flags&USB_DEVICE_ID_MATCH_INT_SUBCLASS,
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    id->bInterfaceSubClass);
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ADD(alias, "ip",
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    id->match_flags&USB_DEVICE_ID_MATCH_INT_PROTOCOL,
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    id->bInterfaceProtocol);
157b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan
158ac551828993eecb8499ef9cc3c828fceb49bcf7aJean Delvare	add_wildcard(alias);
159b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan	buf_printf(&mod->dev_table_buf,
160b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan		   "MODULE_ALIAS(\"%s\");\n", alias);
161b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan}
162b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan
16355f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum/* Handles increment/decrement of BCD formatted integers */
16455f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum/* Returns the previous value, so it works like i++ or i-- */
16555f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallumstatic unsigned int incbcd(unsigned int *bcd,
16655f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum			   int inc,
16755f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum			   unsigned char max,
16855f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum			   size_t chars)
16955f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum{
17055f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum	unsigned int init = *bcd, i, j;
17155f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum	unsigned long long c, dec = 0;
17255f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum
17355f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum	/* If bcd is not in BCD format, just increment */
17455f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum	if (max > 0x9) {
17555f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum		*bcd += inc;
17655f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum		return init;
17755f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum	}
17855f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum
17955f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum	/* Convert BCD to Decimal */
18055f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum	for (i=0 ; i < chars ; i++) {
18155f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum		c = (*bcd >> (i << 2)) & 0xf;
18255f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum		c = c > 9 ? 9 : c; /* force to bcd just in case */
18355f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum		for (j=0 ; j < i ; j++)
18455f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum			c = c * 10;
18555f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum		dec += c;
18655f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum	}
18755f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum
18855f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum	/* Do our increment/decrement */
18955f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum	dec += inc;
19055f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum	*bcd  = 0;
19155f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum
19255f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum	/* Convert back to BCD */
19355f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum	for (i=0 ; i < chars ; i++) {
19455f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum		for (c=1,j=0 ; j < i ; j++)
19555f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum			c = c * 10;
19655f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum		c = (dec / c) % 10;
19755f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum		*bcd += c << (i << 2);
19855f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum	}
19955f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum	return init;
20055f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum}
20155f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum
202b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kaganstatic void do_usb_entry_multi(struct usb_device_id *id, struct module *mod)
203b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan{
204b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan	unsigned int devlo, devhi;
205afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum	unsigned char chi, clo, max;
206b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan	int ndigits;
207b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan
208b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan	id->match_flags = TO_NATIVE(id->match_flags);
209b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan	id->idVendor = TO_NATIVE(id->idVendor);
210b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan	id->idProduct = TO_NATIVE(id->idProduct);
211b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan
212b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan	devlo = id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO ?
213b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan		TO_NATIVE(id->bcdDevice_lo) : 0x0U;
214b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan	devhi = id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI ?
215b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan		TO_NATIVE(id->bcdDevice_hi) : ~0x0U;
216b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan
217afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum	/* Figure out if this entry is in bcd or hex format */
218afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum	max = 0x9; /* Default to decimal format */
219afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum	for (ndigits = 0 ; ndigits < sizeof(id->bcdDevice_lo) * 2 ; ndigits++) {
220afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum		clo = (devlo >> (ndigits << 2)) & 0xf;
221afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum		chi = ((devhi > 0x9999 ? 0x9999 : devhi) >> (ndigits << 2)) & 0xf;
222afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum		if (clo > max || chi > max) {
223afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum			max = 0xf;
224afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum			break;
225afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum		}
226afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum	}
227afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum
228b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan	/*
229b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan	 * Some modules (visor) have empty slots as placeholder for
230b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan	 * run-time specification that results in catch-all alias
231b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan	 */
232de6f92b9ee00e9f841fb1a63d0bd60593ec55dbeGreg Kroah-Hartman	if (!(id->idVendor | id->idProduct | id->bDeviceClass | id->bInterfaceClass))
233b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan		return;
234b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan
235b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan	/* Convert numeric bcdDevice range into fnmatch-able pattern(s) */
236b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan	for (ndigits = sizeof(id->bcdDevice_lo) * 2 - 1; devlo <= devhi; ndigits--) {
237b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan		clo = devlo & 0xf;
238b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan		chi = devhi & 0xf;
239afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum		if (chi > max)	/* If we are in bcd mode, truncate if necessary */
240afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum			chi = max;
241b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan		devlo >>= 4;
242b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan		devhi >>= 4;
243b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan
244b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan		if (devlo == devhi || !ndigits) {
245afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum			do_usb_entry(id, devlo, ndigits, clo, chi, max, mod);
246b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan			break;
247b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan		}
248b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan
249afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum		if (clo > 0x0)
25055f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum			do_usb_entry(id,
25155f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum				     incbcd(&devlo, 1, max,
25255f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum					    sizeof(id->bcdDevice_lo) * 2),
25355f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum				     ndigits, clo, max, max, mod);
254b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan
255afe2dab4f6d32d5650aaba42f2c7ec9c0622f4ddNathaniel McCallum		if (chi < max)
25655f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum			do_usb_entry(id,
25755f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum				     incbcd(&devhi, -1, max,
25855f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum					    sizeof(id->bcdDevice_lo) * 2),
25955f49f26821f379c451deb9fd6de8e59afb9b37eNathaniel McCallum				     ndigits, 0x0, chi, max, mod);
260b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan	}
261b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan}
262b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan
263b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kaganstatic void do_usb_table(void *symval, unsigned long size,
264b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan			 struct module *mod)
265b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan{
266b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan	unsigned int i;
267b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan	const unsigned long id_size = sizeof(struct usb_device_id);
268b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan
269e00498258c215b46bd24f12ab3a2ed1bcb4772feKees Cook	device_id_check(mod->name, "usb", size, id_size, symval);
270fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg
271b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan	/* Leave last one: it's the terminator. */
272b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan	size -= id_size;
273b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan
274b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan	for (i = 0; i < size; i += id_size)
275b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan		do_usb_entry_multi(symval + i, mod);
2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
278e8c84f9a5f06912c94c38961096c994da3890a2eJiri Slaby/* Looks like: hid:bNvNpN */
279e8c84f9a5f06912c94c38961096c994da3890a2eJiri Slabystatic int do_hid_entry(const char *filename,
280e8c84f9a5f06912c94c38961096c994da3890a2eJiri Slaby			     struct hid_device_id *id, char *alias)
281e8c84f9a5f06912c94c38961096c994da3890a2eJiri Slaby{
2822b639386a2a26c84c8d26c649cf657ebd43a7bc8Jiri Slaby	id->bus = TO_NATIVE(id->bus);
283e8c84f9a5f06912c94c38961096c994da3890a2eJiri Slaby	id->vendor = TO_NATIVE(id->vendor);
284e8c84f9a5f06912c94c38961096c994da3890a2eJiri Slaby	id->product = TO_NATIVE(id->product);
285e8c84f9a5f06912c94c38961096c994da3890a2eJiri Slaby
286e8c84f9a5f06912c94c38961096c994da3890a2eJiri Slaby	sprintf(alias, "hid:b%04X", id->bus);
287e8c84f9a5f06912c94c38961096c994da3890a2eJiri Slaby	ADD(alias, "v", id->vendor != HID_ANY_ID, id->vendor);
288e8c84f9a5f06912c94c38961096c994da3890a2eJiri Slaby	ADD(alias, "p", id->product != HID_ANY_ID, id->product);
289e8c84f9a5f06912c94c38961096c994da3890a2eJiri Slaby
290e8c84f9a5f06912c94c38961096c994da3890a2eJiri Slaby	return 1;
291e8c84f9a5f06912c94c38961096c994da3890a2eJiri Slaby}
292e8c84f9a5f06912c94c38961096c994da3890a2eJiri Slaby
2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Looks like: ieee1394:venNmoNspNverN */
2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int do_ieee1394_entry(const char *filename,
2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     struct ieee1394_device_id *id, char *alias)
2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	id->match_flags = TO_NATIVE(id->match_flags);
2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	id->vendor_id = TO_NATIVE(id->vendor_id);
2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	id->model_id = TO_NATIVE(id->model_id);
3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	id->specifier_id = TO_NATIVE(id->specifier_id);
3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	id->version = TO_NATIVE(id->version);
3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	strcpy(alias, "ieee1394:");
3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ADD(alias, "ven", id->match_flags & IEEE1394_MATCH_VENDOR_ID,
3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    id->vendor_id);
3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ADD(alias, "mo", id->match_flags & IEEE1394_MATCH_MODEL_ID,
3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    id->model_id);
3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ADD(alias, "sp", id->match_flags & IEEE1394_MATCH_SPECIFIER_ID,
3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    id->specifier_id);
3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ADD(alias, "ver", id->match_flags & IEEE1394_MATCH_VERSION,
3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    id->version);
3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
313ac551828993eecb8499ef9cc3c828fceb49bcf7aJean Delvare	add_wildcard(alias);
3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 1;
3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Looks like: pci:vNdNsvNsdNbcNscNiN. */
3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int do_pci_entry(const char *filename,
3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			struct pci_device_id *id, char *alias)
3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Class field can be divided into these three. */
3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned char baseclass, subclass, interface,
3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		baseclass_mask, subclass_mask, interface_mask;
3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	id->vendor = TO_NATIVE(id->vendor);
3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	id->device = TO_NATIVE(id->device);
3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	id->subvendor = TO_NATIVE(id->subvendor);
3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	id->subdevice = TO_NATIVE(id->subdevice);
3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	id->class = TO_NATIVE(id->class);
3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	id->class_mask = TO_NATIVE(id->class_mask);
3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	strcpy(alias, "pci:");
3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ADD(alias, "v", id->vendor != PCI_ANY_ID, id->vendor);
3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ADD(alias, "d", id->device != PCI_ANY_ID, id->device);
3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ADD(alias, "sv", id->subvendor != PCI_ANY_ID, id->subvendor);
3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ADD(alias, "sd", id->subdevice != PCI_ANY_ID, id->subdevice);
3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	baseclass = (id->class) >> 16;
3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	baseclass_mask = (id->class_mask) >> 16;
3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	subclass = (id->class) >> 8;
3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	subclass_mask = (id->class_mask) >> 8;
3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	interface = id->class;
3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	interface_mask = id->class_mask;
3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if ((baseclass_mask != 0 && baseclass_mask != 0xFF)
3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    || (subclass_mask != 0 && subclass_mask != 0xFF)
3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    || (interface_mask != 0 && interface_mask != 0xFF)) {
348cb80514d9c517cc1d101ef304529a0e9b76b4468Sam Ravnborg		warn("Can't handle masks in %s:%04X\n",
349cb80514d9c517cc1d101ef304529a0e9b76b4468Sam Ravnborg		     filename, id->class_mask);
3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ADD(alias, "bc", baseclass_mask == 0xFF, baseclass);
3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ADD(alias, "sc", subclass_mask == 0xFF, subclass);
3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ADD(alias, "i", interface_mask == 0xFF, interface);
356ac551828993eecb8499ef9cc3c828fceb49bcf7aJean Delvare	add_wildcard(alias);
3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 1;
3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
36062070fa42c4ac23d1d71146a4c14702302b80245Sam Ravnborg/* looks like: "ccw:tNmNdtNdmN" */
3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int do_ccw_entry(const char *filename,
3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			struct ccw_device_id *id, char *alias)
3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	id->match_flags = TO_NATIVE(id->match_flags);
3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	id->cu_type = TO_NATIVE(id->cu_type);
3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	id->cu_model = TO_NATIVE(id->cu_model);
3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	id->dev_type = TO_NATIVE(id->dev_type);
3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	id->dev_model = TO_NATIVE(id->dev_model);
3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	strcpy(alias, "ccw:");
3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ADD(alias, "t", id->match_flags&CCW_DEVICE_ID_MATCH_CU_TYPE,
3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    id->cu_type);
3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ADD(alias, "m", id->match_flags&CCW_DEVICE_ID_MATCH_CU_MODEL,
3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    id->cu_model);
3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ADD(alias, "dt", id->match_flags&CCW_DEVICE_ID_MATCH_DEVICE_TYPE,
3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    id->dev_type);
377de1d9c033f32ce39bf60e25be3b8624225fa9181Bastian Blank	ADD(alias, "dm", id->match_flags&CCW_DEVICE_ID_MATCH_DEVICE_MODEL,
3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	    id->dev_model);
379ac551828993eecb8499ef9cc3c828fceb49bcf7aJean Delvare	add_wildcard(alias);
3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 1;
3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3831534c3820c26aca4e2567f97b8add8bea40e7e2bMartin Schwidefsky/* looks like: "ap:tN" */
3841534c3820c26aca4e2567f97b8add8bea40e7e2bMartin Schwidefskystatic int do_ap_entry(const char *filename,
3851534c3820c26aca4e2567f97b8add8bea40e7e2bMartin Schwidefsky		       struct ap_device_id *id, char *alias)
3861534c3820c26aca4e2567f97b8add8bea40e7e2bMartin Schwidefsky{
387ac551828993eecb8499ef9cc3c828fceb49bcf7aJean Delvare	sprintf(alias, "ap:t%02X*", id->dev_type);
3881534c3820c26aca4e2567f97b8add8bea40e7e2bMartin Schwidefsky	return 1;
3891534c3820c26aca4e2567f97b8add8bea40e7e2bMartin Schwidefsky}
3901534c3820c26aca4e2567f97b8add8bea40e7e2bMartin Schwidefsky
3917e9db9eaefdb8798730790214ff1b7746006ec98Cornelia Huck/* looks like: "css:tN" */
3927e9db9eaefdb8798730790214ff1b7746006ec98Cornelia Huckstatic int do_css_entry(const char *filename,
3937e9db9eaefdb8798730790214ff1b7746006ec98Cornelia Huck			struct css_device_id *id, char *alias)
3947e9db9eaefdb8798730790214ff1b7746006ec98Cornelia Huck{
3957e9db9eaefdb8798730790214ff1b7746006ec98Cornelia Huck	sprintf(alias, "css:t%01X", id->type);
3967e9db9eaefdb8798730790214ff1b7746006ec98Cornelia Huck	return 1;
3977e9db9eaefdb8798730790214ff1b7746006ec98Cornelia Huck}
3987e9db9eaefdb8798730790214ff1b7746006ec98Cornelia Huck
3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Looks like: "serio:tyNprNidNexN" */
4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int do_serio_entry(const char *filename,
4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			  struct serio_device_id *id, char *alias)
4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	id->type = TO_NATIVE(id->type);
4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	id->proto = TO_NATIVE(id->proto);
4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	id->id = TO_NATIVE(id->id);
4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	id->extra = TO_NATIVE(id->extra);
4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	strcpy(alias, "serio:");
4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ADD(alias, "ty", id->type != SERIO_ANY, id->type);
4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ADD(alias, "pr", id->proto != SERIO_ANY, id->proto);
4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ADD(alias, "id", id->id != SERIO_ANY, id->id);
4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ADD(alias, "ex", id->extra != SERIO_ANY, id->extra);
4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
414ac551828993eecb8499ef9cc3c828fceb49bcf7aJean Delvare	add_wildcard(alias);
4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 1;
4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
41829b71a1ca74491fab9fed09e9d835d840d042690Thomas Renninger/* looks like: "acpi:ACPI0003 or acpi:PNP0C0B" or "acpi:LNXVIDEO" */
41929b71a1ca74491fab9fed09e9d835d840d042690Thomas Renningerstatic int do_acpi_entry(const char *filename,
42029b71a1ca74491fab9fed09e9d835d840d042690Thomas Renninger			struct acpi_device_id *id, char *alias)
42129b71a1ca74491fab9fed09e9d835d840d042690Thomas Renninger{
422ac551828993eecb8499ef9cc3c828fceb49bcf7aJean Delvare	sprintf(alias, "acpi*:%s:*", id->id);
42329b71a1ca74491fab9fed09e9d835d840d042690Thomas Renninger	return 1;
42429b71a1ca74491fab9fed09e9d835d840d042690Thomas Renninger}
42529b71a1ca74491fab9fed09e9d835d840d042690Thomas Renninger
4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* looks like: "pnp:dD" */
42722454cb99fc39f2629ad06a7eccb3df312f8830eKay Sieversstatic void do_pnp_device_entry(void *symval, unsigned long size,
42822454cb99fc39f2629ad06a7eccb3df312f8830eKay Sievers				struct module *mod)
4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
43022454cb99fc39f2629ad06a7eccb3df312f8830eKay Sievers	const unsigned long id_size = sizeof(struct pnp_device_id);
4315e4c6564c95ce127beeefe75e15cd11c93487436Kay Sievers	const unsigned int count = (size / id_size)-1;
4325e4c6564c95ce127beeefe75e15cd11c93487436Kay Sievers	const struct pnp_device_id *devs = symval;
4335e4c6564c95ce127beeefe75e15cd11c93487436Kay Sievers	unsigned int i;
43422454cb99fc39f2629ad06a7eccb3df312f8830eKay Sievers
43522454cb99fc39f2629ad06a7eccb3df312f8830eKay Sievers	device_id_check(mod->name, "pnp", size, id_size, symval);
43622454cb99fc39f2629ad06a7eccb3df312f8830eKay Sievers
4375e4c6564c95ce127beeefe75e15cd11c93487436Kay Sievers	for (i = 0; i < count; i++) {
4385e4c6564c95ce127beeefe75e15cd11c93487436Kay Sievers		const char *id = (char *)devs[i].id;
43972638f598ec9f05a43fcb22dc1dd8dc34c43acc1Kay Sievers		char acpi_id[sizeof(devs[0].id)];
44072638f598ec9f05a43fcb22dc1dd8dc34c43acc1Kay Sievers		int j;
4415e4c6564c95ce127beeefe75e15cd11c93487436Kay Sievers
4425e4c6564c95ce127beeefe75e15cd11c93487436Kay Sievers		buf_printf(&mod->dev_table_buf,
4435e4c6564c95ce127beeefe75e15cd11c93487436Kay Sievers			   "MODULE_ALIAS(\"pnp:d%s*\");\n", id);
44472638f598ec9f05a43fcb22dc1dd8dc34c43acc1Kay Sievers
44572638f598ec9f05a43fcb22dc1dd8dc34c43acc1Kay Sievers		/* fix broken pnp bus lowercasing */
44672638f598ec9f05a43fcb22dc1dd8dc34c43acc1Kay Sievers		for (j = 0; j < sizeof(acpi_id); j++)
44772638f598ec9f05a43fcb22dc1dd8dc34c43acc1Kay Sievers			acpi_id[j] = toupper(id[j]);
4485e4c6564c95ce127beeefe75e15cd11c93487436Kay Sievers		buf_printf(&mod->dev_table_buf,
44972638f598ec9f05a43fcb22dc1dd8dc34c43acc1Kay Sievers			   "MODULE_ALIAS(\"acpi*:%s:*\");\n", acpi_id);
4505e4c6564c95ce127beeefe75e15cd11c93487436Kay Sievers	}
4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4530c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers/* looks like: "pnp:dD" for every device of the card */
4540c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sieversstatic void do_pnp_card_entries(void *symval, unsigned long size,
4550c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers				struct module *mod)
4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4570c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers	const unsigned long id_size = sizeof(struct pnp_card_device_id);
4580c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers	const unsigned int count = (size / id_size)-1;
4590c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers	const struct pnp_card_device_id *cards = symval;
4600c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers	unsigned int i;
4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4620c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers	device_id_check(mod->name, "pnp", size, id_size, symval);
4630c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers
4640c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers	for (i = 0; i < count; i++) {
4650c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers		unsigned int j;
4660c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers		const struct pnp_card_device_id *card = &cards[i];
4670c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers
4680c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers		for (j = 0; j < PNP_MAX_DEVICES; j++) {
4690c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers			const char *id = (char *)card->devs[j].id;
4700c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers			int i2, j2;
4710c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers			int dup = 0;
4720c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers
4730c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers			if (!id[0])
4740c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers				break;
4750c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers
4760c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers			/* find duplicate, already added value */
4770c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers			for (i2 = 0; i2 < i && !dup; i2++) {
4780c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers				const struct pnp_card_device_id *card2 = &cards[i2];
4790c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers
4800c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers				for (j2 = 0; j2 < PNP_MAX_DEVICES; j2++) {
4810c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers					const char *id2 = (char *)card2->devs[j2].id;
4820c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers
4830c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers					if (!id2[0])
4840c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers						break;
4850c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers
4860c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers					if (!strcmp(id, id2)) {
4870c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers						dup = 1;
4880c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers						break;
4890c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers					}
4900c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers				}
4910c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers			}
4920c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers
4930c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers			/* add an individual alias for every device entry */
49422454cb99fc39f2629ad06a7eccb3df312f8830eKay Sievers			if (!dup) {
49572638f598ec9f05a43fcb22dc1dd8dc34c43acc1Kay Sievers				char acpi_id[sizeof(card->devs[0].id)];
49672638f598ec9f05a43fcb22dc1dd8dc34c43acc1Kay Sievers				int k;
49772638f598ec9f05a43fcb22dc1dd8dc34c43acc1Kay Sievers
4980c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers				buf_printf(&mod->dev_table_buf,
4990c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers					   "MODULE_ALIAS(\"pnp:d%s*\");\n", id);
50072638f598ec9f05a43fcb22dc1dd8dc34c43acc1Kay Sievers
50172638f598ec9f05a43fcb22dc1dd8dc34c43acc1Kay Sievers				/* fix broken pnp bus lowercasing */
50272638f598ec9f05a43fcb22dc1dd8dc34c43acc1Kay Sievers				for (k = 0; k < sizeof(acpi_id); k++)
50372638f598ec9f05a43fcb22dc1dd8dc34c43acc1Kay Sievers					acpi_id[k] = toupper(id[k]);
50422454cb99fc39f2629ad06a7eccb3df312f8830eKay Sievers				buf_printf(&mod->dev_table_buf,
50572638f598ec9f05a43fcb22dc1dd8dc34c43acc1Kay Sievers					   "MODULE_ALIAS(\"acpi*:%s:*\");\n", acpi_id);
50622454cb99fc39f2629ad06a7eccb3df312f8830eKay Sievers			}
5070c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers		}
5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
51190829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski/* Looks like: pcmcia:mNcNfNfnNpfnNvaNvbNvcNvdN. */
51290829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowskistatic int do_pcmcia_entry(const char *filename,
51390829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski			   struct pcmcia_device_id *id, char *alias)
51490829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski{
51590829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski	unsigned int i;
51690829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski
5174fb7edce52e5b6cf41e3375822d74a27f0b6f2ddKars de Jong	id->match_flags = TO_NATIVE(id->match_flags);
51890829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski	id->manf_id = TO_NATIVE(id->manf_id);
51990829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski	id->card_id = TO_NATIVE(id->card_id);
52090829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski	id->func_id = TO_NATIVE(id->func_id);
52190829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski	id->function = TO_NATIVE(id->function);
52290829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski	id->device_no = TO_NATIVE(id->device_no);
5234fb7edce52e5b6cf41e3375822d74a27f0b6f2ddKars de Jong
52490829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski	for (i=0; i<4; i++) {
52590829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski		id->prod_id_hash[i] = TO_NATIVE(id->prod_id_hash[i]);
52690829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski       }
52790829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski
52890829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski       strcpy(alias, "pcmcia:");
52990829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski       ADD(alias, "m", id->match_flags & PCMCIA_DEV_ID_MATCH_MANF_ID,
53090829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski	   id->manf_id);
53190829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski       ADD(alias, "c", id->match_flags & PCMCIA_DEV_ID_MATCH_CARD_ID,
53290829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski	   id->card_id);
53390829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski       ADD(alias, "f", id->match_flags & PCMCIA_DEV_ID_MATCH_FUNC_ID,
53490829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski	   id->func_id);
53590829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski       ADD(alias, "fn", id->match_flags & PCMCIA_DEV_ID_MATCH_FUNCTION,
53690829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski	   id->function);
53790829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski       ADD(alias, "pfn", id->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO,
53890829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski	   id->device_no);
53990829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski       ADD(alias, "pa", id->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID1, id->prod_id_hash[0]);
54090829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski       ADD(alias, "pb", id->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID2, id->prod_id_hash[1]);
54190829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski       ADD(alias, "pc", id->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID3, id->prod_id_hash[2]);
54290829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski       ADD(alias, "pd", id->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID4, id->prod_id_hash[3]);
54390829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski
544ac551828993eecb8499ef9cc3c828fceb49bcf7aJean Delvare	add_wildcard(alias);
54590829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski       return 1;
54690829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski}
54790829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski
54890829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski
54990829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski
5505e6557722e69840506eb8bc5a1edcdb4e447a917Jeff Mahoneystatic int do_of_entry (const char *filename, struct of_device_id *of, char *alias)
5515e6557722e69840506eb8bc5a1edcdb4e447a917Jeff Mahoney{
552d1ab423502e787e264b4797a5fa200d804c4fd63Sylvain Munaut    int len;
5535e6557722e69840506eb8bc5a1edcdb4e447a917Jeff Mahoney    char *tmp;
554d1ab423502e787e264b4797a5fa200d804c4fd63Sylvain Munaut    len = sprintf (alias, "of:N%sT%s",
5555e6557722e69840506eb8bc5a1edcdb4e447a917Jeff Mahoney                    of->name[0] ? of->name : "*",
556d1ab423502e787e264b4797a5fa200d804c4fd63Sylvain Munaut                    of->type[0] ? of->type : "*");
557d1ab423502e787e264b4797a5fa200d804c4fd63Sylvain Munaut
558d1ab423502e787e264b4797a5fa200d804c4fd63Sylvain Munaut    if (of->compatible[0])
559d1ab423502e787e264b4797a5fa200d804c4fd63Sylvain Munaut        sprintf (&alias[len], "%sC%s",
560d1ab423502e787e264b4797a5fa200d804c4fd63Sylvain Munaut                     of->type[0] ? "*" : "",
561d1ab423502e787e264b4797a5fa200d804c4fd63Sylvain Munaut                     of->compatible);
5625e6557722e69840506eb8bc5a1edcdb4e447a917Jeff Mahoney
5635e6557722e69840506eb8bc5a1edcdb4e447a917Jeff Mahoney    /* Replace all whitespace with underscores */
5645e6557722e69840506eb8bc5a1edcdb4e447a917Jeff Mahoney    for (tmp = alias; tmp && *tmp; tmp++)
5655e6557722e69840506eb8bc5a1edcdb4e447a917Jeff Mahoney        if (isspace (*tmp))
5665e6557722e69840506eb8bc5a1edcdb4e447a917Jeff Mahoney            *tmp = '_';
5675e6557722e69840506eb8bc5a1edcdb4e447a917Jeff Mahoney
568ac551828993eecb8499ef9cc3c828fceb49bcf7aJean Delvare    add_wildcard(alias);
5695e6557722e69840506eb8bc5a1edcdb4e447a917Jeff Mahoney    return 1;
5705e6557722e69840506eb8bc5a1edcdb4e447a917Jeff Mahoney}
5715e6557722e69840506eb8bc5a1edcdb4e447a917Jeff Mahoney
572fb120da678c517f72d4b39932062c2191827b331Stephen Rothwellstatic int do_vio_entry(const char *filename, struct vio_device_id *vio,
573fb120da678c517f72d4b39932062c2191827b331Stephen Rothwell		char *alias)
574fb120da678c517f72d4b39932062c2191827b331Stephen Rothwell{
575fb120da678c517f72d4b39932062c2191827b331Stephen Rothwell	char *tmp;
576fb120da678c517f72d4b39932062c2191827b331Stephen Rothwell
577fb120da678c517f72d4b39932062c2191827b331Stephen Rothwell	sprintf(alias, "vio:T%sS%s", vio->type[0] ? vio->type : "*",
578fb120da678c517f72d4b39932062c2191827b331Stephen Rothwell			vio->compat[0] ? vio->compat : "*");
579fb120da678c517f72d4b39932062c2191827b331Stephen Rothwell
580fb120da678c517f72d4b39932062c2191827b331Stephen Rothwell	/* Replace all whitespace with underscores */
581fb120da678c517f72d4b39932062c2191827b331Stephen Rothwell	for (tmp = alias; tmp && *tmp; tmp++)
582fb120da678c517f72d4b39932062c2191827b331Stephen Rothwell		if (isspace (*tmp))
583fb120da678c517f72d4b39932062c2191827b331Stephen Rothwell			*tmp = '_';
584fb120da678c517f72d4b39932062c2191827b331Stephen Rothwell
585ac551828993eecb8499ef9cc3c828fceb49bcf7aJean Delvare	add_wildcard(alias);
586fb120da678c517f72d4b39932062c2191827b331Stephen Rothwell	return 1;
587fb120da678c517f72d4b39932062c2191827b331Stephen Rothwell}
588fb120da678c517f72d4b39932062c2191827b331Stephen Rothwell
5891d8f430c15b3a345db990e285742c67c2f52f9a6Rusty Russell#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
5901d8f430c15b3a345db990e285742c67c2f52f9a6Rusty Russell
5911d8f430c15b3a345db990e285742c67c2f52f9a6Rusty Russellstatic void do_input(char *alias,
5921d8f430c15b3a345db990e285742c67c2f52f9a6Rusty Russell		     kernel_ulong_t *arr, unsigned int min, unsigned int max)
5931d8f430c15b3a345db990e285742c67c2f52f9a6Rusty Russell{
5941d8f430c15b3a345db990e285742c67c2f52f9a6Rusty Russell	unsigned int i;
595ddc5d3414593e4d7ad7fbd33e7f7517fcc234544Dmitry Torokhov
596ddc5d3414593e4d7ad7fbd33e7f7517fcc234544Dmitry Torokhov	for (i = min; i < max; i++)
597e0e92632715f08dddeddb72b76e04c20126e1f67Hans de Goede		if (arr[i / BITS_PER_LONG] & (1L << (i%BITS_PER_LONG)))
598ddc5d3414593e4d7ad7fbd33e7f7517fcc234544Dmitry Torokhov			sprintf(alias + strlen(alias), "%X,*", i);
5991d8f430c15b3a345db990e285742c67c2f52f9a6Rusty Russell}
6001d8f430c15b3a345db990e285742c67c2f52f9a6Rusty Russell
6011d8f430c15b3a345db990e285742c67c2f52f9a6Rusty Russell/* input:b0v0p0e0-eXkXrXaXmXlXsXfXwX where X is comma-separated %02X. */
6021d8f430c15b3a345db990e285742c67c2f52f9a6Rusty Russellstatic int do_input_entry(const char *filename, struct input_device_id *id,
6031d8f430c15b3a345db990e285742c67c2f52f9a6Rusty Russell			  char *alias)
6041d8f430c15b3a345db990e285742c67c2f52f9a6Rusty Russell{
6051d8f430c15b3a345db990e285742c67c2f52f9a6Rusty Russell	sprintf(alias, "input:");
6061d8f430c15b3a345db990e285742c67c2f52f9a6Rusty Russell
607ddc5d3414593e4d7ad7fbd33e7f7517fcc234544Dmitry Torokhov	ADD(alias, "b", id->flags & INPUT_DEVICE_ID_MATCH_BUS, id->bustype);
608ddc5d3414593e4d7ad7fbd33e7f7517fcc234544Dmitry Torokhov	ADD(alias, "v", id->flags & INPUT_DEVICE_ID_MATCH_VENDOR, id->vendor);
609ddc5d3414593e4d7ad7fbd33e7f7517fcc234544Dmitry Torokhov	ADD(alias, "p", id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT, id->product);
610ddc5d3414593e4d7ad7fbd33e7f7517fcc234544Dmitry Torokhov	ADD(alias, "e", id->flags & INPUT_DEVICE_ID_MATCH_VERSION, id->version);
6111d8f430c15b3a345db990e285742c67c2f52f9a6Rusty Russell
6121d8f430c15b3a345db990e285742c67c2f52f9a6Rusty Russell	sprintf(alias + strlen(alias), "-e*");
613ddc5d3414593e4d7ad7fbd33e7f7517fcc234544Dmitry Torokhov	if (id->flags & INPUT_DEVICE_ID_MATCH_EVBIT)
614dc24f0e708c8a6a27b5b967a2599c04973054398Sam Ravnborg		do_input(alias, id->evbit, 0, INPUT_DEVICE_ID_EV_MAX);
6151d8f430c15b3a345db990e285742c67c2f52f9a6Rusty Russell	sprintf(alias + strlen(alias), "k*");
616ddc5d3414593e4d7ad7fbd33e7f7517fcc234544Dmitry Torokhov	if (id->flags & INPUT_DEVICE_ID_MATCH_KEYBIT)
617dc24f0e708c8a6a27b5b967a2599c04973054398Sam Ravnborg		do_input(alias, id->keybit,
618dc24f0e708c8a6a27b5b967a2599c04973054398Sam Ravnborg			 INPUT_DEVICE_ID_KEY_MIN_INTERESTING,
619dc24f0e708c8a6a27b5b967a2599c04973054398Sam Ravnborg			 INPUT_DEVICE_ID_KEY_MAX);
6201d8f430c15b3a345db990e285742c67c2f52f9a6Rusty Russell	sprintf(alias + strlen(alias), "r*");
621ddc5d3414593e4d7ad7fbd33e7f7517fcc234544Dmitry Torokhov	if (id->flags & INPUT_DEVICE_ID_MATCH_RELBIT)
622dc24f0e708c8a6a27b5b967a2599c04973054398Sam Ravnborg		do_input(alias, id->relbit, 0, INPUT_DEVICE_ID_REL_MAX);
6231d8f430c15b3a345db990e285742c67c2f52f9a6Rusty Russell	sprintf(alias + strlen(alias), "a*");
624ddc5d3414593e4d7ad7fbd33e7f7517fcc234544Dmitry Torokhov	if (id->flags & INPUT_DEVICE_ID_MATCH_ABSBIT)
625dc24f0e708c8a6a27b5b967a2599c04973054398Sam Ravnborg		do_input(alias, id->absbit, 0, INPUT_DEVICE_ID_ABS_MAX);
6261d8f430c15b3a345db990e285742c67c2f52f9a6Rusty Russell	sprintf(alias + strlen(alias), "m*");
627ddc5d3414593e4d7ad7fbd33e7f7517fcc234544Dmitry Torokhov	if (id->flags & INPUT_DEVICE_ID_MATCH_MSCIT)
628dc24f0e708c8a6a27b5b967a2599c04973054398Sam Ravnborg		do_input(alias, id->mscbit, 0, INPUT_DEVICE_ID_MSC_MAX);
6291d8f430c15b3a345db990e285742c67c2f52f9a6Rusty Russell	sprintf(alias + strlen(alias), "l*");
630ddc5d3414593e4d7ad7fbd33e7f7517fcc234544Dmitry Torokhov	if (id->flags & INPUT_DEVICE_ID_MATCH_LEDBIT)
631dc24f0e708c8a6a27b5b967a2599c04973054398Sam Ravnborg		do_input(alias, id->ledbit, 0, INPUT_DEVICE_ID_LED_MAX);
6321d8f430c15b3a345db990e285742c67c2f52f9a6Rusty Russell	sprintf(alias + strlen(alias), "s*");
633ddc5d3414593e4d7ad7fbd33e7f7517fcc234544Dmitry Torokhov	if (id->flags & INPUT_DEVICE_ID_MATCH_SNDBIT)
634dc24f0e708c8a6a27b5b967a2599c04973054398Sam Ravnborg		do_input(alias, id->sndbit, 0, INPUT_DEVICE_ID_SND_MAX);
6351d8f430c15b3a345db990e285742c67c2f52f9a6Rusty Russell	sprintf(alias + strlen(alias), "f*");
636ddc5d3414593e4d7ad7fbd33e7f7517fcc234544Dmitry Torokhov	if (id->flags & INPUT_DEVICE_ID_MATCH_FFBIT)
637dc24f0e708c8a6a27b5b967a2599c04973054398Sam Ravnborg		do_input(alias, id->ffbit, 0, INPUT_DEVICE_ID_FF_MAX);
6381d8f430c15b3a345db990e285742c67c2f52f9a6Rusty Russell	sprintf(alias + strlen(alias), "w*");
639ddc5d3414593e4d7ad7fbd33e7f7517fcc234544Dmitry Torokhov	if (id->flags & INPUT_DEVICE_ID_MATCH_SWBIT)
640dc24f0e708c8a6a27b5b967a2599c04973054398Sam Ravnborg		do_input(alias, id->swbit, 0, INPUT_DEVICE_ID_SW_MAX);
6411d8f430c15b3a345db990e285742c67c2f52f9a6Rusty Russell	return 1;
6421d8f430c15b3a345db990e285742c67c2f52f9a6Rusty Russell}
6431d8f430c15b3a345db990e285742c67c2f52f9a6Rusty Russell
64407563c711fbc25389e58ab9c9f0b9de2fce56760Michael Tokarevstatic int do_eisa_entry(const char *filename, struct eisa_device_id *eisa,
64507563c711fbc25389e58ab9c9f0b9de2fce56760Michael Tokarev		char *alias)
64607563c711fbc25389e58ab9c9f0b9de2fce56760Michael Tokarev{
64707563c711fbc25389e58ab9c9f0b9de2fce56760Michael Tokarev	if (eisa->sig[0])
64807563c711fbc25389e58ab9c9f0b9de2fce56760Michael Tokarev		sprintf(alias, EISA_DEVICE_MODALIAS_FMT "*", eisa->sig);
649ac551828993eecb8499ef9cc3c828fceb49bcf7aJean Delvare	else
650ac551828993eecb8499ef9cc3c828fceb49bcf7aJean Delvare		strcat(alias, "*");
65107563c711fbc25389e58ab9c9f0b9de2fce56760Michael Tokarev	return 1;
65207563c711fbc25389e58ab9c9f0b9de2fce56760Michael Tokarev}
65307563c711fbc25389e58ab9c9f0b9de2fce56760Michael Tokarev
654f3cf2673358e4221afbb59721a8580a8f35479a5Kyle McMartin/* Looks like: parisc:tNhvNrevNsvN */
655f3cf2673358e4221afbb59721a8580a8f35479a5Kyle McMartinstatic int do_parisc_entry(const char *filename, struct parisc_device_id *id,
656f3cf2673358e4221afbb59721a8580a8f35479a5Kyle McMartin		char *alias)
657f3cf2673358e4221afbb59721a8580a8f35479a5Kyle McMartin{
658f3cf2673358e4221afbb59721a8580a8f35479a5Kyle McMartin	id->hw_type = TO_NATIVE(id->hw_type);
659f3cf2673358e4221afbb59721a8580a8f35479a5Kyle McMartin	id->hversion = TO_NATIVE(id->hversion);
660f3cf2673358e4221afbb59721a8580a8f35479a5Kyle McMartin	id->hversion_rev = TO_NATIVE(id->hversion_rev);
661f3cf2673358e4221afbb59721a8580a8f35479a5Kyle McMartin	id->sversion = TO_NATIVE(id->sversion);
662f3cf2673358e4221afbb59721a8580a8f35479a5Kyle McMartin
663f3cf2673358e4221afbb59721a8580a8f35479a5Kyle McMartin	strcpy(alias, "parisc:");
664f354ef8abe5d6d967c023b21980241e6f883a698Kyle McMartin	ADD(alias, "t", id->hw_type != PA_HWTYPE_ANY_ID, id->hw_type);
665f354ef8abe5d6d967c023b21980241e6f883a698Kyle McMartin	ADD(alias, "hv", id->hversion != PA_HVERSION_ANY_ID, id->hversion);
666f354ef8abe5d6d967c023b21980241e6f883a698Kyle McMartin	ADD(alias, "rev", id->hversion_rev != PA_HVERSION_REV_ANY_ID, id->hversion_rev);
667f354ef8abe5d6d967c023b21980241e6f883a698Kyle McMartin	ADD(alias, "sv", id->sversion != PA_SVERSION_ANY_ID, id->sversion);
668f3cf2673358e4221afbb59721a8580a8f35479a5Kyle McMartin
669ac551828993eecb8499ef9cc3c828fceb49bcf7aJean Delvare	add_wildcard(alias);
670f3cf2673358e4221afbb59721a8580a8f35479a5Kyle McMartin	return 1;
671f3cf2673358e4221afbb59721a8580a8f35479a5Kyle McMartin}
672f3cf2673358e4221afbb59721a8580a8f35479a5Kyle McMartin
673d59b66c7a575cfa8e01f483875d131e42b539bbcPierre Ossman/* Looks like: sdio:cNvNdN. */
674d59b66c7a575cfa8e01f483875d131e42b539bbcPierre Ossmanstatic int do_sdio_entry(const char *filename,
675d59b66c7a575cfa8e01f483875d131e42b539bbcPierre Ossman			struct sdio_device_id *id, char *alias)
676d59b66c7a575cfa8e01f483875d131e42b539bbcPierre Ossman{
677d59b66c7a575cfa8e01f483875d131e42b539bbcPierre Ossman	id->class = TO_NATIVE(id->class);
678d59b66c7a575cfa8e01f483875d131e42b539bbcPierre Ossman	id->vendor = TO_NATIVE(id->vendor);
679d59b66c7a575cfa8e01f483875d131e42b539bbcPierre Ossman	id->device = TO_NATIVE(id->device);
680d59b66c7a575cfa8e01f483875d131e42b539bbcPierre Ossman
681d59b66c7a575cfa8e01f483875d131e42b539bbcPierre Ossman	strcpy(alias, "sdio:");
682d59b66c7a575cfa8e01f483875d131e42b539bbcPierre Ossman	ADD(alias, "c", id->class != (__u8)SDIO_ANY_ID, id->class);
683d59b66c7a575cfa8e01f483875d131e42b539bbcPierre Ossman	ADD(alias, "v", id->vendor != (__u16)SDIO_ANY_ID, id->vendor);
684d59b66c7a575cfa8e01f483875d131e42b539bbcPierre Ossman	ADD(alias, "d", id->device != (__u16)SDIO_ANY_ID, id->device);
685ac551828993eecb8499ef9cc3c828fceb49bcf7aJean Delvare	add_wildcard(alias);
686038a5008b2f395c85e6e71d6ddf3c684e7c405b0Linus Torvalds	return 1;
687038a5008b2f395c85e6e71d6ddf3c684e7c405b0Linus Torvalds}
688038a5008b2f395c85e6e71d6ddf3c684e7c405b0Linus Torvalds
68961e115a56d1aafd6e6a8a9fee8ac099a6128ac7bMichael Buesch/* Looks like: ssb:vNidNrevN. */
69061e115a56d1aafd6e6a8a9fee8ac099a6128ac7bMichael Bueschstatic int do_ssb_entry(const char *filename,
69161e115a56d1aafd6e6a8a9fee8ac099a6128ac7bMichael Buesch			struct ssb_device_id *id, char *alias)
69261e115a56d1aafd6e6a8a9fee8ac099a6128ac7bMichael Buesch{
69361e115a56d1aafd6e6a8a9fee8ac099a6128ac7bMichael Buesch	id->vendor = TO_NATIVE(id->vendor);
69461e115a56d1aafd6e6a8a9fee8ac099a6128ac7bMichael Buesch	id->coreid = TO_NATIVE(id->coreid);
69561e115a56d1aafd6e6a8a9fee8ac099a6128ac7bMichael Buesch	id->revision = TO_NATIVE(id->revision);
696d59b66c7a575cfa8e01f483875d131e42b539bbcPierre Ossman
69761e115a56d1aafd6e6a8a9fee8ac099a6128ac7bMichael Buesch	strcpy(alias, "ssb:");
69861e115a56d1aafd6e6a8a9fee8ac099a6128ac7bMichael Buesch	ADD(alias, "v", id->vendor != SSB_ANY_VENDOR, id->vendor);
69961e115a56d1aafd6e6a8a9fee8ac099a6128ac7bMichael Buesch	ADD(alias, "id", id->coreid != SSB_ANY_ID, id->coreid);
70061e115a56d1aafd6e6a8a9fee8ac099a6128ac7bMichael Buesch	ADD(alias, "rev", id->revision != SSB_ANY_REV, id->revision);
701ac551828993eecb8499ef9cc3c828fceb49bcf7aJean Delvare	add_wildcard(alias);
702d59b66c7a575cfa8e01f483875d131e42b539bbcPierre Ossman	return 1;
703d59b66c7a575cfa8e01f483875d131e42b539bbcPierre Ossman}
704d59b66c7a575cfa8e01f483875d131e42b539bbcPierre Ossman
7058369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki/* Looks like: bcma:mNidNrevNclN. */
7068369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłeckistatic int do_bcma_entry(const char *filename,
7078369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki			 struct bcma_device_id *id, char *alias)
7088369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki{
7098369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki	id->manuf = TO_NATIVE(id->manuf);
7108369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki	id->id = TO_NATIVE(id->id);
7118369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki	id->rev = TO_NATIVE(id->rev);
7128369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki	id->class = TO_NATIVE(id->class);
7138369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki
7148369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki	strcpy(alias, "bcma:");
7158369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki	ADD(alias, "m", id->manuf != BCMA_ANY_MANUF, id->manuf);
7168369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki	ADD(alias, "id", id->id != BCMA_ANY_ID, id->id);
7178369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki	ADD(alias, "rev", id->rev != BCMA_ANY_REV, id->rev);
7188369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki	ADD(alias, "cl", id->class != BCMA_ANY_CLASS, id->class);
7198369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki	add_wildcard(alias);
7208369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki	return 1;
7218369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki}
7228369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki
723b01d9f2863349b0e041b90c3c86a998ee0fed2b0Rusty Russell/* Looks like: virtio:dNvN */
724b01d9f2863349b0e041b90c3c86a998ee0fed2b0Rusty Russellstatic int do_virtio_entry(const char *filename, struct virtio_device_id *id,
725b01d9f2863349b0e041b90c3c86a998ee0fed2b0Rusty Russell			   char *alias)
726b01d9f2863349b0e041b90c3c86a998ee0fed2b0Rusty Russell{
727b01d9f2863349b0e041b90c3c86a998ee0fed2b0Rusty Russell	id->device = TO_NATIVE(id->device);
728b01d9f2863349b0e041b90c3c86a998ee0fed2b0Rusty Russell	id->vendor = TO_NATIVE(id->vendor);
729b01d9f2863349b0e041b90c3c86a998ee0fed2b0Rusty Russell
730b01d9f2863349b0e041b90c3c86a998ee0fed2b0Rusty Russell	strcpy(alias, "virtio:");
731e3353853730eb99c56b7b0aed1667d51c0e3699aChristian Borntraeger	ADD(alias, "d", id->device != VIRTIO_DEV_ANY_ID, id->device);
732b01d9f2863349b0e041b90c3c86a998ee0fed2b0Rusty Russell	ADD(alias, "v", id->vendor != VIRTIO_DEV_ANY_ID, id->vendor);
733b01d9f2863349b0e041b90c3c86a998ee0fed2b0Rusty Russell
734ac551828993eecb8499ef9cc3c828fceb49bcf7aJean Delvare	add_wildcard(alias);
735b01d9f2863349b0e041b90c3c86a998ee0fed2b0Rusty Russell	return 1;
736b01d9f2863349b0e041b90c3c86a998ee0fed2b0Rusty Russell}
737b01d9f2863349b0e041b90c3c86a998ee0fed2b0Rusty Russell
738d2653e92732bd3911feff6bee5e23dbf959381dbJean Delvare/* Looks like: i2c:S */
739d2653e92732bd3911feff6bee5e23dbf959381dbJean Delvarestatic int do_i2c_entry(const char *filename, struct i2c_device_id *id,
740d2653e92732bd3911feff6bee5e23dbf959381dbJean Delvare			char *alias)
741d2653e92732bd3911feff6bee5e23dbf959381dbJean Delvare{
742d2653e92732bd3911feff6bee5e23dbf959381dbJean Delvare	sprintf(alias, I2C_MODULE_PREFIX "%s", id->name);
743d2653e92732bd3911feff6bee5e23dbf959381dbJean Delvare
744d2653e92732bd3911feff6bee5e23dbf959381dbJean Delvare	return 1;
745d2653e92732bd3911feff6bee5e23dbf959381dbJean Delvare}
746d2653e92732bd3911feff6bee5e23dbf959381dbJean Delvare
747e0626e3844e8f430fc1a4417f523a00797df7ca6Anton Vorontsov/* Looks like: spi:S */
74875368bf6c2876d8f33abfe77aa3864869a3893ebAnton Vorontsovstatic int do_spi_entry(const char *filename, struct spi_device_id *id,
74975368bf6c2876d8f33abfe77aa3864869a3893ebAnton Vorontsov			char *alias)
75075368bf6c2876d8f33abfe77aa3864869a3893ebAnton Vorontsov{
751e0626e3844e8f430fc1a4417f523a00797df7ca6Anton Vorontsov	sprintf(alias, SPI_MODULE_PREFIX "%s", id->name);
75275368bf6c2876d8f33abfe77aa3864869a3893ebAnton Vorontsov
75375368bf6c2876d8f33abfe77aa3864869a3893ebAnton Vorontsov	return 1;
75475368bf6c2876d8f33abfe77aa3864869a3893ebAnton Vorontsov}
75575368bf6c2876d8f33abfe77aa3864869a3893ebAnton Vorontsov
756d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhousestatic const struct dmifield {
757d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse	const char *prefix;
758d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse	int field;
759d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse} dmi_fields[] = {
760d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse	{ "bvn", DMI_BIOS_VENDOR },
761d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse	{ "bvr", DMI_BIOS_VERSION },
762d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse	{ "bd",  DMI_BIOS_DATE },
763d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse	{ "svn", DMI_SYS_VENDOR },
764d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse	{ "pn",  DMI_PRODUCT_NAME },
765d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse	{ "pvr", DMI_PRODUCT_VERSION },
766d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse	{ "rvn", DMI_BOARD_VENDOR },
767d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse	{ "rn",  DMI_BOARD_NAME },
768d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse	{ "rvr", DMI_BOARD_VERSION },
769d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse	{ "cvn", DMI_CHASSIS_VENDOR },
770d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse	{ "ct",  DMI_CHASSIS_TYPE },
771d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse	{ "cvr", DMI_CHASSIS_VERSION },
772d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse	{ NULL,  DMI_NONE }
773d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse};
774d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse
775d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhousestatic void dmi_ascii_filter(char *d, const char *s)
776d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse{
777d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse	/* Filter out characters we don't want to see in the modalias string */
778d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse	for (; *s; s++)
779d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse		if (*s > ' ' && *s < 127 && *s != ':')
780d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse			*(d++) = *s;
781d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse
782d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse	*d = 0;
783d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse}
784d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse
785d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse
786d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhousestatic int do_dmi_entry(const char *filename, struct dmi_system_id *id,
787d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse			char *alias)
788d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse{
789d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse	int i, j;
790d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse
791d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse	sprintf(alias, "dmi*");
792d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse
793d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse	for (i = 0; i < ARRAY_SIZE(dmi_fields); i++) {
794d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse		for (j = 0; j < 4; j++) {
795d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse			if (id->matches[j].slot &&
796d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse			    id->matches[j].slot == dmi_fields[i].field) {
797d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse				sprintf(alias + strlen(alias), ":%s*",
798d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse					dmi_fields[i].prefix);
799d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse				dmi_ascii_filter(alias + strlen(alias),
800d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse						 id->matches[j].substr);
801d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse				strcat(alias, "*");
802d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse			}
803d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse		}
804d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse	}
805d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse
806d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse	strcat(alias, ":");
807d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse	return 1;
808d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse}
80957fee4a58fe802272742caae248872c392a60670Eric Miao
81057fee4a58fe802272742caae248872c392a60670Eric Miaostatic int do_platform_entry(const char *filename,
81157fee4a58fe802272742caae248872c392a60670Eric Miao			     struct platform_device_id *id, char *alias)
81257fee4a58fe802272742caae248872c392a60670Eric Miao{
81357fee4a58fe802272742caae248872c392a60670Eric Miao	sprintf(alias, PLATFORM_MODULE_PREFIX "%s", id->name);
81457fee4a58fe802272742caae248872c392a60670Eric Miao	return 1;
81557fee4a58fe802272742caae248872c392a60670Eric Miao}
81657fee4a58fe802272742caae248872c392a60670Eric Miao
8178626d3b4328061f5b82b11ae1d6918a0c3602f42David Woodhousestatic int do_mdio_entry(const char *filename,
8188626d3b4328061f5b82b11ae1d6918a0c3602f42David Woodhouse			 struct mdio_device_id *id, char *alias)
8198626d3b4328061f5b82b11ae1d6918a0c3602f42David Woodhouse{
8208626d3b4328061f5b82b11ae1d6918a0c3602f42David Woodhouse	int i;
8218626d3b4328061f5b82b11ae1d6918a0c3602f42David Woodhouse
8228626d3b4328061f5b82b11ae1d6918a0c3602f42David Woodhouse	alias += sprintf(alias, MDIO_MODULE_PREFIX);
8238626d3b4328061f5b82b11ae1d6918a0c3602f42David Woodhouse
8248626d3b4328061f5b82b11ae1d6918a0c3602f42David Woodhouse	for (i = 0; i < 32; i++) {
8258626d3b4328061f5b82b11ae1d6918a0c3602f42David Woodhouse		if (!((id->phy_id_mask >> (31-i)) & 1))
8268626d3b4328061f5b82b11ae1d6918a0c3602f42David Woodhouse			*(alias++) = '?';
8278626d3b4328061f5b82b11ae1d6918a0c3602f42David Woodhouse		else if ((id->phy_id >> (31-i)) & 1)
8288626d3b4328061f5b82b11ae1d6918a0c3602f42David Woodhouse			*(alias++) = '1';
8298626d3b4328061f5b82b11ae1d6918a0c3602f42David Woodhouse		else
8308626d3b4328061f5b82b11ae1d6918a0c3602f42David Woodhouse			*(alias++) = '0';
8318626d3b4328061f5b82b11ae1d6918a0c3602f42David Woodhouse	}
8328626d3b4328061f5b82b11ae1d6918a0c3602f42David Woodhouse
8338626d3b4328061f5b82b11ae1d6918a0c3602f42David Woodhouse	/* Terminate the string */
8348626d3b4328061f5b82b11ae1d6918a0c3602f42David Woodhouse	*alias = 0;
8358626d3b4328061f5b82b11ae1d6918a0c3602f42David Woodhouse
8368626d3b4328061f5b82b11ae1d6918a0c3602f42David Woodhouse	return 1;
8378626d3b4328061f5b82b11ae1d6918a0c3602f42David Woodhouse}
8388626d3b4328061f5b82b11ae1d6918a0c3602f42David Woodhouse
839bf54a2b3c0dbf76136f00ff785bf6d8f6291311dGeert Uytterhoeven/* Looks like: zorro:iN. */
840bf54a2b3c0dbf76136f00ff785bf6d8f6291311dGeert Uytterhoevenstatic int do_zorro_entry(const char *filename, struct zorro_device_id *id,
841bf54a2b3c0dbf76136f00ff785bf6d8f6291311dGeert Uytterhoeven			  char *alias)
842bf54a2b3c0dbf76136f00ff785bf6d8f6291311dGeert Uytterhoeven{
843bf54a2b3c0dbf76136f00ff785bf6d8f6291311dGeert Uytterhoeven	id->id = TO_NATIVE(id->id);
844bf54a2b3c0dbf76136f00ff785bf6d8f6291311dGeert Uytterhoeven	strcpy(alias, "zorro:");
845bf54a2b3c0dbf76136f00ff785bf6d8f6291311dGeert Uytterhoeven	ADD(alias, "i", id->id != ZORRO_WILDCARD, id->id);
846bf54a2b3c0dbf76136f00ff785bf6d8f6291311dGeert Uytterhoeven	return 1;
847bf54a2b3c0dbf76136f00ff785bf6d8f6291311dGeert Uytterhoeven}
848bf54a2b3c0dbf76136f00ff785bf6d8f6291311dGeert Uytterhoeven
849fedb3d27d9e8606b3867b5ae49d6258458a07a72Ondrej Zary/* looks like: "pnp:dD" */
850fedb3d27d9e8606b3867b5ae49d6258458a07a72Ondrej Zarystatic int do_isapnp_entry(const char *filename,
851fedb3d27d9e8606b3867b5ae49d6258458a07a72Ondrej Zary			   struct isapnp_device_id *id, char *alias)
852fedb3d27d9e8606b3867b5ae49d6258458a07a72Ondrej Zary{
853fedb3d27d9e8606b3867b5ae49d6258458a07a72Ondrej Zary	sprintf(alias, "pnp:d%c%c%c%x%x%x%x*",
854fedb3d27d9e8606b3867b5ae49d6258458a07a72Ondrej Zary		'A' + ((id->vendor >> 2) & 0x3f) - 1,
855fedb3d27d9e8606b3867b5ae49d6258458a07a72Ondrej Zary		'A' + (((id->vendor & 3) << 3) | ((id->vendor >> 13) & 7)) - 1,
856fedb3d27d9e8606b3867b5ae49d6258458a07a72Ondrej Zary		'A' + ((id->vendor >> 8) & 0x1f) - 1,
857fedb3d27d9e8606b3867b5ae49d6258458a07a72Ondrej Zary		(id->function >> 4) & 0x0f, id->function & 0x0f,
858fedb3d27d9e8606b3867b5ae49d6258458a07a72Ondrej Zary		(id->function >> 12) & 0x0f, (id->function >> 8) & 0x0f);
859fedb3d27d9e8606b3867b5ae49d6258458a07a72Ondrej Zary	return 1;
860fedb3d27d9e8606b3867b5ae49d6258458a07a72Ondrej Zary}
861fedb3d27d9e8606b3867b5ae49d6258458a07a72Ondrej Zary
862f606ddf42fd4edc558eeb48bfee66d2c591571d2Adrian Bunk/* Ignore any prefix, eg. some architectures prepend _ */
8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline int sym_is(const char *symbol, const char *name)
8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	const char *match;
8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	match = strstr(symbol, name);
8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!match)
8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
8703a5dd791abef032fe57fc652c0232913c696e59bMike Frysinger	return match[strlen(name)] == '\0';
8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void do_table(void *symval, unsigned long size,
8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     unsigned long id_size,
875fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg		     const char *device_id,
8761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     void *function,
8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     struct module *mod)
8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int i;
8801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char alias[500];
8811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int (*do_entry)(const char *, void *entry, char *alias) = function;
8821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
883e00498258c215b46bd24f12ab3a2ed1bcb4772feKees Cook	device_id_check(mod->name, device_id, size, id_size, symval);
8841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Leave last one: it's the terminator. */
8851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	size -= id_size;
8861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 0; i < size; i += id_size) {
8881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (do_entry(mod->name, symval+i, alias)) {
8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			buf_printf(&mod->dev_table_buf,
8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				   "MODULE_ALIAS(\"%s\");\n", alias);
8911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Create MODULE_ALIAS() statements.
8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * At this time, we cannot write the actual output C source yet,
8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * so we write into the mod->dev_table_buf buffer. */
8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid handle_moddevtable(struct module *mod, struct elf_info *info,
8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			Elf_Sym *sym, const char *symname)
9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	void *symval;
902e00498258c215b46bd24f12ab3a2ed1bcb4772feKees Cook	char *zeros = NULL;
9031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* We're looking for a section relative symbol */
9051ce53adf13a54375d2a5c7cdbe341b2558389615Denys Vlasenko	if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections)
9061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
9071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9089239fabf848397ec26356b5f267c787840ba4bb7David Miller	/* We're looking for an object */
9099239fabf848397ec26356b5f267c787840ba4bb7David Miller	if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT)
9109239fabf848397ec26356b5f267c787840ba4bb7David Miller		return;
9119239fabf848397ec26356b5f267c787840ba4bb7David Miller
912e00498258c215b46bd24f12ab3a2ed1bcb4772feKees Cook	/* Handle all-NULL symbols allocated into .bss */
9131ce53adf13a54375d2a5c7cdbe341b2558389615Denys Vlasenko	if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) {
914e00498258c215b46bd24f12ab3a2ed1bcb4772feKees Cook		zeros = calloc(1, sym->st_size);
915e00498258c215b46bd24f12ab3a2ed1bcb4772feKees Cook		symval = zeros;
916e00498258c215b46bd24f12ab3a2ed1bcb4772feKees Cook	} else {
917e00498258c215b46bd24f12ab3a2ed1bcb4772feKees Cook		symval = (void *)info->hdr
9181ce53adf13a54375d2a5c7cdbe341b2558389615Denys Vlasenko			+ info->sechdrs[get_secindex(info, sym)].sh_offset
919e00498258c215b46bd24f12ab3a2ed1bcb4772feKees Cook			+ sym->st_value;
920e00498258c215b46bd24f12ab3a2ed1bcb4772feKees Cook	}
9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
9221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (sym_is(symname, "__mod_pci_device_table"))
923fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg		do_table(symval, sym->st_size,
924fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg			 sizeof(struct pci_device_id), "pci",
9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 do_pci_entry, mod);
9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else if (sym_is(symname, "__mod_usb_device_table"))
927b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan		/* special case to handle bcdDevice ranges */
928b19dcd9341a81ff6e04fcec396f77eeb91570584Roman Kagan		do_usb_table(symval, sym->st_size, mod);
929e8c84f9a5f06912c94c38961096c994da3890a2eJiri Slaby	else if (sym_is(symname, "__mod_hid_device_table"))
930e8c84f9a5f06912c94c38961096c994da3890a2eJiri Slaby		do_table(symval, sym->st_size,
931e8c84f9a5f06912c94c38961096c994da3890a2eJiri Slaby			 sizeof(struct hid_device_id), "hid",
932e8c84f9a5f06912c94c38961096c994da3890a2eJiri Slaby			 do_hid_entry, mod);
9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else if (sym_is(symname, "__mod_ieee1394_device_table"))
934fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg		do_table(symval, sym->st_size,
935fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg			 sizeof(struct ieee1394_device_id), "ieee1394",
9361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 do_ieee1394_entry, mod);
9371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else if (sym_is(symname, "__mod_ccw_device_table"))
938fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg		do_table(symval, sym->st_size,
939fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg			 sizeof(struct ccw_device_id), "ccw",
9401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 do_ccw_entry, mod);
9411534c3820c26aca4e2567f97b8add8bea40e7e2bMartin Schwidefsky	else if (sym_is(symname, "__mod_ap_device_table"))
9421534c3820c26aca4e2567f97b8add8bea40e7e2bMartin Schwidefsky		do_table(symval, sym->st_size,
9431534c3820c26aca4e2567f97b8add8bea40e7e2bMartin Schwidefsky			 sizeof(struct ap_device_id), "ap",
9441534c3820c26aca4e2567f97b8add8bea40e7e2bMartin Schwidefsky			 do_ap_entry, mod);
9457e9db9eaefdb8798730790214ff1b7746006ec98Cornelia Huck	else if (sym_is(symname, "__mod_css_device_table"))
9467e9db9eaefdb8798730790214ff1b7746006ec98Cornelia Huck		do_table(symval, sym->st_size,
9477e9db9eaefdb8798730790214ff1b7746006ec98Cornelia Huck			 sizeof(struct css_device_id), "css",
9487e9db9eaefdb8798730790214ff1b7746006ec98Cornelia Huck			 do_css_entry, mod);
9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else if (sym_is(symname, "__mod_serio_device_table"))
950fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg		do_table(symval, sym->st_size,
951fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg			 sizeof(struct serio_device_id), "serio",
9521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 do_serio_entry, mod);
95329b71a1ca74491fab9fed09e9d835d840d042690Thomas Renninger	else if (sym_is(symname, "__mod_acpi_device_table"))
95429b71a1ca74491fab9fed09e9d835d840d042690Thomas Renninger		do_table(symval, sym->st_size,
95529b71a1ca74491fab9fed09e9d835d840d042690Thomas Renninger			 sizeof(struct acpi_device_id), "acpi",
95629b71a1ca74491fab9fed09e9d835d840d042690Thomas Renninger			 do_acpi_entry, mod);
9571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else if (sym_is(symname, "__mod_pnp_device_table"))
95822454cb99fc39f2629ad06a7eccb3df312f8830eKay Sievers		do_pnp_device_entry(symval, sym->st_size, mod);
9591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else if (sym_is(symname, "__mod_pnp_card_device_table"))
9600c81eed4b9d6273124c7ab5eb99760b4d3a3cb9eKay Sievers		do_pnp_card_entries(symval, sym->st_size, mod);
96190829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski	else if (sym_is(symname, "__mod_pcmcia_device_table"))
962fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg		do_table(symval, sym->st_size,
963fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg			 sizeof(struct pcmcia_device_id), "pcmcia",
96490829cfe1df2466c98a831f6c44f71026665cec1Dominik Brodowski			 do_pcmcia_entry, mod);
9655e6557722e69840506eb8bc5a1edcdb4e447a917Jeff Mahoney        else if (sym_is(symname, "__mod_of_device_table"))
966fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg		do_table(symval, sym->st_size,
967fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg			 sizeof(struct of_device_id), "of",
9685e6557722e69840506eb8bc5a1edcdb4e447a917Jeff Mahoney			 do_of_entry, mod);
969fb120da678c517f72d4b39932062c2191827b331Stephen Rothwell        else if (sym_is(symname, "__mod_vio_device_table"))
970fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg		do_table(symval, sym->st_size,
971fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg			 sizeof(struct vio_device_id), "vio",
972fb120da678c517f72d4b39932062c2191827b331Stephen Rothwell			 do_vio_entry, mod);
9731d8f430c15b3a345db990e285742c67c2f52f9a6Rusty Russell	else if (sym_is(symname, "__mod_input_device_table"))
974fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg		do_table(symval, sym->st_size,
975fb33d81613a4e3e27972a65b6e566de50a447d33Sam Ravnborg			 sizeof(struct input_device_id), "input",
9761d8f430c15b3a345db990e285742c67c2f52f9a6Rusty Russell			 do_input_entry, mod);
97707563c711fbc25389e58ab9c9f0b9de2fce56760Michael Tokarev	else if (sym_is(symname, "__mod_eisa_device_table"))
97807563c711fbc25389e58ab9c9f0b9de2fce56760Michael Tokarev		do_table(symval, sym->st_size,
97907563c711fbc25389e58ab9c9f0b9de2fce56760Michael Tokarev			 sizeof(struct eisa_device_id), "eisa",
98007563c711fbc25389e58ab9c9f0b9de2fce56760Michael Tokarev			 do_eisa_entry, mod);
981f3cf2673358e4221afbb59721a8580a8f35479a5Kyle McMartin	else if (sym_is(symname, "__mod_parisc_device_table"))
982f3cf2673358e4221afbb59721a8580a8f35479a5Kyle McMartin		do_table(symval, sym->st_size,
983f3cf2673358e4221afbb59721a8580a8f35479a5Kyle McMartin			 sizeof(struct parisc_device_id), "parisc",
984f3cf2673358e4221afbb59721a8580a8f35479a5Kyle McMartin			 do_parisc_entry, mod);
985d59b66c7a575cfa8e01f483875d131e42b539bbcPierre Ossman	else if (sym_is(symname, "__mod_sdio_device_table"))
986d59b66c7a575cfa8e01f483875d131e42b539bbcPierre Ossman		do_table(symval, sym->st_size,
987d59b66c7a575cfa8e01f483875d131e42b539bbcPierre Ossman			 sizeof(struct sdio_device_id), "sdio",
988d59b66c7a575cfa8e01f483875d131e42b539bbcPierre Ossman			 do_sdio_entry, mod);
98961e115a56d1aafd6e6a8a9fee8ac099a6128ac7bMichael Buesch	else if (sym_is(symname, "__mod_ssb_device_table"))
99061e115a56d1aafd6e6a8a9fee8ac099a6128ac7bMichael Buesch		do_table(symval, sym->st_size,
99161e115a56d1aafd6e6a8a9fee8ac099a6128ac7bMichael Buesch			 sizeof(struct ssb_device_id), "ssb",
99261e115a56d1aafd6e6a8a9fee8ac099a6128ac7bMichael Buesch			 do_ssb_entry, mod);
9938369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki	else if (sym_is(symname, "__mod_bcma_device_table"))
9948369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki		do_table(symval, sym->st_size,
9958369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki			 sizeof(struct bcma_device_id), "bcma",
9968369ae33b705222aa05ab53c7d6b4458f4ed161bRafał Miłecki			 do_bcma_entry, mod);
997b01d9f2863349b0e041b90c3c86a998ee0fed2b0Rusty Russell	else if (sym_is(symname, "__mod_virtio_device_table"))
998b01d9f2863349b0e041b90c3c86a998ee0fed2b0Rusty Russell		do_table(symval, sym->st_size,
999b01d9f2863349b0e041b90c3c86a998ee0fed2b0Rusty Russell			 sizeof(struct virtio_device_id), "virtio",
1000b01d9f2863349b0e041b90c3c86a998ee0fed2b0Rusty Russell			 do_virtio_entry, mod);
1001d2653e92732bd3911feff6bee5e23dbf959381dbJean Delvare	else if (sym_is(symname, "__mod_i2c_device_table"))
1002d2653e92732bd3911feff6bee5e23dbf959381dbJean Delvare		do_table(symval, sym->st_size,
1003d2653e92732bd3911feff6bee5e23dbf959381dbJean Delvare			 sizeof(struct i2c_device_id), "i2c",
1004d2653e92732bd3911feff6bee5e23dbf959381dbJean Delvare			 do_i2c_entry, mod);
100575368bf6c2876d8f33abfe77aa3864869a3893ebAnton Vorontsov	else if (sym_is(symname, "__mod_spi_device_table"))
100675368bf6c2876d8f33abfe77aa3864869a3893ebAnton Vorontsov		do_table(symval, sym->st_size,
100775368bf6c2876d8f33abfe77aa3864869a3893ebAnton Vorontsov			 sizeof(struct spi_device_id), "spi",
100875368bf6c2876d8f33abfe77aa3864869a3893ebAnton Vorontsov			 do_spi_entry, mod);
1009d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse	else if (sym_is(symname, "__mod_dmi_device_table"))
1010d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse		do_table(symval, sym->st_size,
1011d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse			 sizeof(struct dmi_system_id), "dmi",
1012d945b697d0eea5a811ec299c5f1a25889bb0242bDavid Woodhouse			 do_dmi_entry, mod);
101357fee4a58fe802272742caae248872c392a60670Eric Miao	else if (sym_is(symname, "__mod_platform_device_table"))
101457fee4a58fe802272742caae248872c392a60670Eric Miao		do_table(symval, sym->st_size,
101557fee4a58fe802272742caae248872c392a60670Eric Miao			 sizeof(struct platform_device_id), "platform",
101657fee4a58fe802272742caae248872c392a60670Eric Miao			 do_platform_entry, mod);
10178626d3b4328061f5b82b11ae1d6918a0c3602f42David Woodhouse	else if (sym_is(symname, "__mod_mdio_device_table"))
10188626d3b4328061f5b82b11ae1d6918a0c3602f42David Woodhouse		do_table(symval, sym->st_size,
10198626d3b4328061f5b82b11ae1d6918a0c3602f42David Woodhouse			 sizeof(struct mdio_device_id), "mdio",
10208626d3b4328061f5b82b11ae1d6918a0c3602f42David Woodhouse			 do_mdio_entry, mod);
1021bf54a2b3c0dbf76136f00ff785bf6d8f6291311dGeert Uytterhoeven	else if (sym_is(symname, "__mod_zorro_device_table"))
1022bf54a2b3c0dbf76136f00ff785bf6d8f6291311dGeert Uytterhoeven		do_table(symval, sym->st_size,
1023bf54a2b3c0dbf76136f00ff785bf6d8f6291311dGeert Uytterhoeven			 sizeof(struct zorro_device_id), "zorro",
1024bf54a2b3c0dbf76136f00ff785bf6d8f6291311dGeert Uytterhoeven			 do_zorro_entry, mod);
1025fedb3d27d9e8606b3867b5ae49d6258458a07a72Ondrej Zary	else if (sym_is(symname, "__mod_isapnp_device_table"))
1026fedb3d27d9e8606b3867b5ae49d6258458a07a72Ondrej Zary		do_table(symval, sym->st_size,
1027fedb3d27d9e8606b3867b5ae49d6258458a07a72Ondrej Zary			sizeof(struct isapnp_device_id), "isa",
1028fedb3d27d9e8606b3867b5ae49d6258458a07a72Ondrej Zary			do_isapnp_entry, mod);
1029e00498258c215b46bd24f12ab3a2ed1bcb4772feKees Cook	free(zeros);
10301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
10311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Now add out buffered information to the generated C source */
10331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid add_moddevtable(struct buffer *buf, struct module *mod)
10341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
10351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf_printf(buf, "\n");
10361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	buf_write(buf, mod->dev_table_buf.p, mod->dev_table_buf.pos);
10371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	free(mod->dev_table_buf.p);
10381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1039