Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6363b3f3 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'ipmi-for-4.15' of git://github.com/cminyard/linux-ipmi

Pull IPMI updates from Corey Minyard:
 "This is a fairly large rework of the IPMI code, along with a bunch of
  smaller fixes. The major changes have been in the next tree for a
  couple of months, so they should be good to do in.

   - Some users had IPMI systems where the GUID of the IPMI controller
     could change. So rescanning of the GUID was added. The naming of
     some sysfs things was dependent on the GUID, however, so this
     resulted in the sysfs interface code in IPMI changing to remove
     that dependency and name the IPMI BMCs like other sysfs devices.

   - The ipmi_si_intf.c code was fairly bloated with all the different
     discovery methods (PCI, ACPI, SMBIOS, OF, platform, module
     parameters, hot add). The structure of how the interfaces were
     added was redone to make them more modular, then the individual
     methods were pulled out into their own files"

* tag 'ipmi-for-4.15' of git://github.com/cminyard/linux-ipmi: (48 commits)
  ipmi_si: Delete an error message for a failed memory allocation in try_smi_init()
  ipmi_si: fix memory leak on new_smi
  ipmi: remove redundant initialization of bmc
  ipmi: pr_err() strings should end with newlines
  ipmi: Clean up some print operations
  ipmi: Make the DMI probe into a generic platform probe
  ipmi: Make the IPMI proc interface configurable
  ipmi_ssif: Add device attrs for the things in proc
  ipmi_si: Add device attrs for the things in proc
  ipmi_si: remove ipmi_smi_alloc() function
  ipmi_si: Move port and mem I/O handling to their own files
  ipmi_si: Get rid of unused spacing and port fields
  ipmi_si: Move PARISC handling to another file
  ipmi_si: Move PCI setup to another file
  ipmi_si: Move platform device handling to another file
  ipmi_si: Move hardcode handling to a separate file.
  ipmi_si: Move the hotmod handling to another file.
  ipmi_si: Change ipmi_si_add_smi() to take just I/O info
  ipmi_si: Move io setup into io structure
  ipmi_si: Move irq setup handling into the io struct
  ...
parents 1b6115fb 6297fabd
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -81,7 +81,9 @@ If you want the driver to put an event into the event log on a panic,
enable the 'Generate a panic event to all BMCs on a panic' option.  If
you want the whole panic string put into the event log using OEM
events, enable the 'Generate OEM events containing the panic string'
option.
option.  You can also enable these dynamically by setting the module
parameter named "panic_op" in the ipmi_msghandler module to "event"
or "string".  Setting that parameter to "none" disables this function.

Basic Design
------------
+25 −10
Original line number Diff line number Diff line
@@ -22,24 +22,39 @@ config IPMI_DMI_DECODE

if IPMI_HANDLER

config IPMI_PROC_INTERFACE
       bool 'Provide an interface for IPMI stats in /proc (deprecated)'
       depends on PROC_FS
       default y
       help
         Do not use this any more, use sysfs for this info.  It will be
	 removed in future kernel versions.

config IPMI_PANIC_EVENT
       bool 'Generate a panic event to all BMCs on a panic'
       help
         When a panic occurs, this will cause the IPMI message handler to
	 generate an IPMI event describing the panic to each interface
	 registered with the message handler.
	 When a panic occurs, this will cause the IPMI message handler to,
	 by default, generate an IPMI event describing the panic to each
	 interface registered with the message handler.  This is always
	 available, the module parameter for ipmi_msghandler named
	 panic_op can be set to "event" to chose this value, this config
	 simply causes the default value to be set to "event".

