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