From 17aa0a1e48bf9dd596c7678b93bd5aaaad94aeb8 Mon Sep 17 00:00:00 2001 From: Lyonel Vincent Date: Tue, 20 Jun 2017 20:49:30 +0200 Subject: [PATCH] merge Petr Oros' pull request cf. https://github.com/lyonel/lshw/pull/29 * Proper detect vendor_id/device_id for virtual functions * Sync SMBIOS with latest specification --- src/core/dmi.cc | 323 +++++++++++++++++++++++++++++++++--------------------- src/core/pci.cc | 13 ++- src/core/sysfs.cc | 10 ++ src/core/sysfs.h | 2 + 4 files changed, 221 insertions(+), 127 deletions(-) diff --git a/src/core/dmi.cc b/src/core/dmi.cc index 250f485..d1b0b07 100644 --- a/src/core/dmi.cc +++ b/src/core/dmi.cc @@ -408,6 +408,13 @@ static unsigned long dmi_cache_size(u16 n) return (n & 0x7FFF) * 1024; // value is in 1K blocks } +static unsigned long long dmi_cache_size_long(u32 n) +{ + if (n & (1 << 31)) + return (n & 0x7FFFFFFF) * 64 * 1024; // value is in 64K blocks + else + return (n & 0x7FFFFFFF) * 1024; // value is in 1K blocks +} static void dmi_cache_sramtype(u16 c, hwNode & n) @@ -657,9 +664,13 @@ void dmi_chassis(u8 code, hwNode & n) "tablet", N_("Tablet"), NULL, "convertible", N_("Convertible"), NULL, "detachable", N_("Detachable"), NULL, /* 0x20 */ + "iot-gateway", N_("IoT Gateway"), NULL, + "embedded", N_("Embedded PC"), NULL, + "mini", N_("Mini PC"), NULL, + "stick", N_("Stick PC"), NULL, /* 0x24 */ }; - if(code <= 0x20) + if(code <= 0x24) { if(n.getDescription()=="") n.setDescription(_(chassis_type[1+3*code])); @@ -720,9 +731,9 @@ static const char *dmi_processor_family(uint16_t code) "Core Solo mobile", "Atom", "Core M", - "", - "", - "", + "Core M3", + "Core M5", + "Core M7", "Alpha", /* 0x30 */ "Alpha 21064", "Alpha 21066", @@ -780,9 +791,9 @@ static const char *dmi_processor_family(uint16_t code) "Athlon X4", /* 0x66 */ "Opteron X1000", "Opteron X2000 APU", - "", - "", - "", + "Opteron A", + "Opteron X3000 APU", + "Zen", "", "", "", @@ -938,6 +949,8 @@ static const char *dmi_processor_family(uint16_t code) switch (code) { + case 0x100: return "ARMv7"; + case 0x101: return "ARMv8"; case 0x104: return "SH-3"; case 0x105: return "SH-4"; case 0x118: return "ARM"; @@ -966,7 +979,8 @@ static void dmi_table(const u8 *buf, int len, hwNode & node, int dmiversionmaj, -int dmiversionmin) +int dmiversionmin, +int dmiversionrev) { struct dmi_header *dm; hwNode *hardwarenode = NULL; @@ -1008,24 +1022,34 @@ int dmiversionmin) // BIOS Information Block { string release(dmi_string(dm, - data[8])); + data[0x08])); hwNode newnode("firmware", hw::memory, dmi_string(dm, - data[4])); + data[0x04])); newnode.setVersion(dmi_string(dm, data[5])); - newnode.setCapacity(64 * data[9] * 1024); - newnode.setSize(16 * (0x10000 - (data[7] << 8 | data[6]))); -//newnode.setPhysId(16 * (data[7] << 8 | data[6])); + if (data[0x09] != 0xFF) + newnode.setCapacity(64 * (data[0x09] + 1) * 1024); + else + { + if (dm->length < 0x1A) + newnode.setCapacity(16 * 1024 * 1024); + else + { + unsigned int unit = (data[0x19] << 8 | data[0x18]) & 0x4000 ? 1024 : 1024 * 1024; + newnode.setCapacity(((data[0x19] << 8 | data[0x18]) & 0x3FFF) * unit); + } + } + newnode.setSize(16 * (0x10000 - (data[0x07] << 8 | data[0x06]))); newnode.setPhysId(dm->handle); newnode.setDescription(_("BIOS")); newnode.addHint("icon", string("chip")); newnode.claim(); - dmi_bios_features(data[13] << 24 | data[12] << 16 | data[11] << 8 | - data[10], - data[17] << 24 | data[16] << 16 | data[15] << 8 | - data[14], newnode); + dmi_bios_features(data[0x0D] << 24 | data[0x0C] << 16 | data[0x0B] << 8 | + data[0x0A], + data[0x11] << 24 | data[0x10] << 16 | data[0x0F] << 8 | + data[0x0E], newnode); if (dm->length > 0x12) dmi_bios_features_ext(&data[0x12], dm->length - 0x12, newnode); @@ -1039,12 +1063,12 @@ int dmiversionmin) case 1: // System Information Block node.setHandle(handle); - node.setVendor(dmi_string(dm, data[4])); - node.setProduct(dmi_string(dm, data[5])); - node.setVersion(dmi_string(dm, data[6])); - node.setSerial(dmi_string(dm, data[7])); + node.setVendor(dmi_string(dm, data[0x04])); + node.setProduct(dmi_string(dm, data[0x05])); + node.setVersion(dmi_string(dm, data[0x06])); + node.setSerial(dmi_string(dm, data[0x07])); if (dm->length >= 0x19) - node.setConfig("uuid", dmi_uuid(data + 8)); + node.setConfig("uuid", dmi_uuid(data + 0x08)); if (dm->length >= 0x1B) { node.setConfig("sku", dmi_string(dm, data[0x19])); @@ -1057,15 +1081,14 @@ int dmiversionmin) case 2: // Board Information Block { - - // we are the only system board on the computer so connect everything to us + // we are the only system board on the computer so connect everything to us if ((dm->length <= 0x0E) || (data[0x0E] == 0)) { - hardwarenode->setVendor(dmi_string(dm, data[4])); - hardwarenode->setProduct(dmi_string(dm, data[5])); - hardwarenode->setVersion(dmi_string(dm, data[6])); - hardwarenode->setSerial(dmi_string(dm, data[7])); - if(dm->length >= 0x0a) + hardwarenode->setVendor(dmi_string(dm, data[0x04])); + hardwarenode->setProduct(dmi_string(dm, data[0x05])); + hardwarenode->setVersion(dmi_string(dm, data[0x06])); + hardwarenode->setSerial(dmi_string(dm, data[0x07])); + if(dm->length >= 0x0A) hardwarenode->setSlot(dmi_string(dm, data[0x0A])); hardwarenode->setHandle(handle); hardwarenode->setDescription(_("Motherboard")); @@ -1083,10 +1106,10 @@ int dmiversionmin) (data[0x0F + 2 * i + 1] << 8 | data[0x0F + 2 * i])); - newnode.setVendor(dmi_string(dm, data[4])); - newnode.setProduct(dmi_string(dm, data[5])); - newnode.setVersion(dmi_string(dm, data[6])); - newnode.setSerial(dmi_string(dm, data[7])); + newnode.setVendor(dmi_string(dm, data[0x04])); + newnode.setProduct(dmi_string(dm, data[0x05])); + newnode.setVersion(dmi_string(dm, data[0x06])); + newnode.setSerial(dmi_string(dm, data[0x07])); newnode.setSlot(dmi_string(dm, data[0x0A])); newnode.setHandle(handle); newnode.setPhysId(dm->handle); @@ -1102,14 +1125,14 @@ int dmiversionmin) // special case: if the system characteristics are still unknown, // use values from the chassis if (node.getVendor() == "") - node.setVendor(dmi_string(dm, data[4])); + node.setVendor(dmi_string(dm, data[0x04])); if (node.getProduct() == "") - node.setProduct(dmi_string(dm, data[5])); + node.setProduct(dmi_string(dm, data[0x05])); if (node.getVersion() == "") - node.setVersion(dmi_string(dm, data[6])); + node.setVersion(dmi_string(dm, data[0x06])); if (node.getSerial() == "") - node.setSerial(dmi_string(dm, data[7])); - dmi_chassis(data[5] & 0x7F, node); + node.setSerial(dmi_string(dm, data[0x07])); + dmi_chassis(data[0x05] & 0x7F, node); break; case 4: @@ -1120,16 +1143,16 @@ int dmiversionmin) newnode.claim(); newnode.setBusInfo(cpubusinfo(currentcpu++)); - newnode.setSlot(dmi_string(dm, data[4])); + newnode.setSlot(dmi_string(dm, data[0x04])); newnode.setDescription(_("CPU")); newnode.addHint("icon", string("cpu")); if (dm->length >= 0x2A) newnode.setProduct(dmi_processor_family( (((uint16_t) data[0x29]) << 8) + data[0x28])); else - newnode.setProduct(dmi_processor_family(data[6])); + newnode.setProduct(dmi_processor_family(data[0x06])); newnode.setVersion(dmi_string(dm, data[0x10])); - newnode.setVendor(dmi_string(dm, data[7])); + newnode.setVendor(dmi_string(dm, data[0x07])); newnode.setPhysId(dm->handle); if (dm->length > 0x1A) { @@ -1177,15 +1200,30 @@ int dmiversionmin) } if (dm->length >= 0x28) - { + { if (data[0x23] != 0) - newnode.setConfig("cores", data[0x23]); + { + if (data[0x23] == 0xFF) + newnode.setConfig("cores", data[0x2B] << 8 | data[0x2A]); + else + newnode.setConfig("cores", data[0x23]); + } if (data[0x24] != 0) - newnode.setConfig("enabledcores", data[0x24]); + { + if (data[0x24] == 0xFF) + newnode.setConfig("enabledcores", data[0x2D] << 8 | data[0x2C]); + else + newnode.setConfig("enabledcores", data[0x24]); + } if (data[0x25] != 0) - newnode.setConfig("threads", data[0x25]); + { + if (data[0x25] == 0xFF) + newnode.setConfig("threads", data[0x2F] << 8 | data[0x2E]); + else + newnode.setConfig("threads", data[0x25]); + } if (data[0x26] & 0x4) - newnode.addCapability("lm", _("64-bit capable")); + newnode.addCapability("lm", _("64-bit capable")); } newnode.setHandle(handle); @@ -1207,7 +1245,7 @@ int dmiversionmin) newnode.setHandle(handle); newnode.setPhysId(dm->handle); - size = data[0x0E] * (1 << data[8]) * 1024 * 1024; + size = data[0x0E] * (1 << data[0x08]) * 1024 * 1024; newnode.setCapacity(size); // loop through the controller's slots and link them to us @@ -1237,44 +1275,44 @@ int dmiversionmin) unsigned long long size = 0; newnode.setDescription(_("empty memory bank")); - newnode.setSlot(dmi_string(dm, data[4]).c_str()); + newnode.setSlot(dmi_string(dm, data[0x04]).c_str()); if (data[6]) - clock = 1000000000 / data[6]; // convert value from ns to Hz + clock = 1000000000 / data[0x06]; // convert value from ns to Hz newnode.setClock(clock); - newnode.setDescription(dmi_decode_ram(data[8] << 8 | data[7])); + newnode.setDescription(dmi_decode_ram(data[0x08] << 8 | data[0x07])); newnode.addHint("icon", string("memory")); // installed size - switch (data[9] & 0x7F) + switch (data[0x09] & 0x7F) { case 0x7D: case 0x7E: case 0x7F: break; default: - size = (1 << (data[9] & 0x7F)) << 20; + size = (1 << (data[0x09] & 0x7F)) << 20; } - if (data[9] & 0x80) + if (data[0x09] & 0x80) size *= 2; // enabled size - switch (data[10] & 0x7F) + switch (data[0x0A] & 0x7F) { case 0x7D: case 0x7E: case 0x7F: break; default: - capacity = (1 << (data[10] & 0x7F)) << 20; + capacity = (1 << (data[0x0A] & 0x7F)) << 20; } - if (data[10] & 0x80) + if (data[0x0A] & 0x80) capacity *= 2; newnode.setCapacity(capacity); newnode.setSize(size); if(newnode.getSize()==0) newnode.setDescription(newnode.getDescription() + " " + _("[empty]")); - if ((data[11] & 4) == 0) + if ((data[0x0B] & 4) == 0) { - if (data[11] & (1 << 0)) + if (data[0x0B] & (1 << 0)) // bank has uncorrectable errors (BIOS disabled) newnode.disable(); } @@ -1291,8 +1329,8 @@ int dmiversionmin) hw::memory); int level; - newnode.setSlot(dmi_string(dm, data[4])); - u = data[6] << 8 | data[5]; + newnode.setSlot(dmi_string(dm, data[0x04])); + u = data[0x06] << 8 | data[0x05]; level = 1 + (u & 7); if (dm->length > 0x11) @@ -1305,11 +1343,19 @@ int dmiversionmin) newnode.disable(); newnode.setConfig("level", level); - newnode.setSize(dmi_cache_size(data[9] | data[10] << 8)); - newnode.setCapacity(dmi_cache_size(data[7] | (data[8] << 8))); + if ((data[0x08] << 8 | data[0x07]) == 0xFFFF) + newnode.setCapacity(dmi_cache_size_long(data[0x16] << 24 | data[0x15] << 16 | data[0x14] << 8 | data[0x13])); + else + newnode.setCapacity(dmi_cache_size(data[0x08] << 8 | data[0x07])); + + if ((data[0x0A] << 8 | data[0x09]) == 0xFFFF) + newnode.setSize(dmi_cache_size_long(data[0x1A] << 24 | data[0x19] << 16 | data[0x18] << 8 | data[0x17])); + else + newnode.setSize(dmi_cache_size(data[0x0A] << 8 | data[0x09])); + if ((dm->length > 0x0F) && (data[0x0F] != 0)) { - // convert from ns to Hz + // convert from ns to Hz newnode.setClock(1000000000 / data[0x0F]); } @@ -1338,16 +1384,16 @@ int dmiversionmin) hwNode newnode("cardslot", hw::bus); newnode.setHandle(handle); - newnode.setSlot(dmi_string(dm, data[4])); + newnode.setSlot(dmi_string(dm, data[0x04])); printf("\t\tType: %s%s%s\n", - dmi_bus_width(data[6]), - dmi_card_size(data[8]), dmi_bus_name(data[5])); - if (data[7] == 3) + dmi_bus_width(data[0x06]), + dmi_card_size(data[0x08]), dmi_bus_name(data[0x05])); + if (data[0x07] == 3) printf("\t\tStatus: Available.\n"); - if (data[7] == 4) + if (data[0x07] == 4) printf("\t\tStatus: In use.\n"); - if (data[11] & 0xFE) - dmi_card_props(data[11]); + if (data[0x0B] & 0xFE) + dmi_card_props(data[0x0B]); //hardwarenode->addChild(newnode); } #endif @@ -1374,13 +1420,13 @@ int dmiversionmin) case 13: #if 0 printf("\tBIOS Language Information\n"); - printf("\t\tInstallable Languages: %u\n", data[4]); - for (u = 1; u <= data[4]; u++) + printf("\t\tInstallable Languages: %u\n", data[0x04]); + for (u = 1; u <= data[0x04]; u++) { printf("\t\t\t%s\n", dmi_string(dm, u).c_str()); } printf("\t\tCurrently Installed Language: %s\n", - dmi_string(dm, data[21]).c_str()); + dmi_string(dm, data[0x15]).c_str()); #endif break; case 14: @@ -1395,7 +1441,7 @@ int dmiversionmin) string id = "memory"; string description = ""; bool claim = false, memory_icon = false; - switch (data[5]) + switch (data[0x05]) { case 0x03: description = _("System Memory"); @@ -1433,12 +1433,12 @@ int dmiversionrev) newnode.setHandle(handle); newnode.setPhysId(dm->handle); newnode.setDescription(description); - newnode.setSlot(dmi_memory_array_location(data[4])); + newnode.setSlot(dmi_memory_array_location(data[0x04])); if (memory_icon) newnode.addHint("icon", string("memory")); if (claim) newnode.claim(); - switch (data[6]) + switch (data[0x06]) { case 0x04: newnode.addCapability("parity", _("Parity error correction")); @@ -1457,7 +1503,7 @@ int dmiversionmin) newnode.setConfig("errordetection", "crc"); break; } - u2 = data[10] << 24 | data[9] << 16 | data[8] << 8 | data[7]; + u2 = data[0x0A] << 24 | data[0x09] << 16 | data[0x08] << 8 | data[0x07]; if (u2 != 0x80000000) // magic value for "unknown" newnode.setCapacity(u2 * 1024); else if (dm->length >= 0x17) @@ -1489,15 +1535,15 @@ int dmiversionmin) string arrayhandle; newnode.setDescription(_("empty memory bank")); newnode.addHint("icon", string("memory")); - arrayhandle = dmi_handle(data[5] << 8 | data[4]); + arrayhandle = dmi_handle(data[0x05] << 8 | data[0x04]); strcpy(bits, ""); // total width - u = data[9] << 8 | data[8]; - if (u != 0xffff) + u = data[0x09] << 8 | data[0x08]; + if (u != 0xFFFF) width = u; //data width - u = data[11] << 8 | data[10]; - if ((u != 0xffff) && (u != 0)) + u = data[0x0B] << 8 | data[0x0A]; + if ((u != 0xFFFF) && (u != 0)) { if ((u == width) || (width == 0)) { @@ -1520,26 +1566,26 @@ int dmiversionmin) } // size - u = data[13] << 8 | data[12]; - if(u == 0x7fff) { - unsigned long long extendsize = (data[0x1f] << 24) | (data[0x1e] << 16) | (data[0x1d] << 8) | data[0x1c]; - extendsize &= 0x7fffffffUL; + u = data[0x0D] << 8 | data[0x0C]; + if(u == 0x7FFF) { + unsigned long long extendsize = (data[0x1F] << 24) | (data[0x1E] << 16) | (data[0x1D] << 8) | data[0x1C]; + extendsize &= 0x7FFFFFFFUL; size = extendsize * 1024ULL * 1024ULL; } else - if (u != 0xffff) - size = (1024ULL * (u & 0x7fff) * ((u & 0x8000) ? 1 : 1024ULL)); - description += string(dmi_memory_device_form_factor(data[14])); - slot = dmi_string(dm, data[16]); -//printf("\t\tBank Locator: %s\n", dmi_string(dm, data[17])); - description += string(dmi_memory_device_type(data[18])); - u = data[20] << 8 | data[19]; - if (u & 0x1ffe) + if (u != 0xFFFF) + size = (1024ULL * (u & 0x7FFF) * ((u & 0x8000) ? 1 : 1024ULL)); + description += string(dmi_memory_device_form_factor(data[0x0E])); + slot = dmi_string(dm, data[0x10]); +//printf("\t\tBank Locator: %s\n", dmi_string(dm, data[0x11])); + description += string(dmi_memory_device_type(data[0x12])); + u = data[0x14] << 8 | data[0x13]; + if (u & 0x1FFE) description += dmi_memory_device_detail(u); - if (dm->length > 21) + if (dm->length > 0x15) { char buffer[80]; - u = data[22] << 8 | data[21]; + u = data[0x16] << 8 | data[0x15]; // speed clock = u * 1000000; // u is a frequency in MHz if (u == 0) @@ -1553,12 +1599,12 @@ int dmiversionmin) newnode.setHandle(handle); //newnode.setPhysId(dm->handle); newnode.setSlot(slot); - if (dm->length > 23) - newnode.setVendor(dmi_string(dm, data[23])); - if (dm->length > 24) - newnode.setSerial(dmi_string(dm, data[24])); - if (dm->length > 26) - newnode.setProduct(dmi_string(dm, data[26])); + if (dm->length > 0x17) + newnode.setVendor(dmi_string(dm, data[0x17])); + if (dm->length > 0x18) + newnode.setSerial(dmi_string(dm, data[0x18])); + if (dm->length > 0x1A) + newnode.setProduct(dmi_string(dm, data[0x1A])); newnode.setDescription(description); newnode.setSize(size); if(newnode.getSize()==0) @@ -1586,10 +1632,20 @@ int dmiversionmin) { hwNode newnode("range", hw::address); - unsigned long start, end; + uint64_t start = 0, end = 0; string arrayhandle = dmi_handle(data[0x0D] << 8 | data[0x0C]); - start = ((data[4] | data[5] << 8) | (data[6] | data[7] << 8) << 16); - end = ((data[8] | data[9] << 8) | (data[10] | data[11] << 8) << 16); + start = data[0x07] << 24 | data[0x06] << 16 | data[0x05] << 8 | data[0x04]; + if (start == 0xFFFFFFFF) + start = uint64_t(data[0x16]) << 56 | uint64_t(data[0x15]) << 48 | + uint64_t(data[0x14]) << 40 | uint64_t(data[0x13]) << 32 | + uint64_t(data[0x12]) << 24 | uint64_t(data[0x11]) << 16 | + uint64_t(data[0x10]) << 8 | uint64_t(data[0x0F]); + end = data[0x0B] << 24 | data[0x0A] << 16 | data[0x09] << 8 | data[0x08]; + if (end == 0xFFFFFFFF) + end = uint64_t(data[0x1E]) << 56 | uint64_t(data[0x1D]) << 48 | + uint64_t(data[0x1C]) << 40 | uint64_t(data[0x1B]) << 32 | + uint64_t(data[0x1A]) << 24 | uint64_t(data[0x19]) << 16 | + uint64_t(data[0x18]) << 8 | uint64_t(data[0x17]); if (end - start < 512) // memory range is smaller thant 512KB { // consider that values were expressed in megagytes @@ -1614,10 +1670,20 @@ int dmiversionmin) { hwNode newnode("range", hw::address); - unsigned long start, end; + unsigned long long start = 0, end = 0; string devicehandle = dmi_handle(data[0x0D] << 8 | data[0x0C]); - start = ((data[4] | data[5] << 8) | (data[6] | data[7] << 8) << 16); - end = ((data[8] | data[9] << 8) | (data[10] | data[11] << 8) << 16); + start = data[0x07] << 24 | data[0x06] << 16 | data[0x05] << 8 | data[0x04]; + if (start == 0xFFFFFFFF) + start = uint64_t(data[0x16]) << 56 | uint64_t(data[0x15]) << 48 | + uint64_t(data[0x14]) << 40 | uint64_t(data[0x13]) << 32 | + uint64_t(data[0x12]) << 24 | uint64_t(data[0x11]) << 16 | + uint64_t(data[0x10]) << 8 | uint64_t(data[0x0F]); + end = data[0x0B] << 24 | data[0x0A] << 16 | data[0x09] << 8 | data[0x08]; + if (end == 0xFFFFFFFF) + end = uint64_t(data[0x1E]) << 56 | uint64_t(data[0x1D]) << 48 | + uint64_t(data[0x1C]) << 40 | uint64_t(data[0x1B]) << 32 | + uint64_t(data[0x1A]) << 24 | uint64_t(data[0x19]) << 16 | + uint64_t(data[0x18]) << 8 | uint64_t(data[0x17]); if (end - start < 512) // memory range is smaller than 512KB { // consider that values were expressed in megagytes @@ -1661,11 +1727,11 @@ int dmiversionmin) batt.setVersion(dmi_string(dm, data[0x06])); if(data[0x07] || dm->length<0x1A) batt.setSerial(dmi_string(dm, data[0x07])); - batt.setConfig("voltage", dmi_battery_voltage(data[0x0c] + 256*data[0x0d])); + batt.setConfig("voltage", dmi_battery_voltage(data[0x0C] + 256*data[0x0D])); if(dm->length<0x1A) - batt.setCapacity(dmi_battery_capacity(data[0x0a] + 256*data[0x0b], 1)); + batt.setCapacity(dmi_battery_capacity(data[0x0A] + 256*data[0x0B], 1)); else - batt.setCapacity(dmi_battery_capacity(data[0x0a] + 256*data[0x0b], data[0x15])); + batt.setCapacity(dmi_battery_capacity(data[0x0A] + 256*data[0x0B], data[0x15])); if(data[0x09]!=0x02 || dm->length<0x1A) batt.setDescription(hw::strip(string(dmi_battery_chemistry(data[0x09])) + " Battery")); @@ -1724,7 +1790,7 @@ int dmiversionmin) // System Boot Information if (dm->length < 0x0B) break; - node.setConfig("boot", dmi_bootinfo(data[0x0a])); + node.setConfig("boot", dmi_bootinfo(data[0x0A])); break; case 33: // 64-bit Memory Error Information @@ -1755,9 +1821,9 @@ int dmiversionmin) power.setDescription(dmi_string(dm, data[0x06])); power.setVendor(dmi_string(dm, data[0x07])); power.setSerial(dmi_string(dm, data[0x08])); - power.setProduct(dmi_string(dm, data[0x0a])); - power.setVersion(dmi_string(dm, data[0x0b])); - power.setCapacity(data[0x0c] + 256*data[0x0d]); + power.setProduct(dmi_string(dm, data[0x0A])); + power.setVersion(dmi_string(dm, data[0x0B])); + power.setCapacity(data[0x0C] + 256*data[0x0D]); node.addChild(power); } break; @@ -1780,17 +1846,19 @@ int dmiversionmin) static bool smbios_entry_point(const u8 *buf, size_t len, - hwNode & n, u16 & dmimaj, u16 & dmimin, + hwNode & n, u16 & dmimaj, u16 & dmimin, u16 & dmirev, uint32_t & table_len, uint64_t & table_base) { u8 smmajver = 0; u8 smminver = 0; + u8 smdocrev = 0; if (len >= 24 && memcmp(buf, "_SM3_", 5) == 0 && checksum(buf, buf[6])) { // SMBIOS 3.0 entry point structure (64-bit) dmimaj = smmajver = buf[7]; dmimin = smminver = buf[8]; + dmirev = smdocrev = buf[9]; table_len = (((uint32_t) buf[15]) << 24) + (((uint32_t) buf[14]) << 16) + (((uint32_t) buf[13]) << 8) + @@ -1823,9 +1891,16 @@ static bool smbios_entry_point(const u8 *buf, size_t len, if (smmajver > 0) { char buffer[20]; - snprintf(buffer, sizeof(buffer), "%d.%d", smmajver, smminver); + if (smmajver == 3) + snprintf(buffer, sizeof(buffer), "%d.%d.%d", smmajver, smminver, smdocrev); + else + snprintf(buffer, sizeof(buffer), "%d.%d", smmajver, smminver); n.addCapability("smbios-"+string(buffer), "SMBIOS version "+string(buffer)); - snprintf(buffer, sizeof(buffer), "%d.%d", dmimaj, dmimin); + + if (dmimaj == 3) + snprintf(buffer, sizeof(buffer), "%d.%d.%d", dmimaj, dmimin, dmirev); + else + snprintf(buffer, sizeof(buffer), "%d.%d", dmimaj, dmimin); n.addCapability("dmi-"+string(buffer), "DMI version "+string(buffer)); return true; @@ -1842,7 +1917,7 @@ static bool scan_dmi_sysfs(hwNode & n) uint32_t table_len = 0; uint64_t table_base = 0; - u16 dmimaj = 0, dmimin = 0; + u16 dmimaj = 0, dmimin = 0, dmirev = 0; ifstream ep_stream(SYSFSDMI "/smbios_entry_point", ifstream::in | ifstream::binary | ifstream::ate); @@ -1853,7 +1938,7 @@ static bool scan_dmi_sysfs(hwNode & n) if (!ep_stream) return false; if (!smbios_entry_point(ep_buf.data(), ep_len, n, - dmimaj, dmimin, table_len, table_base)) + dmimaj, dmimin, dmirev, table_len, table_base)) return false; ifstream dmi_stream(SYSFSDMI "/DMI", @@ -1864,7 +1939,7 @@ static bool scan_dmi_sysfs(hwNode & n) dmi_stream.read((char *)dmi_buf.data(), dmi_len); if (!dmi_stream) return false; - dmi_table(dmi_buf.data(), dmi_len, n, dmimaj, dmimin); + dmi_table(dmi_buf.data(), dmi_len, n, dmimaj, dmimin, dmirev); return true; } @@ -1902,7 +1977,7 @@ static bool scan_dmi_devmem(hwNode & n) u32 mmoffset = 0; void *mmp = NULL; bool efi = true; - u16 dmimaj = 0, dmimin = 0; + u16 dmimaj = 0, dmimin = 0, dmirev = 0; if (fd == -1) return false; @@ -1932,7 +2007,7 @@ static bool scan_dmi_devmem(hwNode & n) } uint32_t len; uint64_t base; - if (smbios_entry_point(buf, sizeof(buf), n, dmimaj, dmimin, len, base)) + if (smbios_entry_point(buf, sizeof(buf), n, dmimaj, dmimin, dmirev, len, base)) { u8 *dmi_buf = (u8 *)malloc(len); mmoffset = base % getpagesize(); @@ -1944,7 +2019,7 @@ static bool scan_dmi_devmem(hwNode & n) } memcpy(dmi_buf, (u8 *) mmp + mmoffset, len); munmap(mmp, mmoffset + len); - dmi_table(dmi_buf, len, n, dmimaj, dmimin); + dmi_table(dmi_buf, len, n, dmimaj, dmimin, dmirev); free(dmi_buf); break; } diff --git a/src/core/pci.cc b/src/core/pci.cc index d1625cf..fa6a1e5 100644 --- a/src/core/pci.cc +++ b/src/core/pci.cc @@ -774,8 +774,12 @@ static hwNode *scan_pci_dev(struct pci_dev &d, hwNode & n) if(!pcidb_loaded) pcidb_loaded = load_pcidb(); - d.vendor_id = get_conf_word(d, PCI_VENDOR_ID); - d.device_id = get_conf_word(d, PCI_DEVICE_ID); + u_int16_t tmp_vendor_id = get_conf_word(d, PCI_VENDOR_ID); + u_int16_t tmp_device_id = get_conf_word(d, PCI_DEVICE_ID); + if ((tmp_vendor_id & tmp_device_id) != 0xffff) { + d.vendor_id = tmp_vendor_id; + d.device_id = tmp_device_id; + } u_int16_t dclass = get_conf_word(d, PCI_CLASS_DEVICE); u_int16_t cmd = get_conf_word(d, PCI_COMMAND); u_int16_t status = get_conf_word(d, PCI_STATUS); @@ -1122,6 +1126,7 @@ bool scan_pci(hwNode & n) if(matches(devices[i]->d_name, "^[[:xdigit:]]+:[[:xdigit:]]+:[[:xdigit:]]+\\.[[:xdigit:]]+$")) { string devicepath = string(devices[i]->d_name)+"/config"; + sysfs::entry device_entry = sysfs::entry::byBus("pci", devices[i]->d_name); struct pci_dev d; int fd = open(devicepath.c_str(), O_RDONLY); if (fd >= 0) @@ -1136,6 +1141,8 @@ bool scan_pci(hwNode & n) } sscanf(devices[i]->d_name, "%hx:%hx:%hhx.%hhx", &d.domain, &d.bus, &d.dev, &d.func); + sscanf(device_entry.vendor().c_str(), "%hx", &d.vendor_id); + sscanf(device_entry.device().c_str(), "%hx", &d.device_id); hwNode *device = scan_pci_dev(d, n); if(device) @@ -1166,7 +1173,7 @@ bool scan_pci(hwNode & n) device->claim(); } - device->setModalias(sysfs::entry::byBus("pci", devices[i]->d_name).modalias()); + device->setModalias(device_entry.modalias()); if(exists(resourcename)) { diff --git a/src/core/sysfs.cc b/src/core/sysfs.cc index 97dbab5..486f8ee 100644 --- a/src/core/sysfs.cc +++ b/src/core/sysfs.cc @@ -358,6 +358,16 @@ string entry::modalias() const return get_string(This->devpath+"/modalias"); } +string entry::device() const +{ + return get_string(This->devpath+"/device"); +} + +string entry::vendor() const +{ + return get_string(This->devpath+"/vendor"); +} + vector < entry > sysfs::entries_by_bus(const string & busname) { vector < entry > result; diff --git a/src/core/sysfs.h b/src/core/sysfs.h index d37e2d4..dffa4b2 100644 --- a/src/core/sysfs.h +++ b/src/core/sysfs.h @@ -26,6 +26,8 @@ namespace sysfs string businfo() const; string driver() const; string modalias() const; + string device() const; + string vendor() const; entry parent() const; string name_in_class(const string &) const; string string_attr(const string & name, const string & def = "") const; -- 2.14.0