" interface separated by commas. The types are 'kcs',"
" 'smic', and 'bt'. For example si_type=kcs,bt will set"
" the first interface to kcs and the second to bt");
-module_param_array(addrs, long, num_addrs, 0);
+module_param_array(addrs, long, &num_addrs, 0);
MODULE_PARM_DESC(addrs, "Sets the memory address of each interface, the"
" addresses separated by commas. Only use if an interface"
" is in memory. Otherwise, set it to zero or leave"
" it blank.");
-module_param_array(ports, int, num_ports, 0);
+module_param_array(ports, int, &num_ports, 0);
MODULE_PARM_DESC(ports, "Sets the port address of each interface, the"
" addresses separated by commas. Only use if an interface"
" is a port. Otherwise, set it to zero or leave"
" it blank.");
-module_param_array(irqs, int, num_irqs, 0);
+module_param_array(irqs, int, &num_irqs, 0);
MODULE_PARM_DESC(irqs, "Sets the interrupt of each interface, the"
" addresses separated by commas. Only use if an interface"
" has an interrupt. Otherwise, set it to zero or leave"
" it blank.");
-module_param_array(regspacings, int, num_regspacings, 0);
+module_param_array(regspacings, int, &num_regspacings, 0);
MODULE_PARM_DESC(regspacings, "The number of bytes between the start address"
" and each successive register used by the interface. For"
" instance, if the start address is 0xca2 and the spacing"
" is 2, then the second address is at 0xca4. Defaults"
" to 1.");
-module_param_array(regsizes, int, num_regsizes, 0);
+module_param_array(regsizes, int, &num_regsizes, 0);
MODULE_PARM_DESC(regsizes, "The size of the specific IPMI register in bytes."
" This should generally be 1, 2, 4, or 8 for an 8-bit,"
" 16-bit, 32-bit, or 64-bit register. Use this if you"
" the 8-bit IPMI register has to be read from a larger"
" register.");
-module_param_array(regshifts, int, num_regshifts, 0);
+module_param_array(regshifts, int, &num_regshifts, 0);
MODULE_PARM_DESC(regshifts, "The amount to shift the data read from the."
" IPMI register, in bits. For instance, if the data"
" is read from a 32-bit word and the IPMI data is in"
#define IPMI_MEM_ADDR_SPACE 1
#define IPMI_IO_ADDR_SPACE 2
-#if defined(CONFIG_ACPI_INTERPETER) || defined(CONFIG_X86) || defined(CONFIG_PCI)
+#if defined(CONFIG_ACPI_INTERPRETER) || defined(CONFIG_X86) || defined(CONFIG_PCI)
static int is_new_interface(int intf, u8 addr_space, unsigned long base_addr)
{
int i;
memset(info, 0, sizeof(*info));
info->io_setup = mem_setup;
- info->io.info = (void *) addrs[intf_num];
+ info->io.info = &addrs[intf_num];
info->io.addr = NULL;
info->io.regspacing = regspacings[intf_num];
if (!info->io.regspacing)
static int acpi_failure = 0;
/* For GPE-type interrupts. */
-u32 ipmi_acpi_gpe(void *context)
+static u32 ipmi_acpi_gpe(void *context)
{
struct smi_info *smi_info = context;
unsigned long flags;
status = acpi_install_gpe_handler(NULL,
info->irq,
ACPI_GPE_LEVEL_TRIGGERED,
- ipmi_acpi_gpe,
+ &ipmi_acpi_gpe,
info);
if (status != AE_OK) {
printk(KERN_WARNING
if (!info->irq)
return;
- acpi_remove_gpe_handler(NULL, info->irq, ipmi_acpi_gpe);
+ acpi_remove_gpe_handler(NULL, info->irq, &ipmi_acpi_gpe);
}
/*
u8 *data = (u8 *)dm;
unsigned long base_addr;
u8 reg_spacing;
+ u8 len = dm->length;
- ipmi_data->type = data[0x04];
+ ipmi_data->type = data[4];
- memcpy(&base_addr,&data[0x08],sizeof(unsigned long));
- if (base_addr & 1) {
- /* I/O */
- base_addr &= 0xFFFE;
+ memcpy(&base_addr, data+8, sizeof(unsigned long));
+ if (len >= 0x11) {
+ if (base_addr & 1) {
+ /* I/O */
+ base_addr &= 0xFFFE;
+ ipmi_data->addr_space = IPMI_IO_ADDR_SPACE;
+ }
+ else {
+ /* Memory */
+ ipmi_data->addr_space = IPMI_MEM_ADDR_SPACE;
+ }
+ /* If bit 4 of byte 0x10 is set, then the lsb for the address
+ is odd. */
+ ipmi_data->base_addr = base_addr | ((data[0x10] & 0x10) >> 4);
+
+ ipmi_data->irq = data[0x11];
+
+ /* The top two bits of byte 0x10 hold the register spacing. */
+ reg_spacing = (data[0x10] & 0xC0) >> 6;
+ switch(reg_spacing){
+ case 0x00: /* Byte boundaries */
+ ipmi_data->offset = 1;
+ break;
+ case 0x01: /* 32-bit boundaries */
+ ipmi_data->offset = 4;
+ break;
+ case 0x02: /* 16-byte boundaries */
+ ipmi_data->offset = 16;
+ break;
+ default:
+ /* Some other interface, just ignore it. */
+ return -EIO;
+ }
+ } else {
+ /* Old DMI spec. */
+ ipmi_data->base_addr = base_addr;
ipmi_data->addr_space = IPMI_IO_ADDR_SPACE;
- }
- else {
- /* Memory */
- ipmi_data->addr_space = IPMI_MEM_ADDR_SPACE;
- }
-
- /* The top two bits of byte 0x10 hold the register spacing. */
- reg_spacing = (data[0x10] & 0xC0) >> 6;
- switch(reg_spacing){
- case 0x00: /* Byte boundaries */
ipmi_data->offset = 1;
- break;
- case 0x01: /* 32-bit boundaries */
- ipmi_data->offset = 4;
- break;
- case 0x02: /* 16-bit boundaries */
- ipmi_data->offset = 2;
- default:
- printk("ipmi_si: Unknown SMBIOS IPMI Base Addr"
- " Modifier: 0x%x\n", reg_spacing);
- return -EIO;
}
- /* If bit 4 of byte 0x10 is set, then the lsb for the address
- is odd. */
- ipmi_data->base_addr = base_addr | ((data[0x10] & 0x10) >> 4);
-
- ipmi_data->irq = data[0x11];
-
if (is_new_interface(-1, ipmi_data->addr_space,ipmi_data->base_addr))
- return 0;
+ return 0;
- memset(ipmi_data,0,sizeof(dmi_ipmi_data_t));
+ memset(ipmi_data, 0, sizeof(dmi_ipmi_data_t));
return -1;
}
pci_smic_checked = 1;
- if ((pci_dev = pci_find_device(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID,
+ if ((pci_dev = pci_get_device(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID,
NULL)))
;
- else if ((pci_dev = pci_find_class(PCI_ERMC_CLASSCODE, NULL)) &&
+ else if ((pci_dev = pci_get_class(PCI_ERMC_CLASSCODE, NULL)) &&
pci_dev->subsystem_vendor == PCI_HP_VENDOR_ID)
fe_rmc = 1;
else
error = pci_read_config_word(pci_dev, PCI_MMC_ADDR_CW, &base_addr);
if (error)
{
+ pci_dev_put(pci_dev);
printk(KERN_ERR
"ipmi_si: pci_read_config_word() failed (%d).\n",
error);
/* Bit 0: 1 specifies programmed I/O, 0 specifies memory mapped I/O */
if (!(base_addr & 0x0001))
{
+ pci_dev_put(pci_dev);
printk(KERN_ERR
"ipmi_si: memory mapped I/O not supported for PCI"
" smic.\n");
/* Data register starts at base address + 1 in eRMC */
++base_addr;
- if (!is_new_interface(-1, IPMI_IO_ADDR_SPACE, base_addr))
- return -ENODEV;
+ if (!is_new_interface(-1, IPMI_IO_ADDR_SPACE, base_addr)) {
+ pci_dev_put(pci_dev);
+ return -ENODEV;
+ }
info = kmalloc(sizeof(*info), GFP_KERNEL);
if (!info) {
+ pci_dev_put(pci_dev);
printk(KERN_ERR "ipmi_si: Could not allocate SI data (5)\n");
return -ENOMEM;
}
printk("ipmi_si: Found PCI SMIC at I/O address 0x%lx\n",
(long unsigned int) base_addr);
+ pci_dev_put(pci_dev);
return 0;
}
#endif /* CONFIG_PCI */
}
module_init(init_ipmi_si);
-void __exit cleanup_one_si(struct smi_info *to_clean)
+static void __exit cleanup_one_si(struct smi_info *to_clean)
{
int rv;
unsigned long flags;
interface is in a clean state. */
while ((to_clean->curr_msg) || (to_clean->si_state != SI_NORMAL)) {
poll(to_clean);
+ set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(1);
}