* [PATCH 0/5] 2.6.13-rc5-mm1, remove uneeded function
@ 2005-08-10 10:32 Andrey Panin
2005-08-10 10:32 ` [PATCH 1/5] 2.6.13-rc5-mm1, remove old debugging code Andrey Panin
0 siblings, 1 reply; 9+ messages in thread
From: Andrey Panin @ 2005-08-10 10:32 UTC (permalink / raw)
To: Andrew Morton, linux-kernel
After elimination of central DMI blacklist dmi_scan_machine() function
became a wrapper for dmi_iterate(). This patch moves some code around to
kill unneeded function.
Signed-off-by: Andrey Panin <pazke@donpac.ru>
arch/i386/kernel/dmi_scan.c | 85 ++++++++++++++++++++------------------------
1 files changed, 40 insertions(+), 45 deletions(-)
diff -urdpNX /usr/share/dontdiff linux-2.6.13-rc5-mm1.vanilla/arch/i386/kernel/dmi_scan.c linux-2.6.13-rc5-mm1/arch/i386/kernel/dmi_scan.c
--- linux-2.6.13-rc5-mm1.vanilla/arch/i386/kernel/dmi_scan.c 2005-06-12 23:07:37.000000000 +0400
+++ linux-2.6.13-rc5-mm1/arch/i386/kernel/dmi_scan.c 2005-06-14 23:18:18.000000000 +0400
@@ -84,49 +84,6 @@ static int __init dmi_checksum(u8 *buf)
return sum == 0;
}
-static int __init dmi_iterate(void (*decode)(struct dmi_header *))
-{
- u8 buf[15];
- char __iomem *p, *q;
-
- /*
- * 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 = ioremap(0xF0000, 0x10000);
- if (p == NULL)
- return -1;
-
- for (q = p; q < p + 0x10000; q += 16) {
- memcpy_fromio(buf, q, 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");
-
- dmi_printk((KERN_INFO "%d structures occupying %d bytes.\n",
- num, len));
- dmi_printk((KERN_INFO "DMI table at 0x%08X.\n", base));
-
- if (dmi_table(base,len, num, decode) == 0)
- return 0;
- }
- }
- return -1;
-}
-
static char *dmi_ident[DMI_STRING_MAX];
/*
@@ -190,8 +147,46 @@ static void __init dmi_decode(struct dmi
void __init dmi_scan_machine(void)
{
- if (dmi_iterate(dmi_decode))
- printk(KERN_INFO "DMI not present.\n");
+ u8 buf[15];
+ char __iomem *p, *q;
+
+ /*
+ * 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 = ioremap(0xF0000, 0x10000);
+ if (p == NULL)
+ goto out;
+
+ for (q = p; q < p + 0x10000; q += 16) {
+ memcpy_fromio(buf, q, 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");
+
+ dmi_printk((KERN_INFO "%d structures occupying %d bytes.\n",
+ num, len));
+ dmi_printk((KERN_INFO "DMI table at 0x%08X.\n", base));
+
+ if (dmi_table(base,len, num, dmi_decode) == 0)
+ return;
+ }
+ }
+
+out: printk(KERN_INFO "DMI not present.\n");
}
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH 1/5] 2.6.13-rc5-mm1, remove old debugging code 2005-08-10 10:32 [PATCH 0/5] 2.6.13-rc5-mm1, remove uneeded function Andrey Panin @ 2005-08-10 10:32 ` Andrey Panin 2005-08-10 10:32 ` [PATCH 2/5] 2.6.13-rc5-mm1, make dmi_string() behave like strdup() Andrey Panin 0 siblings, 1 reply; 9+ messages in thread From: Andrey Panin @ 2005-08-10 10:32 UTC (permalink / raw) To: Andrew Morton, linux-kernel DMI debugging code is unused for ages. This patch removes it. Signed-off-by: Andrey Panin <pazke@donpac.ru> arch/i386/kernel/dmi_scan.c | 21 --------------------- 1 files changed, 21 deletions(-) diff -urdpNX /usr/share/dontdiff linux-2.6.13-rc5-mm1.vanilla/arch/i386/kernel/dmi_scan.c linux-2.6.13-rc5-mm1/arch/i386/kernel/dmi_scan.c --- linux-2.6.13-rc5-mm1.vanilla/arch/i386/kernel/dmi_scan.c 2005-06-14 23:24:54.000000000 +0400 +++ linux-2.6.13-rc5-mm1/arch/i386/kernel/dmi_scan.c 2005-06-14 23:25:07.000000000 +0400 @@ -12,13 +12,6 @@ struct dmi_header { u16 handle; }; -#undef DMI_DEBUG - -#ifdef DMI_DEBUG -#define dmi_printk(x) printk x -#else -#define dmi_printk(x) -#endif static char * __init dmi_string(struct dmi_header *dm, u8 s) { @@ -117,29 +110,19 @@ static void __init dmi_decode(struct dmi switch(dm->type) { case 0: - dmi_printk(("BIOS Vendor: %s\n", dmi_string(dm, data[4]))); dmi_save_ident(dm, DMI_BIOS_VENDOR, 4); - dmi_printk(("BIOS Version: %s\n", dmi_string(dm, data[5]))); dmi_save_ident(dm, DMI_BIOS_VERSION, 5); - dmi_printk(("BIOS Release: %s\n", dmi_string(dm, data[8]))); dmi_save_ident(dm, DMI_BIOS_DATE, 8); break; case 1: - dmi_printk(("System Vendor: %s\n", dmi_string(dm, data[4]))); dmi_save_ident(dm, DMI_SYS_VENDOR, 4); - dmi_printk(("Product Name: %s\n", dmi_string(dm, data[5]))); dmi_save_ident(dm, DMI_PRODUCT_NAME, 5); - dmi_printk(("Version: %s\n", dmi_string(dm, data[6]))); dmi_save_ident(dm, DMI_PRODUCT_VERSION, 6); - dmi_printk(("Serial Number: %s\n", dmi_string(dm, data[7]))); dmi_save_ident(dm, DMI_PRODUCT_SERIAL, 7); break; case 2: - dmi_printk(("Board Vendor: %s\n", dmi_string(dm, data[4]))); dmi_save_ident(dm, DMI_BOARD_VENDOR, 4); - dmi_printk(("Board Name: %s\n", dmi_string(dm, data[5]))); dmi_save_ident(dm, DMI_BOARD_NAME, 5); - dmi_printk(("Board Version: %s\n", dmi_string(dm, data[6]))); dmi_save_ident(dm, DMI_BOARD_VERSION, 6); break; } @@ -177,10 +160,6 @@ void __init dmi_scan_machine(void) else printk(KERN_INFO "DMI present.\n"); - dmi_printk((KERN_INFO "%d structures occupying %d bytes.\n", - num, len)); - dmi_printk((KERN_INFO "DMI table at 0x%08X.\n", base)); - if (dmi_table(base,len, num, dmi_decode) == 0) return; } ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/5] 2.6.13-rc5-mm1, make dmi_string() behave like strdup() 2005-08-10 10:32 ` [PATCH 1/5] 2.6.13-rc5-mm1, remove old debugging code Andrey Panin @ 2005-08-10 10:32 ` Andrey Panin 2005-08-10 10:32 ` [PATCH 3/5] 2.6.13-rc5-mm1, add onboard devices discovery Andrey Panin 0 siblings, 1 reply; 9+ messages in thread From: Andrey Panin @ 2005-08-10 10:32 UTC (permalink / raw) To: Andrew Morton, linux-kernel This patch changes dmi_string() function to allocate string copy by itself, to avoid code duplication in the next patch. Signed-off-by: Andrey Panin <pazke@donpac.ru> arch/i386/kernel/dmi_scan.c | 39 +++++++++++++++++++++++---------------- 1 files changed, 23 insertions(+), 16 deletions(-) diff -urdpNX /usr/share/dontdiff linux-2.6.13-rc5-mm1.vanilla/arch/i386/kernel/dmi_scan.c linux-2.6.13-rc5-mm1/arch/i386/kernel/dmi_scan.c --- linux-2.6.13-rc5-mm1.vanilla/arch/i386/kernel/dmi_scan.c 2005-06-14 23:31:39.000000000 +0400 +++ linux-2.6.13-rc5-mm1/arch/i386/kernel/dmi_scan.c 2005-06-14 23:31:51.000000000 +0400 @@ -16,15 +16,25 @@ struct dmi_header { static char * __init dmi_string(struct dmi_header *dm, u8 s) { u8 *bp = ((u8 *) dm) + dm->length; + char *str = ""; - if (!s) - return ""; - s--; - while (s > 0 && *bp) { - bp += strlen(bp) + 1; + if (s) { s--; - } - return bp; + while (s > 0 && *bp) { + bp += strlen(bp) + 1; + s--; + } + + if (*bp != 0) { + str = alloc_bootmem(strlen(bp) + 1); + if (str != NULL) + strcpy(str, bp); + else + printk(KERN_ERR "dmi_string: out of memory.\n"); + } + } + + return str; } /* @@ -84,19 +94,16 @@ static char *dmi_ident[DMI_STRING_MAX]; */ static void __init dmi_save_ident(struct dmi_header *dm, int slot, int string) { - char *d = (char*)dm; - char *p = dmi_string(dm, d[string]); + char *p, *d = (char*) dm; - if (p == NULL || *p == 0) - return; if (dmi_ident[slot]) return; - dmi_ident[slot] = alloc_bootmem(strlen(p) + 1); - if(dmi_ident[slot]) - strcpy(dmi_ident[slot], p); - else - printk(KERN_ERR "dmi_save_ident: out of memory.\n"); + p = dmi_string(dm, d[string]); + if (p == NULL) + return; + + dmi_ident[slot] = p; } /* ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 3/5] 2.6.13-rc5-mm1, add onboard devices discovery 2005-08-10 10:32 ` [PATCH 2/5] 2.6.13-rc5-mm1, make dmi_string() behave like strdup() Andrey Panin @ 2005-08-10 10:32 ` Andrey Panin 2005-08-10 10:32 ` [PATCH 4/5] 2.6.13-rc5-mm1, IPMI, use dmi_find_device() Andrey Panin 0 siblings, 1 reply; 9+ messages in thread From: Andrey Panin @ 2005-08-10 10:32 UTC (permalink / raw) To: Andrew Morton, linux-kernel, cminyard This patch adds onboard devices and IPMI BMC discovery into DMI scan code. Drivers can use dmi_find_device() function to search for devices by type and name. Signed-off-by: Andrey Panin <pazke@donpac.ru> arch/i386/kernel/dmi_scan.c | 102 ++++++++++++++++++++++++++++++++++++++------ include/linux/dmi.h | 34 +++++++++++++- 2 files changed, 121 insertions(+), 15 deletions(-) diff -urdpNX /usr/share/dontdiff linux-2.6.13-rc5-mm1.vanilla/arch/i386/kernel/dmi_scan.c linux-2.6.13-rc5-mm1/arch/i386/kernel/dmi_scan.c --- linux-2.6.13-rc5-mm1.vanilla/arch/i386/kernel/dmi_scan.c 2005-08-09 14:39:13.000000000 +0400 +++ linux-2.6.13-rc5-mm1/arch/i386/kernel/dmi_scan.c 2005-08-09 15:07:57.000000000 +0400 @@ -6,13 +6,6 @@ #include <linux/bootmem.h> -struct dmi_header { - u8 type; - u8 length; - u16 handle; -}; - - static char * __init dmi_string(struct dmi_header *dm, u8 s) { u8 *bp = ((u8 *) dm) + dm->length; @@ -88,6 +81,7 @@ static int __init dmi_checksum(u8 *buf) } static char *dmi_ident[DMI_STRING_MAX]; +static LIST_HEAD(dmi_devices); /* * Save a DMI string @@ -106,6 +100,58 @@ static void __init dmi_save_ident(struct 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) + (i * 2); + + /* Skip disabled device */ + if ((*d & 0x80) == 0) + continue; + + dev = alloc_bootmem(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 = alloc_bootmem(dm->length); + if (data == NULL) { + printk(KERN_ERR "dmi_save_ipmi_device: out of memory.\n"); + return; + } + + memcpy(data, dm, dm->length); + + dev = alloc_bootmem(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 @@ -113,25 +159,28 @@ static void __init dmi_save_ident(struct */ static void __init dmi_decode(struct dmi_header *dm) { - u8 *data __attribute__((__unused__)) = (u8 *)dm; - switch(dm->type) { - case 0: + 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: + 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: + 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); } } @@ -221,3 +270,32 @@ 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); diff -urdpNX /usr/share/dontdiff linux-2.6.13-rc5-mm1.vanilla/include/linux/dmi.h linux-2.6.13-rc5-mm1/include/linux/dmi.h --- linux-2.6.13-rc5-mm1.vanilla/include/linux/dmi.h 2005-06-12 23:08:16.000000000 +0400 +++ linux-2.6.13-rc5-mm1/include/linux/dmi.h 2005-06-12 22:45:19.000000000 +0400 @@ -16,6 +16,24 @@ enum dmi_field { DMI_STRING_MAX, }; +enum dmi_device_type { + DMI_DEV_TYPE_ANY = 0, + DMI_DEV_TYPE_OTHER, + DMI_DEV_TYPE_UNKNOWN, + DMI_DEV_TYPE_VIDEO, + DMI_DEV_TYPE_SCSI, + DMI_DEV_TYPE_ETHERNET, + DMI_DEV_TYPE_TOKENRING, + DMI_DEV_TYPE_SOUND, + DMI_DEV_TYPE_IPMI = -1 +}; + +struct dmi_header { + u8 type; + u8 length; + u16 handle; +}; + /* * DMI callbacks for problem boards */ @@ -26,22 +44,32 @@ struct dmi_strmatch { struct dmi_system_id { int (*callback)(struct dmi_system_id *); - char *ident; + const char *ident; struct dmi_strmatch matches[4]; void *driver_data; }; -#define DMI_MATCH(a,b) { a, b } +#define DMI_MATCH(a, b) { a, b } + +struct dmi_device { + struct list_head list; + int type; + const char *name; + void *device_data; /* Type specific data */ +}; #if defined(CONFIG_X86) && !defined(CONFIG_X86_64) extern int dmi_check_system(struct dmi_system_id *list); extern char * dmi_get_system_info(int field); - +extern struct dmi_device * dmi_find_device(int type, const char *name, + struct dmi_device *from); #else static inline int dmi_check_system(struct dmi_system_id *list) { return 0; } static inline char * dmi_get_system_info(int field) { return NULL; } +static struct dmi_device * dmi_find_device(int type, const char *name, + struct dmi_device *from) { return NULL; } #endif ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 4/5] 2.6.13-rc5-mm1, IPMI, use dmi_find_device() 2005-08-10 10:32 ` [PATCH 3/5] 2.6.13-rc5-mm1, add onboard devices discovery Andrey Panin @ 2005-08-10 10:32 ` Andrey Panin 2005-08-10 10:32 ` [PATCH 5/5] 2.6.13-rc5-mm1, driver for IBM Automatic Server Restart watchdog Andrey Panin 2005-08-10 14:12 ` [PATCH 4/5] 2.6.13-rc5-mm1, IPMI, use dmi_find_device() Corey Minyard 0 siblings, 2 replies; 9+ messages in thread From: Andrey Panin @ 2005-08-10 10:32 UTC (permalink / raw) To: Andrew Morton, linux-kernel, cminyard This patch replaces homebrew DMI scanning code in IPMI System Interface driver with dmi_find_device() call. Signed-off-by: Andrey Panin <pazke@donpac.ru> drivers/char/ipmi/ipmi_si_intf.c | 105 ++++++--------------------------------- 1 files changed, 17 insertions(+), 88 deletions(-) diff -urdpNX /usr/share/dontdiff linux-2.6.13-rc5-mm1.vanilla/drivers/char/ipmi/ipmi_si_intf.c linux-2.6.13-rc5-mm1/drivers/char/ipmi/ipmi_si_intf.c --- linux-2.6.13-rc5-mm1.vanilla/drivers/char/ipmi/ipmi_si_intf.c 2005-08-08 14:32:07.000000000 +0400 +++ linux-2.6.13-rc5-mm1/drivers/char/ipmi/ipmi_si_intf.c 2005-08-08 11:39:00.000000000 +0400 @@ -75,6 +75,7 @@ static inline void add_usec_to_timer(str #include <asm/io.h> #include "ipmi_si_sm.h" #include <linux/init.h> +#include <linux/dmi.h> /* Measure times between events in the driver. */ #undef DEBUG_TIMING @@ -1642,22 +1643,15 @@ typedef struct dmi_ipmi_data static dmi_ipmi_data_t dmi_data[SI_MAX_DRIVERS]; static int dmi_data_entries; -typedef struct dmi_header -{ - u8 type; - u8 length; - u16 handle; -} dmi_header_t; - -static int decode_dmi(dmi_header_t __iomem *dm, int intf_num) +static int __init decode_dmi(struct dmi_header *dm, int intf_num) { - u8 __iomem *data = (u8 __iomem *)dm; + u8 *data = (u8 *)dm; unsigned long base_addr; u8 reg_spacing; - u8 len = readb(&dm->length); + u8 len = dm->length; dmi_ipmi_data_t *ipmi_data = dmi_data+intf_num; - ipmi_data->type = readb(&data[4]); + ipmi_data->type = data[4]; memcpy(&base_addr, data+8, sizeof(unsigned long)); if (len >= 0x11) { @@ -1672,12 +1666,12 @@ static int decode_dmi(dmi_header_t __iom } /* If bit 4 of byte 0x10 is set, then the lsb for the address is odd. */ - ipmi_data->base_addr = base_addr | ((readb(&data[0x10]) & 0x10) >> 4); + ipmi_data->base_addr = base_addr | ((data[0x10] & 0x10) >> 4); - ipmi_data->irq = readb(&data[0x11]); + ipmi_data->irq = data[0x11]; /* The top two bits of byte 0x10 hold the register spacing. */ - reg_spacing = (readb(&data[0x10]) & 0xC0) >> 6; + reg_spacing = (data[0x10] & 0xC0) >> 6; switch(reg_spacing){ case 0x00: /* Byte boundaries */ ipmi_data->offset = 1; @@ -1705,7 +1699,7 @@ static int decode_dmi(dmi_header_t __iom ipmi_data->offset = 1; } - ipmi_data->slave_addr = readb(&data[6]); + ipmi_data->slave_addr = data[6]; if (is_new_interface(-1, ipmi_data->addr_space,ipmi_data->base_addr)) { dmi_data_entries++; @@ -1717,82 +1711,17 @@ static int decode_dmi(dmi_header_t __iom return -1; } -static int dmi_table(u32 base, int len, int num) -{ - u8 __iomem *buf; - struct dmi_header __iomem *dm; - u8 __iomem *data; - int i=1; - int status=-1; - int intf_num = 0; - - buf = ioremap(base, len); - if(buf==NULL) - return -1; - - data = buf; - - while(i<num && (data - buf) < len) - { - dm=(dmi_header_t __iomem *)data; - - if((data-buf+readb(&dm->length)) >= len) - break; - - if (readb(&dm->type) == 38) { - if (decode_dmi(dm, intf_num) == 0) { - intf_num++; - if (intf_num >= SI_MAX_DRIVERS) - break; - } - } - - data+=readb(&dm->length); - while((data-buf) < len && (readb(data)||readb(data+1))) - data++; - data+=2; - i++; - } - iounmap(buf); - - return status; -} - -static inline int dmi_checksum(u8 *buf) -{ - u8 sum=0; - int a; - - for(a=0; a<15; a++) - sum+=buf[a]; - return (sum==0); -} - -static int dmi_decode(void) +static void __init dmi_find_bmc(void) { - u8 buf[15]; - u32 fp=0xF0000; - -#ifdef CONFIG_SIMNOW - return -1; -#endif + struct dmi_device *dev = NULL; + int intf_num = 0; - while(fp < 0xFFFFF) - { - isa_memcpy_fromio(buf, fp, 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]; + while ((dev = dmi_find_device(DMI_DEV_TYPE_IPMI, NULL, dev))) { + if (intf_num >= SI_MAX_DRIVERS) + break; - if(dmi_table(base, len, num) == 0) - return 0; - } - fp+=16; + decode_dmi((struct dmi_header *) dev->device_data, intf_num++); } - - return -1; } static int try_init_smbios(int intf_num, struct smi_info **new_info) @@ -2382,7 +2311,7 @@ static __init int init_ipmi_si(void) printk(KERN_INFO "IPMI System Interface driver.\n"); #ifdef CONFIG_X86 - dmi_decode(); + dmi_find_bmc(); #endif rv = init_one_smi(0, &(smi_infos[pos])); ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 5/5] 2.6.13-rc5-mm1, driver for IBM Automatic Server Restart watchdog 2005-08-10 10:32 ` [PATCH 4/5] 2.6.13-rc5-mm1, IPMI, use dmi_find_device() Andrey Panin @ 2005-08-10 10:32 ` Andrey Panin 2005-08-17 20:14 ` Andrew Morton 2005-08-10 14:12 ` [PATCH 4/5] 2.6.13-rc5-mm1, IPMI, use dmi_find_device() Corey Minyard 1 sibling, 1 reply; 9+ messages in thread From: Andrey Panin @ 2005-08-10 10:32 UTC (permalink / raw) To: Andrew Morton, linux-kernel This patch adds driver for IBM Automatic Server Restart watchdog hardware found in some IBM eServer xSeries machines. This driver is based on the ugly driver provided by IBM. Driver was tested on IBM eServer 226. Signed-off-by: Andrey Panin <pazke@donpac.ru> drivers/char/watchdog/Kconfig | 10 + drivers/char/watchdog/Makefile | 1 drivers/char/watchdog/ibmasr.c | 407 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 418 insertions(+) diff -urdpN linux-2.6.13-rc5-mm1.vanilla/drivers/char/watchdog/ibmasr.c linux-2.6.13-rc5-mm1/drivers/char/watchdog/ibmasr.c --- linux-2.6.13-rc5-mm1.vanilla/drivers/char/watchdog/ibmasr.c 1970-01-01 03:00:00.000000000 +0300 +++ linux-2.6.13-rc5-mm1/drivers/char/watchdog/ibmasr.c 2005-08-10 11:43:45.000000000 +0400 @@ -0,0 +1,407 @@ +/* + * IBM Automatic Server Restart driver. + * + * Copyright (c) 2005 Andrey Panin <pazke@donpac.ru> + * + * Based on driver written by Pete Reynolds. + * Copyright (c) IBM Corporation, 1998-2004. + * + * This software may be used and distributed according to the terms + * of the GNU Public License, incorporated herein by reference. + */ + +#include <linux/config.h> +#include <linux/fs.h> +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/timer.h> +#include <linux/miscdevice.h> +#include <linux/watchdog.h> +#include <linux/dmi.h> + +#include <asm/io.h> +#include <asm/uaccess.h> + + +enum { + ASMTYPE_UNKNOWN, + ASMTYPE_TOPAZ, + ASMTYPE_JASPER, + ASMTYPE_PEARL, + ASMTYPE_JUNIPER, + ASMTYPE_SPRUCE, +}; + +#define PFX "ibmasr: " + +#define TOPAZ_ASR_REG_OFFSET 4 +#define TOPAZ_ASR_TOGGLE 0x40 +#define TOPAZ_ASR_DISABLE 0x80 + +/* PEARL ASR S/W REGISTER SUPERIO PORT ADDRESSES */ +#define PEARL_BASE 0xe04 +#define PEARL_WRITE 0xe06 +#define PEARL_READ 0xe07 + +#define PEARL_ASR_DISABLE_MASK 0x80 /* bit 7: disable = 1, enable = 0 */ +#define PEARL_ASR_TOGGLE_MASK 0x40 /* bit 6: 0, then 1, then 0 */ + +/* JASPER OFFSET FROM SIO BASE ADDR TO ASR S/W REGISTERS. */ +#define JASPER_ASR_REG_OFFSET 0x38 + +#define JASPER_ASR_DISABLE_MASK 0x01 /* bit 0: disable = 1, enable = 0 */ +#define JASPER_ASR_TOGGLE_MASK 0x02 /* bit 1: 0, then 1, then 0 */ + +#define JUNIPER_BASE_ADDRESS 0x54b /* Base address of Juniper ASR */ +#define JUNIPER_ASR_DISABLE_MASK 0x01 /* bit 0: disable = 1 enable = 0 */ +#define JUNIPER_ASR_TOGGLE_MASK 0x02 /* bit 1: 0, then 1, then 0 */ + +#define SPRUCE_BASE_ADDRESS 0x118e /* Base address of Spruce ASR */ +#define SPRUCE_ASR_DISABLE_MASK 0x01 /* bit 1: disable = 1 enable = 0 */ +#define SPRUCE_ASR_TOGGLE_MASK 0x02 /* bit 0: 0, then 1, then 0 */ + + +static int nowayout = WATCHDOG_NOWAYOUT; + +static unsigned long asr_is_open; +static char asr_expect_close; + +static unsigned int asr_type, asr_base, asr_length; +static unsigned int asr_read_addr, asr_write_addr; +static unsigned char asr_toggle_mask, asr_disable_mask; + +static void asr_toggle(void) +{ + unsigned char reg = inb(asr_read_addr); + + outb(reg & ~asr_toggle_mask, asr_write_addr); + reg = inb(asr_read_addr); + + outb(reg | asr_toggle_mask, asr_write_addr); + reg = inb(asr_read_addr); + + outb(reg & ~asr_toggle_mask, asr_write_addr); + reg = inb(asr_read_addr); +} + +static void asr_enable(void) +{ + unsigned char reg; + + if (asr_type == ASMTYPE_TOPAZ) { + /* asr_write_addr == asr_read_addr */ + reg = inb(asr_read_addr); + outb(reg & ~(TOPAZ_ASR_TOGGLE | TOPAZ_ASR_DISABLE), + asr_read_addr); + } else { + /* + * First make sure the hardware timer is reset by toggling + * ASR hardware timer line. + */ + asr_toggle(); + + reg = inb(asr_read_addr); + outb(reg & ~asr_disable_mask, asr_write_addr); + } + reg = inb(asr_read_addr); +} + +static void asr_disable(void) +{ + unsigned char reg = inb(asr_read_addr); + + if (asr_type == ASMTYPE_TOPAZ) + /* asr_write_addr == asr_read_addr */ + outb(reg | TOPAZ_ASR_TOGGLE | TOPAZ_ASR_DISABLE, + asr_read_addr); + else { + outb(reg | asr_toggle_mask, asr_write_addr); + reg = inb(asr_read_addr); + + outb(reg | asr_disable_mask, asr_write_addr); + } + reg = inb(asr_read_addr); +} + +static int __init asr_get_base_address(void) +{ + unsigned char low, high; + const char *type = ""; + + asr_length = 1; + + switch (asr_type) { + case ASMTYPE_TOPAZ: + /* SELECT SuperIO CHIP FOR QUERYING (WRITE 0x07 TO BOTH 0x2E and 0x2F) */ + outb(0x07, 0x2e); + outb(0x07, 0x2f); + + /* SELECT AND READ THE HIGH-NIBBLE OF THE GPIO BASE ADDRESS */ + outb(0x60, 0x2e); + high = inb(0x2f); + + /* SELECT AND READ THE LOW-NIBBLE OF THE GPIO BASE ADDRESS */ + outb(0x61, 0x2e); + low = inb(0x2f); + + asr_base = (high << 16) | low; + asr_read_addr = asr_write_addr = + asr_base + TOPAZ_ASR_REG_OFFSET; + asr_length = 5; + + break; + + case ASMTYPE_JASPER: + type = "Jaspers "; + + /* FIXME: need to use pci_config_lock here, but it's not exported */ + +/* spin_lock_irqsave(&pci_config_lock, flags);*/ + + /* Select the SuperIO chip in the PCI I/O port register */ + outl(0x8000f858, 0xcf8); + + /* + * Read the base address for the SuperIO chip. + * Only the lower 16 bits are valid, but the address is word + * aligned so the last bit must be masked off. + */ + asr_base = inl(0xcfc) & 0xfffe; + +/* spin_unlock_irqrestore(&pci_config_lock, flags);*/ + + asr_read_addr = asr_write_addr = + asr_base + JASPER_ASR_REG_OFFSET; + asr_toggle_mask = JASPER_ASR_TOGGLE_MASK; + asr_disable_mask = JASPER_ASR_DISABLE_MASK; + asr_length = JASPER_ASR_REG_OFFSET + 1; + + break; + + case ASMTYPE_PEARL: + type = "Pearls "; + asr_base = PEARL_BASE; + asr_read_addr = PEARL_READ; + asr_write_addr = PEARL_WRITE; + asr_toggle_mask = PEARL_ASR_TOGGLE_MASK; + asr_disable_mask = PEARL_ASR_DISABLE_MASK; + asr_length = 4; + break; + + case ASMTYPE_JUNIPER: + type = "Junipers "; + asr_base = JUNIPER_BASE_ADDRESS; + asr_read_addr = asr_write_addr = asr_base; + asr_toggle_mask = JUNIPER_ASR_TOGGLE_MASK; + asr_disable_mask = JUNIPER_ASR_DISABLE_MASK; + break; + + case ASMTYPE_SPRUCE: + type = "Spruce's "; + asr_base = SPRUCE_BASE_ADDRESS; + asr_read_addr = asr_write_addr = asr_base; + asr_toggle_mask = SPRUCE_ASR_TOGGLE_MASK; + asr_disable_mask = SPRUCE_ASR_DISABLE_MASK; + break; + } + + if (!request_region(asr_base, asr_length, "ibmasr")) { + printk(KERN_ERR PFX "address %#x already in use\n", + asr_base); + return -EBUSY; + } + + printk(KERN_INFO PFX "found %sASR @ addr %#x\n", type, asr_base); + + return 0; +} + + +static ssize_t asr_write(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + if (count) { + if (!nowayout) { + size_t i; + + /* In case it was set long ago */ + asr_expect_close = 0; + + for (i = 0; i != count; i++) { + char c; + if (get_user(c, buf + i)) + return -EFAULT; + if (c == 'V') + asr_expect_close = 42; + } + } + asr_toggle(); + } + return count; +} + +static int asr_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + static const struct watchdog_info ident = { + .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | + WDIOF_MAGICCLOSE, + .identity = "IBM ASR" + }; + void __user *argp = (void __user *)arg; + int __user *p = argp; + int heartbeat; + + switch (cmd) { + case WDIOC_GETSUPPORT: + return copy_to_user(argp, &ident, sizeof(ident)) ? + -EFAULT : 0; + + case WDIOC_GETSTATUS: + case WDIOC_GETBOOTSTATUS: + return put_user(0, p); + + case WDIOC_KEEPALIVE: + asr_toggle(); + return 0; + + + case WDIOC_SETTIMEOUT: + if (get_user(heartbeat, p)) + return -EFAULT; + /* Fall */ + + case WDIOC_GETTIMEOUT: + heartbeat = 256; + return put_user(heartbeat, p); + + case WDIOC_SETOPTIONS: { + int new_options, retval = -EINVAL; + + if (get_user(new_options, p)) + return -EFAULT; + + if (new_options & WDIOS_DISABLECARD) { + asr_disable(); + retval = 0; + } + + if (new_options & WDIOS_ENABLECARD) { + asr_enable(); + asr_toggle(); + retval = 0; + } + + return retval; + } + } + + return -ENOIOCTLCMD; +} + +static int asr_open(struct inode *inode, struct file *file) +{ + if(test_and_set_bit(0, &asr_is_open)) + return -EBUSY; + + asr_toggle(); + asr_enable(); + + return nonseekable_open(inode, file); +} + +static int asr_release(struct inode *inode, struct file *file) +{ + if (asr_expect_close == 42) + asr_disable(); + else { + printk(KERN_CRIT PFX "unexpected close, not stopping watchdog!\n"); + asr_toggle(); + } + clear_bit(0, &asr_is_open); + asr_expect_close = 0; + return 0; +} + +static struct file_operations asr_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .write = asr_write, + .ioctl = asr_ioctl, + .open = asr_open, + .release = asr_release, +}; + +static struct miscdevice asr_miscdev = { + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &asr_fops, +}; + + +struct ibmasr_id { + const char *desc; + int type; +}; + +static struct ibmasr_id __initdata ibmasr_id_table[] = { + { "IBM Automatic Server Restart - eserver xSeries 220", ASMTYPE_TOPAZ }, + { "IBM Automatic Server Restart - Machine Type 8673", ASMTYPE_PEARL }, + { "IBM Automatic Server Restart - Machine Type 8480", ASMTYPE_JASPER }, + { "IBM Automatic Server Restart - Machine Type 8482", ASMTYPE_JUNIPER }, + { "IBM Automatic Server Restart - Machine Type 8648", ASMTYPE_SPRUCE }, + { NULL } +}; + +static int __init ibmasr_init(void) +{ + struct ibmasr_id *id; + int rc; + + for (id = ibmasr_id_table; id->desc; id++) { + if (dmi_find_device(DMI_DEV_TYPE_OTHER, id->desc, NULL)) { + asr_type = id->type; + break; + } + } + + if (!asr_type) + return -ENODEV; + + rc = misc_register(&asr_miscdev); + if (rc < 0) { + printk(KERN_ERR PFX "failed to register misc device\n"); + return rc; + } + + rc = asr_get_base_address(); + if (rc) { + misc_deregister(&asr_miscdev); + return rc; + } + + return 0; +} + +static void __exit ibmasr_exit(void) +{ + if (!nowayout) + asr_disable(); + + misc_deregister(&asr_miscdev); + + release_region(asr_base, asr_length); +} + +module_init(ibmasr_init); +module_exit(ibmasr_exit); + +module_param(nowayout, int, 0); +MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); + +MODULE_DESCRIPTION("IBM Automatic Server Restart driver"); +MODULE_AUTHOR("Andrey Panin"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); diff -urdpN linux-2.6.13-rc5-mm1.vanilla/drivers/char/watchdog/Kconfig linux-2.6.13-rc5-mm1/drivers/char/watchdog/Kconfig --- linux-2.6.13-rc5-mm1.vanilla/drivers/char/watchdog/Kconfig 2005-08-09 11:03:44.000000000 +0400 +++ linux-2.6.13-rc5-mm1/drivers/char/watchdog/Kconfig 2005-08-08 13:55:10.000000000 +0400 @@ -548,6 +548,16 @@ config WDT_501_PCI can do this via the tachometer parameter. Only do this if you have a fan tachometer actually set up. +config IBMASR + tristate "IBM Automatic Server Restart" + depends on WATCHDOG && X86 + help + This is the driver for the IBM Automatic Server Restart watchdog + timer builtin into some eServer xSeries machines. + + To compile this driver as a module, choose M here: the + module will be called ibmasr. + # # USB-based Watchdog Cards # diff -urdpN linux-2.6.13-rc5-mm1.vanilla/drivers/char/watchdog/Makefile linux-2.6.13-rc5-mm1/drivers/char/watchdog/Makefile --- linux-2.6.13-rc5-mm1.vanilla/drivers/char/watchdog/Makefile 2005-08-09 11:03:44.000000000 +0400 +++ linux-2.6.13-rc5-mm1/drivers/char/watchdog/Makefile 2005-08-08 13:55:10.000000000 +0400 @@ -48,6 +48,7 @@ obj-$(CONFIG_CPU5_WDT) += cpu5wdt.o obj-$(CONFIG_W83627HF_WDT) += w83627hf_wdt.o obj-$(CONFIG_W83877F_WDT) += w83877f_wdt.o obj-$(CONFIG_MACHZ_WDT) += machzwd.o +obj-$(CONFIG_IBMASR) += ibmasr.o # PowerPC Architecture obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 5/5] 2.6.13-rc5-mm1, driver for IBM Automatic Server Restart watchdog 2005-08-10 10:32 ` [PATCH 5/5] 2.6.13-rc5-mm1, driver for IBM Automatic Server Restart watchdog Andrey Panin @ 2005-08-17 20:14 ` Andrew Morton 2005-08-18 4:49 ` Andrey Panin 0 siblings, 1 reply; 9+ messages in thread From: Andrew Morton @ 2005-08-17 20:14 UTC (permalink / raw) To: Andrey Panin; +Cc: linux-kernel, Greg KH Andrey Panin <pazke@donpac.ru> wrote: > > > This patch adds driver for IBM Automatic Server Restart watchdog hardware > found in some IBM eServer xSeries machines. This driver is based on the ugly > driver provided by IBM. Driver was tested on IBM eServer 226. > > ... > + > + case ASMTYPE_JASPER: > + type = "Jaspers "; > + > + /* FIXME: need to use pci_config_lock here, but it's not exported */ That's gregkh material. > + > +/* spin_lock_irqsave(&pci_config_lock, flags);*/ > + > + /* Select the SuperIO chip in the PCI I/O port register */ > + outl(0x8000f858, 0xcf8); > + > + /* > + * Read the base address for the SuperIO chip. > + * Only the lower 16 bits are valid, but the address is word > + * aligned so the last bit must be masked off. > + */ > + asr_base = inl(0xcfc) & 0xfffe; > + > +/* spin_unlock_irqrestore(&pci_config_lock, flags);*/ > > ... > > +static int asr_ioctl(struct inode *inode, struct file *file, > + unsigned int cmd, unsigned long arg) > +{ > + static const struct watchdog_info ident = { > + .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | > + WDIOF_MAGICCLOSE, > + .identity = "IBM ASR" > + }; > + void __user *argp = (void __user *)arg; > + int __user *p = argp; > + int heartbeat; > + > + switch (cmd) { > + case WDIOC_GETSUPPORT: > + return copy_to_user(argp, &ident, sizeof(ident)) ? > + -EFAULT : 0; > + > + case WDIOC_GETSTATUS: > + case WDIOC_GETBOOTSTATUS: > + return put_user(0, p); > + > + case WDIOC_KEEPALIVE: > + asr_toggle(); > + return 0; > + > + > + case WDIOC_SETTIMEOUT: > + if (get_user(heartbeat, p)) > + return -EFAULT; > + /* Fall */ > + > + case WDIOC_GETTIMEOUT: > + heartbeat = 256; > + return put_user(heartbeat, p); Something very wrong is happening with WDIOC_SETTIMEOUT and WDIOC_GETTIMEOUT. They're both no-ops and the effect of WDIOC_SETTIMEOUT is immidiately overwritten. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 5/5] 2.6.13-rc5-mm1, driver for IBM Automatic Server Restart watchdog 2005-08-17 20:14 ` Andrew Morton @ 2005-08-18 4:49 ` Andrey Panin 0 siblings, 0 replies; 9+ messages in thread From: Andrey Panin @ 2005-08-18 4:49 UTC (permalink / raw) To: Andrew Morton; +Cc: linux-kernel [-- Attachment #1: Type: text/plain, Size: 2394 bytes --] On 229, 08 17, 2005 at 01:14:15PM -0700, Andrew Morton wrote: > Andrey Panin <pazke@donpac.ru> wrote: > > > > > > This patch adds driver for IBM Automatic Server Restart watchdog hardware > > found in some IBM eServer xSeries machines. This driver is based on the ugly > > driver provided by IBM. Driver was tested on IBM eServer 226. > > > > ... > > + > > + case ASMTYPE_JASPER: > > + type = "Jaspers "; > > + > > + /* FIXME: need to use pci_config_lock here, but it's not exported */ > > That's gregkh material. > > > + > > +/* spin_lock_irqsave(&pci_config_lock, flags);*/ > > + > > + /* Select the SuperIO chip in the PCI I/O port register */ > > + outl(0x8000f858, 0xcf8); > > + > > + /* > > + * Read the base address for the SuperIO chip. > > + * Only the lower 16 bits are valid, but the address is word > > + * aligned so the last bit must be masked off. > > + */ > > + asr_base = inl(0xcfc) & 0xfffe; > > + > > +/* spin_unlock_irqrestore(&pci_config_lock, flags);*/ > > > > ... > > > > +static int asr_ioctl(struct inode *inode, struct file *file, > > + unsigned int cmd, unsigned long arg) > > +{ > > + static const struct watchdog_info ident = { > > + .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | > > + WDIOF_MAGICCLOSE, > > + .identity = "IBM ASR" > > + }; > > + void __user *argp = (void __user *)arg; > > + int __user *p = argp; > > + int heartbeat; > > + > > + switch (cmd) { > > + case WDIOC_GETSUPPORT: > > + return copy_to_user(argp, &ident, sizeof(ident)) ? > > + -EFAULT : 0; > > + > > + case WDIOC_GETSTATUS: > > + case WDIOC_GETBOOTSTATUS: > > + return put_user(0, p); > > + > > + case WDIOC_KEEPALIVE: > > + asr_toggle(); > > + return 0; > > + > > + > > + case WDIOC_SETTIMEOUT: > > + if (get_user(heartbeat, p)) > > + return -EFAULT; > > + /* Fall */ > > + > > + case WDIOC_GETTIMEOUT: > > + heartbeat = 256; > > + return put_user(heartbeat, p); > > Something very wrong is happening with WDIOC_SETTIMEOUT and > WDIOC_GETTIMEOUT. They're both no-ops and the effect of WDIOC_SETTIMEOUT > is immidiately overwritten. Hardware has fixed timeout value, so WDIOC_SETTIMEOUT is noop and WDIOC_GETTIMEOUT always returns 256. -- Andrey Panin | Linux and UNIX system administrator pazke@donpac.ru | PGP key: wwwkeys.pgp.net [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 189 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 4/5] 2.6.13-rc5-mm1, IPMI, use dmi_find_device() 2005-08-10 10:32 ` [PATCH 4/5] 2.6.13-rc5-mm1, IPMI, use dmi_find_device() Andrey Panin 2005-08-10 10:32 ` [PATCH 5/5] 2.6.13-rc5-mm1, driver for IBM Automatic Server Restart watchdog Andrey Panin @ 2005-08-10 14:12 ` Corey Minyard 1 sibling, 0 replies; 9+ messages in thread From: Corey Minyard @ 2005-08-10 14:12 UTC (permalink / raw) To: Andrey Panin; +Cc: Andrew Morton, linux-kernel Andrew, this patch (along with the patch 3/5) works fine for me and is an obvious improvement to the IPMI driver. You will need to remove the patch named dmi_table-counting-in-ipmi_si_intfc.patch first. Thanks, Andrey. -Corey On Wed, 2005-08-10 at 14:32 +0400, Andrey Panin wrote: > This patch replaces homebrew DMI scanning code in IPMI System Interface driver > with dmi_find_device() call. > > Signed-off-by: Andrey Panin <pazke@donpac.ru> > > drivers/char/ipmi/ipmi_si_intf.c | 105 ++++++--------------------------------- > 1 files changed, 17 insertions(+), 88 deletions(-) > > diff -urdpNX /usr/share/dontdiff linux-2.6.13-rc5-mm1.vanilla/drivers/char/ipmi/ipmi_si_intf.c linux-2.6.13-rc5-mm1/drivers/char/ipmi/ipmi_si_intf.c > --- linux-2.6.13-rc5-mm1.vanilla/drivers/char/ipmi/ipmi_si_intf.c 2005-08-08 14:32:07.000000000 +0400 > +++ linux-2.6.13-rc5-mm1/drivers/char/ipmi/ipmi_si_intf.c 2005-08-08 11:39:00.000000000 +0400 > @@ -75,6 +75,7 @@ static inline void add_usec_to_timer(str > #include <asm/io.h> > #include "ipmi_si_sm.h" > #include <linux/init.h> > +#include <linux/dmi.h> > > /* Measure times between events in the driver. */ > #undef DEBUG_TIMING > @@ -1642,22 +1643,15 @@ typedef struct dmi_ipmi_data > static dmi_ipmi_data_t dmi_data[SI_MAX_DRIVERS]; > static int dmi_data_entries; > > -typedef struct dmi_header > -{ > - u8 type; > - u8 length; > - u16 handle; > -} dmi_header_t; > - > -static int decode_dmi(dmi_header_t __iomem *dm, int intf_num) > +static int __init decode_dmi(struct dmi_header *dm, int intf_num) > { > - u8 __iomem *data = (u8 __iomem *)dm; > + u8 *data = (u8 *)dm; > unsigned long base_addr; > u8 reg_spacing; > - u8 len = readb(&dm->length); > + u8 len = dm->length; > dmi_ipmi_data_t *ipmi_data = dmi_data+intf_num; > > - ipmi_data->type = readb(&data[4]); > + ipmi_data->type = data[4]; > > memcpy(&base_addr, data+8, sizeof(unsigned long)); > if (len >= 0x11) { > @@ -1672,12 +1666,12 @@ static int decode_dmi(dmi_header_t __iom > } > /* If bit 4 of byte 0x10 is set, then the lsb for the address > is odd. */ > - ipmi_data->base_addr = base_addr | ((readb(&data[0x10]) & 0x10) >> 4); > + ipmi_data->base_addr = base_addr | ((data[0x10] & 0x10) >> 4); > > - ipmi_data->irq = readb(&data[0x11]); > + ipmi_data->irq = data[0x11]; > > /* The top two bits of byte 0x10 hold the register spacing. */ > - reg_spacing = (readb(&data[0x10]) & 0xC0) >> 6; > + reg_spacing = (data[0x10] & 0xC0) >> 6; > switch(reg_spacing){ > case 0x00: /* Byte boundaries */ > ipmi_data->offset = 1; > @@ -1705,7 +1699,7 @@ static int decode_dmi(dmi_header_t __iom > ipmi_data->offset = 1; > } > > - ipmi_data->slave_addr = readb(&data[6]); > + ipmi_data->slave_addr = data[6]; > > if (is_new_interface(-1, ipmi_data->addr_space,ipmi_data->base_addr)) { > dmi_data_entries++; > @@ -1717,82 +1711,17 @@ static int decode_dmi(dmi_header_t __iom > return -1; > } > > -static int dmi_table(u32 base, int len, int num) > -{ > - u8 __iomem *buf; > - struct dmi_header __iomem *dm; > - u8 __iomem *data; > - int i=1; > - int status=-1; > - int intf_num = 0; > - > - buf = ioremap(base, len); > - if(buf==NULL) > - return -1; > - > - data = buf; > - > - while(i<num && (data - buf) < len) > - { > - dm=(dmi_header_t __iomem *)data; > - > - if((data-buf+readb(&dm->length)) >= len) > - break; > - > - if (readb(&dm->type) == 38) { > - if (decode_dmi(dm, intf_num) == 0) { > - intf_num++; > - if (intf_num >= SI_MAX_DRIVERS) > - break; > - } > - } > - > - data+=readb(&dm->length); > - while((data-buf) < len && (readb(data)||readb(data+1))) > - data++; > - data+=2; > - i++; > - } > - iounmap(buf); > - > - return status; > -} > - > -static inline int dmi_checksum(u8 *buf) > -{ > - u8 sum=0; > - int a; > - > - for(a=0; a<15; a++) > - sum+=buf[a]; > - return (sum==0); > -} > - > -static int dmi_decode(void) > +static void __init dmi_find_bmc(void) > { > - u8 buf[15]; > - u32 fp=0xF0000; > - > -#ifdef CONFIG_SIMNOW > - return -1; > -#endif > + struct dmi_device *dev = NULL; > + int intf_num = 0; > > - while(fp < 0xFFFFF) > - { > - isa_memcpy_fromio(buf, fp, 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]; > + while ((dev = dmi_find_device(DMI_DEV_TYPE_IPMI, NULL, dev))) { > + if (intf_num >= SI_MAX_DRIVERS) > + break; > > - if(dmi_table(base, len, num) == 0) > - return 0; > - } > - fp+=16; > + decode_dmi((struct dmi_header *) dev->device_data, intf_num++); > } > - > - return -1; > } > > static int try_init_smbios(int intf_num, struct smi_info **new_info) > @@ -2382,7 +2311,7 @@ static __init int init_ipmi_si(void) > printk(KERN_INFO "IPMI System Interface driver.\n"); > > #ifdef CONFIG_X86 > - dmi_decode(); > + dmi_find_bmc(); > #endif > > rv = init_one_smi(0, &(smi_infos[pos])); > ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2005-08-18 4:49 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2005-08-10 10:32 [PATCH 0/5] 2.6.13-rc5-mm1, remove uneeded function Andrey Panin 2005-08-10 10:32 ` [PATCH 1/5] 2.6.13-rc5-mm1, remove old debugging code Andrey Panin 2005-08-10 10:32 ` [PATCH 2/5] 2.6.13-rc5-mm1, make dmi_string() behave like strdup() Andrey Panin 2005-08-10 10:32 ` [PATCH 3/5] 2.6.13-rc5-mm1, add onboard devices discovery Andrey Panin 2005-08-10 10:32 ` [PATCH 4/5] 2.6.13-rc5-mm1, IPMI, use dmi_find_device() Andrey Panin 2005-08-10 10:32 ` [PATCH 5/5] 2.6.13-rc5-mm1, driver for IBM Automatic Server Restart watchdog Andrey Panin 2005-08-17 20:14 ` Andrew Morton 2005-08-18 4:49 ` Andrey Panin 2005-08-10 14:12 ` [PATCH 4/5] 2.6.13-rc5-mm1, IPMI, use dmi_find_device() Corey Minyard
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox