From d1bdc40b3389b1165e705c7794441417ed2a43bd Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Tue, 16 Oct 2012 15:53:36 -0500 Subject: [PATCH 1/5] IPMI: Remove SMBus driver info from the docs Some documentation for the SMBus driver is in the IPMI docs, but that code is not in the kernel tree at this point. So remove the docs to avoid confusion. Signed-off-by: Corey Minyard Signed-off-by: Linus Torvalds --- Documentation/IPMI.txt | 65 ++---------------------------------------- 1 file changed, 3 insertions(+), 62 deletions(-) diff --git a/Documentation/IPMI.txt b/Documentation/IPMI.txt index b2bea15137d2..16eb4c9e9233 100644 --- a/Documentation/IPMI.txt +++ b/Documentation/IPMI.txt @@ -42,13 +42,7 @@ The driver interface depends on your hardware. If your system properly provides the SMBIOS info for IPMI, the driver will detect it and just work. If you have a board with a standard interface (These will generally be either "KCS", "SMIC", or "BT", consult your hardware -manual), choose the 'IPMI SI handler' option. A driver also exists -for direct I2C access to the IPMI management controller. Some boards -support this, but it is unknown if it will work on every board. For -this, choose 'IPMI SMBus handler', but be ready to try to do some -figuring to see if it will work on your system if the SMBIOS/APCI -information is wrong or not present. It is fairly safe to have both -these enabled and let the drivers auto-detect what is present. +manual), choose the 'IPMI SI handler' option. You should generally enable ACPI on your system, as systems with IPMI can have ACPI tables describing them. @@ -58,8 +52,7 @@ their job correctly, the IPMI controller should be automatically detected (via ACPI or SMBIOS tables) and should just work. Sadly, many boards do not have this information. The driver attempts standard defaults, but they may not work. If you fall into this -situation, you need to read the section below named 'The SI Driver' or -"The SMBus Driver" on how to hand-configure your system. +situation, you need to read the section below named 'The SI Driver'. IPMI defines a standard watchdog timer. You can enable this with the 'IPMI Watchdog Timer' config option. If you compile the driver into @@ -104,12 +97,7 @@ driver, each open file for this device ties in to the message handler as an IPMI user. ipmi_si - A driver for various system interfaces. This supports KCS, -SMIC, and BT interfaces. Unless you have an SMBus interface or your -own custom interface, you probably need to use this. - -ipmi_smb - A driver for accessing BMCs on the SMBus. It uses the -I2C kernel driver's SMBus interfaces to send and receive IPMI messages -over the SMBus. +SMIC, and BT interfaces. ipmi_watchdog - IPMI requires systems to have a very capable watchdog timer. This driver implements the standard Linux watchdog timer @@ -482,53 +470,6 @@ for specifying an interface. Note that when removing an interface, only the first three parameters (si type, address type, and address) are used for the comparison. Any options are ignored for removing. -The SMBus Driver ----------------- - -The SMBus driver allows up to 4 SMBus devices to be configured in the -system. By default, the driver will register any SMBus interfaces it finds -in the I2C address range of 0x20 to 0x4f on any adapter. You can change this -at module load time (for a module) with: - - modprobe ipmi_smb.o - addr=,[,,[,...]] - dbg=,... - [defaultprobe=1] [dbg_probe=1] - -The addresses are specified in pairs, the first is the adapter ID and the -second is the I2C address on that adapter. - -The debug flags are bit flags for each BMC found, they are: -IPMI messages: 1, driver state: 2, timing: 4, I2C probe: 8 - -Setting smb_defaultprobe to zero disabled the default probing of SMBus -interfaces at address range 0x20 to 0x4f. This means that only the -BMCs specified on the smb_addr line will be detected. - -Setting smb_dbg_probe to 1 will enable debugging of the probing and -detection process for BMCs on the SMBusses. - -Discovering the IPMI compliant BMC on the SMBus can cause devices -on the I2C bus to fail. The SMBus driver writes a "Get Device ID" IPMI -message as a block write to the I2C bus and waits for a response. -This action can be detrimental to some I2C devices. It is highly recommended -that the known I2c address be given to the SMBus driver in the smb_addr -parameter. The default address range will not be used when a smb_addr -parameter is provided. - -When compiled into the kernel, the addresses can be specified on the -kernel command line as: - - ipmb_smb.addr=,[,,[,...]] - ipmi_smb.dbg=,... - ipmi_smb.defaultprobe=0 ipmi_smb.dbg_probe=1 - -These are the same options as on the module command line. - -Note that you might need some I2C changes if CONFIG_IPMI_PANIC_EVENT -is enabled along with this, so the I2C driver knows to run to -completion during sending a panic event. - Other Pieces ------------ From 4033741ff9f727fbf5efb9337c826703534d49b7 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 16 Oct 2012 15:53:37 -0500 Subject: [PATCH 2/5] ACPI: Reorder IPMI driver before any other ACPI drivers Drivers may make calls that require the ACPI IPMI driver to have been initialised already, so make sure that it appears earlier in the build order. Signed-off-by: Matthew Garrett Signed-off-by: Corey Minyard Signed-off-by: Linus Torvalds --- drivers/acpi/Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 47199e2a9130..82422fe90f81 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -47,6 +47,10 @@ acpi-y += video_detect.o endif # These are (potentially) separate modules + +# IPMI may be used by other drivers, so it has to initialise before them +obj-$(CONFIG_ACPI_IPMI) += acpi_ipmi.o + obj-$(CONFIG_ACPI_AC) += ac.o obj-$(CONFIG_ACPI_BUTTON) += button.o obj-$(CONFIG_ACPI_FAN) += fan.o @@ -70,6 +74,5 @@ processor-y += processor_idle.o processor_thermal.o processor-$(CONFIG_CPU_FREQ) += processor_perflib.o obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o -obj-$(CONFIG_ACPI_IPMI) += acpi_ipmi.o obj-$(CONFIG_ACPI_APEI) += apei/ From 061475b65c126454aaaaddcbd40e7118424fc860 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 16 Oct 2012 15:53:38 -0500 Subject: [PATCH 3/5] IPMI: Change link order IPMI must be initialised before ACPI in order to ensure that any IPMI services are available before ACPI driver initialisation attempts to use any IPMI operation regions. Signed-off-by: Matthew Garrett Signed-off-by: Corey Minyard Signed-off-by: Linus Torvalds --- drivers/Makefile | 4 ++++ drivers/char/Makefile | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/Makefile b/drivers/Makefile index 03da5b663aef..a16a8d001ae0 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -17,6 +17,10 @@ obj-$(CONFIG_PARISC) += parisc/ obj-$(CONFIG_RAPIDIO) += rapidio/ obj-y += video/ obj-y += idle/ + +# IPMI must come before ACPI in order to provide IPMI opregion support +obj-$(CONFIG_IPMI_HANDLER) += char/ipmi/ + obj-$(CONFIG_ACPI) += acpi/ obj-$(CONFIG_SFI) += sfi/ # PnP must come after ACPI since it will eventually need to check if acpi diff --git a/drivers/char/Makefile b/drivers/char/Makefile index d0b27a39f1d4..7ff1d0d208a7 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -52,7 +52,6 @@ obj-$(CONFIG_TELCLOCK) += tlclk.o obj-$(CONFIG_MWAVE) += mwave/ obj-$(CONFIG_AGP) += agp/ obj-$(CONFIG_PCMCIA) += pcmcia/ -obj-$(CONFIG_IPMI_HANDLER) += ipmi/ obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o obj-$(CONFIG_TCG_TPM) += tpm/ From 9ebca93bf3b350910c66516cbec68899eeddfd8e Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Tue, 16 Oct 2012 15:53:39 -0500 Subject: [PATCH 4/5] IPMI: Fix some uninitialized warning There was a spot where the compiler couldn't tell some variables would be set. So initialize them to make the warning go away. Signed-off-by: Corey Minyard Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_msghandler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 2c29942b1326..a0c84bb30856 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -1880,7 +1880,7 @@ int ipmi_request_supply_msgs(ipmi_user_t user, struct ipmi_recv_msg *supplied_recv, int priority) { - unsigned char saddr, lun; + unsigned char saddr = 0, lun = 0; int rv; if (!user) From a6c16c2803089f032f86fe15e952176c0713d6e3 Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Tue, 16 Oct 2012 15:53:40 -0500 Subject: [PATCH 5/5] IPMI: Detect register spacing on PCI interfaces The IPMI spec defines a way to detect register spacing for PCI interfaces, so implement it. Signed-off-by: Steven Hsieh Signed-off-by: Corey Minyard Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_si_intf.c | 36 ++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 83f85cf7fb1b..32a6c7e256bd 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -2424,6 +2424,38 @@ static void ipmi_pci_cleanup(struct smi_info *info) pci_disable_device(pdev); } +static int __devinit ipmi_pci_probe_regspacing(struct smi_info *info) +{ + if (info->si_type == SI_KCS) { + unsigned char status; + int regspacing; + + info->io.regsize = DEFAULT_REGSIZE; + info->io.regshift = 0; + info->io_size = 2; + info->handlers = &kcs_smi_handlers; + + /* detect 1, 4, 16byte spacing */ + for (regspacing = DEFAULT_REGSPACING; regspacing <= 16;) { + info->io.regspacing = regspacing; + if (info->io_setup(info)) { + dev_err(info->dev, + "Could not setup I/O space\n"); + return DEFAULT_REGSPACING; + } + /* write invalid cmd */ + info->io.outputb(&info->io, 1, 0x10); + /* read status back */ + status = info->io.inputb(&info->io, 1); + info->io_cleanup(info); + if (status) + return regspacing; + regspacing *= 4; + } + } + return DEFAULT_REGSPACING; +} + static int __devinit ipmi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -2476,8 +2508,8 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev, } info->io.addr_data = pci_resource_start(pdev, 0); - info->io.regspacing = DEFAULT_REGSPACING; - info->io.regsize = DEFAULT_REGSPACING; + info->io.regspacing = ipmi_pci_probe_regspacing(info); + info->io.regsize = DEFAULT_REGSIZE; info->io.regshift = 0; info->irq = pdev->irq;