config IPMI_PANIC_STRING
	bool 'Generate OEM events containing the panic string'
	depends on IPMI_PANIC_EVENT
	help
	  When a panic occurs, this will cause the IPMI message handler to
	  generate IPMI OEM type f0 events holding the IPMB address of the
	  panic generator (byte 4 of the event), a sequence number for the
	  string (byte 5 of the event) and part of the string (the rest of the
	  event).  Bytes 1, 2, and 3 are the normal usage for an OEM event.
	  You can fetch these events and use the sequence numbers to piece the
	  string together.
	  When a panic occurs, this will cause the IPMI message handler to,
	  by default, generate IPMI OEM type f0 events holding the IPMB
	  address of the panic generator (byte 4 of the event), a sequence
	  number for the string (byte 5 of the event) and part of the
	  string (the rest of the event).  Bytes 1, 2, and 3 are the normal
	  usage for an OEM event.  You can fetch these events and use the
	  sequence numbers to piece the string together.  This config
	  parameter sets the default value to generate these events,
	  the module parameter for ipmi_msghandler named panic_op can
	  be set to "string" to chose this value, this config simply
	  causes the default value to be set to "string".

config IPMI_DEVICE_INTERFACE
       tristate 'Device interface for IPMI'
+9 −1
Original line number Diff line number Diff line
@@ -3,7 +3,15 @@
# Makefile for the ipmi drivers.
#

ipmi_si-y := ipmi_si_intf.o ipmi_kcs_sm.o ipmi_smic_sm.o ipmi_bt_sm.o
ipmi_si-y := ipmi_si_intf.o ipmi_kcs_sm.o ipmi_smic_sm.o ipmi_bt_sm.o \
	ipmi_si_hotmod.o ipmi_si_hardcode.o ipmi_si_platform.o \
	ipmi_si_port_io.o ipmi_si_mem_io.o
ifdef CONFIG_PCI
ipmi_si-y += ipmi_si_pci.o
endif
ifdef CONFIG_PARISC
ipmi_si-y += ipmi_si_parisc.o
endif

obj-$(CONFIG_IPMI_HANDLER) += ipmi_msghandler.o
obj-$(CONFIG_IPMI_DEVICE_INTERFACE) += ipmi_devintf.o
+52 −24
Original line number Diff line number Diff line
@@ -9,10 +9,16 @@
#include <linux/dmi.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include "ipmi_si_sm.h"
#include "ipmi_dmi.h"

#define IPMI_DMI_TYPE_KCS	0x01
#define IPMI_DMI_TYPE_SMIC	0x02
#define IPMI_DMI_TYPE_BT	0x03
#define IPMI_DMI_TYPE_SSIF	0x04

