Codebase list hwinfo / 96375cc
Update upstream source from tag 'upstream/21.71' Update to upstream version '21.71' with Debian dir 0d2002d4332dd4eabae2c336a8bb77f9bb2901f9 Tomasz Buchert 3 years ago
3 changed file(s) with 128 addition(s) and 20 deletion(s). Raw diff Collapse all Expand all
26322632 }
26332633
26342634
2635 /*
2636 * Read directory, return a list of canonicalized entries with file type 'type'.
2637 *
2638 * The difference to read_dir() is that symlinks are resolved and the
2639 * canonical path within sysfs is returned.
2640 */
2641 str_list_t *read_dir_canonical(char *dir_name, int type)
2642 {
2643 str_list_t *list = read_dir(dir_name, type);
2644
2645 if(!list) return list;
2646
2647 for(str_list_t *sl = list; sl; sl = sl->next) {
2648 char *tmp = new_str(hd_read_sysfs_link(dir_name, sl->str));
2649 free_mem(sl->str);
2650 sl->str = tmp;
2651 }
2652
2653 return list;
2654 }
2655
2656
26352657 char *hd_read_sysfs_link(char *base_dir, char *link_name)
26362658 {
26372659 char *s = NULL;
26472669 free_mem(s);
26482670
26492671 return buf;
2672 }
2673
2674
2675 /*
2676 * Return list with all elements in list that are subcomponents of comp.
2677 *
2678 * If max > 0 at most max elements are returned.
2679 *
2680 * Note: it must really be a subdirectory or attribute below comp. A
2681 * component is *not* a subcomponent of itself.
2682 * IOW: the path in list must really be longer than comp to qualify.
2683 */
2684 str_list_t *subcomponent_list(str_list_t *list, char *comp, int max)
2685 {
2686 str_list_t *sub_list = NULL;
2687
2688 if(!list || !comp) return sub_list;
2689
2690 size_t comp_len = strlen(comp);
2691
2692 for(str_list_t *sl = list; sl; sl = sl->next) {
2693 if(
2694 !strncmp(sl->str, comp, comp_len) &&
2695 sl->str[comp_len] == '/'
2696 ) {
2697 add_str_list(&sub_list, sl->str);
2698 if(!--max) return sub_list;
2699 }
2700 }
2701
2702 return sub_list;
2703 }
2704
2705
2706 /*
2707 * Check if list contains a subcomponent of comp.
2708 *
2709 * Returns 0 (no) or 1 (yes).
2710 */
2711 int has_subcomponent(str_list_t *list, char *comp)
2712 {
2713 str_list_t *sl = subcomponent_list(list, comp, 1);
2714 if(!sl) return 0;
2715
2716 free_str_list(sl);
2717
2718 return 1;
26502719 }
26512720
26522721
119119 str_list_t *reverse_str_list(str_list_t *list);
120120 str_list_t *read_file(char *file_name, unsigned start_line, unsigned lines);
121121 str_list_t *read_dir(char *dir_name, int type);
122 str_list_t *read_dir_canonical(char *dir_name, int type);
122123 char *hd_read_sysfs_link(char *base_dir, char *link_name);
124 str_list_t *subcomponent_list(str_list_t *list, char *comp, int max);
125 int has_subcomponent(str_list_t *list, char *comp);
123126 void progress(hd_data_t *hd_data, unsigned pos, unsigned count, char *msg);
124127
125128 void remove_hd_entries(hd_data_t *hd_data);
938938 void hd_read_platform(hd_data_t *hd_data)
939939 {
940940 char *s, *platform_type, *device_type, *driver;
941 str_list_t *sf_bus, *sf_bus_e, *sf_eth_dev = NULL;
942 char *sf_dev, *sf_eth_net;
941 str_list_t *sf_bus, *sf_bus_e, *sf_bus_canonical, *sf_eth_dev = NULL;
942 char *sf_dev;
943943 int mv643xx_eth_seen = 0;
944944 int is_net, is_storage, is_usb, is_xhci, is_ehci;
945945 hd_t *hd;
946
947 sf_bus = read_dir("/sys/bus/platform/devices", 'l');
946 char *sysfs_device_dir = "/sys/bus/platform/devices";
947
948 sf_bus = read_dir(sysfs_device_dir, 'l');
949 sf_bus_canonical = read_dir_canonical(sysfs_device_dir, 'l');
948950
949951 if(!sf_bus) {
950952 ADD2LOG("sysfs: no such bus: platform\n");
951953 return;
952954 }
953955
956 /* list of network interfaces */
957 str_list_t *net_list = read_dir_canonical("/sys/class/net", 'l');
958
954959 for(sf_bus_e = sf_bus; sf_bus_e; sf_bus_e = sf_bus_e->next) {
955 sf_dev = new_str(hd_read_sysfs_link("/sys/bus/platform/devices", sf_bus_e->str));
960 sf_dev = new_str(hd_read_sysfs_link(sysfs_device_dir, sf_bus_e->str));
956961
957962 ADD2LOG(
958963 " platform device: name = %s\n path = %s\n",
976981 driver = hd_sysfs_find_driver(hd_data, hd_sysfs_id(sf_dev), 1);
977982 if(!driver) driver = "";
978983 ADD2LOG(" type = \"%s\", modalias = \"%s\", driver = \"%s\"\n", device_type, platform_type, driver);
984 /*
985 * it's a network device if
986 * - there's a link to a network interface in a subdir *AND*
987 * - there's no other device that is actually a subdevice of this one
988 */
979989 is_net = 0;
980 sf_eth_net = new_str(hd_read_sysfs_link(sf_dev, "net"));
981 sf_eth_dev = read_dir(sf_eth_net, 'd');
982 is_net = sf_eth_net && sf_eth_dev;
990 sf_eth_dev = subcomponent_list(net_list, sf_dev, 0);
991 is_net = !!sf_eth_dev && !has_subcomponent(sf_bus_canonical, sf_dev);
983992 is_storage =
984993 !strcmp(device_type, "sata") ||
985994 !strcmp(platform_type, "acpi:HISI0161:") ||
9971006 strstr(driver, "xhci-")
9981007 );
9991008 is_ehci = !!strstr(driver, "ehci-");
1000 if(is_net) ADD2LOG(" is net: sf_eth_net = %s\n", sf_eth_net);
1009 if(is_net) {
1010 for(str_list_t *sl = sf_eth_dev; sl; sl = sl->next) {
1011 ADD2LOG(" is net: interface = %s\n", sl->str);
1012 }
1013 }
10011014 if(is_storage) ADD2LOG(" is storage\n");
10021015 if(is_usb) ADD2LOG(" is usb\n");
10031016 if(is_xhci) ADD2LOG(" is xhci\n");
10041017 if(is_ehci) ADD2LOG(" is ehci\n");
1005 free_mem(sf_eth_net);
1006 free_str_list(sf_eth_dev);
10071018 if(
10081019 /* there is 'mv643xx_eth.0', 'mv643xx_eth.1' and 'mv643xx_eth_shared.' */
10091020 is_net &&
10131024 add_mv643xx_eth(hd_data, sf_bus_e->str, platform_type);
10141025 }
10151026 else if(is_net) {
1016 hd = add_hd_entry(hd_data, __LINE__, 0);
1017 hd->base_class.id = bc_network;
1018 hd->sub_class.id = 0;
1019 str_printf(&hd->device.name, 0, "ARM Ethernet controller");
1020 hd->modalias = new_str(platform_type);
1021 hd->sysfs_id = new_str(hd_sysfs_id(sf_dev));
1022 hd->sysfs_bus_id = new_str(sf_bus_e->str);
1023 s = hd_sysfs_find_driver(hd_data, hd->sysfs_id, 1);
1024 if(s) add_str_list(&hd->drivers, s);
1027 /* note there might be more than one interface per device - hence this is a list */
1028 for(str_list_t *sl = sf_eth_dev; sl; sl = sl->next) {
1029 hd = add_hd_entry(hd_data, __LINE__, 0);
1030 hd->base_class.id = bc_network;
1031 hd->sub_class.id = 0;
1032 str_printf(&hd->device.name, 0, "ARM Ethernet controller");
1033 hd->modalias = new_str(platform_type);
1034 /*
1035 * the interface link ends with 'net' + interface, e.g. .../net/ethX
1036 * -> strip these two parts to form the sysfs id
1037 */
1038 char *tmp = new_str(hd_sysfs_id(sl->str));
1039 char *slash = strrchr(tmp, '/');
1040 if(slash) *slash = 0, slash = strrchr(tmp, '/');
1041 if(slash) *slash = 0;
1042 hd->sysfs_id = new_str(tmp);
1043 free_mem(tmp);
1044 /*
1045 * the bus id is the last part of the sysfs id - if that fails for
1046 * some reason fall back to device link name
1047 */
1048 tmp = strrchr(hd->sysfs_id, '/');
1049 if(tmp) {
1050 hd->sysfs_bus_id = new_str(tmp + 1);
1051 }
1052 else {
1053 hd->sysfs_bus_id = new_str(sf_bus_e->str);
1054 }
1055 s = hd_sysfs_find_driver(hd_data, hd->sysfs_id, 1);
1056 if(s) add_str_list(&hd->drivers, s);
1057 }
10251058 }
10261059 else if(is_storage) {
10271060 hd = add_hd_entry(hd_data, __LINE__, 0);
10631096 s = hd_sysfs_find_driver(hd_data, hd->sysfs_id, 1);
10641097 if(s) add_str_list(&hd->drivers, s);
10651098 }
1099 free_str_list(sf_eth_dev);
10661100 free_mem(device_type);
10671101 free_mem(platform_type);
10681102 }
10691103
10701104 free_mem(sf_dev);
10711105 }
1106
1107 free_str_list(net_list);
10721108
10731109 free_str_list(sf_bus);
10741110 }