mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] IPMI: reserve I/O ports separately
@ 2006-05-26 17:31 Corey Minyard
  0 siblings, 0 replies; only message in thread
From: Corey Minyard @ 2006-05-26 17:31 UTC (permalink / raw)
  To: akpm, torvalds
  Cc: linux-kernel, Jordan_Hargrave, Matt_Domsch, openipmi-developer

This patch is pretty important to get in for IPMI, new systems have
been changing the way ACPI and IPMI interact, and this works around
the problems for now.  This is a temporary fix until we get proper
ACPI handling in IPMI.

Fixed releasing already-allocated regions when a later request fails,
and forward-ported it to HEAD.

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.

Signed-off-by: Jordan Hargrave <Jordan_Hargrave@dell.com>
Signed-off-by: Matt Domsch <Matt_Domsch@dell.com>
Signed-off-by: Corey Minyard <minyard@acm.org>

diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index b36eef0..96a9e24 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -1184,20 +1184,20 @@ static void port_outl(struct si_sm_io *i
 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,23 @@ static int port_setup(struct smi_info *i
 		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;
 }
 

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2006-05-26 17:31 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-05-26 17:31 [PATCH] IPMI: reserve I/O ports separately Corey Minyard

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®