fsl_pq_mdio: Fix kernel oops during OF address translation

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Linux Kernel Mailing List
Date: Saturday, April 24, 2010 - 3:59 pm

Gitweb:     http://git.kernel.org/linus/3b1fd3e55a39824e68bc8dd055d14892476e3671
Commit:     3b1fd3e55a39824e68bc8dd055d14892476e3671
Parent:     fda48a0d7a8412cedacda46a9c0bf8ef9cd13559
Author:     Anton Vorontsov <avorontsov@mvista.com>
AuthorDate: Fri Apr 23 07:12:35 2010 +0000
Committer:  David S. Miller <davem@davemloft.net>
CommitDate: Fri Apr 23 16:20:25 2010 -0700

    fsl_pq_mdio: Fix kernel oops during OF address translation
    
    Old P1020RDB device trees were not specifing tbipa address for
    MDIO nodes, which is now causing this kernel oops:
    
     ...
     eth2: TX BD ring size for Q[6]: 256
     eth2: TX BD ring size for Q[7]: 256
     Unable to handle kernel paging request for data at address 0x00000000
     Faulting instruction address: 0xc0015504
     Oops: Kernel access of bad area, sig: 11 [#1]
     ...
     NIP [c0015504] memcpy+0x3c/0x9c
     LR [c000a9f8] __of_translate_address+0xfc/0x21c
     Call Trace:
     [df839e00] [c000a94c] __of_translate_address+0x50/0x21c (unreliable)
     [df839e50] [c01a33e8] get_gfar_tbipa+0xb0/0xe0
     ...
    
    The old device trees are buggy, though having a dead ethernet is
    better than a dead kernel, so fix the issue by using of_iomap().
    
    Also, a somewhat similar issue exist in the probe() routine, though
    there the oops is only a possibility. Nonetheless, fix it too.
    
    Signed-off-by: Anton Vorontsov <avorontsov@mvista.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
---
 drivers/net/fsl_pq_mdio.c |   20 ++++++++++++++------
 1 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c
index d5160ed..3acac5f 100644
--- a/drivers/net/fsl_pq_mdio.c
+++ b/drivers/net/fsl_pq_mdio.c
@@ -205,8 +205,6 @@ static int fsl_pq_mdio_find_free(struct mii_bus *new_bus)
 static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs, struct device_node *np)
 {
 	struct gfar __iomem *enet_regs;
-	u32 __iomem *ioremap_tbipa;
-	u64 addr, size;
 
 	/*
 	 * This is mildly evil, but so is our hardware for doing this.
@@ -220,9 +218,7 @@ static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs, struct devi
 		return &enet_regs->tbipa;
 	} else if (of_device_is_compatible(np, "fsl,etsec2-mdio") ||
 			of_device_is_compatible(np, "fsl,etsec2-tbi")) {
-		addr = of_translate_address(np, of_get_address(np, 1, &size, NULL));
-		ioremap_tbipa = ioremap(addr, size);
-		return ioremap_tbipa;
+		return of_iomap(np, 1);
 	} else
 		return NULL;
 }
@@ -279,6 +275,7 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev,
 	u32 __iomem *tbipa;
 	struct mii_bus *new_bus;
 	int tbiaddr = -1;
+	const u32 *addrp;
 	u64 addr = 0, size = 0;
 	int err = 0;
 
@@ -297,8 +294,19 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev,
 	new_bus->priv = priv;
 	fsl_pq_mdio_bus_name(new_bus->id, np);
 
+	addrp = of_get_address(np, 0, &size, NULL);
+	if (!addrp) {
+		err = -EINVAL;
+		goto err_free_bus;
+	}
+
 	/* Set the PHY base address */
-	addr = of_translate_address(np, of_get_address(np, 0, &size, NULL));
+	addr = of_translate_address(np, addrp);
+	if (addr == OF_BAD_ADDR) {
+		err = -EINVAL;
+		goto err_free_bus;
+	}
+
 	map = ioremap(addr, size);
 	if (!map) {
 		err = -ENOMEM;
--
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
fsl_pq_mdio: Fix kernel oops during OF address translation, Linux Kernel Mailing ..., (Sat Apr 24, 3:59 pm)