From c76bd3290828192c923dcf3db8c6b8565648a642 Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Tue, 30 May 2006 21:25:57 -0700 Subject: [PATCH] --- yaml --- r: 27044 b: refs/heads/master c: d61a3ead268084cc271d7b2aa2950fc822a37cf5 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/char/ipmi/ipmi_si_intf.c | 38 +++++++++++++++----------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/[refs] b/[refs] index 9f9b954a7dd0..09a9bc36146c 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 44d7aff035118e8c3993aa3fa05d358d1008e982 +refs/heads/master: d61a3ead268084cc271d7b2aa2950fc822a37cf5 diff --git a/trunk/drivers/char/ipmi/ipmi_si_intf.c b/trunk/drivers/char/ipmi/ipmi_si_intf.c index b36eef0e9d19..02a7dd7a8a55 100644 --- a/trunk/drivers/char/ipmi/ipmi_si_intf.c +++ b/trunk/drivers/char/ipmi/ipmi_si_intf.c @@ -1184,20 +1184,20 @@ static void port_outl(struct si_sm_io *io, unsigned int offset, static void port_cleanup(struct smi_info *info) { unsigned int addr = info->io.addr_data; - int mapsize; + int idx; if (addr) { - mapsize = ((info->io_size * info->io.regspacing) - - (info->io.regspacing - info->io.regsize)); - - release_region (addr, mapsize); + for (idx = 0; idx < info->io_size; idx++) { + release_region(addr + idx * info->io.regspacing, + info->io.regsize); + } } } static int port_setup(struct smi_info *info) { unsigned int addr = info->io.addr_data; - int mapsize; + int idx; if (!addr) return -ENODEV; @@ -1225,16 +1225,22 @@ static int port_setup(struct smi_info *info) return -EINVAL; } - /* 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 - * between the first address to the end of the last full - * register. */ - mapsize = ((info->io_size * info->io.regspacing) - - (info->io.regspacing - info->io.regsize)); - - if (request_region(addr, mapsize, DEVICE_NAME) == NULL) - return -EIO; + /* Some BIOSes reserve disjoint I/O regions in their ACPI + * tables. This causes problems when trying to register the + * entire I/O region. Therefore we must register each I/O + * port separately. + */ + for (idx = 0; idx < info->io_size; idx++) { + if (request_region(addr + idx * info->io.regspacing, + info->io.regsize, DEVICE_NAME) == NULL) { + /* Undo allocations */ + while (idx--) { + release_region(addr + idx * info->io.regspacing, + info->io.regsize); + } + return -EIO; + } + } return 0; }