From 96e239434c629491e57a359a2f876b6d41476336 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Fri, 15 Jan 2016 22:08:44 +0100 Subject: firmware: dmi_scan: Optimize dmi_save_extended_devices Calling dmi_string_nosave isn't cheap, so avoid calling it twice in a row for the same string. Signed-off-by: Jean Delvare Cc: Jordan Hargrave Cc: Narendra K diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 0e08e66..28b2f0a 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -345,15 +345,17 @@ static void __init dmi_save_dev_onboard(int instance, int segment, int bus, static void __init dmi_save_extended_devices(const struct dmi_header *dm) { + const char *name; const u8 *d = (u8 *) dm + 5; /* Skip disabled device */ if ((*d & 0x80) == 0) return; + name = dmi_string_nosave(dm, *(d - 1)); dmi_save_dev_onboard(*(d+1), *(u16 *)(d+2), *(d+4), *(d+5), - dmi_string_nosave(dm, *(d-1))); - dmi_save_one_device(*d & 0x7f, dmi_string_nosave(dm, *(d - 1))); + name); + dmi_save_one_device(*d & 0x7f, name); } static void __init count_mem_devices(const struct dmi_header *dm, void *v) -- cgit v0.10.2 From 45b9825708198311cbe00daf9d1a40098c12c45b Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Fri, 15 Jan 2016 22:08:44 +0100 Subject: firmware: dmi_scan: Clarify dmi_save_extended_devices Get rid of the arbitrary 5-byte pointer offset, it served no purpose and made it harder to match the code with the SMBIOS specification. Signed-off-by: Jean Delvare Cc: Jordan Hargrave Cc: Narendra K diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 28b2f0a..ce666ef 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -346,16 +346,15 @@ static void __init dmi_save_dev_onboard(int instance, int segment, int bus, static void __init dmi_save_extended_devices(const struct dmi_header *dm) { const char *name; - const u8 *d = (u8 *) dm + 5; + const u8 *d = (u8 *)dm; /* Skip disabled device */ - if ((*d & 0x80) == 0) + if ((d[0x5] & 0x80) == 0) return; - name = dmi_string_nosave(dm, *(d - 1)); - dmi_save_dev_onboard(*(d+1), *(u16 *)(d+2), *(d+4), *(d+5), - name); - dmi_save_one_device(*d & 0x7f, name); + name = dmi_string_nosave(dm, d[0x4]); + dmi_save_dev_onboard(d[0x6], *(u16 *)(d + 0x7), d[0x9], d[0xA], name); + dmi_save_one_device(d[0x5] & 0x7f, name); } static void __init count_mem_devices(const struct dmi_header *dm, void *v) -- cgit v0.10.2 From bfab8b48598f851dfeca2b40fd06969bf8634d37 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Fri, 15 Jan 2016 22:08:44 +0100 Subject: firmware: dmi_scan: Fix dmi_find_device description The description of dmi_find_device was apparently copied from a similar function in a different subsystem, but the parameter names were not adjusted as needed. Signed-off-by: Jean Delvare Cc: Andrey Panin diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index ce666ef..908653f 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -870,7 +870,7 @@ EXPORT_SYMBOL(dmi_name_in_vendors); * @from: previous device found in search, or %NULL for new search. * * Iterates through the list of known onboard devices. If a device is - * found with a matching @vendor and @device, a pointer to its device + * found with a matching @type and @name, a pointer to its device * structure is returned. Otherwise, %NULL is returned. * A new search is initiated by passing %NULL as the @from argument. * If @from is not %NULL, searches continue from next device. -- cgit v0.10.2 From e5b6c1518878e157df4121c1caf70d9c470a6d31 Mon Sep 17 00:00:00 2001 From: Jordan Hargrave Date: Fri, 15 Jan 2016 22:08:45 +0100 Subject: firmware: dmi_scan: Save SMBIOS Type 9 System Slots Save SMBIOS Type 9 System Slots during DMI scan. PCI address of onboard devices was already saved but not for slots. Signed-off-by: Jordan Hargrave Signed-off-by: Jean Delvare diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 908653f..88bebe1 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -321,26 +321,31 @@ static void __init dmi_save_ipmi_device(const struct dmi_header *dm) list_add_tail(&dev->list, &dmi_devices); } -static void __init dmi_save_dev_onboard(int instance, int segment, int bus, - int devfn, const char *name) +static void __init dmi_save_dev_pciaddr(int instance, int segment, int bus, + int devfn, const char *name, int type) { - struct dmi_dev_onboard *onboard_dev; + struct dmi_dev_onboard *dev; - onboard_dev = dmi_alloc(sizeof(*onboard_dev) + strlen(name) + 1); - if (!onboard_dev) + /* Ignore invalid values */ + if (type == DMI_DEV_TYPE_DEV_SLOT && + segment == 0xFFFF && bus == 0xFF && devfn == 0xFF) return; - onboard_dev->instance = instance; - onboard_dev->segment = segment; - onboard_dev->bus = bus; - onboard_dev->devfn = devfn; + dev = dmi_alloc(sizeof(*dev) + strlen(name) + 1); + if (!dev) + return; - strcpy((char *)&onboard_dev[1], name); - onboard_dev->dev.type = DMI_DEV_TYPE_DEV_ONBOARD; - onboard_dev->dev.name = (char *)&onboard_dev[1]; - onboard_dev->dev.device_data = onboard_dev; + dev->instance = instance; + dev->segment = segment; + dev->bus = bus; + dev->devfn = devfn; - list_add(&onboard_dev->dev.list, &dmi_devices); + strcpy((char *)&dev[1], name); + dev->dev.type = type; + dev->dev.name = (char *)&dev[1]; + dev->dev.device_data = dev; + + list_add(&dev->dev.list, &dmi_devices); } static void __init dmi_save_extended_devices(const struct dmi_header *dm) @@ -353,10 +358,23 @@ static void __init dmi_save_extended_devices(const struct dmi_header *dm) return; name = dmi_string_nosave(dm, d[0x4]); - dmi_save_dev_onboard(d[0x6], *(u16 *)(d + 0x7), d[0x9], d[0xA], name); + dmi_save_dev_pciaddr(d[0x6], *(u16 *)(d + 0x7), d[0x9], d[0xA], name, + DMI_DEV_TYPE_DEV_ONBOARD); dmi_save_one_device(d[0x5] & 0x7f, name); } +static void __init dmi_save_system_slot(const struct dmi_header *dm) +{ + const u8 *d = (u8 *)dm; + + /* Need SMBIOS 2.6+ structure */ + if (dm->length < 0x11) + return; + dmi_save_dev_pciaddr(*(u16 *)(d + 0x9), *(u16 *)(d + 0xD), d[0xF], + d[0x10], dmi_string_nosave(dm, d[0x4]), + DMI_DEV_TYPE_DEV_SLOT); +} + static void __init count_mem_devices(const struct dmi_header *dm, void *v) { if (dm->type != DMI_ENTRY_MEM_DEVICE) @@ -427,6 +445,9 @@ static void __init dmi_decode(const struct dmi_header *dm, void *dummy) dmi_save_ident(dm, DMI_CHASSIS_SERIAL, 7); dmi_save_ident(dm, DMI_CHASSIS_ASSET_TAG, 8); break; + case 9: /* System Slots */ + dmi_save_system_slot(dm); + break; case 10: /* Onboard Devices Information */ dmi_save_devices(dm); break; diff --git a/include/linux/dmi.h b/include/linux/dmi.h index 5055ac3..5e9c74c 100644 --- a/include/linux/dmi.h +++ b/include/linux/dmi.h @@ -22,6 +22,7 @@ enum dmi_device_type { DMI_DEV_TYPE_IPMI = -1, DMI_DEV_TYPE_OEM_STRING = -2, DMI_DEV_TYPE_DEV_ONBOARD = -3, + DMI_DEV_TYPE_DEV_SLOT = -4, }; enum dmi_entry_type { -- cgit v0.10.2