From patchwork Sun Sep 14 22:10:27 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Noever X-Patchwork-Id: 389137 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 507D11400D5 for ; Mon, 15 Sep 2014 08:10:45 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752855AbaINWKo (ORCPT ); Sun, 14 Sep 2014 18:10:44 -0400 Received: from mail-we0-f180.google.com ([74.125.82.180]:53622 "EHLO mail-we0-f180.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752832AbaINWKn (ORCPT ); Sun, 14 Sep 2014 18:10:43 -0400 Received: by mail-we0-f180.google.com with SMTP id t60so3072451wes.39 for ; Sun, 14 Sep 2014 15:10:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=QpQ59WqDyQEfSE6LlEmpOM5m5JPbVv1IkwdRaphVfJ0=; b=niH6K6LTUnh+fa18QCUwm9SEZVhtEJEFCTnU5Q64LojtC60E3l0zqWaeS8xRJea0lo 45xNKTNZRiY15jADycmpykXNok5IouE+q5MtC4IkB/XNVk3tjhXND5qyAqRyM8bHAxX5 xfvfBSEnxuUjbExcNY0SFMYZJLDxdFYSbG7ShQX2RKrKK+T92rlVicwxOhvjHDxE/f6B J0hgiVr5JOZSGCr+G65yip8Q/CUTG/Cn8mtAWwM6bWZm0liVB5GO1QIG2SEx645sHmhD 3y3DLUpWNkYfCH11juzn0SBbhO0sUAbuOVQSSPFLnpL2UbtP4PTvN93gH33Fn9zvKwvB XHqA== X-Received: by 10.180.108.176 with SMTP id hl16mr18754247wib.4.1410732642330; Sun, 14 Sep 2014 15:10:42 -0700 (PDT) Received: from linuxbook.localdomain (77-58-151-250.dclient.hispeed.ch. [77.58.151.250]) by mx.google.com with ESMTPSA id ky3sm12604980wjb.39.2014.09.14.15.10.40 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 14 Sep 2014 15:10:41 -0700 (PDT) From: Andreas Noever To: Bjorn Helgaas Cc: Andreas Noever , David Henningsson , "linux-pci@vger.kernel.org" , Thomas Richter Subject: Re: [PATCH] Add pci=assign-busses quirk to Dell Latitude D505 Date: Mon, 15 Sep 2014 00:10:27 +0200 Message-Id: <1410732627-25445-1-git-send-email-andreas.noever@gmail.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <20140913031818.GA25656@google.com> References: <20140913031818.GA25656@google.com> Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org [+cc Thomas, your regression has probably the same cause] This looks a like it is going to be a little more complicated than anticipated. pci_scan_bus has two main branches. One for "broken" hardware and cardbus and another one for bridges whose configuration looks sane. David's working 3.2 Kernel does the following: pci 0000:00:1e.0: PCI bridge to [bus 01-01] (subtractive decode) pci 0000:01:01.0: bridge configuration invalid ([bus 00-00]), reconfiguring The 00:1e bridge is deemed sane and the 01:01 (cardbus) bridge below it is deemed broken. pci_scan_bridge than assigns bus [2-5] to 01:01 without touching 1e (so we just got 4 imaginary busses). We just print a warning: pci_bus 0000:02: [bus 02-05] partially hidden behind transparent bridge 0000:01 [bus 01-01] After returning to 00:1e (in the sane branch) we also do not update our subordinate and just return. Later yenta_socket sees that this is nuts and carefully increases the subordinate of 00:1e. My patch series for 3.15 was trying to make sure that pci_scan_bus does not overstep its resources. So now we now refuse to create bus 2 under [01-01] (fc1b2531 PCI: Don't scan random busses in pci_scan_bridge()) and a little later we would forbid the cardbus code in pci_scan_bridge from reserving 4 more busses (1820ffdc PCI: Make sure bus number resources stay within their parents bounds). At least these two would need to be reverted. As an alternative the following patch tries grow the bus window, if necessary by growing its parents bus window (recursively). This should make the yenta fixup unnecessary. I have tested the patch with normal pci bridges + setpci, since I don't have access to a cardbus system. So if you have time please test this and/or try to revert the two mentioned commits. Thanks, Andreas --- drivers/pci/probe.c | 45 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index e3cf8a2..81dd668 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -740,6 +740,30 @@ struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, } EXPORT_SYMBOL(pci_add_new_bus); +int pci_grow_bus(struct pci_bus *bus, int bus_max) +{ + struct resource *res = &bus->busn_res; + struct resource old_res = *res; + int ret; + if (res->end >= bus_max) + return 0; + if (!bus->self || pci_is_root_bus(bus)) { + dev_printk(KERN_DEBUG, &bus->dev, + "root busn_res %pR cannot grow\n", &res); + return -EBUSY; + } + ret = pci_grow_bus(bus->parent, bus_max); + if (ret) + return ret; + ret = adjust_resource(res, res->start, bus_max - res->start + 1); + dev_printk(KERN_DEBUG, &bus->dev, + "busn_res: %pR end %s grown to %02x\n", + &old_res, ret ? "cannot be" : "has", bus_max); + + pci_write_config_byte(bus->self, PCI_SUBORDINATE_BUS, bus_max); + return ret; +} + /* * If it's a bridge, configure it and scan the bus behind it. * For CardBus bridges, we don't scan behind as the devices will @@ -814,12 +838,11 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass) } cmax = pci_scan_child_bus(child); - if (cmax > subordinate) - dev_warn(&dev->dev, "bridge has subordinate %02x but max busn %02x\n", - subordinate, cmax); - /* subordinate should equal child->busn_res.end */ - if (subordinate > max) - max = subordinate; + if (cmax > child->busn_res.end) + dev_warn(&dev->dev, "bridge has bus resource %pR but max busn %02x\n", + &child->busn_res, cmax); + if (child->busn_res.end > max) + max = child->busn_res.end; } else { /* * We need to assign a number to this bus which we always @@ -840,8 +863,10 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass) if (max >= bus->busn_res.end) { dev_warn(&dev->dev, "can't allocate child bus %02x from %pR\n", - max, &bus->busn_res); - goto out; + max + 1, &bus->busn_res); + /* Try to resize bus */ + if (pci_grow_bus(bus, max + 1)) + goto out; } /* Clear errors */ @@ -908,6 +933,7 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass) break; } } + dev_info(&dev->dev, "adding %02x bus numbers for cardbus\n", i); max += i; } /* @@ -916,7 +942,8 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, int pass) if (max > bus->busn_res.end) { dev_warn(&dev->dev, "max busn %02x is outside %pR\n", max, &bus->busn_res); - max = bus->busn_res.end; + if (pci_grow_bus(bus, max)) + max = bus->busn_res.end; } pci_bus_update_busn_res_end(child, max); pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max);