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