938 | 938 |
void hd_read_platform(hd_data_t *hd_data)
|
939 | 939 |
{
|
940 | 940 |
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;
|
943 | 943 |
int mv643xx_eth_seen = 0;
|
944 | 944 |
int is_net, is_storage, is_usb, is_xhci, is_ehci;
|
945 | 945 |
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');
|
948 | 950 |
|
949 | 951 |
if(!sf_bus) {
|
950 | 952 |
ADD2LOG("sysfs: no such bus: platform\n");
|
951 | 953 |
return;
|
952 | 954 |
}
|
953 | 955 |
|
|
956 |
/* list of network interfaces */
|
|
957 |
str_list_t *net_list = read_dir_canonical("/sys/class/net", 'l');
|
|
958 |
|
954 | 959 |
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));
|
956 | 961 |
|
957 | 962 |
ADD2LOG(
|
958 | 963 |
" platform device: name = %s\n path = %s\n",
|
|
976 | 981 |
driver = hd_sysfs_find_driver(hd_data, hd_sysfs_id(sf_dev), 1);
|
977 | 982 |
if(!driver) driver = "";
|
978 | 983 |
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 |
*/
|
979 | 989 |
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);
|
983 | 992 |
is_storage =
|
984 | 993 |
!strcmp(device_type, "sata") ||
|
985 | 994 |
!strcmp(platform_type, "acpi:HISI0161:") ||
|
|
997 | 1006 |
strstr(driver, "xhci-")
|
998 | 1007 |
);
|
999 | 1008 |
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 |
}
|
1001 | 1014 |
if(is_storage) ADD2LOG(" is storage\n");
|
1002 | 1015 |
if(is_usb) ADD2LOG(" is usb\n");
|
1003 | 1016 |
if(is_xhci) ADD2LOG(" is xhci\n");
|
1004 | 1017 |
if(is_ehci) ADD2LOG(" is ehci\n");
|
1005 | |
free_mem(sf_eth_net);
|
1006 | |
free_str_list(sf_eth_dev);
|
1007 | 1018 |
if(
|
1008 | 1019 |
/* there is 'mv643xx_eth.0', 'mv643xx_eth.1' and 'mv643xx_eth_shared.' */
|
1009 | 1020 |
is_net &&
|
|
1013 | 1024 |
add_mv643xx_eth(hd_data, sf_bus_e->str, platform_type);
|
1014 | 1025 |
}
|
1015 | 1026 |
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 |
}
|
1025 | 1058 |
}
|
1026 | 1059 |
else if(is_storage) {
|
1027 | 1060 |
hd = add_hd_entry(hd_data, __LINE__, 0);
|
|
1063 | 1096 |
s = hd_sysfs_find_driver(hd_data, hd->sysfs_id, 1);
|
1064 | 1097 |
if(s) add_str_list(&hd->drivers, s);
|
1065 | 1098 |
}
|
|
1099 |
free_str_list(sf_eth_dev);
|
1066 | 1100 |
free_mem(device_type);
|
1067 | 1101 |
free_mem(platform_type);
|
1068 | 1102 |
}
|
1069 | 1103 |
|
1070 | 1104 |
free_mem(sf_dev);
|
1071 | 1105 |
}
|
|
1106 |
|
|
1107 |
free_str_list(net_list);
|
1072 | 1108 |
|
1073 | 1109 |
free_str_list(sf_bus);
|
1074 | 1110 |
}
|