diff options
Diffstat (limited to 'drivers/pci/setup-res.c')
| -rw-r--r-- | drivers/pci/setup-res.c | 49 |
1 files changed, 36 insertions, 13 deletions
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 12403516776a..b711fb7181e2 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
| @@ -135,23 +135,16 @@ void pci_disable_bridge_window(struct pci_dev *dev) | |||
| 135 | } | 135 | } |
| 136 | #endif /* CONFIG_PCI_QUIRKS */ | 136 | #endif /* CONFIG_PCI_QUIRKS */ |
| 137 | 137 | ||
| 138 | int pci_assign_resource(struct pci_dev *dev, int resno) | 138 | static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, |
| 139 | int resno) | ||
| 139 | { | 140 | { |
| 140 | struct pci_bus *bus = dev->bus; | ||
| 141 | struct resource *res = dev->resource + resno; | 141 | struct resource *res = dev->resource + resno; |
| 142 | resource_size_t size, min, align; | 142 | resource_size_t size, min, align; |
| 143 | int ret; | 143 | int ret; |
| 144 | 144 | ||
| 145 | size = resource_size(res); | 145 | size = resource_size(res); |
| 146 | min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM; | 146 | min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM; |
| 147 | |||
| 148 | align = resource_alignment(res); | 147 | align = resource_alignment(res); |
| 149 | if (!align) { | ||
| 150 | dev_info(&dev->dev, "BAR %d: can't allocate resource (bogus " | ||
| 151 | "alignment) %pR flags %#lx\n", | ||
| 152 | resno, res, res->flags); | ||
| 153 | return -EINVAL; | ||
| 154 | } | ||
| 155 | 148 | ||
| 156 | /* First, try exact prefetching match.. */ | 149 | /* First, try exact prefetching match.. */ |
| 157 | ret = pci_bus_alloc_resource(bus, res, size, align, min, | 150 | ret = pci_bus_alloc_resource(bus, res, size, align, min, |
| @@ -169,10 +162,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
| 169 | pcibios_align_resource, dev); | 162 | pcibios_align_resource, dev); |
| 170 | } | 163 | } |
| 171 | 164 | ||
| 172 | if (ret) { | 165 | if (!ret) { |
| 173 | dev_info(&dev->dev, "BAR %d: can't allocate %s resource %pR\n", | ||
| 174 | resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res); | ||
| 175 | } else { | ||
| 176 | res->flags &= ~IORESOURCE_STARTALIGN; | 166 | res->flags &= ~IORESOURCE_STARTALIGN; |
| 177 | if (resno < PCI_BRIDGE_RESOURCES) | 167 | if (resno < PCI_BRIDGE_RESOURCES) |
| 178 | pci_update_resource(dev, resno); | 168 | pci_update_resource(dev, resno); |
| @@ -181,6 +171,39 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
| 181 | return ret; | 171 | return ret; |
| 182 | } | 172 | } |
| 183 | 173 | ||
| 174 | int pci_assign_resource(struct pci_dev *dev, int resno) | ||
| 175 | { | ||
| 176 | struct resource *res = dev->resource + resno; | ||
| 177 | resource_size_t align; | ||
| 178 | struct pci_bus *bus; | ||
| 179 | int ret; | ||
| 180 | |||
| 181 | align = resource_alignment(res); | ||
| 182 | if (!align) { | ||
| 183 | dev_info(&dev->dev, "BAR %d: can't allocate resource (bogus " | ||
| 184 | "alignment) %pR flags %#lx\n", | ||
| 185 | resno, res, res->flags); | ||
| 186 | return -EINVAL; | ||
| 187 | } | ||
| 188 | |||
| 189 | bus = dev->bus; | ||
| 190 | while ((ret = __pci_assign_resource(bus, dev, resno))) { | ||
| 191 | if (bus->parent && bus->self->transparent) | ||
| 192 | bus = bus->parent; | ||
| 193 | else | ||
| 194 | bus = NULL; | ||
| 195 | if (bus) | ||
| 196 | continue; | ||
| 197 | break; | ||
| 198 | } | ||
| 199 | |||
| 200 | if (ret) | ||
| 201 | dev_info(&dev->dev, "BAR %d: can't allocate %s resource %pR\n", | ||
| 202 | resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res); | ||
| 203 | |||
| 204 | return ret; | ||
| 205 | } | ||
| 206 | |||
| 184 | #if 0 | 207 | #if 0 |
| 185 | int pci_assign_resource_fixed(struct pci_dev *dev, int resno) | 208 | int pci_assign_resource_fixed(struct pci_dev *dev, int resno) |
| 186 | { | 209 | { |
