Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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