Commit 9bc63696 authored by Corey Minyard's avatar Corey Minyard Committed by Linus Torvalds

[PATCH] IPMI updates for 2.6.0-test3

Here are some minor updates to the IPMI driver.  They fix the following:

    * A missing check for copy_to_user() in the watchdog driver.
    * Removal of unnecessary check_region() calls.
    * Fixes for the ACPI configuration. The previous one would only work
      with memory addresses, this will work with memory addresses,
      ports, and hadle checking that the type is correct.
parent b8850b35
...@@ -1018,52 +1018,81 @@ static int init_one_kcs(int kcs_port, ...@@ -1018,52 +1018,81 @@ static int init_one_kcs(int kcs_port,
#ifdef CONFIG_ACPI_INTERPRETER #ifdef CONFIG_ACPI_INTERPRETER
/* Retrieve the base physical address from ACPI tables. Originally
from Hewlett-Packard simple bmc.c, a GPL KCS driver. */
#include <linux/acpi.h> #include <linux/acpi.h>
struct SPMITable { struct SPMITable {
s8 Signature[4]; s8 Signature[4];
u32 Length; u32 Length;
u8 Revision; u8 Revision;
u8 Checksum; u8 Checksum;
s8 OEMID[6]; s8 OEMID[6];
s8 OEMTableID[8]; s8 OEMTableID[8];
s8 OEMRevision[4]; s8 OEMRevision[4];
s8 CreatorID[4]; s8 CreatorID[4];
s8 CreatorRevision[4]; s8 CreatorRevision[4];
s16 InterfaceType; u8 InterfaceType[2];
s16 SpecificationRevision; s16 SpecificationRevision;
u8 InterruptType;
u8 GPE; /*
s16 Reserved; * Bit 0 - SCI interrupt supported
u64 GlobalSystemInterrupt; * Bit 1 - I/O APIC/SAPIC
u8 BaseAddress[12]; */
u8 UID[4]; u8 InterruptType;
} __attribute__ ((packed));
/* If bit 0 of InterruptType is set, then this is the SCI
static unsigned long acpi_find_bmc(void) interrupt in the GPEx_STS register. */
{ u8 GPE;
acpi_status status;
struct acpi_table_header *spmi; s16 Reserved;
static unsigned long io_base = 0;
/* If bit 1 of InterruptType is set, then this is the I/O
if (io_base != 0) APIC/SAPIC interrupt. */
return io_base; u32 GlobalSystemInterrupt;
/* The actual register address. */
struct acpi_generic_address addr;
u8 UID[4];
s8 spmi_id[1]; /* A '\0' terminated array starts here. */
};
static int acpi_find_bmc(unsigned long *physaddr, int *port)
{
acpi_status status;
struct SPMITable *spmi;
status = acpi_get_firmware_table("SPMI", 1, status = acpi_get_firmware_table("SPMI", 1,
ACPI_LOGICAL_ADDRESSING, &spmi); ACPI_LOGICAL_ADDRESSING,
(struct acpi_table_header **) &spmi);
if (status != AE_OK)
goto not_found;
if (spmi->InterfaceType[0] != 1)
/* Not IPMI. */
goto not_found;
if (spmi->InterfaceType[1] != 1)
/* Not KCS. */
goto not_found;
if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
*physaddr = spmi->addr.address;
printk("ipmi_kcs_intf: Found ACPI-specified state machine"
" at memory address 0x%lx\n",
(unsigned long) spmi->addr.address);
} else if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
*port = spmi->addr.address;
printk("ipmi_kcs_intf: Found ACPI-specified state machine"
" at I/O address 0x%lx\n",
(int) spmi->addr.address);
} else
goto not_found; /* Not an address type we recognise. */
if (status != AE_OK) { return 0;
printk(KERN_ERR "ipmi_kcs: SPMI table not found.\n");
return 0;
}
memcpy(&io_base, ((struct SPMITable *)spmi)->BaseAddress, not_found:
sizeof(io_base)); return -ENODEV;
return io_base;
} }
#endif #endif
...@@ -1074,6 +1103,7 @@ static __init int init_ipmi_kcs(void) ...@@ -1074,6 +1103,7 @@ static __init int init_ipmi_kcs(void)
int i = 0; int i = 0;
#ifdef CONFIG_ACPI_INTERPRETER #ifdef CONFIG_ACPI_INTERPRETER
unsigned long physaddr = 0; unsigned long physaddr = 0;
int port = 0;
#endif #endif
if (initialized) if (initialized)
...@@ -1101,20 +1131,19 @@ static __init int init_ipmi_kcs(void) ...@@ -1101,20 +1131,19 @@ static __init int init_ipmi_kcs(void)
/* Only try the defaults if enabled and resources are available /* Only try the defaults if enabled and resources are available
(because they weren't already specified above). */ (because they weren't already specified above). */
if (kcs_trydefaults) { if (kcs_trydefaults && (pos == 0)) {
rv = -EINVAL;
#ifdef CONFIG_ACPI_INTERPRETER #ifdef CONFIG_ACPI_INTERPRETER
if ((physaddr = acpi_find_bmc())) { if (rv && (physaddr = acpi_find_bmc(&physaddr, &port) == 0)) {
if (!check_mem_region(physaddr, 2)) { rv = init_one_kcs(port,
rv = init_one_kcs(0, 0,
0, physaddr,
physaddr, &(kcs_infos[pos]));
&(kcs_infos[pos])); if (rv == 0)
if (rv == 0) pos++;
pos++;
}
} }
#endif #endif
if (!check_region(DEFAULT_IO_PORT, 2)) { if (rv) {
rv = init_one_kcs(DEFAULT_IO_PORT, rv = init_one_kcs(DEFAULT_IO_PORT,
0, 0,
0, 0,
......
...@@ -559,7 +559,10 @@ static int ipmi_ioctl(struct inode *inode, struct file *file, ...@@ -559,7 +559,10 @@ static int ipmi_ioctl(struct inode *inode, struct file *file,
case WDIOC_GETSTATUS: case WDIOC_GETSTATUS:
val = 0; val = 0;
return copy_to_user((void *) arg, &val, sizeof(val)); i = copy_to_user((void *) arg, &val, sizeof(val));
if (i)
return -EFAULT;
return 0;
default: default:
return -ENOIOCTLCMD; return -ENOIOCTLCMD;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment