Blame view

scripts/mod/file2alias.c 32.6 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  /* Simple code to turn various tables in an ELF file into alias definitions.
   * This deals with kernel datastructures where they should be
   * dealt with: in the kernel source.
   *
   * Copyright 2002-2003  Rusty Russell, IBM Corporation
   *           2003       Kai Germaschewski
   *
   *
   * This software may be used and distributed according to the terms
   * of the GNU General Public License, incorporated herein by reference.
   */
  
  #include "modpost.h"
  
  /* We use the ELF typedefs for kernel_ulong_t but bite the bullet and
   * use either stdint.h or inttypes.h for the rest. */
  #if KERNEL_ELFCLASS == ELFCLASS32
  typedef Elf32_Addr	kernel_ulong_t;
1d8f430c1   Rusty Russell   [PATCH] Input: ad...
19
  #define BITS_PER_LONG 32
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
20
21
  #else
  typedef Elf64_Addr	kernel_ulong_t;
1d8f430c1   Rusty Russell   [PATCH] Input: ad...
22
  #define BITS_PER_LONG 64
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
23
24
25
26
27
28
  #endif
  #ifdef __sun__
  #include <inttypes.h>
  #else
  #include <stdint.h>
  #endif
5e6557722   Jeff Mahoney   [PATCH] openfirmw...
29
  #include <ctype.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30
31
32
33
34
  typedef uint32_t	__u32;
  typedef uint16_t	__u16;
  typedef unsigned char	__u8;
  
  /* Big exception to the "don't include kernel headers into userspace, which
62070fa42   Sam Ravnborg   kbuild: kill trai...
35
   * even potentially has different endianness and word sizes, since
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
   * we handle those differences explicitly below */
  #include "../../include/linux/mod_devicetable.h"
  
  #define ADD(str, sep, cond, field)                              \
  do {                                                            \
          strcat(str, sep);                                       \
          if (cond)                                               \
                  sprintf(str + strlen(str),                      \
                          sizeof(field) == 1 ? "%02X" :           \
                          sizeof(field) == 2 ? "%04X" :           \
                          sizeof(field) == 4 ? "%08X" : "",       \
                          field);                                 \
          else                                                    \
                  sprintf(str + strlen(str), "*");                \
  } while(0)
ac5518289   Jean Delvare   modpost: i2c alia...
51
52
53
54
55
56
57
58
  /* Always end in a wildcard, for future extension */
  static inline void add_wildcard(char *str)
  {
  	int len = strlen(str);
  
  	if (str[len - 1] != '*')
  		strcat(str + len, "*");
  }
4ce6efed4   Sam Ravnborg   kbuild: soften mo...
59
  unsigned int cross_build = 0;
fb33d8161   Sam Ravnborg   kbuild: improve e...
60
61
62
63
  /**
   * Check that sizeof(device_id type) are consistent with size of section
   * in .o file. If in-consistent then userspace and kernel does not agree
   * on actual size which is a bug.
e00498258   Kees Cook   kbuild: make modp...
64
   * Also verify that the final entry in the table is all zeros.
4ce6efed4   Sam Ravnborg   kbuild: soften mo...
65
   * Ignore both checks if build host differ from target host and size differs.
fb33d8161   Sam Ravnborg   kbuild: improve e...
66
   **/
e00498258   Kees Cook   kbuild: make modp...
67
68
69
  static void device_id_check(const char *modname, const char *device_id,
  			    unsigned long size, unsigned long id_size,
  			    void *symval)
