From: Mark Salter <msalter@redhat.com>
To: minyard@acm.org
Cc: openipmi-developer@lists.sourceforge.net,
linux-kernel@vger.kernel.org, Corey Minyard <cminyard@mvista.com>
Subject: Re: [PATCH] IPMI: reserve memio regions separately
Date: Wed, 27 Apr 2016 09:24:13 -0400 [thread overview]
Message-ID: <1461763453.20711.7.camel@redhat.com> (raw)
In-Reply-To: <1461731468-10585-1-git-send-email-minyard@acm.org>
On Tue, 2016-04-26 at 23:31 -0500, minyard@acm.org wrote:
> From: Corey Minyard <cminyard@mvista.com>
>
> Commit d61a3ead2680 ("[PATCH] IPMI: reserve I/O ports separately")
> changed the way I/O ports were reserved and includes this comment in
> log:
>
> Some BIOSes reserve disjoint I/O regions in their ACPI tables for the IPMI
> controller. This causes problems when trying to register the entire I/O
> region. Therefore we must register each I/O port separately.
>
> There is a similar problem with memio regions on an arm64 platform
> (AMD Seattle). Where I see:
>
> ipmi message handler version 39.2
> ipmi_si AMDI0300:00: probing via device tree
> ipmi_si AMDI0300:00: ipmi_si: probing via ACPI
> ipmi_si AMDI0300:00: [mem 0xe0010000] regsize 1 spacing 4 irq 23
> ipmi_si: Adding ACPI-specified kcs state machine
> IPMI System Interface driver.
> ipmi_si: Trying ACPI-specified kcs state machine at mem \
> address 0xe0010000, slave address 0x0, irq 23
> ipmi_si: Could not set up I/O space
>
> The problem is that the ACPI core registers disjoint regions for the
> platform device:
>
> e0010000-e0010000 : AMDI0300:00
> e0010004-e0010004 : AMDI0300:00
>
> and the ipmi_si driver tries to register one region e0010000-e0010004.
>
> Based on a patch from Mark Salter <msalter@redhat.com>
>
> Signed-off-by: Corey Minyard <cminyard@mvista.com>
> ---
This works for me as well.
Tested-by: Mark Salter <msalter@redhat.com>
> drivers/char/ipmi/ipmi_si_intf.c | 40 +++++++++++++++++++++++++++-------------
> 1 file changed, 27 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
> index 6ecf9af..a815044 100644
> --- a/drivers/char/ipmi/ipmi_si_intf.c
> +++ b/drivers/char/ipmi/ipmi_si_intf.c
> @@ -1637,25 +1637,28 @@ static void mem_outq(const struct si_sm_io *io, unsigned int offset,
> }
> #endif
>
> -static void mem_cleanup(struct smi_info *info)
> +static void mem_region_cleanup(struct smi_info *info, int num)
> {
> unsigned long addr = info->io.addr_data;
> - int mapsize;
> + int idx;
> +
> + for (idx = 0; idx < num; idx++)
> + release_mem_region(addr + idx * info->io.regspacing,
> + info->io.regsize);
> +}
>
> +static void mem_cleanup(struct smi_info *info)
> +{
> if (info->io.addr) {
> iounmap(info->io.addr);
> -
> - mapsize = ((info->io_size * info->io.regspacing)
> - - (info->io.regspacing - info->io.regsize));
> -
> - release_mem_region(addr, mapsize);
> + mem_region_cleanup(info, info->io_size);
> }
> }
>
> static int mem_setup(struct smi_info *info)
> {
> unsigned long addr = info->io.addr_data;
> - int mapsize;
> + int mapsize, idx;
>
> if (!addr)
> return -ENODEV;
> @@ -1692,6 +1695,21 @@ static int mem_setup(struct smi_info *info)
> }
>
> /*
> + * Some BIOSes reserve disjoint memory regions in their ACPI
> + * tables. This causes problems when trying to request the
> + * entire region. Therefore we must request each register
> + * separately.
> + */
> + for (idx = 0; idx < info->io_size; idx++) {
> + if (request_mem_region(addr + idx * info->io.regspacing,
> + info->io.regsize, DEVICE_NAME) == NULL) {
> + /* Undo allocations */
> + mem_region_cleanup(info, idx);
> + return -EIO;
> + }
> + }
> +
> + /*
> * Calculate the total amount of memory to claim. This is an
> * unusual looking calculation, but it avoids claiming any
> * more memory than it has to. It will claim everything
> @@ -1700,13 +1718,9 @@ static int mem_setup(struct smi_info *info)
> */
> mapsize = ((info->io_size * info->io.regspacing)
> - (info->io.regspacing - info->io.regsize));
> -
> - if (request_mem_region(addr, mapsize, DEVICE_NAME) == NULL)
> - return -EIO;
> -
> info->io.addr = ioremap(addr, mapsize);
> if (info->io.addr == NULL) {
> - release_mem_region(addr, mapsize);
> + mem_region_cleanup(info, info->io_size);
> return -EIO;
> }
> return 0;
next prev parent reply other threads:[~2016-04-27 13:24 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-04-25 16:08 [PATCH] IPMI: reserve memio regions separately Mark Salter
2016-04-27 4:31 ` minyard
2016-04-27 13:24 ` Mark Salter [this message]
2016-04-27 13:38 ` Corey Minyard
2016-04-27 12:52 ` Corey Minyard
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1461763453.20711.7.camel@redhat.com \
--to=msalter@redhat.com \
--cc=cminyard@mvista.com \
--cc=linux-kernel@vger.kernel.org \
--cc=minyard@acm.org \
--cc=openipmi-developer@lists.sourceforge.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.