.. | .. |
---|
36 | 36 | typedef unsigned char __u8; |
---|
37 | 37 | typedef struct { |
---|
38 | 38 | __u8 b[16]; |
---|
| 39 | +} guid_t; |
---|
| 40 | + |
---|
| 41 | +/* backwards compatibility, don't use in new code */ |
---|
| 42 | +typedef struct { |
---|
| 43 | + __u8 b[16]; |
---|
39 | 44 | } uuid_le; |
---|
| 45 | +typedef struct { |
---|
| 46 | + __u8 b[16]; |
---|
| 47 | +} uuid_t; |
---|
| 48 | +#define UUID_STRING_LEN 36 |
---|
40 | 49 | |
---|
41 | 50 | /* Big exception to the "don't include kernel headers into userspace, which |
---|
42 | 51 | * even potentially has different endianness and word sizes, since |
---|
.. | .. |
---|
50 | 59 | int (*do_entry)(const char *filename, void *symval, char *alias); |
---|
51 | 60 | }; |
---|
52 | 61 | |
---|
| 62 | +/* Size of alias provided to do_entry functions */ |
---|
| 63 | +#define ALIAS_SIZE 500 |
---|
| 64 | + |
---|
53 | 65 | /* Define a variable f that holds the value of field f of struct devid |
---|
54 | 66 | * based at address m. |
---|
55 | 67 | */ |
---|
56 | 68 | #define DEF_FIELD(m, devid, f) \ |
---|
57 | 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 | + |
---|
58 | 78 | /* Define a variable f that holds the address of field f of struct devid |
---|
59 | 79 | * based at address m. Due to the way typeof works, for a field of type |
---|
60 | 80 | * T[N] the variable has type T(*)[N], _not_ T*. |
---|
61 | 81 | */ |
---|
62 | 82 | #define DEF_FIELD_ADDR(m, devid, f) \ |
---|
63 | | - typeof(((struct devid *)0)->f) *f = ((m) + OFF_##devid##_##f) |
---|
| 83 | + DEF_FIELD_ADDR_VAR(m, devid, f, f) |
---|
64 | 84 | |
---|
65 | 85 | #define ADD(str, sep, cond, field) \ |
---|
66 | 86 | do { \ |
---|
.. | .. |
---|
586 | 606 | |
---|
587 | 607 | for (i = 0; i < count; i++) { |
---|
588 | 608 | unsigned int j; |
---|
589 | | - DEF_FIELD_ADDR(symval + i*id_size, pnp_card_device_id, devs); |
---|
| 609 | + DEF_FIELD_ADDR(symval + i * id_size, pnp_card_device_id, devs); |
---|
590 | 610 | |
---|
591 | 611 | for (j = 0; j < PNP_MAX_DEVICES; j++) { |
---|
592 | 612 | const char *id = (char *)(*devs)[j].id; |
---|
.. | .. |
---|
598 | 618 | |
---|
599 | 619 | /* find duplicate, already added value */ |
---|
600 | 620 | for (i2 = 0; i2 < i && !dup; i2++) { |
---|
601 | | - DEF_FIELD_ADDR(symval + i2*id_size, pnp_card_device_id, devs); |
---|
| 621 | + DEF_FIELD_ADDR_VAR(symval + i2 * id_size, |
---|
| 622 | + pnp_card_device_id, |
---|
| 623 | + devs, devs_dup); |
---|
602 | 624 | |
---|
603 | 625 | for (j2 = 0; j2 < PNP_MAX_DEVICES; j2++) { |
---|
604 | | - const char *id2 = (char *)(*devs)[j2].id; |
---|
| 626 | + const char *id2 = |
---|
| 627 | + (char *)(*devs_dup)[j2].id; |
---|
605 | 628 | |
---|
606 | 629 | if (!id2[0]) |
---|
607 | 630 | break; |
---|
.. | .. |
---|
896 | 919 | return 1; |
---|
897 | 920 | } |
---|
898 | 921 | |
---|
| 922 | +static int do_i3c_entry(const char *filename, void *symval, |
---|
| 923 | + char *alias) |
---|
| 924 | +{ |
---|
| 925 | + DEF_FIELD(symval, i3c_device_id, match_flags); |
---|
| 926 | + DEF_FIELD(symval, i3c_device_id, dcr); |
---|
| 927 | + DEF_FIELD(symval, i3c_device_id, manuf_id); |
---|
| 928 | + DEF_FIELD(symval, i3c_device_id, part_id); |
---|
| 929 | + DEF_FIELD(symval, i3c_device_id, extra_info); |
---|
| 930 | + |
---|
| 931 | + strcpy(alias, "i3c:"); |
---|
| 932 | + ADD(alias, "dcr", match_flags & I3C_MATCH_DCR, dcr); |
---|
| 933 | + ADD(alias, "manuf", match_flags & I3C_MATCH_MANUF, manuf_id); |
---|
| 934 | + ADD(alias, "part", match_flags & I3C_MATCH_PART, part_id); |
---|
| 935 | + ADD(alias, "ext", match_flags & I3C_MATCH_EXTRA_INFO, extra_info); |
---|
| 936 | + |
---|
| 937 | + return 1; |
---|
| 938 | +} |
---|
| 939 | + |
---|
899 | 940 | /* Looks like: spi:S */ |
---|
900 | 941 | static int do_spi_entry(const char *filename, void *symval, |
---|
901 | 942 | char *alias) |
---|
.. | .. |
---|
913 | 954 | { "bvn", DMI_BIOS_VENDOR }, |
---|
914 | 955 | { "bvr", DMI_BIOS_VERSION }, |
---|
915 | 956 | { "bd", DMI_BIOS_DATE }, |
---|
| 957 | + { "br", DMI_BIOS_RELEASE }, |
---|
| 958 | + { "efr", DMI_EC_FIRMWARE_RELEASE }, |
---|
916 | 959 | { "svn", DMI_SYS_VENDOR }, |
---|
917 | 960 | { "pn", DMI_PRODUCT_NAME }, |
---|
918 | 961 | { "pvr", DMI_PRODUCT_VERSION }, |
---|
.. | .. |
---|
1215 | 1258 | return 1; |
---|
1216 | 1259 | } |
---|
1217 | 1260 | |
---|
1218 | | -/* Looks like: sdw:mNpN */ |
---|
| 1261 | +/* Looks like: sdw:mNpNvNcN */ |
---|
1219 | 1262 | static int do_sdw_entry(const char *filename, void *symval, char *alias) |
---|
1220 | 1263 | { |
---|
1221 | 1264 | DEF_FIELD(symval, sdw_device_id, mfg_id); |
---|
1222 | 1265 | DEF_FIELD(symval, sdw_device_id, part_id); |
---|
| 1266 | + DEF_FIELD(symval, sdw_device_id, sdw_version); |
---|
| 1267 | + DEF_FIELD(symval, sdw_device_id, class_id); |
---|
1223 | 1268 | |
---|
1224 | 1269 | strcpy(alias, "sdw:"); |
---|
1225 | 1270 | ADD(alias, "m", mfg_id != 0, mfg_id); |
---|
1226 | 1271 | ADD(alias, "p", part_id != 0, part_id); |
---|
| 1272 | + ADD(alias, "v", sdw_version != 0, sdw_version); |
---|
| 1273 | + ADD(alias, "c", class_id != 0, class_id); |
---|
1227 | 1274 | |
---|
1228 | 1275 | add_wildcard(alias); |
---|
1229 | 1276 | return 1; |
---|
.. | .. |
---|
1276 | 1323 | return 1; |
---|
1277 | 1324 | } |
---|
1278 | 1325 | |
---|
| 1326 | +/* Looks like: tee:uuid */ |
---|
| 1327 | +static int do_tee_entry(const char *filename, void *symval, char *alias) |
---|
| 1328 | +{ |
---|
| 1329 | + DEF_FIELD(symval, tee_client_device_id, uuid); |
---|
| 1330 | + |
---|
| 1331 | + sprintf(alias, "tee:%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", |
---|
| 1332 | + uuid.b[0], uuid.b[1], uuid.b[2], uuid.b[3], uuid.b[4], |
---|
| 1333 | + uuid.b[5], uuid.b[6], uuid.b[7], uuid.b[8], uuid.b[9], |
---|
| 1334 | + uuid.b[10], uuid.b[11], uuid.b[12], uuid.b[13], uuid.b[14], |
---|
| 1335 | + uuid.b[15]); |
---|
| 1336 | + |
---|
| 1337 | + add_wildcard(alias); |
---|
| 1338 | + return 1; |
---|
| 1339 | +} |
---|
| 1340 | + |
---|
| 1341 | +/* Looks like: wmi:guid */ |
---|
| 1342 | +static int do_wmi_entry(const char *filename, void *symval, char *alias) |
---|
| 1343 | +{ |
---|
| 1344 | + int len; |
---|
| 1345 | + DEF_FIELD_ADDR(symval, wmi_device_id, guid_string); |
---|
| 1346 | + |
---|
| 1347 | + if (strlen(*guid_string) != UUID_STRING_LEN) { |
---|
| 1348 | + warn("Invalid WMI device id 'wmi:%s' in '%s'\n", |
---|
| 1349 | + *guid_string, filename); |
---|
| 1350 | + return 0; |
---|
| 1351 | + } |
---|
| 1352 | + |
---|
| 1353 | + len = snprintf(alias, ALIAS_SIZE, WMI_MODULE_PREFIX "%s", *guid_string); |
---|
| 1354 | + if (len < 0 || len >= ALIAS_SIZE) { |
---|
| 1355 | + warn("Could not generate all MODULE_ALIAS's in '%s'\n", |
---|
| 1356 | + filename); |
---|
| 1357 | + return 0; |
---|
| 1358 | + } |
---|
| 1359 | + return 1; |
---|
| 1360 | +} |
---|
| 1361 | + |
---|
| 1362 | +/* Looks like: mhi:S */ |
---|
| 1363 | +static int do_mhi_entry(const char *filename, void *symval, char *alias) |
---|
| 1364 | +{ |
---|
| 1365 | + DEF_FIELD_ADDR(symval, mhi_device_id, chan); |
---|
| 1366 | + sprintf(alias, MHI_DEVICE_MODALIAS_FMT, *chan); |
---|
| 1367 | + |
---|
| 1368 | + return 1; |
---|
| 1369 | +} |
---|
| 1370 | + |
---|
1279 | 1371 | /* Does namelen bytes of name exactly match the symbol? */ |
---|
1280 | 1372 | static bool sym_is(const char *name, unsigned namelen, const char *symbol) |
---|
1281 | 1373 | { |
---|
.. | .. |
---|
1292 | 1384 | struct module *mod) |
---|
1293 | 1385 | { |
---|
1294 | 1386 | unsigned int i; |
---|
1295 | | - char alias[500]; |
---|
| 1387 | + char alias[ALIAS_SIZE]; |
---|
1296 | 1388 | |
---|
1297 | 1389 | device_id_check(mod->name, device_id, size, id_size, symval); |
---|
1298 | 1390 | /* Leave last one: it's the terminator. */ |
---|
.. | .. |
---|
1327 | 1419 | {"vmbus", SIZE_hv_vmbus_device_id, do_vmbus_entry}, |
---|
1328 | 1420 | {"rpmsg", SIZE_rpmsg_device_id, do_rpmsg_entry}, |
---|
1329 | 1421 | {"i2c", SIZE_i2c_device_id, do_i2c_entry}, |
---|
| 1422 | + {"i3c", SIZE_i3c_device_id, do_i3c_entry}, |
---|
1330 | 1423 | {"spi", SIZE_spi_device_id, do_spi_entry}, |
---|
1331 | 1424 | {"dmi", SIZE_dmi_system_id, do_dmi_entry}, |
---|
1332 | 1425 | {"platform", SIZE_platform_device_id, do_platform_entry}, |
---|
.. | .. |
---|
1346 | 1439 | {"fslmc", SIZE_fsl_mc_device_id, do_fsl_mc_entry}, |
---|
1347 | 1440 | {"tbsvc", SIZE_tb_service_id, do_tbsvc_entry}, |
---|
1348 | 1441 | {"typec", SIZE_typec_device_id, do_typec_entry}, |
---|
| 1442 | + {"tee", SIZE_tee_client_device_id, do_tee_entry}, |
---|
| 1443 | + {"wmi", SIZE_wmi_device_id, do_wmi_entry}, |
---|
| 1444 | + {"mhi", SIZE_mhi_device_id, do_mhi_entry}, |
---|
1349 | 1445 | }; |
---|
1350 | 1446 | |
---|
1351 | 1447 | /* Create MODULE_ALIAS() statements. |
---|
.. | .. |
---|
1367 | 1463 | if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT) |
---|
1368 | 1464 | return; |
---|
1369 | 1465 | |
---|
1370 | | - /* All our symbols are of form <prefix>__mod_<name>__<identifier>_device_table. */ |
---|
1371 | | - name = strstr(symname, "__mod_"); |
---|
1372 | | - if (!name) |
---|
| 1466 | + /* All our symbols are of form __mod_<name>__<identifier>_device_table. */ |
---|
| 1467 | + if (strncmp(symname, "__mod_", strlen("__mod_"))) |
---|
1373 | 1468 | return; |
---|
1374 | | - name += strlen("__mod_"); |
---|
| 1469 | + name = symname + strlen("__mod_"); |
---|
1375 | 1470 | namelen = strlen(name); |
---|
1376 | 1471 | if (namelen < strlen("_device_table")) |
---|
1377 | 1472 | return; |
---|
.. | .. |
---|
1395 | 1490 | /* First handle the "special" cases */ |
---|
1396 | 1491 | if (sym_is(name, namelen, "usb")) |
---|
1397 | 1492 | do_usb_table(symval, sym->st_size, mod); |
---|
1398 | | - if (sym_is(name, namelen, "of")) |
---|
| 1493 | + else if (sym_is(name, namelen, "of")) |
---|
1399 | 1494 | do_of_table(symval, sym->st_size, mod); |
---|
1400 | 1495 | else if (sym_is(name, namelen, "pnp")) |
---|
1401 | 1496 | do_pnp_device_entry(symval, sym->st_size, mod); |
---|