fb33d8161   Sam Ravnborg   kbuild: improve e...
70
  {
e00498258   Kees Cook   kbuild: make modp...
71
  	int i;
fb33d8161   Sam Ravnborg   kbuild: improve e...
72
  	if (size % id_size || size < id_size) {
4ce6efed4   Sam Ravnborg   kbuild: soften mo...
73
74
  		if (cross_build != 0)
  			return;
fb33d8161   Sam Ravnborg   kbuild: improve e...
75
76
77
78
79
80
81
82
  		fatal("%s: sizeof(struct %s_device_id)=%lu is not a modulo "
  		      "of the size of section __mod_%s_device_table=%lu.
  "
  		      "Fix definition of struct %s_device_id "
  		      "in mod_devicetable.h
  ",
  		      modname, device_id, id_size, device_id, size, device_id);
  	}
e00498258   Kees Cook   kbuild: make modp...
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
  	/* Verify last one is a terminator */
  	for (i = 0; i < id_size; i++ ) {
  		if (*(uint8_t*)(symval+size-id_size+i)) {
  			fprintf(stderr,"%s: struct %s_device_id is %lu bytes.  "
  				"The last of %lu is:
  ",
  				modname, device_id, id_size, size / id_size);
  			for (i = 0; i < id_size; i++ )
  				fprintf(stderr,"0x%02x ",
  					*(uint8_t*)(symval+size-id_size+i) );
  			fprintf(stderr,"
  ");
  			fatal("%s: struct %s_device_id is not terminated "
  				"with a NULL entry!
  ", modname, device_id);
  		}
  	}
fb33d8161   Sam Ravnborg   kbuild: improve e...
100
  }
b19dcd934   Roman Kagan   [PATCH] USB: scri...
101
102
103
104
105
  /* USB is special because the bcdDevice can be matched against a numeric range */
  /* Looks like "usb:vNpNdNdcNdscNdpNicNiscNipN" */
  static void do_usb_entry(struct usb_device_id *id,
  			 unsigned int bcdDevice_initial, int bcdDevice_initial_digits,
  			 unsigned char range_lo, unsigned char range_hi,
afe2dab4f   Nathaniel McCallum   USB: add hex/bcd ...
106
  			 unsigned char max, struct module *mod)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
107
  {
b19dcd934   Roman Kagan   [PATCH] USB: scri...
108
  	char alias[500];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
109
110
111
112
113
  	strcpy(alias, "usb:");
  	ADD(alias, "v", id->match_flags&USB_DEVICE_ID_MATCH_VENDOR,
  	    id->idVendor);
  	ADD(alias, "p", id->match_flags&USB_DEVICE_ID_MATCH_PRODUCT,
  	    id->idProduct);
b19dcd934   Roman Kagan   [PATCH] USB: scri...
114
115
116
117
118
119
  
  	strcat(alias, "d");
  	if (bcdDevice_initial_digits)
  		sprintf(alias + strlen(alias), "%0*X",
  			bcdDevice_initial_digits, bcdDevice_initial);
  	if (range_lo == range_hi)
afe2dab4f   Nathaniel McCallum   USB: add hex/bcd ...
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
  		sprintf(alias + strlen(alias), "%X", range_lo);
  	else if (range_lo > 0 || range_hi < max) {
  		if (range_lo > 0x9 || range_hi < 0xA)
  			sprintf(alias + strlen(alias),
  				"[%X-%X]",
  				range_lo,
  				range_hi);
  		else {
  			sprintf(alias + strlen(alias),
  				range_lo < 0x9 ? "[%X-9" : "[%X",
  				range_lo);
  			sprintf(alias + strlen(alias),
  				range_hi > 0xA ? "a-%X]" : "%X]",
  				range_lo);
  		}
  	}
b19dcd934   Roman Kagan   [PATCH] USB: scri...
136
137
  	if (bcdDevice_initial_digits < (sizeof(id->bcdDevice_lo) * 2 - 1))
  		strcat(alias, "*");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
  	ADD(alias, "dc", id->match_flags&USB_DEVICE_ID_MATCH_DEV_CLASS,
  	    id->bDeviceClass);
  	ADD(alias, "dsc",
  	    id->match_flags&USB_DEVICE_ID_MATCH_DEV_SUBCLASS,
  	    id->bDeviceSubClass);
  	ADD(alias, "dp",
  	    id->match_flags&USB_DEVICE_ID_MATCH_DEV_PROTOCOL,
  	    id->bDeviceProtocol);
  	ADD(alias, "ic",
  	    id->match_flags&USB_DEVICE_ID_MATCH_INT_CLASS,
  	    id->bInterfaceClass);
  	ADD(alias, "isc",
  	    id->match_flags&USB_DEVICE_ID_MATCH_INT_SUBCLASS,
  	    id->bInterfaceSubClass);
  	ADD(alias, "ip",
  	    id->match_flags&USB_DEVICE_ID_MATCH_INT_PROTOCOL,
  	    id->bInterfaceProtocol);
b19dcd934   Roman Kagan   [PATCH] USB: scri...
155

ac5518289   Jean Delvare   modpost: i2c alia...
156
  	add_wildcard(alias);
b19dcd934   Roman Kagan   [PATCH] USB: scri...
157
158
159
160
  	buf_printf(&mod->dev_table_buf,
  		   "MODULE_ALIAS(\"%s\");
  ", alias);
  }
55f49f268   Nathaniel McCallum   USB: handle bcd i...
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
  /* Handles increment/decrement of BCD formatted integers */
  /* Returns the previous value, so it works like i++ or i-- */
  static unsigned int incbcd(unsigned int *bcd,
  			   int inc,
  			   unsigned char max,
  			   size_t chars)
  {
  	unsigned int init = *bcd, i, j;
  	unsigned long long c, dec = 0;
  
  	/* If bcd is not in BCD format, just increment */
  	if (max > 0x9) {
  		*bcd += inc;
  		return init;
  	}
  
  	/* Convert BCD to Decimal */
  	for (i=0 ; i < chars ; i++) {
  		c = (*bcd >> (i << 2)) & 0xf;
  		c = c > 9 ? 9 : c; /* force to bcd just in case */
  		for (j=0 ; j < i ; j++)
  			c = c * 10;
  		dec += c;
  	}
  
  	/* Do our increment/decrement */
  	dec += inc;
  	*bcd  = 0;
  
  	/* Convert back to BCD */
  	for (i=0 ; i < chars ; i++) {
  		for (c=1,j=0 ; j < i ; j++)
  			c = c * 10;
  		c = (dec / c) % 10;
  		*bcd += c << (i << 2);
  	}
  	return init;
  }
b19dcd934   Roman Kagan   [PATCH] USB: scri...
199
200
201
  static void do_usb_entry_multi(struct usb_device_id *id, struct module *mod)
  {
  	unsigned int devlo, devhi;
afe2dab4f   Nathaniel McCallum   USB: add hex/bcd ...
202
  	unsigned char chi, clo, max;
b19dcd934   Roman Kagan   [PATCH] USB: scri...
203
204
205
206
207
208
209
210
211
212
  	int ndigits;
  
  	id->match_flags = TO_NATIVE(id->match_flags);
  	id->idVendor = TO_NATIVE(id->idVendor);
  	id->idProduct = TO_NATIVE(id->idProduct);
  
  	devlo = id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO ?
  		TO_NATIVE(id->bcdDevice_lo) : 0x0U;
  	devhi = id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI ?
  		TO_NATIVE(id->bcdDevice_hi) : ~0x0U;
afe2dab4f   Nathaniel McCallum   USB: add hex/bcd ...
213
214
215
216
217
218
219
220
221
222
  	/* Figure out if this entry is in bcd or hex format */
  	max = 0x9; /* Default to decimal format */
  	for (ndigits = 0 ; ndigits < sizeof(id->bcdDevice_lo) * 2 ; ndigits++) {
  		clo = (devlo >> (ndigits << 2)) & 0xf;
  		chi = ((devhi > 0x9999 ? 0x9999 : devhi) >> (ndigits << 2)) & 0xf;
  		if (clo > max || chi > max) {
  			max = 0xf;
  			break;
  		}
  	}
b19dcd934   Roman Kagan   [PATCH] USB: scri...
223
224
225
226
  	/*
  	 * Some modules (visor) have empty slots as placeholder for
  	 * run-time specification that results in catch-all alias
  	 */
de6f92b9e   Greg Kroah-Hartman   USB: handle idVen...
227
  	if (!(id->idVendor | id->idProduct | id->bDeviceClass | id->bInterfaceClass))
b19dcd934   Roman Kagan   [PATCH] USB: scri...
228
229
230
231
232
233
  		return;
  
  	/* Convert numeric bcdDevice range into fnmatch-able pattern(s) */
  	for (ndigits = sizeof(id->bcdDevice_lo) * 2 - 1; devlo <= devhi; ndigits--) {
  		clo = devlo & 0xf;
  		chi = devhi & 0xf;
afe2dab4f   Nathaniel McCallum   USB: add hex/bcd ...
234
235
  		if (chi > max)	/* If we are in bcd mode, truncate if necessary */
  			chi = max;
b19dcd934   Roman Kagan   [PATCH] USB: scri...
236
237
238
239
  		devlo >>= 4;
  		devhi >>= 4;
  
  		if (devlo == devhi || !ndigits) {
afe2dab4f   Nathaniel McCallum   USB: add hex/bcd ...
240
  			do_usb_entry(id, devlo, ndigits, clo, chi, max, mod);
b19dcd934   Roman Kagan   [PATCH] USB: scri...
241
242
  			break;
  		}
afe2dab4f   Nathaniel McCallum   USB: add hex/bcd ...
243
  		if (clo > 0x0)
55f49f268   Nathaniel McCallum   USB: handle bcd i...
244
245
246
247
  			do_usb_entry(id,
  				     incbcd(&devlo, 1, max,
  					    sizeof(id->bcdDevice_lo) * 2),
  				     ndigits, clo, max, max, mod);
b19dcd934   Roman Kagan   [PATCH] USB: scri...
248

afe2dab4f   Nathaniel McCallum   USB: add hex/bcd ...
249
  		if (chi < max)
55f49f268   Nathaniel McCallum   USB: handle bcd i...
250
251
252
253
  			do_usb_entry(id,
  				     incbcd(&devhi, -1, max,
  					    sizeof(id->bcdDevice_lo) * 2),
  				     ndigits, 0x0, chi, max, mod);
b19dcd934   Roman Kagan   [PATCH] USB: scri...
254
255
256
257
258
259
260
261
  	}
  }
  
  static void do_usb_table(void *symval, unsigned long size,
  			 struct module *mod)
  {
  	unsigned int i;
  	const unsigned long id_size = sizeof(struct usb_device_id);
e00498258   Kees Cook   kbuild: make modp...
262
  	device_id_check(mod->name, "usb", size, id_size, symval);
fb33d8161   Sam Ravnborg   kbuild: improve e...
263

b19dcd934   Roman Kagan   [PATCH] USB: scri...
264
265
266
267
268
  	/* Leave last one: it's the terminator. */
  	size -= id_size;
  
  	for (i = 0; i < size; i += id_size)
  		do_usb_entry_multi(symval + i, mod);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
269
  }
e8c84f9a5   Jiri Slaby   modpost: add supp...
270
271
272
273
  /* Looks like: hid:bNvNpN */
  static int do_hid_entry(const char *filename,
  			     struct hid_device_id *id, char *alias)
  {
2b639386a   Jiri Slaby   HID: fix bus endi...
274
  	id->bus = TO_NATIVE(id->bus);
e8c84f9a5   Jiri Slaby   modpost: add supp...
275
276
277
278
279
280
281
282
283
  	id->vendor = TO_NATIVE(id->vendor);
  	id->product = TO_NATIVE(id->product);
  
  	sprintf(alias, "hid:b%04X", id->bus);
  	ADD(alias, "v", id->vendor != HID_ANY_ID, id->vendor);
  	ADD(alias, "p", id->product != HID_ANY_ID, id->product);
  
  	return 1;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
  /* Looks like: ieee1394:venNmoNspNverN */
  static int do_ieee1394_entry(const char *filename,
  			     struct ieee1394_device_id *id, char *alias)
  {
  	id->match_flags = TO_NATIVE(id->match_flags);
  	id->vendor_id = TO_NATIVE(id->vendor_id);
  	id->model_id = TO_NATIVE(id->model_id);
  	id->specifier_id = TO_NATIVE(id->specifier_id);
  	id->version = TO_NATIVE(id->version);
  
  	strcpy(alias, "ieee1394:");
  	ADD(alias, "ven", id->match_flags & IEEE1394_MATCH_VENDOR_ID,
  	    id->vendor_id);
  	ADD(alias, "mo", id->match_flags & IEEE1394_MATCH_MODEL_ID,
  	    id->model_id);
  	ADD(alias, "sp", id->match_flags & IEEE1394_MATCH_SPECIFIER_ID,
  	    id->specifier_id);
  	ADD(alias, "ver", id->match_flags & IEEE1394_MATCH_VERSION,
  	    id->version);
ac5518289   Jean Delvare   modpost: i2c alia...
303
  	add_wildcard(alias);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
  	return 1;
  }
  
  /* Looks like: pci:vNdNsvNsdNbcNscNiN. */
  static int do_pci_entry(const char *filename,
  			struct pci_device_id *id, char *alias)
  {
  	/* Class field can be divided into these three. */
  	unsigned char baseclass, subclass, interface,
  		baseclass_mask, subclass_mask, interface_mask;
  
  	id->vendor = TO_NATIVE(id->vendor);
  	id->device = TO_NATIVE(id->device);
  	id->subvendor = TO_NATIVE(id->subvendor);
  	id->subdevice = TO_NATIVE(id->subdevice);
  	id->class = TO_NATIVE(id->class);
  	id->class_mask = TO_NATIVE(id->class_mask);
  
  	strcpy(alias, "pci:");
  	ADD(alias, "v", id->vendor != PCI_ANY_ID, id->vendor);
  	ADD(alias, "d", id->device != PCI_ANY_ID, id->device);
  	ADD(alias, "sv", id->subvendor != PCI_ANY_ID, id->subvendor);
  	ADD(alias, "sd", id->subdevice != PCI_ANY_ID, id->subdevice);
  
  	baseclass = (id->class) >> 16;
  	baseclass_mask = (id->class_mask) >> 16;
  	subclass = (id->class) >> 8;
  	subclass_mask = (id->class_mask) >> 8;
  	interface = id->class;
  	interface_mask = id->class_mask;
  
  	if ((baseclass_mask != 0 && baseclass_mask != 0xFF)
  	    || (subclass_mask != 0 && subclass_mask != 0xFF)
  	    || (interface_mask != 0 && interface_mask != 0xFF)) {
cb80514d9   Sam Ravnborg   kbuild: use warn(...
338
339
340
  		warn("Can't handle masks in %s:%04X
  ",
  		     filename, id->class_mask);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
341
342
343
344
345
346
  		return 0;
  	}
  
  	ADD(alias, "bc", baseclass_mask == 0xFF, baseclass);
  	ADD(alias, "sc", subclass_mask == 0xFF, subclass);
  	ADD(alias, "i", interface_mask == 0xFF, interface);
ac5518289   Jean Delvare   modpost: i2c alia...
347
  	add_wildcard(alias);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
348
349
  	return 1;
  }
62070fa42   Sam Ravnborg   kbuild: kill trai...
350
  /* looks like: "ccw:tNmNdtNdmN" */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
  static int do_ccw_entry(const char *filename,
  			struct ccw_device_id *id, char *alias)
  {
  	id->match_flags = TO_NATIVE(id->match_flags);
  	id->cu_type = TO_NATIVE(id->cu_type);
  	id->cu_model = TO_NATIVE(id->cu_model);
  	id->dev_type = TO_NATIVE(id->dev_type);
  	id->dev_model = TO_NATIVE(id->dev_model);
  
  	strcpy(alias, "ccw:");
  	ADD(alias, "t", id->match_flags&CCW_DEVICE_ID_MATCH_CU_TYPE,
  	    id->cu_type);
  	ADD(alias, "m", id->match_flags&CCW_DEVICE_ID_MATCH_CU_MODEL,
  	    id->cu_model);
  	ADD(alias, "dt", id->match_flags&CCW_DEVICE_ID_MATCH_DEVICE_TYPE,
  	    id->dev_type);
de1d9c033   Bastian Blank   [PATCH] s390: fix...
367
  	ADD(alias, "dm", id->match_flags&CCW_DEVICE_ID_MATCH_DEVICE_MODEL,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
368
  	    id->dev_model);
ac5518289   Jean Delvare   modpost: i2c alia...
369
  	add_wildcard(alias);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
370
371
  	return 1;
  }
1534c3820   Martin Schwidefsky   [S390] zcrypt adj...
372
373
374
375
  /* looks like: "ap:tN" */
  static int do_ap_entry(const char *filename,
  		       struct ap_device_id *id, char *alias)
  {
ac5518289   Jean Delvare   modpost: i2c alia...
376
  	sprintf(alias, "ap:t%02X*", id->dev_type);
1534c3820   Martin Schwidefsky   [S390] zcrypt adj...
377
378
  	return 1;
  }
7e9db9eae   Cornelia Huck   [S390] cio: Intro...
379
380
381
382
383
384
385
  /* looks like: "css:tN" */
  static int do_css_entry(const char *filename,
  			struct css_device_id *id, char *alias)
  {
  	sprintf(alias, "css:t%01X", id->type);
  	return 1;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
386
387
388
389
390
391
392
393
394
395
396
397
398
399
  /* Looks like: "serio:tyNprNidNexN" */
  static int do_serio_entry(const char *filename,
  			  struct serio_device_id *id, char *alias)
  {
  	id->type = TO_NATIVE(id->type);
  	id->proto = TO_NATIVE(id->proto);
  	id->id = TO_NATIVE(id->id);
  	id->extra = TO_NATIVE(id->extra);
  
  	strcpy(alias, "serio:");
  	ADD(alias, "ty", id->type != SERIO_ANY, id->type);
  	ADD(alias, "pr", id->proto != SERIO_ANY, id->proto);
  	ADD(alias, "id", id->id != SERIO_ANY, id->id);
  	ADD(alias, "ex", id->extra != SERIO_ANY, id->extra);
ac5518289   Jean Delvare   modpost: i2c alia...
400
  	add_wildcard(alias);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
401
402
  	return 1;
  }
29b71a1ca   Thomas Renninger   ACPI: autoload mo...
403
404
405
406
  /* looks like: "acpi:ACPI0003 or acpi:PNP0C0B" or "acpi:LNXVIDEO" */
  static int do_acpi_entry(const char *filename,
  			struct acpi_device_id *id, char *alias)
  {
ac5518289   Jean Delvare   modpost: i2c alia...
407
  	sprintf(alias, "acpi*:%s:*", id->id);
29b71a1ca   Thomas Renninger   ACPI: autoload mo...
408
409
  	return 1;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
410
  /* looks like: "pnp:dD" */
22454cb99   Kay Sievers   pnp: add acpi:* m...
411
412
  static void do_pnp_device_entry(void *symval, unsigned long size,
  				struct module *mod)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
413
  {
22454cb99   Kay Sievers   pnp: add acpi:* m...
414
  	const unsigned long id_size = sizeof(struct pnp_device_id);
5e4c6564c   Kay Sievers   pnp: fix "add acp...
415
416
417
  	const unsigned int count = (size / id_size)-1;
  	const struct pnp_device_id *devs = symval;
  	unsigned int i;
22454cb99   Kay Sievers   pnp: add acpi:* m...
418
419
  
  	device_id_check(mod->name, "pnp", size, id_size, symval);
5e4c6564c   Kay Sievers   pnp: fix "add acp...
420
421
  	for (i = 0; i < count; i++) {
  		const char *id = (char *)devs[i].id;
72638f598   Kay Sievers   PNP: fix broken p...
422
423
  		char acpi_id[sizeof(devs[0].id)];
  		int j;
5e4c6564c   Kay Sievers   pnp: fix "add acp...
424
425
426
427
  
  		buf_printf(&mod->dev_table_buf,
  			   "MODULE_ALIAS(\"pnp:d%s*\");
  ", id);
72638f598   Kay Sievers   PNP: fix broken p...
428
429
430
431
  
  		/* fix broken pnp bus lowercasing */
  		for (j = 0; j < sizeof(acpi_id); j++)
  			acpi_id[j] = toupper(id[j]);
5e4c6564c   Kay Sievers   pnp: fix "add acp...
432
  		buf_printf(&mod->dev_table_buf,
72638f598   Kay Sievers   PNP: fix broken p...
433
434
  			   "MODULE_ALIAS(\"acpi*:%s:*\");
  ", acpi_id);
5e4c6564c   Kay Sievers   pnp: fix "add acp...
435
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
436
  }
0c81eed4b   Kay Sievers   PNP: add all PNP ...
437
438
439
  /* looks like: "pnp:dD" for every device of the card */
  static void do_pnp_card_entries(void *symval, unsigned long size,
  				struct module *mod)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
440
  {
0c81eed4b   Kay Sievers   PNP: add all PNP ...
441
442
443
444
  	const unsigned long id_size = sizeof(struct pnp_card_device_id);
  	const unsigned int count = (size / id_size)-1;
  	const struct pnp_card_device_id *cards = symval;
  	unsigned int i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
445

0c81eed4b   Kay Sievers   PNP: add all PNP ...
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
  	device_id_check(mod->name, "pnp", size, id_size, symval);
  
  	for (i = 0; i < count; i++) {
  		unsigned int j;
  		const struct pnp_card_device_id *card = &cards[i];
  
  		for (j = 0; j < PNP_MAX_DEVICES; j++) {
  			const char *id = (char *)card->devs[j].id;
  			int i2, j2;
  			int dup = 0;
  
  			if (!id[0])
  				break;
  
  			/* find duplicate, already added value */
  			for (i2 = 0; i2 < i && !dup; i2++) {
  				const struct pnp_card_device_id *card2 = &cards[i2];
  
  				for (j2 = 0; j2 < PNP_MAX_DEVICES; j2++) {
  					const char *id2 = (char *)card2->devs[j2].id;
  
  					if (!id2[0])
  						break;
  
  					if (!strcmp(id, id2)) {
  						dup = 1;
  						break;
  					}
  				}
  			}
  
  			/* add an individual alias for every device entry */
22454cb99   Kay Sievers   pnp: add acpi:* m...
478
  			if (!dup) {
72638f598   Kay Sievers   PNP: fix broken p...
479
480
  				char acpi_id[sizeof(card->devs[0].id)];
  				int k;
0c81eed4b   Kay Sievers   PNP: add all PNP ...
481
482
483
  				buf_printf(&mod->dev_table_buf,
  					   "MODULE_ALIAS(\"pnp:d%s*\");
  ", id);
72638f598   Kay Sievers   PNP: fix broken p...
484
485
486
487
  
  				/* fix broken pnp bus lowercasing */
  				for (k = 0; k < sizeof(acpi_id); k++)
  					acpi_id[k] = toupper(id[k]);
22454cb99   Kay Sievers   pnp: add acpi:* m...
488
  				buf_printf(&mod->dev_table_buf,
72638f598   Kay Sievers   PNP: fix broken p...
489
490
  					   "MODULE_ALIAS(\"acpi*:%s:*\");
  ", acpi_id);
22454cb99   Kay Sievers   pnp: add acpi:* m...
491
  			}
0c81eed4b   Kay Sievers   PNP: add all PNP ...
492
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
493
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
494
  }
90829cfe1   Dominik Brodowski   [PATCH] pcmcia: f...
495
496
497
498
499
  /* Looks like: pcmcia:mNcNfNfnNpfnNvaNvbNvcNvdN. */
  static int do_pcmcia_entry(const char *filename,
  			   struct pcmcia_device_id *id, char *alias)
  {
  	unsigned int i;
4fb7edce5   Kars de Jong   [PATCH] pcmcia: f...
500
  	id->match_flags = TO_NATIVE(id->match_flags);
90829cfe1   Dominik Brodowski   [PATCH] pcmcia: f...
501
502
503
504
505
  	id->manf_id = TO_NATIVE(id->manf_id);
  	id->card_id = TO_NATIVE(id->card_id);
  	id->func_id = TO_NATIVE(id->func_id);
  	id->function = TO_NATIVE(id->function);
  	id->device_no = TO_NATIVE(id->device_no);
4fb7edce5   Kars de Jong   [PATCH] pcmcia: f...
506

90829cfe1   Dominik Brodowski   [PATCH] pcmcia: f...
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
  	for (i=0; i<4; i++) {
  		id->prod_id_hash[i] = TO_NATIVE(id->prod_id_hash[i]);
         }
  
         strcpy(alias, "pcmcia:");
         ADD(alias, "m", id->match_flags & PCMCIA_DEV_ID_MATCH_MANF_ID,
  	   id->manf_id);
         ADD(alias, "c", id->match_flags & PCMCIA_DEV_ID_MATCH_CARD_ID,
  	   id->card_id);
         ADD(alias, "f", id->match_flags & PCMCIA_DEV_ID_MATCH_FUNC_ID,
  	   id->func_id);
         ADD(alias, "fn", id->match_flags & PCMCIA_DEV_ID_MATCH_FUNCTION,
  	   id->function);
         ADD(alias, "pfn", id->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO,
  	   id->device_no);
         ADD(alias, "pa", id->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID1, id->prod_id_hash[0]);
         ADD(alias, "pb", id->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID2, id->prod_id_hash[1]);
         ADD(alias, "pc", id->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID3, id->prod_id_hash[2]);
         ADD(alias, "pd", id->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID4, id->prod_id_hash[3]);
ac5518289   Jean Delvare   modpost: i2c alia...
526
  	add_wildcard(alias);
90829cfe1   Dominik Brodowski   [PATCH] pcmcia: f...
527
528
         return 1;
  }
5e6557722   Jeff Mahoney   [PATCH] openfirmw...
529
530
  static int do_of_entry (const char *filename, struct of_device_id *of, char *alias)
  {
d1ab42350   Sylvain Munaut   powerpc: Fix the ...
531
      int len;
5e6557722   Jeff Mahoney   [PATCH] openfirmw...
532
      char *tmp;
d1ab42350   Sylvain Munaut   powerpc: Fix the ...
533
      len = sprintf (alias, "of:N%sT%s",
5e6557722   Jeff Mahoney   [PATCH] openfirmw...
534
                      of->name[0] ? of->name : "*",
d1ab42350   Sylvain Munaut   powerpc: Fix the ...
535
536
537
538
539
540
                      of->type[0] ? of->type : "*");
  
      if (of->compatible[0])
          sprintf (&alias[len], "%sC%s",
                       of->type[0] ? "*" : "",
                       of->compatible);
5e6557722   Jeff Mahoney   [PATCH] openfirmw...
541
542
543
544
545
  
      /* Replace all whitespace with underscores */
      for (tmp = alias; tmp && *tmp; tmp++)
          if (isspace (*tmp))
              *tmp = '_';
ac5518289   Jean Delvare   modpost: i2c alia...
546
      add_wildcard(alias);
5e6557722   Jeff Mahoney   [PATCH] openfirmw...
547
548
      return 1;
  }
fb120da67   Stephen Rothwell   [PATCH] Make MODU...
549
550
551
552
553
554
555
556
557
558
559
560
  static int do_vio_entry(const char *filename, struct vio_device_id *vio,
  		char *alias)
  {
  	char *tmp;
  
  	sprintf(alias, "vio:T%sS%s", vio->type[0] ? vio->type : "*",
  			vio->compat[0] ? vio->compat : "*");
  
  	/* Replace all whitespace with underscores */
  	for (tmp = alias; tmp && *tmp; tmp++)
  		if (isspace (*tmp))
  			*tmp = '_';
ac5518289   Jean Delvare   modpost: i2c alia...
561
  	add_wildcard(alias);
fb120da67   Stephen Rothwell   [PATCH] Make MODU...
562
563
  	return 1;
  }
1d8f430c1   Rusty Russell   [PATCH] Input: ad...
564
565
566
567
568
569
  #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
  
  static void do_input(char *alias,
  		     kernel_ulong_t *arr, unsigned int min, unsigned int max)
  {
  	unsigned int i;
ddc5d3414   Dmitry Torokhov   Input: move input...
570
571
  
  	for (i = min; i < max; i++)
e0e926327   Hans de Goede   [PATCH] PATCH: 1 ...
572
  		if (arr[i / BITS_PER_LONG] & (1L << (i%BITS_PER_LONG)))
ddc5d3414   Dmitry Torokhov   Input: move input...
573
  			sprintf(alias + strlen(alias), "%X,*", i);
1d8f430c1   Rusty Russell   [PATCH] Input: ad...
574
575
576
577
578
579
580
  }
  
  /* input:b0v0p0e0-eXkXrXaXmXlXsXfXwX where X is comma-separated %02X. */
  static int do_input_entry(const char *filename, struct input_device_id *id,
  			  char *alias)
  {
  	sprintf(alias, "input:");
ddc5d3414   Dmitry Torokhov   Input: move input...
581
582
583
584
  	ADD(alias, "b", id->flags & INPUT_DEVICE_ID_MATCH_BUS, id->bustype);
  	ADD(alias, "v", id->flags & INPUT_DEVICE_ID_MATCH_VENDOR, id->vendor);
  	ADD(alias, "p", id->flags & INPUT_DEVICE_ID_MATCH_PRODUCT, id->product);
  	ADD(alias, "e", id->flags & INPUT_DEVICE_ID_MATCH_VERSION, id->version);
1d8f430c1   Rusty Russell   [PATCH] Input: ad...
585
586
  
  	sprintf(alias + strlen(alias), "-e*");
ddc5d3414   Dmitry Torokhov   Input: move input...
587
  	if (id->flags & INPUT_DEVICE_ID_MATCH_EVBIT)
dc24f0e70   Sam Ravnborg   kbuild: remove de...
588
  		do_input(alias, id->evbit, 0, INPUT_DEVICE_ID_EV_MAX);
1d8f430c1   Rusty Russell   [PATCH] Input: ad...
589
  	sprintf(alias + strlen(alias), "k*");
ddc5d3414   Dmitry Torokhov   Input: move input...
590
  	if (id->flags & INPUT_DEVICE_ID_MATCH_KEYBIT)
dc24f0e70   Sam Ravnborg   kbuild: remove de...
591
592
593
  		do_input(alias, id->keybit,
  			 INPUT_DEVICE_ID_KEY_MIN_INTERESTING,
  			 INPUT_DEVICE_ID_KEY_MAX);
1d8f430c1   Rusty Russell   [PATCH] Input: ad...
594
  	sprintf(alias + strlen(alias), "r*");
ddc5d3414   Dmitry Torokhov   Input: move input...
595
  	if (id->flags & INPUT_DEVICE_ID_MATCH_RELBIT)
dc24f0e70   Sam Ravnborg   kbuild: remove de...
596
  		do_input(alias, id->relbit, 0, INPUT_DEVICE_ID_REL_MAX);
1d8f430c1   Rusty Russell   [PATCH] Input: ad...
597
  	sprintf(alias + strlen(alias), "a*");
ddc5d3414   Dmitry Torokhov   Input: move input...
598
  	if (id->flags & INPUT_DEVICE_ID_MATCH_ABSBIT)
dc24f0e70   Sam Ravnborg   kbuild: remove de...
599
  		do_input(alias, id->absbit, 0, INPUT_DEVICE_ID_ABS_MAX);
1d8f430c1   Rusty Russell   [PATCH] Input: ad...
600
  	sprintf(alias + strlen(alias), "m*");
ddc5d3414   Dmitry Torokhov   Input: move input...
601
  	if (id->flags & INPUT_DEVICE_ID_MATCH_MSCIT)
dc24f0e70   Sam Ravnborg   kbuild: remove de...
602
  		do_input(alias, id->mscbit, 0, INPUT_DEVICE_ID_MSC_MAX);
1d8f430c1   Rusty Russell   [PATCH] Input: ad...
603
  	sprintf(alias + strlen(alias), "l*");
ddc5d3414   Dmitry Torokhov   Input: move input...
604
  	if (id->flags & INPUT_DEVICE_ID_MATCH_LEDBIT)
dc24f0e70   Sam Ravnborg   kbuild: remove de...
605
  		do_input(alias, id->ledbit, 0, INPUT_DEVICE_ID_LED_MAX);
1d8f430c1   Rusty Russell   [PATCH] Input: ad...
606
  	sprintf(alias + strlen(alias), "s*");
ddc5d3414   Dmitry Torokhov   Input: move input...
607
  	if (id->flags & INPUT_DEVICE_ID_MATCH_SNDBIT)
dc24f0e70   Sam Ravnborg   kbuild: remove de...
608
  		do_input(alias, id->sndbit, 0, INPUT_DEVICE_ID_SND_MAX);
1d8f430c1   Rusty Russell   [PATCH] Input: ad...
609
  	sprintf(alias + strlen(alias), "f*");
ddc5d3414   Dmitry Torokhov   Input: move input...
610
  	if (id->flags & INPUT_DEVICE_ID_MATCH_FFBIT)
dc24f0e70   Sam Ravnborg   kbuild: remove de...
611
  		do_input(alias, id->ffbit, 0, INPUT_DEVICE_ID_FF_MAX);
1d8f430c1   Rusty Russell   [PATCH] Input: ad...
612
  	sprintf(alias + strlen(alias), "w*");
ddc5d3414   Dmitry Torokhov   Input: move input...
613
  	if (id->flags & INPUT_DEVICE_ID_MATCH_SWBIT)
dc24f0e70   Sam Ravnborg   kbuild: remove de...
614
  		do_input(alias, id->swbit, 0, INPUT_DEVICE_ID_SW_MAX);
1d8f430c1   Rusty Russell   [PATCH] Input: ad...
615
616
  	return 1;
  }
07563c711   Michael Tokarev   [PATCH] EISA bus ...
617
618
619
620
621
  static int do_eisa_entry(const char *filename, struct eisa_device_id *eisa,
  		char *alias)
  {
  	if (eisa->sig[0])
  		sprintf(alias, EISA_DEVICE_MODALIAS_FMT "*", eisa->sig);
ac5518289   Jean Delvare   modpost: i2c alia...
622
623
  	else
  		strcat(alias, "*");
07563c711   Michael Tokarev   [PATCH] EISA bus ...
624
625
  	return 1;
  }
f3cf26733   Kyle McMartin   [PARISC] generate...
626
627
628
629
630
631
632
633
634
635
  /* Looks like: parisc:tNhvNrevNsvN */
  static int do_parisc_entry(const char *filename, struct parisc_device_id *id,
  		char *alias)
  {
  	id->hw_type = TO_NATIVE(id->hw_type);
  	id->hversion = TO_NATIVE(id->hversion);
  	id->hversion_rev = TO_NATIVE(id->hversion_rev);
  	id->sversion = TO_NATIVE(id->sversion);
  
  	strcpy(alias, "parisc:");
f354ef8ab   Kyle McMartin   [PARISC] rename *...
636
637
638
639
  	ADD(alias, "t", id->hw_type != PA_HWTYPE_ANY_ID, id->hw_type);
  	ADD(alias, "hv", id->hversion != PA_HVERSION_ANY_ID, id->hversion);
  	ADD(alias, "rev", id->hversion_rev != PA_HVERSION_REV_ANY_ID, id->hversion_rev);
  	ADD(alias, "sv", id->sversion != PA_SVERSION_ANY_ID, id->sversion);
f3cf26733   Kyle McMartin   [PARISC] generate...
640

ac5518289   Jean Delvare   modpost: i2c alia...
641
  	add_wildcard(alias);
f3cf26733   Kyle McMartin   [PARISC] generate...
642
643
  	return 1;
  }
d59b66c7a   Pierre Ossman   sdio: add modalia...
644
645
646
647
648
649
650
651
652
653
654
655
  /* Looks like: sdio:cNvNdN. */
  static int do_sdio_entry(const char *filename,
  			struct sdio_device_id *id, char *alias)
  {
  	id->class = TO_NATIVE(id->class);
  	id->vendor = TO_NATIVE(id->vendor);
  	id->device = TO_NATIVE(id->device);
  
  	strcpy(alias, "sdio:");
  	ADD(alias, "c", id->class != (__u8)SDIO_ANY_ID, id->class);
  	ADD(alias, "v", id->vendor != (__u16)SDIO_ANY_ID, id->vendor);
  	ADD(alias, "d", id->device != (__u16)SDIO_ANY_ID, id->device);
ac5518289   Jean Delvare   modpost: i2c alia...
656
  	add_wildcard(alias);
038a5008b   Linus Torvalds   Merge branch 'mas...
657
658
  	return 1;
  }
61e115a56   Michael Buesch   [SSB]: add Sonics...
659
660
661
662
663
664
665
  /* Looks like: ssb:vNidNrevN. */
  static int do_ssb_entry(const char *filename,
  			struct ssb_device_id *id, char *alias)
  {
  	id->vendor = TO_NATIVE(id->vendor);
  	id->coreid = TO_NATIVE(id->coreid);
  	id->revision = TO_NATIVE(id->revision);
d59b66c7a   Pierre Ossman   sdio: add modalia...
666

61e115a56   Michael Buesch   [SSB]: add Sonics...
667
668
669
670
  	strcpy(alias, "ssb:");
  	ADD(alias, "v", id->vendor != SSB_ANY_VENDOR, id->vendor);
  	ADD(alias, "id", id->coreid != SSB_ANY_ID, id->coreid);
  	ADD(alias, "rev", id->revision != SSB_ANY_REV, id->revision);
ac5518289   Jean Delvare   modpost: i2c alia...
671
  	add_wildcard(alias);
d59b66c7a   Pierre Ossman   sdio: add modalia...
672
673
  	return 1;
  }
8369ae33b   Rafał Miłecki   bcma: add Broadco...
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
  /* 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;
  }
b01d9f286   Rusty Russell   Module autoprobin...
691
692
693
694
695
696
697
698
  /* Looks like: virtio:dNvN */
  static int do_virtio_entry(const char *filename, struct virtio_device_id *id,
  			   char *alias)
  {
  	id->device = TO_NATIVE(id->device);
  	id->vendor = TO_NATIVE(id->vendor);
  
  	strcpy(alias, "virtio:");
e33538537   Christian Borntraeger   virtio: enhance i...
699
  	ADD(alias, "d", id->device != VIRTIO_DEV_ANY_ID, id->device);
b01d9f286   Rusty Russell   Module autoprobin...
700
  	ADD(alias, "v", id->vendor != VIRTIO_DEV_ANY_ID, id->vendor);
ac5518289   Jean Delvare   modpost: i2c alia...
701
  	add_wildcard(alias);
b01d9f286   Rusty Russell   Module autoprobin...
702
703
  	return 1;
  }
d2ee52aaf   K. Y. Srinivasan   Staging: hv: Add ...
704
705
706
707
708
709
710
711
712
713
  /*
   * 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;
ebf16e385   Greg Kroah-Hartman   Staging: hv: file...
714
  	char guid_name[((sizeof(id->guid) + 1)) * 2];
d2ee52aaf   K. Y. Srinivasan   Staging: hv: Add ...
715

ebf16e385   Greg Kroah-Hartman   Staging: hv: file...
716
  	for (i = 0; i < (sizeof(id->guid) * 2); i += 2)
d2ee52aaf   K. Y. Srinivasan   Staging: hv: Add ...
717
718
719
720
721
722
723
  		sprintf(&guid_name[i], "%02x", id->guid[i/2]);
  
  	strcpy(alias, "vmbus:");
  	strcat(alias, guid_name);
  
  	return 1;
  }
d2653e927   Jean Delvare   i2c: Add support ...
724
725
726
727
728
729
730
731
  /* Looks like: i2c:S */
  static int do_i2c_entry(const char *filename, struct i2c_device_id *id,
  			char *alias)
  {
  	sprintf(alias, I2C_MODULE_PREFIX "%s", id->name);
  
  	return 1;
  }
e0626e384   Anton Vorontsov   spi: prefix modal...
732
  /* Looks like: spi:S */
75368bf6c   Anton Vorontsov   spi: add support ...
733
734
735
  static int do_spi_entry(const char *filename, struct spi_device_id *id,
  			char *alias)
  {
e0626e384   Anton Vorontsov   spi: prefix modal...
736
  	sprintf(alias, SPI_MODULE_PREFIX "%s", id->name);
75368bf6c   Anton Vorontsov   spi: add support ...
737
738
739
  
  	return 1;
  }
d945b697d   David Woodhouse   Automatic MODULE_...
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
  static const struct dmifield {
  	const char *prefix;
  	int field;
  } dmi_fields[] = {
  	{ "bvn", DMI_BIOS_VENDOR },
  	{ "bvr", DMI_BIOS_VERSION },
  	{ "bd",  DMI_BIOS_DATE },
  	{ "svn", DMI_SYS_VENDOR },
  	{ "pn",  DMI_PRODUCT_NAME },
  	{ "pvr", DMI_PRODUCT_VERSION },
  	{ "rvn", DMI_BOARD_VENDOR },
  	{ "rn",  DMI_BOARD_NAME },
  	{ "rvr", DMI_BOARD_VERSION },
  	{ "cvn", DMI_CHASSIS_VENDOR },
  	{ "ct",  DMI_CHASSIS_TYPE },
  	{ "cvr", DMI_CHASSIS_VERSION },
  	{ NULL,  DMI_NONE }
  };
  
  static void dmi_ascii_filter(char *d, const char *s)
  {
  	/* Filter out characters we don't want to see in the modalias string */
  	for (; *s; s++)
  		if (*s > ' ' && *s < 127 && *s != ':')
  			*(d++) = *s;
  
  	*d = 0;
  }
  
  
  static int do_dmi_entry(const char *filename, struct dmi_system_id *id,
  			char *alias)
  {
  	int i, j;
  
  	sprintf(alias, "dmi*");
  
  	for (i = 0; i < ARRAY_SIZE(dmi_fields); i++) {
  		for (j = 0; j < 4; j++) {
  			if (id->matches[j].slot &&
  			    id->matches[j].slot == dmi_fields[i].field) {
  				sprintf(alias + strlen(alias), ":%s*",
  					dmi_fields[i].prefix);
  				dmi_ascii_filter(alias + strlen(alias),
  						 id->matches[j].substr);
  				strcat(alias, "*");
  			}
  		}
  	}
  
  	strcat(alias, ":");
  	return 1;
  }
57fee4a58   Eric Miao   platform: introdu...
793
794
795
796
797
798
799
  
  static int do_platform_entry(const char *filename,
  			     struct platform_device_id *id, char *alias)
  {
  	sprintf(alias, PLATFORM_MODULE_PREFIX "%s", id->name);
  	return 1;
  }
8626d3b43   David Woodhouse   phylib: Support p...
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
  static int do_mdio_entry(const char *filename,
  			 struct mdio_device_id *id, char *alias)
  {
  	int i;
  
  	alias += sprintf(alias, MDIO_MODULE_PREFIX);
  
  	for (i = 0; i < 32; i++) {
  		if (!((id->phy_id_mask >> (31-i)) & 1))
  			*(alias++) = '?';
  		else if ((id->phy_id >> (31-i)) & 1)
  			*(alias++) = '1';
  		else
  			*(alias++) = '0';
  	}
  
  	/* Terminate the string */
  	*alias = 0;
  
  	return 1;
  }
bf54a2b3c   Geert Uytterhoeven   m68k: amiga - Zor...
821
822
823
824
825
826
827
828
829
  /* Looks like: zorro:iN. */
  static int do_zorro_entry(const char *filename, struct zorro_device_id *id,
  			  char *alias)
  {
  	id->id = TO_NATIVE(id->id);
  	strcpy(alias, "zorro:");
  	ADD(alias, "i", id->id != ZORRO_WILDCARD, id->id);
  	return 1;
  }
fedb3d27d   Ondrej Zary   MODULE_DEVICE_TAB...
830
831
832
833
834
835
836
837
838
839
840
841
  /* looks like: "pnp:dD" */
  static int do_isapnp_entry(const char *filename,
  			   struct isapnp_device_id *id, char *alias)
  {
  	sprintf(alias, "pnp:d%c%c%c%x%x%x%x*",
  		'A' + ((id->vendor >> 2) & 0x3f) - 1,
  		'A' + (((id->vendor & 3) << 3) | ((id->vendor >> 13) & 7)) - 1,
  		'A' + ((id->vendor >> 8) & 0x1f) - 1,
  		(id->function >> 4) & 0x0f, id->function & 0x0f,
  		(id->function >> 12) & 0x0f, (id->function >> 8) & 0x0f);
  	return 1;
  }
523817bd2   Dave Martin   ARM: amba: Auto-g...
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
  /*
   * 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)
  {
  	char *p = *outp;
  	unsigned int i;
  
  	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.
  ",
  		      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;
  }
f606ddf42   Adrian Bunk   remove the v850 port
910
  /* Ignore any prefix, eg. some architectures prepend _ */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
911
912
913
914
915
916
917
  static inline int sym_is(const char *symbol, const char *name)
  {
  	const char *match;
  
  	match = strstr(symbol, name);
  	if (!match)
  		return 0;
3a5dd791a   Mike Frysinger   modpost: fix segf...
918
  	return match[strlen(name)] == '\0';
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
919
920
921
922
  }
  
  static void do_table(void *symval, unsigned long size,
  		     unsigned long id_size,
fb33d8161   Sam Ravnborg   kbuild: improve e...
923
  		     const char *device_id,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
924
925
926
927
928
929
  		     void *function,
  		     struct module *mod)
  {
  	unsigned int i;
  	char alias[500];
  	int (*do_entry)(const char *, void *entry, char *alias) = function;
e00498258   Kees Cook   kbuild: make modp...
930
  	device_id_check(mod->name, device_id, size, id_size, symval);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
931
932
933
934
935
  	/* Leave last one: it's the terminator. */
  	size -= id_size;
  
  	for (i = 0; i < size; i += id_size) {
  		if (do_entry(mod->name, symval+i, alias)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
936
937
938
939
940
941
942
943
944
945
946
947
948
949
  			buf_printf(&mod->dev_table_buf,
  				   "MODULE_ALIAS(\"%s\");
  ", alias);
  		}
  	}
  }
  
  /* Create MODULE_ALIAS() statements.
   * At this time, we cannot write the actual output C source yet,
   * so we write into the mod->dev_table_buf buffer. */
  void handle_moddevtable(struct module *mod, struct elf_info *info,
  			Elf_Sym *sym, const char *symname)
  {
  	void *symval;
e00498258   Kees Cook   kbuild: make modp...
950
  	char *zeros = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
951
952
  
  	/* We're looking for a section relative symbol */
1ce53adf1   Denys Vlasenko   modpost: support ...
953
  	if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
954
  		return;
e00498258   Kees Cook   kbuild: make modp...
955
  	/* Handle all-NULL symbols allocated into .bss */
1ce53adf1   Denys Vlasenko   modpost: support ...
956
  	if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) {
e00498258   Kees Cook   kbuild: make modp...
957
958
959
960
  		zeros = calloc(1, sym->st_size);
  		symval = zeros;
  	} else {
  		symval = (void *)info->hdr
1ce53adf1   Denys Vlasenko   modpost: support ...
961
  			+ info->sechdrs[get_secindex(info, sym)].sh_offset
e00498258   Kees Cook   kbuild: make modp...
962
963
  			+ sym->st_value;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
964
965
  
  	if (sym_is(symname, "__mod_pci_device_table"))
fb33d8161   Sam Ravnborg   kbuild: improve e...
966
967
  		do_table(symval, sym->st_size,
  			 sizeof(struct pci_device_id), "pci",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
968
969
  			 do_pci_entry, mod);
  	else if (sym_is(symname, "__mod_usb_device_table"))
b19dcd934   Roman Kagan   [PATCH] USB: scri...
970
971
  		/* special case to handle bcdDevice ranges */
  		do_usb_table(symval, sym->st_size, mod);
e8c84f9a5   Jiri Slaby   modpost: add supp...
972
973
974
975
  	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);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
976
  	else if (sym_is(symname, "__mod_ieee1394_device_table"))
fb33d8161   Sam Ravnborg   kbuild: improve e...
977
978
  		do_table(symval, sym->st_size,
  			 sizeof(struct ieee1394_device_id), "ieee1394",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
979
980
  			 do_ieee1394_entry, mod);
  	else if (sym_is(symname, "__mod_ccw_device_table"))
fb33d8161   Sam Ravnborg   kbuild: improve e...
981
982
  		do_table(symval, sym->st_size,
  			 sizeof(struct ccw_device_id), "ccw",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
983
  			 do_ccw_entry, mod);
1534c3820   Martin Schwidefsky   [S390] zcrypt adj...
984
985
986
987
  	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);
7e9db9eae   Cornelia Huck   [S390] cio: Intro...
988
989
990
991
  	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);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
992
  	else if (sym_is(symname, "__mod_serio_device_table"))
fb33d8161   Sam Ravnborg   kbuild: improve e...
993
994
  		do_table(symval, sym->st_size,
  			 sizeof(struct serio_device_id), "serio",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
995
  			 do_serio_entry, mod);
29b71a1ca   Thomas Renninger   ACPI: autoload mo...
996
997
998
999
  	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);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1000
  	else if (sym_is(symname, "__mod_pnp_device_table"))
22454cb99   Kay Sievers   pnp: add acpi:* m...
1001
  		do_pnp_device_entry(symval, sym->st_size, mod);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1002
  	else if (sym_is(symname, "__mod_pnp_card_device_table"))
0c81eed4b   Kay Sievers   PNP: add all PNP ...
1003
  		do_pnp_card_entries(symval, sym->st_size, mod);
90829cfe1   Dominik Brodowski   [PATCH] pcmcia: f...
1004
  	else if (sym_is(symname, "__mod_pcmcia_device_table"))
fb33d8161   Sam Ravnborg   kbuild: improve e...
1005
1006
  		do_table(symval, sym->st_size,
  			 sizeof(struct pcmcia_device_id), "pcmcia",
90829cfe1   Dominik Brodowski   [PATCH] pcmcia: f...
1007
  			 do_pcmcia_entry, mod);
5e6557722   Jeff Mahoney   [PATCH] openfirmw...
1008
          else if (sym_is(symname, "__mod_of_device_table"))
fb33d8161   Sam Ravnborg   kbuild: improve e...
1009
1010
  		do_table(symval, sym->st_size,
  			 sizeof(struct of_device_id), "of",
5e6557722   Jeff Mahoney   [PATCH] openfirmw...
1011
  			 do_of_entry, mod);
fb120da67   Stephen Rothwell   [PATCH] Make MODU...
1012
          else if (sym_is(symname, "__mod_vio_device_table"))
fb33d8161   Sam Ravnborg   kbuild: improve e...
1013
1014
  		do_table(symval, sym->st_size,
  			 sizeof(struct vio_device_id), "vio",
fb120da67   Stephen Rothwell   [PATCH] Make MODU...
1015
  			 do_vio_entry, mod);
1d8f430c1   Rusty Russell   [PATCH] Input: ad...
1016
  	else if (sym_is(symname, "__mod_input_device_table"))
fb33d8161   Sam Ravnborg   kbuild: improve e...
1017
1018
  		do_table(symval, sym->st_size,
  			 sizeof(struct input_device_id), "input",
1d8f430c1   Rusty Russell   [PATCH] Input: ad...
1019
  			 do_input_entry, mod);
07563c711   Michael Tokarev   [PATCH] EISA bus ...
1020
1021
1022
1023
  	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);
f3cf26733   Kyle McMartin   [PARISC] generate...
1024
1025
1026
1027
  	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);
d59b66c7a   Pierre Ossman   sdio: add modalia...
1028
1029
1030
1031
  	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);
61e115a56   Michael Buesch   [SSB]: add Sonics...
1032
1033
1034
1035
  	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);
8369ae33b   Rafał Miłecki   bcma: add Broadco...
1036
1037
1038
1039
  	else if (sym_is(symname, "__mod_bcma_device_table"))
  		do_table(symval, sym->st_size,
  			 sizeof(struct bcma_device_id), "bcma",
  			 do_bcma_entry, mod);
b01d9f286   Rusty Russell   Module autoprobin...
1040
1041
1042
1043
  	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);
d2ee52aaf   K. Y. Srinivasan   Staging: hv: Add ...
1044
1045
1046
1047
  	else if (sym_is(symname, "__mod_vmbus_device_table"))
  		do_table(symval, sym->st_size,
  			 sizeof(struct hv_vmbus_device_id), "vmbus",
  			 do_vmbus_entry, mod);
d2653e927   Jean Delvare   i2c: Add support ...
1048
1049
1050
1051
  	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);
75368bf6c   Anton Vorontsov   spi: add support ...
1052
1053
1054
1055
  	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);
d945b697d   David Woodhouse   Automatic MODULE_...
1056
1057
1058
1059
  	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);
57fee4a58   Eric Miao   platform: introdu...
1060
1061
1062
1063
  	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);
8626d3b43   David Woodhouse   phylib: Support p...
1064
1065
1066
1067
  	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);
bf54a2b3c   Geert Uytterhoeven   m68k: amiga - Zor...
1068
1069
1070
1071
  	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);
fedb3d27d   Ondrej Zary   MODULE_DEVICE_TAB...
1072
1073
1074
1075
  	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);
523817bd2   Dave Martin   ARM: amba: Auto-g...
1076
1077
1078
1079
  	else if (sym_is(symname, "__mod_amba_device_table"))
  		do_table(symval, sym->st_size,
  			sizeof(struct amba_id), "amba",
  			do_amba_entry, mod);
e00498258   Kees Cook   kbuild: make modp...
1080
  	free(zeros);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
  }
  
  /* Now add out buffered information to the generated C source */
  void add_moddevtable(struct buffer *buf, struct module *mod)
  {
  	buf_printf(buf, "
  ");
  	buf_write(buf, mod->dev_table_buf.p, mod->dev_table_buf.pos);
  	free(mod->dev_table_buf.p);
  }