struct ipmi_dmi_info {
	int type;
	enum si_type si_type;
	u32 flags;
	unsigned long addr;
	u8 slave_addr;
@@ -23,6 +29,15 @@ static struct ipmi_dmi_info *ipmi_dmi_infos;

static int ipmi_dmi_nr __initdata;

#define set_prop_entry(_p_, _name_, type, val)	\
do {					\
	struct property_entry *_p = &_p_;	\
	_p->name = _name_;			\
	_p->length = sizeof(type);		\
	_p->is_string = false;			\
	_p->value.type##_data = val;		\
} while(0)

static void __init dmi_add_platform_ipmi(unsigned long base_addr,
					 u32 flags,
					 u8 slave_addr,
@@ -33,27 +48,14 @@ static void __init dmi_add_platform_ipmi(unsigned long base_addr,
	struct platform_device *pdev;
	struct resource r[4];
	unsigned int num_r = 1, size;
	struct property_entry p[4] = {
		PROPERTY_ENTRY_U8("slave-addr", slave_addr),
		PROPERTY_ENTRY_U8("ipmi-type", type),
		PROPERTY_ENTRY_U16("i2c-addr", base_addr),
		{ }
	};
	struct property_entry p[5];
	unsigned int pidx = 0;
	char *name, *override;
	int rv;
	enum si_type si_type;
	struct ipmi_dmi_info *info;

	info = kmalloc(sizeof(*info), GFP_KERNEL);
	if (!info) {
		pr_warn("ipmi:dmi: Could not allocate dmi info\n");
	} else {
		info->type = type;
		info->flags = flags;
		info->addr = base_addr;
		info->slave_addr = slave_addr;
		info->next = ipmi_dmi_infos;
		ipmi_dmi_infos = info;
	}
	memset(p, 0, sizeof(p));

	name = "dmi-ipmi-si";
	override = "ipmi_si";
@@ -63,28 +65,53 @@ static void __init dmi_add_platform_ipmi(unsigned long base_addr,
		override = "ipmi_ssif";
		offset = 1;
		size = 1;
		si_type = SI_TYPE_INVALID;
		break;
	case IPMI_DMI_TYPE_BT:
		size = 3;
		si_type = SI_BT;
		break;
	case IPMI_DMI_TYPE_KCS:
		size = 2;
		si_type = SI_KCS;
		break;
	case IPMI_DMI_TYPE_SMIC:
		size = 2;
		si_type = SI_SMIC;
		break;
	default:
		pr_err("ipmi:dmi: Invalid IPMI type: %d", type);
		pr_err("ipmi:dmi: Invalid IPMI type: %d\n", type);
		return;
	}

	if (si_type != SI_TYPE_INVALID)
		set_prop_entry(p[pidx++], "ipmi-type", u8, si_type);
	set_prop_entry(p[pidx++], "slave-addr", u8, slave_addr);
	set_prop_entry(p[pidx++], "addr-source", u8, SI_SMBIOS);

	info = kmalloc(sizeof(*info), GFP_KERNEL);
	if (!info) {
		pr_warn("ipmi:dmi: Could not allocate dmi info\n");
	} else {
		info->si_type = si_type;
		info->flags = flags;
		info->addr = base_addr;
		info->slave_addr = slave_addr;
		info->next = ipmi_dmi_infos;
		ipmi_dmi_infos = info;
	}

	pdev = platform_device_alloc(name, ipmi_dmi_nr);
	if (!pdev) {
		pr_err("ipmi:dmi: Error allocation IPMI platform device");
		pr_err("ipmi:dmi: Error allocation IPMI platform device\n");
		return;
	}
	pdev->driver_override = override;

	if (type == IPMI_DMI_TYPE_SSIF)
	if (type == IPMI_DMI_TYPE_SSIF) {
		set_prop_entry(p[pidx++], "i2c-addr", u16, base_addr);
		goto add_properties;
	}

	memset(r, 0, sizeof(r));

@@ -152,12 +179,13 @@ static void __init dmi_add_platform_ipmi(unsigned long base_addr,
 * This function allows an ACPI-specified IPMI device to look up the
 * slave address from the DMI table.
 */
int ipmi_dmi_get_slave_addr(int type, u32 flags, unsigned long base_addr)
int ipmi_dmi_get_slave_addr(enum si_type si_type, u32 flags,
			    unsigned long base_addr)
{
	struct ipmi_dmi_info *info = ipmi_dmi_infos;

	while (info) {
		if (info->type == type &&
		if (info->si_type == si_type &&
		    info->flags == flags &&
		    info->addr == base_addr)
			return info->slave_addr;
@@ -240,7 +268,7 @@ static void __init dmi_decode_ipmi(const struct dmi_header *dm)
				offset = 16;
				break;
			default:
				pr_err("ipmi:dmi: Invalid offset: 0");
				pr_err("ipmi:dmi: Invalid offset: 0\n");
				return;
			}
		}
+2 −6
Original line number Diff line number Diff line
@@ -3,11 +3,7 @@
 * DMI defines for use by IPMI
 */

#define IPMI_DMI_TYPE_KCS	0x01
#define IPMI_DMI_TYPE_SMIC	0x02
#define IPMI_DMI_TYPE_BT	0x03
#define IPMI_DMI_TYPE_SSIF	0x04

#ifdef CONFIG_IPMI_DMI_DECODE
int ipmi_dmi_get_slave_addr(int type, u32 flags, unsigned long base_addr);
int ipmi_dmi_get_slave_addr(enum si_type si_type, u32 flags,
			    unsigned long base_addr);
#endif
Loading