linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 2/2] I2O: fix and workaround for Motorola/Freescale controller
@ 2006-01-23 23:29 Markus Lidel
  0 siblings, 0 replies; only message in thread
From: Markus Lidel @ 2006-01-23 23:29 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Linux Kernel

[-- Attachment #1: Type: text/plain, Size: 351 bytes --]

Changes:
--------
- This controller violates the I2O spec for the I/O registers. The patch
   contains a workaround which moves the registers to the proper location.
   (originally author: Matthew Starzewski)
- If a message frame is beyond the mapped address range a error is
   returned.

Signed-off-by: Markus Lidel <Markus.Lidel@shadowconnect.com>

[-- Attachment #2: i2o-pci-motorola-freescale-workaround.patch --]
[-- Type: text/x-patch, Size: 1822 bytes --]

--- a/drivers/message/i2o/pci.c	2006-01-23 23:41:42.031509195 +0100
+++ b/drivers/message/i2o/pci.c	2006-01-23 01:03:51.236440918 +0100
@@ -163,6 +168,24 @@
 	c->in_port = c->base.virt + I2O_IN_PORT;
 	c->out_port = c->base.virt + I2O_OUT_PORT;
 
+	/* Motorola/Freescale chip does not follow spec */
+	if (pdev->vendor == PCI_VENDOR_ID_MOTOROLA && pdev->device == 0x18c0) {
+		/* Check if CPU is enabled */
+		if (be32_to_cpu(readl(c->base.virt + 0x10000)) & 0x10000000) {
+			printk(KERN_INFO "%s: MPC82XX needs CPU running to "
+			       "service I2O.\n", c->name);
+			i2o_pci_free(c);
+			return -ENODEV;
+		} else {
+			c->irq_status += I2O_MOTOROLA_PORT_OFFSET;
+			c->irq_mask += I2O_MOTOROLA_PORT_OFFSET;
+			c->in_port += I2O_MOTOROLA_PORT_OFFSET;
+			c->out_port += I2O_MOTOROLA_PORT_OFFSET;
+			printk(KERN_INFO "%s: MPC82XX workarounds activated.\n",
+			       c->name);
+		}
+	}
+
 	if (i2o_dma_alloc(dev, &c->status, 8, GFP_KERNEL)) {
 		i2o_pci_free(c);
 		return -ENOMEM;
--- a/include/linux/i2o.h	2006-01-23 23:42:06.360729954 +0100
+++ b/include/linux/i2o.h	2006-01-23 00:58:44.288144650 +0100
@@ -1115,9 +1115,11 @@
 		return ERR_PTR(-ENOMEM);
 
 	mmsg->mfa = readl(c->in_port);
-	if (mmsg->mfa == I2O_QUEUE_EMPTY) {
+	if (unlikely(mmsg->mfa >= c->in_queue.len)) {
 		mempool_free(mmsg, c->in_msg.mempool);
-		return ERR_PTR(-EBUSY);
+		if(mmsg->mfa == I2O_QUEUE_EMPTY)
+			return ERR_PTR(-EBUSY);
+		return ERR_PTR(-EFAULT);
 	}
 
 	return &mmsg->msg;
--- a/drivers/message/i2o/core.h	2006-01-23 23:41:41.995507388 +0100
+++ b/drivers/message/i2o/core.h	2006-01-23 01:04:57.811975471 +0100
@@ -60,4 +60,7 @@
 #define I2O_IN_PORT	0x40
 #define I2O_OUT_PORT	0x44
 
+/* Motorola/Freescale specific register offset */
+#define I2O_MOTOROLA_PORT_OFFSET	0x10400
+
 #define I2O_IRQ_OUTBOUND_POST	0x00000008

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

only message in thread, other threads:[~2006-01-23 23:29 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-01-23 23:29 [PATCH 2/2] I2O: fix and workaround for Motorola/Freescale controller Markus Lidel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).