1 /* Simple code to turn various tables in an ELF file into alias definitions. 2 * This deals with kernel datastructures where they should be 3 * dealt with: in the kernel source. 4 * 5 * Copyright 2002-2003 Rusty Russell, IBM Corporation 6 * 2003 Kai Germaschewski 7 * 8 * 9 * This software may be used and distributed according to the terms 10 * of the GNU General Public License, incorporated herein by reference. 11 */ 12 13 #include "modpost.h" 14 #include "devicetable-offsets.h" 15 16 /* We use the ELF typedefs for kernel_ulong_t but bite the bullet and 17 * use either stdint.h or inttypes.h for the rest. */ 18 #if KERNEL_ELFCLASS == ELFCLASS32 19 typedef Elf32_Addr kernel_ulong_t; 20 #define BITS_PER_LONG 32 21 #else 22 typedef Elf64_Addr kernel_ulong_t; 23 #define BITS_PER_LONG 64 24 #endif 25 #ifdef __sun__ 26 #include <inttypes.h> 27 #else 28 #include <stdint.h> 29 #endif 30 31 #include <ctype.h> 32 #include <stdbool.h> 33 34 typedef uint32_t __u32; 35 typedef uint16_t __u16; 36 typedef unsigned char __u8; 37 typedef struct { 38 __u8 b[16]; 39 } uuid_le; 40 41 /* Big exception to the "don't include kernel headers into userspace, which 42 * even potentially has different endianness and word sizes, since 43 * we handle those differences explicitly below */ 44 #include "../../include/linux/mod_devicetable.h" 45 46 /* This array collects all instances that use the generic do_table */ 47 struct devtable { 48 const char *device_id; /* name of table, __mod_<name>__*_device_table. */ 49 unsigned long id_size; 50 int (*do_entry)(const char *filename, void *symval, char *alias); 51 }; 52 53 /* Define a variable f that holds the value of field f of struct devid 54 * based at address m. 55 */ 56 #define DEF_FIELD(m, devid, f) \ 57 typeof(((struct devid *)0)->f) f = TO_NATIVE(*(typeof(f) *)((m) + OFF_##devid##_##f)) 58 59 /* Define a variable v that holds the address of field f of struct devid 60 * based at address m. Due to the way typeof works, for a field of type 61 * T[N] the variable has type T(*)[N], _not_ T*. 62 */ 63 #define DEF_FIELD_ADDR_VAR(m, devid, f, v) \ 64 typeof(((struct devid *)0)->f) *v = ((m) + OFF_##devid##_##f) 65 66 /* Define a variable f that holds the address of field f of struct devid 67 * based at address m. Due to the way typeof works, for a field of type 68 * T[N] the variable has type T(*)[N], _not_ T*. 69 */ 70 #define DEF_FIELD_ADDR(m, devid, f) \ 71 DEF_FIELD_ADDR_VAR(m, devid, f, f) 72 73 #define ADD(str, sep, cond, field) \ 74 do { \ 75 strcat(str, sep); \ 76 if (cond) \ 77 sprintf(str + strlen(str), \ 78 sizeof(field) == 1 ? "%02X" : \ 79 sizeof(field) == 2 ? "%04X" : \ 80 sizeof(field) == 4 ? "%08X" : "", \ 81 field); \ 82 else \ 83 sprintf(str + strlen(str), "*"); \ 84 } while(0) 85 86 /* End in a wildcard, for future extension */ 87 static inline void add_wildcard(char *str) 88 { 89 int len = strlen(str); 90 91 if (str[len - 1] != '*') 92 strcat(str + len, "*"); 93 } 94 95 static inline void add_uuid(char *str, uuid_le uuid) 96 { 97 int len = strlen(str); 98 99 sprintf(str + len, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", 100 uuid.b[3], uuid.b[2], uuid.b[1], uuid.b[0], 101 uuid.b[5], uuid.b[4], uuid.b[7], uuid.b[6], 102 uuid.b[8], uuid.b[9], uuid.b[10], uuid.b[11], 103 uuid.b[12], uuid.b[13], uuid.b[14], uuid.b[15]); 104 } 105 106 /** 107 * Check that sizeof(device_id type) are consistent with size of section 108 * in .o file. If in-consistent then userspace and kernel does not agree 109 * on actual size which is a bug. 110 * Also verify that the final entry in the table is all zeros. 111 * Ignore both checks if build host differ from target host and size differs. 112 **/ 113 static void device_id_check(const char *modname, const char *device_id, 114 unsigned long size, unsigned long id_size, 115 void *symval) 116 { 117 int i; 118 119 if (size % id_size || size < id_size) { 120 fatal("%s: sizeof(struct %s_device_id)=%lu is not a modulo " 121 "of the size of " 122 "section __mod_%s__<identifier>_device_table=%lu.\n" 123 "Fix definition of struct %s_device_id " 124 "in mod_devicetable.h\n", 125 modname, device_id, id_size, device_id, size, device_id); 126 } 127 /* Verify last one is a terminator */ 128 for (i = 0; i < id_size; i++ ) { 129 if (*(uint8_t*)(symval+size-id_size+i)) { 130 fprintf(stderr,"%s: struct %s_device_id is %lu bytes. " 131 "The last of %lu is:\n", 132 modname, device_id, id_size, size / id_size); 133 for (i = 0; i < id_size; i++ ) 134 fprintf(stderr,"0x%02x ", 135 *(uint8_t*)(symval+size-id_size+i) ); 136 fprintf(stderr,"\n"); 137 fatal("%s: struct %s_device_id is not terminated " 138 "with a NULL entry!\n", modname, device_id); 139 } 140 } 141 } 142 143 /* USB is special because the bcdDevice can be matched against a numeric range */ 144 /* Looks like "usb:vNpNdNdcNdscNdpNicNiscNipNinN" */ 145 static void do_usb_entry(void *symval, 146 unsigned int bcdDevice_initial, int bcdDevice_initial_digits, 147 unsigned char range_lo, unsigned char range_hi, 148 unsigned char max, struct module *mod) 149 { 150 char alias[500]; 151 DEF_FIELD(symval, usb_device_id, match_flags); 152 DEF_FIELD(symval, usb_device_id, idVendor); 153 DEF_FIELD(symval, usb_device_id, idProduct); 154 DEF_FIELD(symval, usb_device_id, bcdDevice_lo); 155 DEF_FIELD(symval, usb_device_id, bDeviceClass); 156 DEF_FIELD(symval, usb_device_id, bDeviceSubClass); 157 DEF_FIELD(symval, usb_device_id, bDeviceProtocol); 158 DEF_FIELD(symval, usb_device_id, bInterfaceClass); 159 DEF_FIELD(symval, usb_device_id, bInterfaceSubClass); 160 DEF_FIELD(symval, usb_device_id, bInterfaceProtocol); 161 DEF_FIELD(symval, usb_device_id, bInterfaceNumber); 162 163 strcpy(alias, "usb:"); 164 ADD(alias, "v", match_flags&USB_DEVICE_ID_MATCH_VENDOR, 165 idVendor); 166 ADD(alias, "p", match_flags&USB_DEVICE_ID_MATCH_PRODUCT, 167 idProduct); 168 169 strcat(alias, "d"); 170 if (bcdDevice_initial_digits) 171 sprintf(alias + strlen(alias), "%0*X", 172 bcdDevice_initial_digits, bcdDevice_initial); 173 if (range_lo == range_hi) 174 sprintf(alias + strlen(alias), "%X", range_lo); 175 else if (range_lo > 0 || range_hi < max) { 176 if (range_lo > 0x9 || range_hi < 0xA) 177 sprintf(alias + strlen(alias), 178 "[%X-%X]", 179 range_lo, 180 range_hi); 181 else { 182 sprintf(alias + strlen(alias), 183 range_lo < 0x9 ? "[%X-9" : "[%X", 184 range_lo); 185 sprintf(alias + strlen(alias), 186 range_hi > 0xA ? "A-%X]" : "%X]", 187 range_hi); 188 } 189 } 190 if (bcdDevice_initial_digits < (sizeof(bcdDevice_lo) * 2 - 1)) 191 strcat(alias, "*"); 192 193 ADD(alias, "dc", match_flags&USB_DEVICE_ID_MATCH_DEV_CLASS, 194 bDeviceClass); 195 ADD(alias, "dsc", match_flags&USB_DEVICE_ID_MATCH_DEV_SUBCLASS, 196 bDeviceSubClass); 197 ADD(alias, "dp", match_flags&USB_DEVICE_ID_MATCH_DEV_PROTOCOL, 198 bDeviceProtocol); 199 ADD(alias, "ic", match_flags&USB_DEVICE_ID_MATCH_INT_CLASS, 200 bInterfaceClass); 201 ADD(alias, "isc", match_flags&USB_DEVICE_ID_MATCH_INT_SUBCLASS, 202 bInterfaceSubClass); 203 ADD(alias, "ip", match_flags&USB_DEVICE_ID_MATCH_INT_PROTOCOL, 204 bInterfaceProtocol); 205 ADD(alias, "in", match_flags&USB_DEVICE_ID_MATCH_INT_NUMBER, 206 bInterfaceNumber); 207 208 add_wildcard(alias); 209 buf_printf(&mod->dev_table_buf, 210 "MODULE_ALIAS(\"%s\");\n", alias); 211 } 212 213 /* Handles increment/decrement of BCD formatted integers */ 214 /* Returns the previous value, so it works like i++ or i-- */ 215 static unsigned int incbcd(unsigned int *bcd, 216 int inc, 217 unsigned char max, 218 size_t chars) 219 { 220 unsigned int init = *bcd, i, j; 221 unsigned long long c, dec = 0; 222 223 /* If bcd is not in BCD format, just increment */ 224 if (max > 0x9) { 225 *bcd += inc; 226 return init; 227 } 228 229 /* Convert BCD to Decimal */ 230 for (i=0 ; i < chars ; i++) { 231 c = (*bcd >> (i << 2)) & 0xf; 232 c = c > 9 ? 9 : c; /* force to bcd just in case */ 233 for (j=0 ; j < i ; j++) 234 c = c * 10; 235 dec += c; 236 } 237 238 /* Do our increment/decrement */ 239 dec += inc; 240 *bcd = 0; 241 242 /* Convert back to BCD */ 243 for (i=0 ; i < chars ; i++) { 244 for (c=1,j=0 ; j < i ; j++) 245 c = c * 10; 246 c = (dec / c) % 10; 247 *bcd += c << (i << 2); 248 } 249 return init; 250 } 251 252 static void do_usb_entry_multi(void *symval, struct module *mod) 253 { 254 unsigned int devlo, devhi; 255 unsigned char chi, clo, max; 256 int ndigits; 257 258 DEF_FIELD(symval, usb_device_id, match_flags); 259 DEF_FIELD(symval, usb_device_id, idVendor); 260 DEF_FIELD(symval, usb_device_id, idProduct); 261 DEF_FIELD(symval, usb_device_id, bcdDevice_lo); 262 DEF_FIELD(symval, usb_device_id, bcdDevice_hi); 263 DEF_FIELD(symval, usb_device_id, bDeviceClass); 264 DEF_FIELD(symval, usb_device_id, bInterfaceClass); 265 266 devlo = match_flags & USB_DEVICE_ID_MATCH_DEV_LO ? 267 bcdDevice_lo : 0x0U; 268 devhi = match_flags & USB_DEVICE_ID_MATCH_DEV_HI ? 269 bcdDevice_hi : ~0x0U; 270 271 /* Figure out if this entry is in bcd or hex format */ 272 max = 0x9; /* Default to decimal format */ 273 for (ndigits = 0 ; ndigits < sizeof(bcdDevice_lo) * 2 ; ndigits++) { 274 clo = (devlo >> (ndigits << 2)) & 0xf; 275 chi = ((devhi > 0x9999 ? 0x9999 : devhi) >> (ndigits << 2)) & 0xf; 276 if (clo > max || chi > max) { 277 max = 0xf; 278 break; 279 } 280 } 281 282 /* 283 * Some modules (visor) have empty slots as placeholder for 284 * run-time specification that results in catch-all alias 285 */ 286 if (!(idVendor | idProduct | bDeviceClass | bInterfaceClass)) 287 return; 288 289 /* Convert numeric bcdDevice range into fnmatch-able pattern(s) */ 290 for (ndigits = sizeof(bcdDevice_lo) * 2 - 1; devlo <= devhi; ndigits--) { 291 clo = devlo & 0xf; 292 chi = devhi & 0xf; 293 if (chi > max) /* If we are in bcd mode, truncate if necessary */ 294 chi = max; 295 devlo >>= 4; 296 devhi >>= 4; 297 298 if (devlo == devhi || !ndigits) { 299 do_usb_entry(symval, devlo, ndigits, clo, chi, max, mod); 300 break; 301 } 302 303 if (clo > 0x0) 304 do_usb_entry(symval, 305 incbcd(&devlo, 1, max, 306 sizeof(bcdDevice_lo) * 2), 307 ndigits, clo, max, max, mod); 308 309 if (chi < max) 310 do_usb_entry(symval, 311 incbcd(&devhi, -1, max, 312 sizeof(bcdDevice_lo) * 2), 313 ndigits, 0x0, chi, max, mod); 314 } 315 } 316 317 static void do_usb_table(void *symval, unsigned long size, 318 struct module *mod) 319 { 320 unsigned int i; 321 const unsigned long id_size = SIZE_usb_device_id; 322 323 device_id_check(mod->name, "usb", size, id_size, symval); 324 325 /* Leave last one: it's the terminator. */ 326 size -= id_size; 327 328 for (i = 0; i < size; i += id_size) 329 do_usb_entry_multi(symval + i, mod); 330 } 331 332 static void do_of_entry_multi(void *symval, struct module *mod) 333 { 334 char alias[500]; 335 int len; 336 char *tmp; 337 338 DEF_FIELD_ADDR(symval, of_device_id, name); 339 DEF_FIELD_ADDR(symval, of_device_id, type); 340 DEF_FIELD_ADDR(symval, of_device_id, compatible); 341 342 len = sprintf(alias, "of:N%sT%s", (*name)[0] ? *name : "*", 343 (*type)[0] ? *type : "*"); 344 345 if ((*compatible)[0]) 346 sprintf(&alias[len], "%sC%s", (*type)[0] ? "*" : "", 347 *compatible); 348 349 /* Replace all whitespace with underscores */ 350 for (tmp = alias; tmp && *tmp; tmp++) 351 if (isspace(*tmp)) 352 *tmp = '_'; 353 354 buf_printf(&mod->dev_table_buf, "MODULE_ALIAS(\"%s\");\n", alias); 355 strcat(alias, "C"); 356 add_wildcard(alias); 357 buf_printf(&mod->dev_table_buf, "MODULE_ALIAS(\"%s\");\n", alias); 358 } 359 360 static void do_of_table(void *symval, unsigned long size, 361 struct module *mod) 362 { 363 unsigned int i; 364 const unsigned long id_size = SIZE_of_device_id; 365 366 device_id_check(mod->name, "of", size, id_size, symval); 367 368 /* Leave last one: it's the terminator. */ 369 size -= id_size; 370 371 for (i = 0; i < size; i += id_size) 372 do_of_entry_multi(symval + i, mod); 373 } 374 375 /* Looks like: hid:bNvNpN */ 376 static int do_hid_entry(const char *filename, 377 void *symval, char *alias) 378 { 379 DEF_FIELD(symval, hid_device_id, bus); 380 DEF_FIELD(symval, hid_device_id, group); 381 DEF_FIELD(symval, hid_device_id, vendor); 382 DEF_FIELD(symval, hid_device_id, product); 383 384 sprintf(alias, "hid:"); 385 ADD(alias, "b", bus != HID_BUS_ANY, bus); 386 ADD(alias, "g", group != HID_GROUP_ANY, group); 387 ADD(alias, "v", vendor != HID_ANY_ID, vendor); 388 ADD(alias, "p", product != HID_ANY_ID, product); 389 390 return 1; 391 } 392 393 /* Looks like: ieee1394:venNmoNspNverN */ 394 static int do_ieee1394_entry(const char *filename, 395 void *symval, char *alias) 396 { 397 DEF_FIELD(symval, ieee1394_device_id, match_flags); 398 DEF_FIELD(symval, ieee1394_device_id, vendor_id); 399 DEF_FIELD(symval, ieee1394_device_id, model_id); 400 DEF_FIELD(symval, ieee1394_device_id, specifier_id); 401 DEF_FIELD(symval, ieee1394_device_id, version); 402 403 strcpy(alias, "ieee1394:"); 404 ADD(alias, "ven", match_flags & IEEE1394_MATCH_VENDOR_ID, 405 vendor_id); 406 ADD(alias, "mo", match_flags & IEEE1394_MATCH_MODEL_ID, 407 model_id); 408 ADD(alias, "sp", match_flags & IEEE1394_MATCH_SPECIFIER_ID, 409 specifier_id); 410 ADD(alias, "ver", match_flags & IEEE1394_MATCH_VERSION, 411 version); 412 413 add_wildcard(alias); 414 return 1; 415 } 416 417 /* Looks like: pci:vNdNsvNsdNbcNscNiN. */ 418 static int do_pci_entry(const char *filename, 419 void *symval, char *alias) 420 { 421 /* Class field can be divided into these three. */ 422 unsigned char baseclass, subclass, interface, 423 baseclass_mask, subclass_mask, interface_mask; 424 425 DEF_FIELD(symval, pci_device_id, vendor); 426 DEF_FIELD(symval, pci_device_id, device); 427 DEF_FIELD(symval, pci_device_id, subvendor); 428 DEF_FIELD(symval, pci_device_id, subdevice); 429 DEF_FIELD(symval, pci_device_id, class); 430 DEF_FIELD(symval, pci_device_id, class_mask); 431 432 strcpy(alias, "pci:"); 433 ADD(alias, "v", vendor != PCI_ANY_ID, vendor); 434 ADD(alias, "d", device != PCI_ANY_ID, device); 435 ADD(alias, "sv", subvendor != PCI_ANY_ID, subvendor); 436 ADD(alias, "sd", subdevice != PCI_ANY_ID, subdevice); 437 438 baseclass = (class) >> 16; 439 baseclass_mask = (class_mask) >> 16; 440 subclass = (class) >> 8; 441 subclass_mask = (class_mask) >> 8; 442 interface = class; 443 interface_mask = class_mask; 444 445 if ((baseclass_mask != 0 && baseclass_mask != 0xFF) 446 || (subclass_mask != 0 && subclass_mask != 0xFF) 447 || (interface_mask != 0 && interface_mask != 0xFF)) { 448 warn("Can't handle masks in %s:%04X\n", 449 filename, class_mask); 450 return 0; 451 } 452 453 ADD(alias, "bc", baseclass_mask == 0xFF, baseclass); 454 ADD(alias, "sc", subclass_mask == 0xFF, subclass); 455 ADD(alias, "i", interface_mask == 0xFF, interface); 456 add_wildcard(alias); 457 return 1; 458 } 459 460 /* looks like: "ccw:tNmNdtNdmN" */ 461 static int do_ccw_entry(const char *filename, 462 void *symval, char *alias) 463 { 464 DEF_FIELD(symval, ccw_device_id, match_flags); 465 DEF_FIELD(symval, ccw_device_id, cu_type); 466 DEF_FIELD(symval, ccw_device_id, cu_model); 467 DEF_FIELD(symval, ccw_device_id, dev_type); 468 DEF_FIELD(symval, ccw_device_id, dev_model); 469 470 strcpy(alias, "ccw:"); 471 ADD(alias, "t", match_flags&CCW_DEVICE_ID_MATCH_CU_TYPE, 472 cu_type); 473 ADD(alias, "m", match_flags&CCW_DEVICE_ID_MATCH_CU_MODEL, 474 cu_model); 475 ADD(alias, "dt", match_flags&CCW_DEVICE_ID_MATCH_DEVICE_TYPE, 476 dev_type); 477 ADD(alias, "dm", match_flags&CCW_DEVICE_ID_MATCH_DEVICE_MODEL, 478 dev_model); 479 add_wildcard(alias); 480 return 1; 481 } 482 483 /* looks like: "ap:tN" */ 484 static int do_ap_entry(const char *filename, 485 void *symval, char *alias) 486 { 487 DEF_FIELD(symval, ap_device_id, dev_type); 488 489 sprintf(alias, "ap:t%02X*", dev_type); 490 return 1; 491 } 492 493 /* looks like: "css:tN" */ 494 static int do_css_entry(const char *filename, 495 void *symval, char *alias) 496 { 497 DEF_FIELD(symval, css_device_id, type); 498 499 sprintf(alias, "css:t%01X", type); 500 return 1; 501 } 502 503 /* Looks like: "serio:tyNprNidNexN" */ 504 static int do_serio_entry(const char *filename, 505 void *symval, char *alias) 506 { 507 DEF_FIELD(symval, serio_device_id, type); 508 DEF_FIELD(symval, serio_device_id, proto); 509 DEF_FIELD(symval, serio_device_id, id); 510 DEF_FIELD(symval, serio_device_id, extra); 511 512 strcpy(alias, "serio:"); 513 ADD(alias, "ty", type != SERIO_ANY, type); 514 ADD(alias, "pr", proto != SERIO_ANY, proto); 515 ADD(alias, "id", id != SERIO_ANY, id); 516 ADD(alias, "ex", extra != SERIO_ANY, extra); 517 518 add_wildcard(alias); 519 return 1; 520 } 521 522 /* looks like: "acpi:ACPI0003" or "acpi:PNP0C0B" or "acpi:LNXVIDEO" or 523 * "acpi:bbsspp" (bb=base-class, ss=sub-class, pp=prog-if) 524 * 525 * NOTE: Each driver should use one of the following : _HID, _CIDs 526 * or _CLS. Also, bb, ss, and pp can be substituted with ?? 527 * as don't care byte. 528 */ 529 static int do_acpi_entry(const char *filename, 530 void *symval, char *alias) 531 { 532 DEF_FIELD_ADDR(symval, acpi_device_id, id); 533 DEF_FIELD_ADDR(symval, acpi_device_id, cls); 534 DEF_FIELD_ADDR(symval, acpi_device_id, cls_msk); 535 536 if (id && strlen((const char *)*id)) 537 sprintf(alias, "acpi*:%s:*", *id); 538 else if (cls) { 539 int i, byte_shift, cnt = 0; 540 unsigned int msk; 541 542 sprintf(&alias[cnt], "acpi*:"); 543 cnt = 6; 544 for (i = 1; i <= 3; i++) { 545 byte_shift = 8 * (3-i); 546 msk = (*cls_msk >> byte_shift) & 0xFF; 547 if (msk) 548 sprintf(&alias[cnt], "%02x", 549 (*cls >> byte_shift) & 0xFF); 550 else 551 sprintf(&alias[cnt], "??"); 552 cnt += 2; 553 } 554 sprintf(&alias[cnt], ":*"); 555 } 556 return 1; 557 } 558 559 /* looks like: "pnp:dD" */ 560 static void do_pnp_device_entry(void *symval, unsigned long size, 561 struct module *mod) 562 { 563 const unsigned long id_size = SIZE_pnp_device_id; 564 const unsigned int count = (size / id_size)-1; 565 unsigned int i; 566 567 device_id_check(mod->name, "pnp", size, id_size, symval); 568 569 for (i = 0; i < count; i++) { 570 DEF_FIELD_ADDR(symval + i*id_size, pnp_device_id, id); 571 char acpi_id[sizeof(*id)]; 572 int j; 573 574 buf_printf(&mod->dev_table_buf, 575 "MODULE_ALIAS(\"pnp:d%s*\");\n", *id); 576 577 /* fix broken pnp bus lowercasing */ 578 for (j = 0; j < sizeof(acpi_id); j++) 579 acpi_id[j] = toupper((*id)[j]); 580 buf_printf(&mod->dev_table_buf, 581 "MODULE_ALIAS(\"acpi*:%s:*\");\n", acpi_id); 582 } 583 } 584 585 /* looks like: "pnp:dD" for every device of the card */ 586 static void do_pnp_card_entries(void *symval, unsigned long size, 587 struct module *mod) 588 { 589 const unsigned long id_size = SIZE_pnp_card_device_id; 590 const unsigned int count = (size / id_size)-1; 591 unsigned int i; 592 593 device_id_check(mod->name, "pnp", size, id_size, symval); 594 595 for (i = 0; i < count; i++) { 596 unsigned int j; 597 DEF_FIELD_ADDR(symval + i * id_size, pnp_card_device_id, devs); 598 599 for (j = 0; j < PNP_MAX_DEVICES; j++) { 600 const char *id = (char *)(*devs)[j].id; 601 int i2, j2; 602 int dup = 0; 603 604 if (!id[0]) 605 break; 606 607 /* find duplicate, already added value */ 608 for (i2 = 0; i2 < i && !dup; i2++) { 609 DEF_FIELD_ADDR_VAR(symval + i2 * id_size, 610 pnp_card_device_id, 611 devs, devs_dup); 612 613 for (j2 = 0; j2 < PNP_MAX_DEVICES; j2++) { 614 const char *id2 = 615 (char *)(*devs_dup)[j2].id; 616 617 if (!id2[0]) 618 break; 619 620 if (!strcmp(id, id2)) { 621 dup = 1; 622 break; 623 } 624 } 625 } 626 627 /* add an individual alias for every device entry */ 628 if (!dup) { 629 char acpi_id[PNP_ID_LEN]; 630 int k; 631 632 buf_printf(&mod->dev_table_buf, 633 "MODULE_ALIAS(\"pnp:d%s*\");\n", id); 634 635 /* fix broken pnp bus lowercasing */ 636 for (k = 0; k < sizeof(acpi_id); k++) 637 acpi_id[k] = toupper(id[k]); 638 buf_printf(&mod->dev_table_buf, 639 "MODULE_ALIAS(\"acpi*:%s:*\");\n", acpi_id); 640 } 641 } 642 } 643 } 644 645 /* Looks like: pcmcia:mNcNfNfnNpfnNvaNvbNvcNvdN. */ 646 static int do_pcmcia_entry(const char *filename, 647 void *symval, char *alias) 648 { 649 unsigned int i; 650 DEF_FIELD(symval, pcmcia_device_id, match_flags); 651 DEF_FIELD(symval, pcmcia_device_id, manf_id); 652 DEF_FIELD(symval, pcmcia_device_id, card_id); 653 DEF_FIELD(symval, pcmcia_device_id, func_id); 654 DEF_FIELD(symval, pcmcia_device_id, function); 655 DEF_FIELD(symval, pcmcia_device_id, device_no); 656 DEF_FIELD_ADDR(symval, pcmcia_device_id, prod_id_hash); 657 658 for (i=0; i<4; i++) { 659 (*prod_id_hash)[i] = TO_NATIVE((*prod_id_hash)[i]); 660 } 661 662 strcpy(alias, "pcmcia:"); 663 ADD(alias, "m", match_flags & PCMCIA_DEV_ID_MATCH_MANF_ID, 664 manf_id); 665 ADD(alias, "c", match_flags & PCMCIA_DEV_ID_MATCH_CARD_ID, 666 card_id); 667 ADD(alias, "f", match_flags & PCMCIA_DEV_ID_MATCH_FUNC_ID, 668 func_id); 669 ADD(alias, "fn", match_flags & PCMCIA_DEV_ID_MATCH_FUNCTION, 670 function); 671 ADD(alias, "pfn", match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO, 672 device_no); 673 ADD(alias, "pa", match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID1, (*prod_id_hash)[0]); 674 ADD(alias, "pb", match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID2, (*prod_id_hash)[1]); 675 ADD(alias, "pc", match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID3, (*prod_id_hash)[2]); 676 ADD(alias, "pd", match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID4, (*prod_id_hash)[3]); 677 678 add_wildcard(alias); 679 return 1; 680 } 681 682 static int do_vio_entry(const char *filename, void *symval, 683 char *alias) 684 { 685 char *tmp; 686 DEF_FIELD_ADDR(symval, vio_device_id, type); 687 DEF_FIELD_ADDR(symval, vio_device_id, compat); 688 689 sprintf(alias, "vio:T%sS%s", (*type)[0] ? *type : "*", 690 (*compat)[0] ? *compat : "*"); 691 692 /* Replace all whitespace with underscores */ 693 for (tmp = alias; tmp && *tmp; tmp++) 694 if (isspace (*tmp)) 695 *tmp = '_'; 696 697 add_wildcard(alias); 698 return 1; 699 } 700 701 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 702 703 static void do_input(char *alias, 704 kernel_ulong_t *arr, unsigned int min, unsigned int max) 705 { 706 unsigned int i; 707 708 for (i = min / BITS_PER_LONG; i < max / BITS_PER_LONG + 1; i++) 709 arr[i] = TO_NATIVE(arr[i]); 710 for (i = min; i < max; i++) 711 if (arr[i / BITS_PER_LONG] & (1L << (i%BITS_PER_LONG))) 712 sprintf(alias + strlen(alias), "%X,*", i); 713 } 714 715 /* input:b0v0p0e0-eXkXrXaXmXlXsXfXwX where X is comma-separated %02X. */ 716 static int do_input_entry(const char *filename, void *symval, 717 char *alias) 718 { 719 DEF_FIELD(symval, input_device_id, flags); 720 DEF_FIELD(symval, input_device_id, bustype); 721 DEF_FIELD(symval, input_device_id, vendor); 722 DEF_FIELD(symval, input_device_id, product); 723 DEF_FIELD(symval, input_device_id, version); 724 DEF_FIELD_ADDR(symval, input_device_id, evbit); 725 DEF_FIELD_ADDR(symval, input_device_id, keybit); 726 DEF_FIELD_ADDR(symval, input_device_id, relbit); 727 DEF_FIELD_ADDR(symval, input_device_id, absbit); 728 DEF_FIELD_ADDR(symval, input_device_id, mscbit); 729 DEF_FIELD_ADDR(symval, input_device_id, ledbit); 730 DEF_FIELD_ADDR(symval, input_device_id, sndbit); 731 DEF_FIELD_ADDR(symval, input_device_id, ffbit); 732 DEF_FIELD_ADDR(symval, input_device_id, swbit); 733 734 sprintf(alias, "input:"); 735 736 ADD(alias, "b", flags & INPUT_DEVICE_ID_MATCH_BUS, bustype); 737 ADD(alias, "v", flags & INPUT_DEVICE_ID_MATCH_VENDOR, vendor); 738 ADD(alias, "p", flags & INPUT_DEVICE_ID_MATCH_PRODUCT, product); 739 ADD(alias, "e", flags & INPUT_DEVICE_ID_MATCH_VERSION, version); 740 741 sprintf(alias + strlen(alias), "-e*"); 742 if (flags & INPUT_DEVICE_ID_MATCH_EVBIT) 743 do_input(alias, *evbit, 0, INPUT_DEVICE_ID_EV_MAX); 744 sprintf(alias + strlen(alias), "k*"); 745 if (flags & INPUT_DEVICE_ID_MATCH_KEYBIT) 746 do_input(alias, *keybit, 747 INPUT_DEVICE_ID_KEY_MIN_INTERESTING, 748 INPUT_DEVICE_ID_KEY_MAX); 749 sprintf(alias + strlen(alias), "r*"); 750 if (flags & INPUT_DEVICE_ID_MATCH_RELBIT) 751 do_input(alias, *relbit, 0, INPUT_DEVICE_ID_REL_MAX); 752 sprintf(alias + strlen(alias), "a*"); 753 if (flags & INPUT_DEVICE_ID_MATCH_ABSBIT) 754 do_input(alias, *absbit, 0, INPUT_DEVICE_ID_ABS_MAX); 755 sprintf(alias + strlen(alias), "m*"); 756 if (flags & INPUT_DEVICE_ID_MATCH_MSCIT) 757 do_input(alias, *mscbit, 0, INPUT_DEVICE_ID_MSC_MAX); 758 sprintf(alias + strlen(alias), "l*"); 759 if (flags & INPUT_DEVICE_ID_MATCH_LEDBIT) 760 do_input(alias, *ledbit, 0, INPUT_DEVICE_ID_LED_MAX); 761 sprintf(alias + strlen(alias), "s*"); 762 if (flags & INPUT_DEVICE_ID_MATCH_SNDBIT) 763 do_input(alias, *sndbit, 0, INPUT_DEVICE_ID_SND_MAX); 764 sprintf(alias + strlen(alias), "f*"); 765 if (flags & INPUT_DEVICE_ID_MATCH_FFBIT) 766 do_input(alias, *ffbit, 0, INPUT_DEVICE_ID_FF_MAX); 767 sprintf(alias + strlen(alias), "w*"); 768 if (flags & INPUT_DEVICE_ID_MATCH_SWBIT) 769 do_input(alias, *swbit, 0, INPUT_DEVICE_ID_SW_MAX); 770 return 1; 771 } 772 773 static int do_eisa_entry(const char *filename, void *symval, 774 char *alias) 775 { 776 DEF_FIELD_ADDR(symval, eisa_device_id, sig); 777 if (sig[0]) 778 sprintf(alias, EISA_DEVICE_MODALIAS_FMT "*", *sig); 779 else 780 strcat(alias, "*"); 781 return 1; 782 } 783 784 /* Looks like: parisc:tNhvNrevNsvN */ 785 static int do_parisc_entry(const char *filename, void *symval, 786 char *alias) 787 { 788 DEF_FIELD(symval, parisc_device_id, hw_type); 789 DEF_FIELD(symval, parisc_device_id, hversion); 790 DEF_FIELD(symval, parisc_device_id, hversion_rev); 791 DEF_FIELD(symval, parisc_device_id, sversion); 792 793 strcpy(alias, "parisc:"); 794 ADD(alias, "t", hw_type != PA_HWTYPE_ANY_ID, hw_type); 795 ADD(alias, "hv", hversion != PA_HVERSION_ANY_ID, hversion); 796 ADD(alias, "rev", hversion_rev != PA_HVERSION_REV_ANY_ID, hversion_rev); 797 ADD(alias, "sv", sversion != PA_SVERSION_ANY_ID, sversion); 798 799 add_wildcard(alias); 800 return 1; 801 } 802 803 /* Looks like: sdio:cNvNdN. */ 804 static int do_sdio_entry(const char *filename, 805 void *symval, char *alias) 806 { 807 DEF_FIELD(symval, sdio_device_id, class); 808 DEF_FIELD(symval, sdio_device_id, vendor); 809 DEF_FIELD(symval, sdio_device_id, device); 810 811 strcpy(alias, "sdio:"); 812 ADD(alias, "c", class != (__u8)SDIO_ANY_ID, class); 813 ADD(alias, "v", vendor != (__u16)SDIO_ANY_ID, vendor); 814 ADD(alias, "d", device != (__u16)SDIO_ANY_ID, device); 815 add_wildcard(alias); 816 return 1; 817 } 818 819 /* Looks like: ssb:vNidNrevN. */ 820 static int do_ssb_entry(const char *filename, 821 void *symval, char *alias) 822 { 823 DEF_FIELD(symval, ssb_device_id, vendor); 824 DEF_FIELD(symval, ssb_device_id, coreid); 825 DEF_FIELD(symval, ssb_device_id, revision); 826 827 strcpy(alias, "ssb:"); 828 ADD(alias, "v", vendor != SSB_ANY_VENDOR, vendor); 829 ADD(alias, "id", coreid != SSB_ANY_ID, coreid); 830 ADD(alias, "rev", revision != SSB_ANY_REV, revision); 831 add_wildcard(alias); 832 return 1; 833 } 834 835 /* Looks like: bcma:mNidNrevNclN. */ 836 static int do_bcma_entry(const char *filename, 837 void *symval, char *alias) 838 { 839 DEF_FIELD(symval, bcma_device_id, manuf); 840 DEF_FIELD(symval, bcma_device_id, id); 841 DEF_FIELD(symval, bcma_device_id, rev); 842 DEF_FIELD(symval, bcma_device_id, class); 843 844 strcpy(alias, "bcma:"); 845 ADD(alias, "m", manuf != BCMA_ANY_MANUF, manuf); 846 ADD(alias, "id", id != BCMA_ANY_ID, id); 847 ADD(alias, "rev", rev != BCMA_ANY_REV, rev); 848 ADD(alias, "cl", class != BCMA_ANY_CLASS, class); 849 add_wildcard(alias); 850 return 1; 851 } 852 853 /* Looks like: virtio:dNvN */ 854 static int do_virtio_entry(const char *filename, void *symval, 855 char *alias) 856 { 857 DEF_FIELD(symval, virtio_device_id, device); 858 DEF_FIELD(symval, virtio_device_id, vendor); 859 860 strcpy(alias, "virtio:"); 861 ADD(alias, "d", device != VIRTIO_DEV_ANY_ID, device); 862 ADD(alias, "v", vendor != VIRTIO_DEV_ANY_ID, vendor); 863 864 add_wildcard(alias); 865 return 1; 866 } 867 868 /* 869 * Looks like: vmbus:guid 870 * Each byte of the guid will be represented by two hex characters 871 * in the name. 872 */ 873 874 static int do_vmbus_entry(const char *filename, void *symval, 875 char *alias) 876 { 877 int i; 878 DEF_FIELD_ADDR(symval, hv_vmbus_device_id, guid); 879 char guid_name[(sizeof(*guid) + 1) * 2]; 880 881 for (i = 0; i < (sizeof(*guid) * 2); i += 2) 882 sprintf(&guid_name[i], "%02x", TO_NATIVE((guid->b)[i/2])); 883 884 strcpy(alias, "vmbus:"); 885 strcat(alias, guid_name); 886 887 return 1; 888 } 889 890 /* Looks like: rpmsg:S */ 891 static int do_rpmsg_entry(const char *filename, void *symval, 892 char *alias) 893 { 894 DEF_FIELD_ADDR(symval, rpmsg_device_id, name); 895 sprintf(alias, RPMSG_DEVICE_MODALIAS_FMT, *name); 896 897 return 1; 898 } 899 900 /* Looks like: i2c:S */ 901 static int do_i2c_entry(const char *filename, void *symval, 902 char *alias) 903 { 904 DEF_FIELD_ADDR(symval, i2c_device_id, name); 905 sprintf(alias, I2C_MODULE_PREFIX "%s", *name); 906 907 return 1; 908 } 909 910 /* Looks like: spi:S */ 911 static int do_spi_entry(const char *filename, void *symval, 912 char *alias) 913 { 914 DEF_FIELD_ADDR(symval, spi_device_id, name); 915 sprintf(alias, SPI_MODULE_PREFIX "%s", *name); 916 917 return 1; 918 } 919 920 static const struct dmifield { 921 const char *prefix; 922 int field; 923 } dmi_fields[] = { 924 { "bvn", DMI_BIOS_VENDOR }, 925 { "bvr", DMI_BIOS_VERSION }, 926 { "bd", DMI_BIOS_DATE }, 927 { "svn", DMI_SYS_VENDOR }, 928 { "pn", DMI_PRODUCT_NAME }, 929 { "pvr", DMI_PRODUCT_VERSION }, 930 { "rvn", DMI_BOARD_VENDOR }, 931 { "rn", DMI_BOARD_NAME }, 932 { "rvr", DMI_BOARD_VERSION }, 933 { "cvn", DMI_CHASSIS_VENDOR }, 934 { "ct", DMI_CHASSIS_TYPE }, 935 { "cvr", DMI_CHASSIS_VERSION }, 936 { NULL, DMI_NONE } 937 }; 938 939 static void dmi_ascii_filter(char *d, const char *s) 940 { 941 /* Filter out characters we don't want to see in the modalias string */ 942 for (; *s; s++) 943 if (*s > ' ' && *s < 127 && *s != ':') 944 *(d++) = *s; 945 946 *d = 0; 947 } 948 949 950 static int do_dmi_entry(const char *filename, void *symval, 951 char *alias) 952 { 953 int i, j; 954 DEF_FIELD_ADDR(symval, dmi_system_id, matches); 955 sprintf(alias, "dmi*"); 956 957 for (i = 0; i < ARRAY_SIZE(dmi_fields); i++) { 958 for (j = 0; j < 4; j++) { 959 if ((*matches)[j].slot && 960 (*matches)[j].slot == dmi_fields[i].field) { 961 sprintf(alias + strlen(alias), ":%s*", 962 dmi_fields[i].prefix); 963 dmi_ascii_filter(alias + strlen(alias), 964 (*matches)[j].substr); 965 strcat(alias, "*"); 966 } 967 } 968 } 969 970 strcat(alias, ":"); 971 return 1; 972 } 973 974 static int do_platform_entry(const char *filename, 975 void *symval, char *alias) 976 { 977 DEF_FIELD_ADDR(symval, platform_device_id, name); 978 sprintf(alias, PLATFORM_MODULE_PREFIX "%s", *name); 979 return 1; 980 } 981 982 static int do_mdio_entry(const char *filename, 983 void *symval, char *alias) 984 { 985 int i; 986 DEF_FIELD(symval, mdio_device_id, phy_id); 987 DEF_FIELD(symval, mdio_device_id, phy_id_mask); 988 989 alias += sprintf(alias, MDIO_MODULE_PREFIX); 990 991 for (i = 0; i < 32; i++) { 992 if (!((phy_id_mask >> (31-i)) & 1)) 993 *(alias++) = '?'; 994 else if ((phy_id >> (31-i)) & 1) 995 *(alias++) = '1'; 996 else 997 *(alias++) = '0'; 998 } 999 1000 /* Terminate the string */ 1001 *alias = 0; 1002 1003 return 1; 1004 } 1005 1006 /* Looks like: zorro:iN. */ 1007 static int do_zorro_entry(const char *filename, void *symval, 1008 char *alias) 1009 { 1010 DEF_FIELD(symval, zorro_device_id, id); 1011 strcpy(alias, "zorro:"); 1012 ADD(alias, "i", id != ZORRO_WILDCARD, id); 1013 return 1; 1014 } 1015 1016 /* looks like: "pnp:dD" */ 1017 static int do_isapnp_entry(const char *filename, 1018 void *symval, char *alias) 1019 { 1020 DEF_FIELD(symval, isapnp_device_id, vendor); 1021 DEF_FIELD(symval, isapnp_device_id, function); 1022 sprintf(alias, "pnp:d%c%c%c%x%x%x%x*", 1023 'A' + ((vendor >> 2) & 0x3f) - 1, 1024 'A' + (((vendor & 3) << 3) | ((vendor >> 13) & 7)) - 1, 1025 'A' + ((vendor >> 8) & 0x1f) - 1, 1026 (function >> 4) & 0x0f, function & 0x0f, 1027 (function >> 12) & 0x0f, (function >> 8) & 0x0f); 1028 return 1; 1029 } 1030 1031 /* Looks like: "ipack:fNvNdN". */ 1032 static int do_ipack_entry(const char *filename, 1033 void *symval, char *alias) 1034 { 1035 DEF_FIELD(symval, ipack_device_id, format); 1036 DEF_FIELD(symval, ipack_device_id, vendor); 1037 DEF_FIELD(symval, ipack_device_id, device); 1038 strcpy(alias, "ipack:"); 1039 ADD(alias, "f", format != IPACK_ANY_FORMAT, format); 1040 ADD(alias, "v", vendor != IPACK_ANY_ID, vendor); 1041 ADD(alias, "d", device != IPACK_ANY_ID, device); 1042 add_wildcard(alias); 1043 return 1; 1044 } 1045 1046 /* 1047 * Append a match expression for a single masked hex digit. 1048 * outp points to a pointer to the character at which to append. 1049 * *outp is updated on return to point just after the appended text, 1050 * to facilitate further appending. 1051 */ 1052 static void append_nibble_mask(char **outp, 1053 unsigned int nibble, unsigned int mask) 1054 { 1055 char *p = *outp; 1056 unsigned int i; 1057 1058 switch (mask) { 1059 case 0: 1060 *p++ = '?'; 1061 break; 1062 1063 case 0xf: 1064 p += sprintf(p, "%X", nibble); 1065 break; 1066 1067 default: 1068 /* 1069 * Dumbly emit a match pattern for all possible matching 1070 * digits. This could be improved in some cases using ranges, 1071 * but it has the advantage of being trivially correct, and is 1072 * often optimal. 1073 */ 1074 *p++ = '['; 1075 for (i = 0; i < 0x10; i++) 1076 if ((i & mask) == nibble) 1077 p += sprintf(p, "%X", i); 1078 *p++ = ']'; 1079 } 1080 1081 /* Ensure that the string remains NUL-terminated: */ 1082 *p = '\0'; 1083 1084 /* Advance the caller's end-of-string pointer: */ 1085 *outp = p; 1086 } 1087 1088 /* 1089 * looks like: "amba:dN" 1090 * 1091 * N is exactly 8 digits, where each is an upper-case hex digit, or 1092 * a ? or [] pattern matching exactly one digit. 1093 */ 1094 static int do_amba_entry(const char *filename, 1095 void *symval, char *alias) 1096 { 1097 unsigned int digit; 1098 char *p = alias; 1099 DEF_FIELD(symval, amba_id, id); 1100 DEF_FIELD(symval, amba_id, mask); 1101 1102 if ((id & mask) != id) 1103 fatal("%s: Masked-off bit(s) of AMBA device ID are non-zero: " 1104 "id=0x%08X, mask=0x%08X. Please fix this driver.\n", 1105 filename, id, mask); 1106 1107 p += sprintf(alias, "amba:d"); 1108 for (digit = 0; digit < 8; digit++) 1109 append_nibble_mask(&p, 1110 (id >> (4 * (7 - digit))) & 0xf, 1111 (mask >> (4 * (7 - digit))) & 0xf); 1112 1113 return 1; 1114 } 1115 1116 /* 1117 * looks like: "mipscdmm:tN" 1118 * 1119 * N is exactly 2 digits, where each is an upper-case hex digit, or 1120 * a ? or [] pattern matching exactly one digit. 1121 */ 1122 static int do_mips_cdmm_entry(const char *filename, 1123 void *symval, char *alias) 1124 { 1125 DEF_FIELD(symval, mips_cdmm_device_id, type); 1126 1127 sprintf(alias, "mipscdmm:t%02X*", type); 1128 return 1; 1129 } 1130 1131 /* LOOKS like cpu:type:x86,venVVVVfamFFFFmodMMMM:feature:*,FEAT,* 1132 * All fields are numbers. It would be nicer to use strings for vendor 1133 * and feature, but getting those out of the build system here is too 1134 * complicated. 1135 */ 1136 1137 static int do_x86cpu_entry(const char *filename, void *symval, 1138 char *alias) 1139 { 1140 DEF_FIELD(symval, x86_cpu_id, feature); 1141 DEF_FIELD(symval, x86_cpu_id, family); 1142 DEF_FIELD(symval, x86_cpu_id, model); 1143 DEF_FIELD(symval, x86_cpu_id, vendor); 1144 1145 strcpy(alias, "cpu:type:x86,"); 1146 ADD(alias, "ven", vendor != X86_VENDOR_ANY, vendor); 1147 ADD(alias, "fam", family != X86_FAMILY_ANY, family); 1148 ADD(alias, "mod", model != X86_MODEL_ANY, model); 1149 strcat(alias, ":feature:*"); 1150 if (feature != X86_FEATURE_ANY) 1151 sprintf(alias + strlen(alias), "%04X*", feature); 1152 return 1; 1153 } 1154 1155 /* LOOKS like cpu:type:*:feature:*FEAT* */ 1156 static int do_cpu_entry(const char *filename, void *symval, char *alias) 1157 { 1158 DEF_FIELD(symval, cpu_feature, feature); 1159 1160 sprintf(alias, "cpu:type:*:feature:*%04X*", feature); 1161 return 1; 1162 } 1163 1164 /* Looks like: mei:S:uuid:N:* */ 1165 static int do_mei_entry(const char *filename, void *symval, 1166 char *alias) 1167 { 1168 DEF_FIELD_ADDR(symval, mei_cl_device_id, name); 1169 DEF_FIELD_ADDR(symval, mei_cl_device_id, uuid); 1170 DEF_FIELD(symval, mei_cl_device_id, version); 1171 1172 sprintf(alias, MEI_CL_MODULE_PREFIX); 1173 sprintf(alias + strlen(alias), "%s:", (*name)[0] ? *name : "*"); 1174 add_uuid(alias, *uuid); 1175 ADD(alias, ":", version != MEI_CL_VERSION_ANY, version); 1176 1177 strcat(alias, ":*"); 1178 1179 return 1; 1180 } 1181 1182 /* Looks like: rapidio:vNdNavNadN */ 1183 static int do_rio_entry(const char *filename, 1184 void *symval, char *alias) 1185 { 1186 DEF_FIELD(symval, rio_device_id, did); 1187 DEF_FIELD(symval, rio_device_id, vid); 1188 DEF_FIELD(symval, rio_device_id, asm_did); 1189 DEF_FIELD(symval, rio_device_id, asm_vid); 1190 1191 strcpy(alias, "rapidio:"); 1192 ADD(alias, "v", vid != RIO_ANY_ID, vid); 1193 ADD(alias, "d", did != RIO_ANY_ID, did); 1194 ADD(alias, "av", asm_vid != RIO_ANY_ID, asm_vid); 1195 ADD(alias, "ad", asm_did != RIO_ANY_ID, asm_did); 1196 1197 add_wildcard(alias); 1198 return 1; 1199 } 1200 1201 /* Looks like: ulpi:vNpN */ 1202 static int do_ulpi_entry(const char *filename, void *symval, 1203 char *alias) 1204 { 1205 DEF_FIELD(symval, ulpi_device_id, vendor); 1206 DEF_FIELD(symval, ulpi_device_id, product); 1207 1208 sprintf(alias, "ulpi:v%04xp%04x", vendor, product); 1209 1210 return 1; 1211 } 1212 1213 /* Looks like: hdaudio:vNrNaN */ 1214 static int do_hda_entry(const char *filename, void *symval, char *alias) 1215 { 1216 DEF_FIELD(symval, hda_device_id, vendor_id); 1217 DEF_FIELD(symval, hda_device_id, rev_id); 1218 DEF_FIELD(symval, hda_device_id, api_version); 1219 1220 strcpy(alias, "hdaudio:"); 1221 ADD(alias, "v", vendor_id != 0, vendor_id); 1222 ADD(alias, "r", rev_id != 0, rev_id); 1223 ADD(alias, "a", api_version != 0, api_version); 1224 1225 add_wildcard(alias); 1226 return 1; 1227 } 1228 1229 /* Looks like: sdw:mNpN */ 1230 static int do_sdw_entry(const char *filename, void *symval, char *alias) 1231 { 1232 DEF_FIELD(symval, sdw_device_id, mfg_id); 1233 DEF_FIELD(symval, sdw_device_id, part_id); 1234 1235 strcpy(alias, "sdw:"); 1236 ADD(alias, "m", mfg_id != 0, mfg_id); 1237 ADD(alias, "p", part_id != 0, part_id); 1238 1239 add_wildcard(alias); 1240 return 1; 1241 } 1242 1243 /* Looks like: fsl-mc:vNdN */ 1244 static int do_fsl_mc_entry(const char *filename, void *symval, 1245 char *alias) 1246 { 1247 DEF_FIELD(symval, fsl_mc_device_id, vendor); 1248 DEF_FIELD_ADDR(symval, fsl_mc_device_id, obj_type); 1249 1250 sprintf(alias, "fsl-mc:v%08Xd%s", vendor, *obj_type); 1251 return 1; 1252 } 1253 1254 /* Looks like: tbsvc:kSpNvNrN */ 1255 static int do_tbsvc_entry(const char *filename, void *symval, char *alias) 1256 { 1257 DEF_FIELD(symval, tb_service_id, match_flags); 1258 DEF_FIELD_ADDR(symval, tb_service_id, protocol_key); 1259 DEF_FIELD(symval, tb_service_id, protocol_id); 1260 DEF_FIELD(symval, tb_service_id, protocol_version); 1261 DEF_FIELD(symval, tb_service_id, protocol_revision); 1262 1263 strcpy(alias, "tbsvc:"); 1264 if (match_flags & TBSVC_MATCH_PROTOCOL_KEY) 1265 sprintf(alias + strlen(alias), "k%s", *protocol_key); 1266 else 1267 strcat(alias + strlen(alias), "k*"); 1268 ADD(alias, "p", match_flags & TBSVC_MATCH_PROTOCOL_ID, protocol_id); 1269 ADD(alias, "v", match_flags & TBSVC_MATCH_PROTOCOL_VERSION, 1270 protocol_version); 1271 ADD(alias, "r", match_flags & TBSVC_MATCH_PROTOCOL_REVISION, 1272 protocol_revision); 1273 1274 add_wildcard(alias); 1275 return 1; 1276 } 1277 1278 /* Looks like: typec:idNmN */ 1279 static int do_typec_entry(const char *filename, void *symval, char *alias) 1280 { 1281 DEF_FIELD(symval, typec_device_id, svid); 1282 DEF_FIELD(symval, typec_device_id, mode); 1283 1284 sprintf(alias, "typec:id%04X", svid); 1285 ADD(alias, "m", mode != TYPEC_ANY_MODE, mode); 1286 1287 return 1; 1288 } 1289 1290 /* Does namelen bytes of name exactly match the symbol? */ 1291 static bool sym_is(const char *name, unsigned namelen, const char *symbol) 1292 { 1293 if (namelen != strlen(symbol)) 1294 return false; 1295 1296 return memcmp(name, symbol, namelen) == 0; 1297 } 1298 1299 static void do_table(void *symval, unsigned long size, 1300 unsigned long id_size, 1301 const char *device_id, 1302 int (*do_entry)(const char *filename, void *symval, char *alias), 1303 struct module *mod) 1304 { 1305 unsigned int i; 1306 char alias[500]; 1307 1308 device_id_check(mod->name, device_id, size, id_size, symval); 1309 /* Leave last one: it's the terminator. */ 1310 size -= id_size; 1311 1312 for (i = 0; i < size; i += id_size) { 1313 if (do_entry(mod->name, symval+i, alias)) { 1314 buf_printf(&mod->dev_table_buf, 1315 "MODULE_ALIAS(\"%s\");\n", alias); 1316 } 1317 } 1318 } 1319 1320 static const struct devtable devtable[] = { 1321 {"hid", SIZE_hid_device_id, do_hid_entry}, 1322 {"ieee1394", SIZE_ieee1394_device_id, do_ieee1394_entry}, 1323 {"pci", SIZE_pci_device_id, do_pci_entry}, 1324 {"ccw", SIZE_ccw_device_id, do_ccw_entry}, 1325 {"ap", SIZE_ap_device_id, do_ap_entry}, 1326 {"css", SIZE_css_device_id, do_css_entry}, 1327 {"serio", SIZE_serio_device_id, do_serio_entry}, 1328 {"acpi", SIZE_acpi_device_id, do_acpi_entry}, 1329 {"pcmcia", SIZE_pcmcia_device_id, do_pcmcia_entry}, 1330 {"vio", SIZE_vio_device_id, do_vio_entry}, 1331 {"input", SIZE_input_device_id, do_input_entry}, 1332 {"eisa", SIZE_eisa_device_id, do_eisa_entry}, 1333 {"parisc", SIZE_parisc_device_id, do_parisc_entry}, 1334 {"sdio", SIZE_sdio_device_id, do_sdio_entry}, 1335 {"ssb", SIZE_ssb_device_id, do_ssb_entry}, 1336 {"bcma", SIZE_bcma_device_id, do_bcma_entry}, 1337 {"virtio", SIZE_virtio_device_id, do_virtio_entry}, 1338 {"vmbus", SIZE_hv_vmbus_device_id, do_vmbus_entry}, 1339 {"rpmsg", SIZE_rpmsg_device_id, do_rpmsg_entry}, 1340 {"i2c", SIZE_i2c_device_id, do_i2c_entry}, 1341 {"spi", SIZE_spi_device_id, do_spi_entry}, 1342 {"dmi", SIZE_dmi_system_id, do_dmi_entry}, 1343 {"platform", SIZE_platform_device_id, do_platform_entry}, 1344 {"mdio", SIZE_mdio_device_id, do_mdio_entry}, 1345 {"zorro", SIZE_zorro_device_id, do_zorro_entry}, 1346 {"isapnp", SIZE_isapnp_device_id, do_isapnp_entry}, 1347 {"ipack", SIZE_ipack_device_id, do_ipack_entry}, 1348 {"amba", SIZE_amba_id, do_amba_entry}, 1349 {"mipscdmm", SIZE_mips_cdmm_device_id, do_mips_cdmm_entry}, 1350 {"x86cpu", SIZE_x86_cpu_id, do_x86cpu_entry}, 1351 {"cpu", SIZE_cpu_feature, do_cpu_entry}, 1352 {"mei", SIZE_mei_cl_device_id, do_mei_entry}, 1353 {"rapidio", SIZE_rio_device_id, do_rio_entry}, 1354 {"ulpi", SIZE_ulpi_device_id, do_ulpi_entry}, 1355 {"hdaudio", SIZE_hda_device_id, do_hda_entry}, 1356 {"sdw", SIZE_sdw_device_id, do_sdw_entry}, 1357 {"fslmc", SIZE_fsl_mc_device_id, do_fsl_mc_entry}, 1358 {"tbsvc", SIZE_tb_service_id, do_tbsvc_entry}, 1359 {"typec", SIZE_typec_device_id, do_typec_entry}, 1360 }; 1361 1362 /* Create MODULE_ALIAS() statements. 1363 * At this time, we cannot write the actual output C source yet, 1364 * so we write into the mod->dev_table_buf buffer. */ 1365 void handle_moddevtable(struct module *mod, struct elf_info *info, 1366 Elf_Sym *sym, const char *symname) 1367 { 1368 void *symval; 1369 char *zeros = NULL; 1370 const char *name, *identifier; 1371 unsigned int namelen; 1372 1373 /* We're looking for a section relative symbol */ 1374 if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections) 1375 return; 1376 1377 /* We're looking for an object */ 1378 if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT) 1379 return; 1380 1381 /* All our symbols are of form __mod_<name>__<identifier>_device_table. */ 1382 if (strncmp(symname, "__mod_", strlen("__mod_"))) 1383 return; 1384 name = symname + strlen("__mod_"); 1385 namelen = strlen(name); 1386 if (namelen < strlen("_device_table")) 1387 return; 1388 if (strcmp(name + namelen - strlen("_device_table"), "_device_table")) 1389 return; 1390 identifier = strstr(name, "__"); 1391 if (!identifier) 1392 return; 1393 namelen = identifier - name; 1394 1395 /* Handle all-NULL symbols allocated into .bss */ 1396 if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) { 1397 zeros = calloc(1, sym->st_size); 1398 symval = zeros; 1399 } else { 1400 symval = (void *)info->hdr 1401 + info->sechdrs[get_secindex(info, sym)].sh_offset 1402 + sym->st_value; 1403 } 1404 1405 /* First handle the "special" cases */ 1406 if (sym_is(name, namelen, "usb")) 1407 do_usb_table(symval, sym->st_size, mod); 1408 if (sym_is(name, namelen, "of")) 1409 do_of_table(symval, sym->st_size, mod); 1410 else if (sym_is(name, namelen, "pnp")) 1411 do_pnp_device_entry(symval, sym->st_size, mod); 1412 else if (sym_is(name, namelen, "pnp_card")) 1413 do_pnp_card_entries(symval, sym->st_size, mod); 1414 else { 1415 int i; 1416 1417 for (i = 0; i < ARRAY_SIZE(devtable); i++) { 1418 const struct devtable *p = &devtable[i]; 1419 1420 if (sym_is(name, namelen, p->device_id)) { 1421 do_table(symval, sym->st_size, p->id_size, 1422 p->device_id, p->do_entry, mod); 1423 break; 1424 } 1425 } 1426 } 1427 free(zeros); 1428 } 1429 1430 /* Now add out buffered information to the generated C source */ 1431 void add_moddevtable(struct buffer *buf, struct module *mod) 1432 { 1433 buf_printf(buf, "\n"); 1434 buf_write(buf, mod->dev_table_buf.p, mod->dev_table_buf.pos); 1435 free(mod->dev_table_buf.p); 1436 } 1437