From patchwork Fri Jul 16 21:56:42 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jesse Barnes X-Patchwork-Id: 112498 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.4/8.14.3) with ESMTP id o6GLv0nj003112 for ; Fri, 16 Jul 2010 21:57:00 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755447Ab0GPV4n (ORCPT ); Fri, 16 Jul 2010 17:56:43 -0400 Received: from cpoproxy2-pub.bluehost.com ([67.222.39.38]:50423 "HELO cpoproxy2-pub.bluehost.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1751400Ab0GPV4n (ORCPT ); Fri, 16 Jul 2010 17:56:43 -0400 Received: (qmail 6731 invoked by uid 0); 16 Jul 2010 21:56:42 -0000 Received: from unknown (HELO box514.bluehost.com) (74.220.219.114) by cpoproxy2.bluehost.com with SMTP; 16 Jul 2010 21:56:42 -0000 DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=virtuousgeek.org; h=Received:Date:From:To:Cc:Subject:Message-ID:X-Mailer:Mime-Version:Content-Type:Content-Transfer-Encoding:X-Identified-User; b=C3DJjXFSGAAblAWWWV1zL4t77QwdAZlmVkNStZ2o5thdyAS2x41bOnKctkh4IWDW2CVQNofSdPHTVtcz85u0nnx/r0fHXYAD1LZkY4GzdPeBDKgFo9KvvjgdPjKxbYqV; Received: from [75.110.194.140] (helo=localhost) by box514.bluehost.com with esmtpsa (TLSv1:AES128-SHA:128) (Exim 4.69) (envelope-from ) id 1OZstd-0002gy-US; Fri, 16 Jul 2010 15:56:42 -0600 Date: Fri, 16 Jul 2010 14:56:42 -0700 From: Jesse Barnes To: Linus Torvalds Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [git pull] PCI fix Message-ID: <20100716145642.73398601@virtuousgeek.org> X-Mailer: Claws Mail 3.7.6 (GTK+ 2.18.9; x86_64-redhat-linux-gnu) Mime-Version: 1.0 X-Identified-User: {10642:box514.bluehost.com:virtuous:virtuousgeek.org} {sentby:smtp auth 75.110.194.140 authed with jbarnes@virtuousgeek.org} Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Fri, 16 Jul 2010 21:57:00 +0000 (UTC) diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index 6fdb3ec..5525309 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c @@ -184,6 +184,7 @@ static void __init pcibios_allocate_resources(int pass) idx, r, disabled, pass); if (pci_claim_resource(dev, idx) < 0) { /* We'll assign a new address later */ + dev->fw_addr[idx] = r->start; r->end -= r->start; r->start = 0; } diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 92379e2..2aaa131 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c @@ -156,6 +156,38 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, pcibios_align_resource, dev); } + if (ret < 0 && dev->fw_addr[resno]) { + struct resource *root, *conflict; + resource_size_t start, end; + + /* + * If we failed to assign anything, let's try the address + * where firmware left it. That at least has a chance of + * working, which is better than just leaving it disabled. + */ + + if (res->flags & IORESOURCE_IO) + root = &ioport_resource; + else + root = &iomem_resource; + + start = res->start; + end = res->end; + res->start = dev->fw_addr[resno]; + res->end = res->start + size - 1; + dev_info(&dev->dev, "BAR %d: trying firmware assignment %pR\n", + resno, res); + conflict = request_resource_conflict(root, res); + if (conflict) { + dev_info(&dev->dev, + "BAR %d: %pR conflicts with %s %pR\n", resno, + res, conflict->name, conflict); + res->start = start; + res->end = end; + } else + ret = 0; + } + if (!ret) { res->flags &= ~IORESOURCE_STARTALIGN; dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res); diff --git a/include/linux/pci.h b/include/linux/pci.h index 7cb0084..f26fda7 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -288,6 +288,7 @@ struct pci_dev { */ unsigned int irq; struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */ + resource_size_t fw_addr[DEVICE_COUNT_RESOURCE]; /* FW-assigned addr */ /* These fields are used by common fixups */ unsigned int transparent:1; /* Transparent PCI bridge */