diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2006-04-06 10:47:22 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-04-06 10:47:22 -0700 |
commit | 92829af95c1d3e6eaf90b17e1077b5fa7a90949f (patch) | |
tree | 934d5ce7bed6df5fad28c380373ee321fff13719 /driver | |
parent | fe478e333919011b5199264b34a647ea51f654b3 (diff) | |
download | patches-92829af95c1d3e6eaf90b17e1077b5fa7a90949f.tar.gz |
new patch
Diffstat (limited to 'driver')
-rw-r--r-- | driver/dmi-move-dmi_scan.c-from-arch-i386-to-drivers-firmware.patch | 815 |
1 files changed, 815 insertions, 0 deletions
diff --git a/driver/dmi-move-dmi_scan.c-from-arch-i386-to-drivers-firmware.patch b/driver/dmi-move-dmi_scan.c-from-arch-i386-to-drivers-firmware.patch new file mode 100644 index 0000000000000..86317d9df9d3a --- /dev/null +++ b/driver/dmi-move-dmi_scan.c-from-arch-i386-to-drivers-firmware.patch @@ -0,0 +1,815 @@ +From akpm@osdl.org Thu Apr 6 10:21:36 2006 +Message-Id: <200604040006.k3406v9c006915@shell0.pdx.osdl.net> +Subject: DMI: move dmi_scan.c from arch/i386 to drivers/firmware/ +To: bjorn.helgaas@hp.com, ak@muc.de, greg@kroah.com, pazke@orbita1.ru, tony.luck@intel.com, mm-commits@vger.kernel.org +From: Bjorn Helgaas <bjorn.helgaas@hp.com> +Date: Mon, 3 Apr 2006 17:09:22 -0700 + +From: Bjorn Helgaas <bjorn.helgaas@hp.com> + +dmi_scan.c is arch-independent and is used by i386, x86_64, and ia64. +Currently all three arches compile it from arch/i386, which means that ia64 +and x86_64 depend on things in arch/i386 that they wouldn't otherwise care +about. + +This is simply "mv arch/i386/kernel/dmi_scan.c drivers/firmware/" (removing +trailing whitespace) and the associated Makefile changes. All three +architectures already set CONFIG_DMI in their top-level Kconfig files. + +Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com> +Cc: Andi Kleen <ak@muc.de> +Cc: "Luck, Tony" <tony.luck@intel.com> +Cc: Andrey Panin <pazke@orbita1.ru> +Signed-off-by: Andrew Morton <akpm@osdl.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + arch/i386/kernel/Makefile | 2 + arch/i386/kernel/dmi_scan.c | 358 -------------------------------------------- + arch/ia64/kernel/Makefile | 3 + arch/x86_64/kernel/Makefile | 4 + drivers/firmware/Makefile | 3 + drivers/firmware/dmi_scan.c | 358 ++++++++++++++++++++++++++++++++++++++++++++ + 6 files changed, 363 insertions(+), 365 deletions(-) + +--- gregkh-2.6.orig/arch/i386/kernel/Makefile ++++ gregkh-2.6/arch/i386/kernel/Makefile +@@ -6,7 +6,7 @@ extra-y := head.o init_task.o vmlinux.ld + + obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \ + ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \ +- pci-dma.o i386_ksyms.o i387.o dmi_scan.o bootflag.o \ ++ pci-dma.o i386_ksyms.o i387.o bootflag.o \ + quirks.o i8237.o topology.o alternative.o + + obj-y += cpu/ +--- gregkh-2.6.orig/arch/i386/kernel/dmi_scan.c ++++ /dev/null +@@ -1,358 +0,0 @@ +-#include <linux/types.h> +-#include <linux/string.h> +-#include <linux/init.h> +-#include <linux/module.h> +-#include <linux/dmi.h> +-#include <linux/efi.h> +-#include <linux/bootmem.h> +-#include <linux/slab.h> +-#include <asm/dmi.h> +- +-static char * __init dmi_string(struct dmi_header *dm, u8 s) +-{ +- u8 *bp = ((u8 *) dm) + dm->length; +- char *str = ""; +- +- if (s) { +- s--; +- while (s > 0 && *bp) { +- bp += strlen(bp) + 1; +- s--; +- } +- +- if (*bp != 0) { +- str = dmi_alloc(strlen(bp) + 1); +- if (str != NULL) +- strcpy(str, bp); +- else +- printk(KERN_ERR "dmi_string: out of memory.\n"); +- } +- } +- +- return str; +-} +- +-/* +- * We have to be cautious here. We have seen BIOSes with DMI pointers +- * pointing to completely the wrong place for example +- */ +-static int __init dmi_table(u32 base, int len, int num, +- void (*decode)(struct dmi_header *)) +-{ +- u8 *buf, *data; +- int i = 0; +- +- buf = dmi_ioremap(base, len); +- if (buf == NULL) +- return -1; +- +- data = buf; +- +- /* +- * Stop when we see all the items the table claimed to have +- * OR we run off the end of the table (also happens) +- */ +- while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) { +- struct dmi_header *dm = (struct dmi_header *)data; +- /* +- * We want to know the total length (formated area and strings) +- * before decoding to make sure we won't run off the table in +- * dmi_decode or dmi_string +- */ +- data += dm->length; +- while ((data - buf < len - 1) && (data[0] || data[1])) +- data++; +- if (data - buf < len - 1) +- decode(dm); +- data += 2; +- i++; +- } +- dmi_iounmap(buf, len); +- return 0; +-} +- +-static int __init dmi_checksum(u8 *buf) +-{ +- u8 sum = 0; +- int a; +- +- for (a = 0; a < 15; a++) +- sum += buf[a]; +- +- return sum == 0; +-} +- +-static char *dmi_ident[DMI_STRING_MAX]; +-static LIST_HEAD(dmi_devices); +- +-/* +- * Save a DMI string +- */ +-static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string) +-{ +- char *p, *d = (char*) dm; +- +- if (dmi_ident[slot]) +- return; +- +- p = dmi_string(dm, d[string]); +- if (p == NULL) +- return; +- +- dmi_ident[slot] = p; +-} +- +-static void __init dmi_save_devices(struct dmi_header *dm) +-{ +- int i, count = (dm->length - sizeof(struct dmi_header)) / 2; +- struct dmi_device *dev; +- +- for (i = 0; i < count; i++) { +- char *d = (char *)(dm + 1) + (i * 2); +- +- /* Skip disabled device */ +- if ((*d & 0x80) == 0) +- continue; +- +- dev = dmi_alloc(sizeof(*dev)); +- if (!dev) { +- printk(KERN_ERR "dmi_save_devices: out of memory.\n"); +- break; +- } +- +- dev->type = *d++ & 0x7f; +- dev->name = dmi_string(dm, *d); +- dev->device_data = NULL; +- +- list_add(&dev->list, &dmi_devices); +- } +-} +- +-static void __init dmi_save_ipmi_device(struct dmi_header *dm) +-{ +- struct dmi_device *dev; +- void * data; +- +- data = dmi_alloc(dm->length); +- if (data == NULL) { +- printk(KERN_ERR "dmi_save_ipmi_device: out of memory.\n"); +- return; +- } +- +- memcpy(data, dm, dm->length); +- +- dev = dmi_alloc(sizeof(*dev)); +- if (!dev) { +- printk(KERN_ERR "dmi_save_ipmi_device: out of memory.\n"); +- return; +- } +- +- dev->type = DMI_DEV_TYPE_IPMI; +- dev->name = "IPMI controller"; +- dev->device_data = data; +- +- list_add(&dev->list, &dmi_devices); +-} +- +-/* +- * Process a DMI table entry. Right now all we care about are the BIOS +- * and machine entries. For 2.5 we should pull the smbus controller info +- * out of here. +- */ +-static void __init dmi_decode(struct dmi_header *dm) +-{ +- switch(dm->type) { +- case 0: /* BIOS Information */ +- dmi_save_ident(dm, DMI_BIOS_VENDOR, 4); +- dmi_save_ident(dm, DMI_BIOS_VERSION, 5); +- dmi_save_ident(dm, DMI_BIOS_DATE, 8); +- break; +- case 1: /* System Information */ +- dmi_save_ident(dm, DMI_SYS_VENDOR, 4); +- dmi_save_ident(dm, DMI_PRODUCT_NAME, 5); +- dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6); +- dmi_save_ident(dm, DMI_PRODUCT_SERIAL, 7); +- break; +- case 2: /* Base Board Information */ +- dmi_save_ident(dm, DMI_BOARD_VENDOR, 4); +- dmi_save_ident(dm, DMI_BOARD_NAME, 5); +- dmi_save_ident(dm, DMI_BOARD_VERSION, 6); +- break; +- case 10: /* Onboard Devices Information */ +- dmi_save_devices(dm); +- break; +- case 38: /* IPMI Device Information */ +- dmi_save_ipmi_device(dm); +- } +-} +- +-static int __init dmi_present(char __iomem *p) +-{ +- u8 buf[15]; +- memcpy_fromio(buf, p, 15); +- if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) { +- u16 num = (buf[13] << 8) | buf[12]; +- u16 len = (buf[7] << 8) | buf[6]; +- u32 base = (buf[11] << 24) | (buf[10] << 16) | +- (buf[9] << 8) | buf[8]; +- +- /* +- * DMI version 0.0 means that the real version is taken from +- * the SMBIOS version, which we don't know at this point. +- */ +- if (buf[14] != 0) +- printk(KERN_INFO "DMI %d.%d present.\n", +- buf[14] >> 4, buf[14] & 0xF); +- else +- printk(KERN_INFO "DMI present.\n"); +- if (dmi_table(base,len, num, dmi_decode) == 0) +- return 0; +- } +- return 1; +-} +- +-void __init dmi_scan_machine(void) +-{ +- char __iomem *p, *q; +- int rc; +- +- if (efi_enabled) { +- if (efi.smbios == EFI_INVALID_TABLE_ADDR) +- goto out; +- +- /* This is called as a core_initcall() because it isn't +- * needed during early boot. This also means we can +- * iounmap the space when we're done with it. +- */ +- p = dmi_ioremap(efi.smbios, 32); +- if (p == NULL) +- goto out; +- +- rc = dmi_present(p + 0x10); /* offset of _DMI_ string */ +- dmi_iounmap(p, 32); +- if (!rc) +- return; +- } +- else { +- /* +- * no iounmap() for that ioremap(); it would be a no-op, but +- * it's so early in setup that sucker gets confused into doing +- * what it shouldn't if we actually call it. +- */ +- p = dmi_ioremap(0xF0000, 0x10000); +- if (p == NULL) +- goto out; +- +- for (q = p; q < p + 0x10000; q += 16) { +- rc = dmi_present(q); +- if (!rc) +- return; +- } +- } +- out: printk(KERN_INFO "DMI not present or invalid.\n"); +-} +- +-/** +- * dmi_check_system - check system DMI data +- * @list: array of dmi_system_id structures to match against +- * +- * Walk the blacklist table running matching functions until someone +- * returns non zero or we hit the end. Callback function is called for +- * each successfull match. Returns the number of matches. +- */ +-int dmi_check_system(struct dmi_system_id *list) +-{ +- int i, count = 0; +- struct dmi_system_id *d = list; +- +- while (d->ident) { +- for (i = 0; i < ARRAY_SIZE(d->matches); i++) { +- int s = d->matches[i].slot; +- if (s == DMI_NONE) +- continue; +- if (dmi_ident[s] && strstr(dmi_ident[s], d->matches[i].substr)) +- continue; +- /* No match */ +- goto fail; +- } +- count++; +- if (d->callback && d->callback(d)) +- break; +-fail: d++; +- } +- +- return count; +-} +-EXPORT_SYMBOL(dmi_check_system); +- +-/** +- * dmi_get_system_info - return DMI data value +- * @field: data index (see enum dmi_filed) +- * +- * Returns one DMI data value, can be used to perform +- * complex DMI data checks. +- */ +-char *dmi_get_system_info(int field) +-{ +- return dmi_ident[field]; +-} +-EXPORT_SYMBOL(dmi_get_system_info); +- +-/** +- * dmi_find_device - find onboard device by type/name +- * @type: device type or %DMI_DEV_TYPE_ANY to match all device types +- * @desc: device name string or %NULL to match all +- * @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 +- * structure is returned. Otherwise, %NULL is returned. +- * A new search is initiated by passing %NULL to the @from argument. +- * If @from is not %NULL, searches continue from next device. +- */ +-struct dmi_device * dmi_find_device(int type, const char *name, +- struct dmi_device *from) +-{ +- struct list_head *d, *head = from ? &from->list : &dmi_devices; +- +- for(d = head->next; d != &dmi_devices; d = d->next) { +- struct dmi_device *dev = list_entry(d, struct dmi_device, list); +- +- if (((type == DMI_DEV_TYPE_ANY) || (dev->type == type)) && +- ((name == NULL) || (strcmp(dev->name, name) == 0))) +- return dev; +- } +- +- return NULL; +-} +-EXPORT_SYMBOL(dmi_find_device); +- +-/** +- * dmi_get_year - Return year of a DMI date +- * @field: data index (like dmi_get_system_info) +- * +- * Returns -1 when the field doesn't exist. 0 when it is broken. +- */ +-int dmi_get_year(int field) +-{ +- int year; +- char *s = dmi_get_system_info(field); +- +- if (!s) +- return -1; +- if (*s == '\0') +- return 0; +- s = strrchr(s, '/'); +- if (!s) +- return 0; +- +- s += 1; +- year = simple_strtoul(s, NULL, 0); +- if (year && year < 100) { /* 2-digit year */ +- year += 1900; +- if (year < 1996) /* no dates < spec 1.0 */ +- year += 100; +- } +- +- return year; +-} +--- gregkh-2.6.orig/arch/ia64/kernel/Makefile ++++ gregkh-2.6/arch/ia64/kernel/Makefile +@@ -7,7 +7,7 @@ extra-y := head.o init_task.o vmlinux.ld + obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o \ + irq_lsapic.o ivt.o machvec.o pal.o patch.o process.o perfmon.o ptrace.o sal.o \ + salinfo.o semaphore.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o \ +- unwind.o mca.o mca_asm.o topology.o dmi_scan.o ++ unwind.o mca.o mca_asm.o topology.o + + obj-$(CONFIG_IA64_BRL_EMU) += brl_emu.o + obj-$(CONFIG_IA64_GENERIC) += acpi-ext.o +@@ -30,7 +30,6 @@ obj-$(CONFIG_IA64_MCA_RECOVERY) += mca_r + obj-$(CONFIG_KPROBES) += kprobes.o jprobes.o + obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o + mca_recovery-y += mca_drv.o mca_drv_asm.o +-dmi_scan-y += ../../i386/kernel/dmi_scan.o + + # The gate DSO image is built using a special linker script. + targets += gate.so gate-syms.o +--- gregkh-2.6.orig/arch/x86_64/kernel/Makefile ++++ gregkh-2.6/arch/x86_64/kernel/Makefile +@@ -8,7 +8,7 @@ obj-y := process.o signal.o entry.o trap + ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_x86_64.o \ + x8664_ksyms.o i387.o syscall.o vsyscall.o \ + setup64.o bootflag.o e820.o reboot.o quirks.o i8237.o \ +- dmi_scan.o pci-dma.o pci-nommu.o ++ pci-dma.o pci-nommu.o + + obj-$(CONFIG_X86_MCE) += mce.o + obj-$(CONFIG_X86_MCE_INTEL) += mce_intel.o +@@ -49,5 +49,3 @@ intel_cacheinfo-y += ../../i386/kernel/ + quirks-y += ../../i386/kernel/quirks.o + i8237-y += ../../i386/kernel/i8237.o + msr-$(subst m,y,$(CONFIG_X86_MSR)) += ../../i386/kernel/msr.o +-dmi_scan-y += ../../i386/kernel/dmi_scan.o +- +--- gregkh-2.6.orig/drivers/firmware/Makefile ++++ gregkh-2.6/drivers/firmware/Makefile +@@ -1,7 +1,8 @@ + # + # Makefile for the linux kernel. + # +-obj-$(CONFIG_EDD) += edd.o ++obj-$(CONFIG_DMI) += dmi_scan.o ++obj-$(CONFIG_EDD) += edd.o + obj-$(CONFIG_EFI_VARS) += efivars.o + obj-$(CONFIG_EFI_PCDP) += pcdp.o + obj-$(CONFIG_DELL_RBU) += dell_rbu.o +--- /dev/null ++++ gregkh-2.6/drivers/firmware/dmi_scan.c +@@ -0,0 +1,358 @@ ++#include <linux/types.h> ++#include <linux/string.h> ++#include <linux/init.h> ++#include <linux/module.h> ++#include <linux/dmi.h> ++#include <linux/efi.h> ++#include <linux/bootmem.h> ++#include <linux/slab.h> ++#include <asm/dmi.h> ++ ++static char * __init dmi_string(struct dmi_header *dm, u8 s) ++{ ++ u8 *bp = ((u8 *) dm) + dm->length; ++ char *str = ""; ++ ++ if (s) { ++ s--; ++ while (s > 0 && *bp) { ++ bp += strlen(bp) + 1; ++ s--; ++ } ++ ++ if (*bp != 0) { ++ str = dmi_alloc(strlen(bp) + 1); ++ if (str != NULL) ++ strcpy(str, bp); ++ else ++ printk(KERN_ERR "dmi_string: out of memory.\n"); ++ } ++ } ++ ++ return str; ++} ++ ++/* ++ * We have to be cautious here. We have seen BIOSes with DMI pointers ++ * pointing to completely the wrong place for example ++ */ ++static int __init dmi_table(u32 base, int len, int num, ++ void (*decode)(struct dmi_header *)) ++{ ++ u8 *buf, *data; ++ int i = 0; ++ ++ buf = dmi_ioremap(base, len); ++ if (buf == NULL) ++ return -1; ++ ++ data = buf; ++ ++ /* ++ * Stop when we see all the items the table claimed to have ++ * OR we run off the end of the table (also happens) ++ */ ++ while ((i < num) && (data - buf + sizeof(struct dmi_header)) <= len) { ++ struct dmi_header *dm = (struct dmi_header *)data; ++ /* ++ * We want to know the total length (formated area and strings) ++ * before decoding to make sure we won't run off the table in ++ * dmi_decode or dmi_string ++ */ ++ data += dm->length; ++ while ((data - buf < len - 1) && (data[0] || data[1])) ++ data++; ++ if (data - buf < len - 1) ++ decode(dm); ++ data += 2; ++ i++; ++ } ++ dmi_iounmap(buf, len); ++ return 0; ++} ++ ++static int __init dmi_checksum(u8 *buf) ++{ ++ u8 sum = 0; ++ int a; ++ ++ for (a = 0; a < 15; a++) ++ sum += buf[a]; ++ ++ return sum == 0; ++} ++ ++static char *dmi_ident[DMI_STRING_MAX]; ++static LIST_HEAD(dmi_devices); ++ ++/* ++ * Save a DMI string ++ */ ++static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string) ++{ ++ char *p, *d = (char*) dm; ++ ++ if (dmi_ident[slot]) ++ return; ++ ++ p = dmi_string(dm, d[string]); ++ if (p == NULL) ++ return; ++ ++ dmi_ident[slot] = p; ++} ++ ++static void __init dmi_save_devices(struct dmi_header *dm) ++{ ++ int i, count = (dm->length - sizeof(struct dmi_header)) / 2; ++ struct dmi_device *dev; ++ ++ for (i = 0; i < count; i++) { ++ char *d = (char *)(dm + 1) + (i * 2); ++ ++ /* Skip disabled device */ ++ if ((*d & 0x80) == 0) ++ continue; ++ ++ dev = dmi_alloc(sizeof(*dev)); ++ if (!dev) { ++ printk(KERN_ERR "dmi_save_devices: out of memory.\n"); ++ break; ++ } ++ ++ dev->type = *d++ & 0x7f; ++ dev->name = dmi_string(dm, *d); ++ dev->device_data = NULL; ++ ++ list_add(&dev->list, &dmi_devices); ++ } ++} ++ ++static void __init dmi_save_ipmi_device(struct dmi_header *dm) ++{ ++ struct dmi_device *dev; ++ void * data; ++ ++ data = dmi_alloc(dm->length); ++ if (data == NULL) { ++ printk(KERN_ERR "dmi_save_ipmi_device: out of memory.\n"); ++ return; ++ } ++ ++ memcpy(data, dm, dm->length); ++ ++ dev = dmi_alloc(sizeof(*dev)); ++ if (!dev) { ++ printk(KERN_ERR "dmi_save_ipmi_device: out of memory.\n"); ++ return; ++ } ++ ++ dev->type = DMI_DEV_TYPE_IPMI; ++ dev->name = "IPMI controller"; ++ dev->device_data = data; ++ ++ list_add(&dev->list, &dmi_devices); ++} ++ ++/* ++ * Process a DMI table entry. Right now all we care about are the BIOS ++ * and machine entries. For 2.5 we should pull the smbus controller info ++ * out of here. ++ */ ++static void __init dmi_decode(struct dmi_header *dm) ++{ ++ switch(dm->type) { ++ case 0: /* BIOS Information */ ++ dmi_save_ident(dm, DMI_BIOS_VENDOR, 4); ++ dmi_save_ident(dm, DMI_BIOS_VERSION, 5); ++ dmi_save_ident(dm, DMI_BIOS_DATE, 8); ++ break; ++ case 1: /* System Information */ ++ dmi_save_ident(dm, DMI_SYS_VENDOR, 4); ++ dmi_save_ident(dm, DMI_PRODUCT_NAME, 5); ++ dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6); ++ dmi_save_ident(dm, DMI_PRODUCT_SERIAL, 7); ++ break; ++ case 2: /* Base Board Information */ ++ dmi_save_ident(dm, DMI_BOARD_VENDOR, 4); ++ dmi_save_ident(dm, DMI_BOARD_NAME, 5); ++ dmi_save_ident(dm, DMI_BOARD_VERSION, 6); ++ break; ++ case 10: /* Onboard Devices Information */ ++ dmi_save_devices(dm); ++ break; ++ case 38: /* IPMI Device Information */ ++ dmi_save_ipmi_device(dm); ++ } ++} ++ ++static int __init dmi_present(char __iomem *p) ++{ ++ u8 buf[15]; ++ memcpy_fromio(buf, p, 15); ++ if ((memcmp(buf, "_DMI_", 5) == 0) && dmi_checksum(buf)) { ++ u16 num = (buf[13] << 8) | buf[12]; ++ u16 len = (buf[7] << 8) | buf[6]; ++ u32 base = (buf[11] << 24) | (buf[10] << 16) | ++ (buf[9] << 8) | buf[8]; ++ ++ /* ++ * DMI version 0.0 means that the real version is taken from ++ * the SMBIOS version, which we don't know at this point. ++ */ ++ if (buf[14] != 0) ++ printk(KERN_INFO "DMI %d.%d present.\n", ++ buf[14] >> 4, buf[14] & 0xF); ++ else ++ printk(KERN_INFO "DMI present.\n"); ++ if (dmi_table(base,len, num, dmi_decode) == 0) ++ return 0; ++ } ++ return 1; ++} ++ ++void __init dmi_scan_machine(void) ++{ ++ char __iomem *p, *q; ++ int rc; ++ ++ if (efi_enabled) { ++ if (efi.smbios == EFI_INVALID_TABLE_ADDR) ++ goto out; ++ ++ /* This is called as a core_initcall() because it isn't ++ * needed during early boot. This also means we can ++ * iounmap the space when we're done with it. ++ */ ++ p = dmi_ioremap(efi.smbios, 32); ++ if (p == NULL) ++ goto out; ++ ++ rc = dmi_present(p + 0x10); /* offset of _DMI_ string */ ++ dmi_iounmap(p, 32); ++ if (!rc) ++ return; ++ } ++ else { ++ /* ++ * no iounmap() for that ioremap(); it would be a no-op, but ++ * it's so early in setup that sucker gets confused into doing ++ * what it shouldn't if we actually call it. ++ */ ++ p = dmi_ioremap(0xF0000, 0x10000); ++ if (p == NULL) ++ goto out; ++ ++ for (q = p; q < p + 0x10000; q += 16) { ++ rc = dmi_present(q); ++ if (!rc) ++ return; ++ } ++ } ++ out: printk(KERN_INFO "DMI not present or invalid.\n"); ++} ++ ++/** ++ * dmi_check_system - check system DMI data ++ * @list: array of dmi_system_id structures to match against ++ * ++ * Walk the blacklist table running matching functions until someone ++ * returns non zero or we hit the end. Callback function is called for ++ * each successfull match. Returns the number of matches. ++ */ ++int dmi_check_system(struct dmi_system_id *list) ++{ ++ int i, count = 0; ++ struct dmi_system_id *d = list; ++ ++ while (d->ident) { ++ for (i = 0; i < ARRAY_SIZE(d->matches); i++) { ++ int s = d->matches[i].slot; ++ if (s == DMI_NONE) ++ continue; ++ if (dmi_ident[s] && strstr(dmi_ident[s], d->matches[i].substr)) ++ continue; ++ /* No match */ ++ goto fail; ++ } ++ count++; ++ if (d->callback && d->callback(d)) ++ break; ++fail: d++; ++ } ++ ++ return count; ++} ++EXPORT_SYMBOL(dmi_check_system); ++ ++/** ++ * dmi_get_system_info - return DMI data value ++ * @field: data index (see enum dmi_filed) ++ * ++ * Returns one DMI data value, can be used to perform ++ * complex DMI data checks. ++ */ ++char *dmi_get_system_info(int field) ++{ ++ return dmi_ident[field]; ++} ++EXPORT_SYMBOL(dmi_get_system_info); ++ ++/** ++ * dmi_find_device - find onboard device by type/name ++ * @type: device type or %DMI_DEV_TYPE_ANY to match all device types ++ * @desc: device name string or %NULL to match all ++ * @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 ++ * structure is returned. Otherwise, %NULL is returned. ++ * A new search is initiated by passing %NULL to the @from argument. ++ * If @from is not %NULL, searches continue from next device. ++ */ ++struct dmi_device * dmi_find_device(int type, const char *name, ++ struct dmi_device *from) ++{ ++ struct list_head *d, *head = from ? &from->list : &dmi_devices; ++ ++ for(d = head->next; d != &dmi_devices; d = d->next) { ++ struct dmi_device *dev = list_entry(d, struct dmi_device, list); ++ ++ if (((type == DMI_DEV_TYPE_ANY) || (dev->type == type)) && ++ ((name == NULL) || (strcmp(dev->name, name) == 0))) ++ return dev; ++ } ++ ++ return NULL; ++} ++EXPORT_SYMBOL(dmi_find_device); ++ ++/** ++ * dmi_get_year - Return year of a DMI date ++ * @field: data index (like dmi_get_system_info) ++ * ++ * Returns -1 when the field doesn't exist. 0 when it is broken. ++ */ ++int dmi_get_year(int field) ++{ ++ int year; ++ char *s = dmi_get_system_info(field); ++ ++ if (!s) ++ return -1; ++ if (*s == '\0') ++ return 0; ++ s = strrchr(s, '/'); ++ if (!s) ++ return 0; ++ ++ s += 1; ++ year = simple_strtoul(s, NULL, 0); ++ if (year && year < 100) { /* 2-digit year */ ++ year += 1900; ++ if (year < 1996) /* no dates < spec 1.0 */ ++ year += 100; ++ } ++ ++ return year; ++} |