From patchwork Sat Mar 14 14:43:07 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Friedrich Oslage X-Patchwork-Id: 24452 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by ozlabs.org (Postfix) with ESMTP id 2CCB7DDFA4 for ; Sun, 15 Mar 2009 01:43:16 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754126AbZCNOnQ (ORCPT ); Sat, 14 Mar 2009 10:43:16 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754712AbZCNOnP (ORCPT ); Sat, 14 Mar 2009 10:43:15 -0400 Received: from v32062.1blu.de ([88.84.153.122]:43863 "EHLO v32062.1blu.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754126AbZCNOnP (ORCPT ); Sat, 14 Mar 2009 10:43:15 -0400 Received: from ppp-62-216-217-174.dynamic.mnet-online.de ([62.216.217.174] helo=[10.254.3.50]) by v32062.1blu.de with esmtpsa (TLSv1:AES256-SHA:256) (Exim 4.69) (envelope-from ) id 1LiV4t-0003i8-Tq; Sat, 14 Mar 2009 15:43:10 +0100 Message-ID: <49BBC27B.4050200@gentoo.org> Date: Sat, 14 Mar 2009 15:43:07 +0100 From: Friedrich Oslage Reply-To: bluebird@gentoo.org User-Agent: Thunderbird 2.0.0.19 (X11/20090104) MIME-Version: 1.0 To: Meelis Roos CC: sparclinux@vger.kernel.org, David Miller Subject: Re: Ultra1 ESP detection problem References: In-Reply-To: X-Enigmail-Version: 0.95.7 Sender: sparclinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: sparclinux@vger.kernel.org Meelis Roos schrieb: > [ 60.565134] esp: probe of f0062a74 failed with error -12 I can reproduce this on my Ultra 2. I didn't notice it until now because the boot disk is attached to an hme esp(which still works). In esp_sbus_map_regs the of_ioremap call failes because res->start is 0 for non hme cards. Basicly your tree looks like this: SUNW,Ultra-1 sbus SUNW,fas espdma esp Of_bus_sbus_match works for "SUNW,fas" but not for "esp" because it only checks the direct parent and not the parent's parent for name == "sbus". This makes the kernel use of_bus_default_count_cells to calculate the resources for "esp" instead of of_bus_sbus_count_cells. And since of_bus_default_count_cells doesn't work for sbus systems the resources of "esp" aren't detected. I attached a patch, let me know if it works for you. Cheers, Friedrich sparc: of_bus_sbus_match must also check the parent's parents. To determine wheter the bus is sbus not only the direct parent but all the parents of the parent must be checked, too. In a tree like this SUNW,Ultra-2 sbus SUNW,hme SUNW,fas dma/espdma esp only checking the direct parent would make of_match_bus use of_bus_default_count_cells for "esp", instead of the desired of_bus_sbus_count_cells, and return an incorrect cell count. Which, in this case, would make allocating resources for "esp" fail. Reported-by: Meelis Roos Signed-off-by: Friedrich Oslage --- arch/sparc/kernel/of_device_32.c | 13 +++++++++++-- arch/sparc/kernel/of_device_64.c | 13 +++++++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c index 0a83bd7..bee16a5 100644 --- a/arch/sparc/kernel/of_device_32.c +++ b/arch/sparc/kernel/of_device_32.c @@ -246,8 +246,17 @@ static unsigned long of_bus_pci_get_flags(const u32 *addr, unsigned long flags) static int of_bus_sbus_match(struct device_node *np) { - return !strcmp(np->name, "sbus") || - !strcmp(np->name, "sbi"); + /* return true if the direct parent or any of the parent's parents is + * "sbus" or "sbi" + */ + struct device_node *dp = np; + + do { + if (!strcmp(dp->name, "sbus") || !strcmp(dp->name, "sbi")) + return 1; + } while ((dp = dp->parent)); + + return 0; } static void of_bus_sbus_count_cells(struct device_node *child, diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c index b4a12c9..7a27cfd 100644 --- a/arch/sparc/kernel/of_device_64.c +++ b/arch/sparc/kernel/of_device_64.c @@ -301,8 +301,17 @@ static unsigned long of_bus_pci_get_flags(const u32 *addr, unsigned long flags) static int of_bus_sbus_match(struct device_node *np) { - return !strcmp(np->name, "sbus") || - !strcmp(np->name, "sbi"); + /* return true if the direct parent or any of the parent's parents is + * "sbus" or "sbi" + */ + struct device_node *dp = np; + + do { + if (!strcmp(dp->name, "sbus") || !strcmp(dp->name, "sbi")) + return 1; + } while ((dp = dp->parent)); + + return 0; } static void of_bus_sbus_count_cells(struct device_node *child,