diff options
| author | Andrey Panin <pazke@donpac.ru> | 2005-09-06 18:18:37 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-07 19:57:47 -0400 |
| commit | b224cd3a0ca376dd52f382905c1aaf5a83a54692 (patch) | |
| tree | 832d6198d8c54c424c5222da5ae3ff453d691a57 /drivers/char | |
| parent | 8db08ea7e6527eff82d8e45507468003e3cefba3 (diff) | |
[PATCH] IPMI: use dmi_find_device()
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>
Cc: Corey Minyard <minyard@acm.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/char')
| -rw-r--r-- | drivers/char/ipmi/ipmi_si_intf.c | 105 |
1 files changed, 17 insertions, 88 deletions
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index a44b97304e95..51ce508b2f51 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
| @@ -75,6 +75,7 @@ static inline void add_usec_to_timer(struct timer_list *t, long v) | |||
| 75 | #include <asm/io.h> | 75 | #include <asm/io.h> |
| 76 | #include "ipmi_si_sm.h" | 76 | #include "ipmi_si_sm.h" |
| 77 | #include <linux/init.h> | 77 | #include <linux/init.h> |
| 78 | #include <linux/dmi.h> | ||
| 78 | 79 | ||
| 79 | #define IPMI_SI_VERSION "v33" | 80 | #define IPMI_SI_VERSION "v33" |
| 80 | 81 | ||
| @@ -1610,22 +1611,15 @@ typedef struct dmi_ipmi_data | |||
| 1610 | static dmi_ipmi_data_t dmi_data[SI_MAX_DRIVERS]; | 1611 | static dmi_ipmi_data_t dmi_data[SI_MAX_DRIVERS]; |
| 1611 | static int dmi_data_entries; | 1612 | static int dmi_data_entries; |
| 1612 | 1613 | ||
| 1613 | typedef struct dmi_header | 1614 | static int __init decode_dmi(struct dmi_header *dm, int intf_num) |
| 1614 | { | 1615 | { |
| 1615 | u8 type; | 1616 | u8 *data = (u8 *)dm; |
| 1616 | u8 length; | ||
| 1617 | u16 handle; | ||
| 1618 | } dmi_header_t; | ||
| 1619 | |||
| 1620 | static int decode_dmi(dmi_header_t __iomem *dm, int intf_num) | ||
| 1621 | { | ||
| 1622 | u8 __iomem *data = (u8 __iomem *)dm; | ||
| 1623 | unsigned long base_addr; | 1617 | unsigned long base_addr; |
| 1624 | u8 reg_spacing; | 1618 | u8 reg_spacing; |
| 1625 | u8 len = readb(&dm->length); | 1619 | u8 len = dm->length; |
| 1626 | dmi_ipmi_data_t *ipmi_data = dmi_data+intf_num; | 1620 | dmi_ipmi_data_t *ipmi_data = dmi_data+intf_num; |
| 1627 | 1621 | ||
| 1628 | ipmi_data->type = readb(&data[4]); | 1622 | ipmi_data->type = data[4]; |
| 1629 | 1623 | ||
| 1630 | memcpy(&base_addr, data+8, sizeof(unsigned long)); | 1624 | memcpy(&base_addr, data+8, sizeof(unsigned long)); |
| 1631 | if (len >= 0x11) { | 1625 | if (len >= 0x11) { |
| @@ -1640,12 +1634,12 @@ static int decode_dmi(dmi_header_t __iomem *dm, int intf_num) | |||
| 1640 | } | 1634 | } |
| 1641 | /* If bit 4 of byte 0x10 is set, then the lsb for the address | 1635 | /* If bit 4 of byte 0x10 is set, then the lsb for the address |
| 1642 | is odd. */ | 1636 | is odd. */ |
| 1643 | ipmi_data->base_addr = base_addr | ((readb(&data[0x10]) & 0x10) >> 4); | 1637 | ipmi_data->base_addr = base_addr | ((data[0x10] & 0x10) >> 4); |
| 1644 | 1638 | ||
| 1645 | ipmi_data->irq = readb(&data[0x11]); | 1639 | ipmi_data->irq = data[0x11]; |
| 1646 | 1640 | ||
| 1647 | /* The top two bits of byte 0x10 hold the register spacing. */ | 1641 | /* The top two bits of byte 0x10 hold the register spacing. */ |
| 1648 | reg_spacing = (readb(&data[0x10]) & 0xC0) >> 6; | 1642 | reg_spacing = (data[0x10] & 0xC0) >> 6; |
| 1649 | switch(reg_spacing){ | 1643 | switch(reg_spacing){ |
| 1650 | case 0x00: /* Byte boundaries */ | 1644 | case 0x00: /* Byte boundaries */ |
| 1651 | ipmi_data->offset = 1; | 1645 | ipmi_data->offset = 1; |
| @@ -1673,7 +1667,7 @@ static int decode_dmi(dmi_header_t __iomem *dm, int intf_num) | |||
| 1673 | ipmi_data->offset = 1; | 1667 | ipmi_data->offset = 1; |
| 1674 | } | 1668 | } |
| 1675 | 1669 | ||
| 1676 | ipmi_data->slave_addr = readb(&data[6]); | 1670 | ipmi_data->slave_addr = data[6]; |
| 1677 | 1671 | ||
| 1678 | if (is_new_interface(-1, ipmi_data->addr_space,ipmi_data->base_addr)) { | 1672 | if (is_new_interface(-1, ipmi_data->addr_space,ipmi_data->base_addr)) { |
| 1679 | dmi_data_entries++; | 1673 | dmi_data_entries++; |
| @@ -1685,82 +1679,17 @@ static int decode_dmi(dmi_header_t __iomem *dm, int intf_num) | |||
| 1685 | return -1; | 1679 | return -1; |
| 1686 | } | 1680 | } |
| 1687 | 1681 | ||
| 1688 | static int dmi_table(u32 base, int len, int num) | 1682 | static void __init dmi_find_bmc(void) |
| 1689 | { | ||
| 1690 | u8 __iomem *buf; | ||
| 1691 | struct dmi_header __iomem *dm; | ||
| 1692 | u8 __iomem *data; | ||
| 1693 | int i=1; | ||
| 1694 | int status=-1; | ||
| 1695 | int intf_num = 0; | ||
| 1696 | |||
| 1697 | buf = ioremap(base, len); | ||
| 1698 | if(buf==NULL) | ||
| 1699 | return -1; | ||
| 1700 | |||
| 1701 | data = buf; | ||
| 1702 | |||
| 1703 | while(i<num && (data - buf) < len) | ||
| 1704 | { | ||
| 1705 | dm=(dmi_header_t __iomem *)data; | ||
| 1706 | |||
| 1707 | if((data-buf+readb(&dm->length)) >= len) | ||
| 1708 | break; | ||
| 1709 | |||
| 1710 | if (readb(&dm->type) == 38) { | ||
| 1711 | if (decode_dmi(dm, intf_num) == 0) { | ||
| 1712 | intf_num++; | ||
| 1713 | if (intf_num >= SI_MAX_DRIVERS) | ||
| 1714 | break; | ||
| 1715 | } | ||
| 1716 | } | ||
| 1717 | |||
| 1718 | data+=readb(&dm->length); | ||
| 1719 | while((data-buf) < len && (readb(data)||readb(data+1))) | ||
| 1720 | data++; | ||
| 1721 | data+=2; | ||
| 1722 | i++; | ||
| 1723 | } | ||
| 1724 | iounmap(buf); | ||
| 1725 | |||
| 1726 | return status; | ||
| 1727 | } | ||
| 1728 | |||
| 1729 | static inline int dmi_checksum(u8 *buf) | ||
| 1730 | { | ||
| 1731 | u8 sum=0; | ||
| 1732 | int a; | ||
| 1733 | |||
| 1734 | for(a=0; a<15; a++) | ||
| 1735 | sum+=buf[a]; | ||
| 1736 | return (sum==0); | ||
| 1737 | } | ||
| 1738 | |||
| 1739 | static int dmi_decode(void) | ||
| 1740 | { | 1683 | { |
| 1741 | u8 buf[15]; | 1684 | struct dmi_device *dev = NULL; |
| 1742 | u32 fp=0xF0000; | 1685 | int intf_num = 0; |
| 1743 | |||
| 1744 | #ifdef CONFIG_SIMNOW | ||
| 1745 | return -1; | ||
| 1746 | #endif | ||
| 1747 | 1686 | ||
| 1748 | while(fp < 0xFFFFF) | 1687 | while ((dev = dmi_find_device(DMI_DEV_TYPE_IPMI, NULL, dev))) { |
| 1749 | { | 1688 | if (intf_num >= SI_MAX_DRIVERS) |
| 1750 | isa_memcpy_fromio(buf, fp, 15); | 1689 | break; |
| 1751 | if(memcmp(buf, "_DMI_", 5)==0 && dmi_checksum(buf)) | ||
| 1752 | { | ||
| 1753 | u16 num=buf[13]<<8|buf[12]; | ||
| 1754 | u16 len=buf[7]<<8|buf[6]; | ||
| 1755 | u32 base=buf[11]<<24|buf[10]<<16|buf[9]<<8|buf[8]; | ||
| 1756 | 1690 | ||
| 1757 | if(dmi_table(base, len, num) == 0) | 1691 | decode_dmi((struct dmi_header *) dev->device_data, intf_num++); |
| 1758 | return 0; | ||
| 1759 | } | ||
| 1760 | fp+=16; | ||
| 1761 | } | 1692 | } |
| 1762 | |||
| 1763 | return -1; | ||
| 1764 | } | 1693 | } |
| 1765 | 1694 | ||
| 1766 | static int try_init_smbios(int intf_num, struct smi_info **new_info) | 1695 | static int try_init_smbios(int intf_num, struct smi_info **new_info) |
| @@ -2293,7 +2222,7 @@ static __init int init_ipmi_si(void) | |||
| 2293 | printk("\n"); | 2222 | printk("\n"); |
| 2294 | 2223 | ||
| 2295 | #ifdef CONFIG_X86 | 2224 | #ifdef CONFIG_X86 |
| 2296 | dmi_decode(); | 2225 | dmi_find_bmc(); |
| 2297 | #endif | 2226 | #endif |
| 2298 | 2227 | ||
| 2299 | rv = init_one_smi(0, &(smi_infos[pos])); | 2228 | rv = init_one_smi(0, &(smi_infos[pos])); |
