diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-07-18 18:05:22 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-07-18 18:05:22 -0400 |
| commit | 2044f2282d7558c765270d78e19dbdcf6190ca71 (patch) | |
| tree | 03b2c4d211fa8e7e2ef8c489d28a16442f030d57 /drivers/pci/setup-res.c | |
| parent | bea9a6d239cb2aa2ced4dcb0a05e1827ce61fa3d (diff) | |
| parent | 58c84eda07560a6b75b03e8d3b26d6eddfc14011 (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6:
PCI: fall back to original BIOS BAR addresses
Diffstat (limited to 'drivers/pci/setup-res.c')
| -rw-r--r-- | drivers/pci/setup-res.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 92379e2d37e7..2aaa13150de3 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, | |||
| 156 | pcibios_align_resource, dev); | 156 | pcibios_align_resource, dev); |
| 157 | } | 157 | } |
| 158 | 158 | ||
| 159 | if (ret < 0 && dev->fw_addr[resno]) { | ||
| 160 | struct resource *root, *conflict; | ||
| 161 | resource_size_t start, end; | ||
| 162 | |||
| 163 | /* | ||
| 164 | * If we failed to assign anything, let's try the address | ||
| 165 | * where firmware left it. That at least has a chance of | ||
| 166 | * working, which is better than just leaving it disabled. | ||
| 167 | */ | ||
| 168 | |||
| 169 | if (res->flags & IORESOURCE_IO) | ||
| 170 | root = &ioport_resource; | ||
| 171 | else | ||
| 172 | root = &iomem_resource; | ||
| 173 | |||
| 174 | start = res->start; | ||
| 175 | end = res->end; | ||
| 176 | res->start = dev->fw_addr[resno]; | ||
| 177 | res->end = res->start + size - 1; | ||
| 178 | dev_info(&dev->dev, "BAR %d: trying firmware assignment %pR\n", | ||
| 179 | resno, res); | ||
| 180 | conflict = request_resource_conflict(root, res); | ||
| 181 | if (conflict) { | ||
| 182 | dev_info(&dev->dev, | ||
| 183 | "BAR %d: %pR conflicts with %s %pR\n", resno, | ||
| 184 | res, conflict->name, conflict); | ||
| 185 | res->start = start; | ||
| 186 | res->end = end; | ||
| 187 | } else | ||
| 188 | ret = 0; | ||
| 189 | } | ||
| 190 | |||
| 159 | if (!ret) { | 191 | if (!ret) { |
| 160 | res->flags &= ~IORESOURCE_STARTALIGN; | 192 | res->flags &= ~IORESOURCE_STARTALIGN; |
| 161 | dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res); | 193 | dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res); |
