aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/setup-bus.c1
-rw-r--r--drivers/pci/setup-res.c49
2 files changed, 36 insertions, 14 deletions
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index e1c360a5b0db..b636e245445d 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -58,7 +58,6 @@ static void pbus_assign_resources_sorted(const struct pci_bus *bus)
58 res = list->res; 58 res = list->res;
59 idx = res - &list->dev->resource[0]; 59 idx = res - &list->dev->resource[0];
60 if (pci_assign_resource(list->dev, idx)) { 60 if (pci_assign_resource(list->dev, idx)) {
61 /* FIXME: get rid of this */
62 res->start = 0; 61 res->start = 0;
63 res->end = 0; 62 res->end = 0;
64 res->flags = 0; 63 res->flags = 0;
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index 3039fcb86afc..0b6908b48935 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
138int pci_assign_resource(struct pci_dev *dev, int resno) 138static 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
174int 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
185int pci_assign_resource_fixed(struct pci_dev *dev, int resno) 208int pci_assign_resource_fixed(struct pci_dev *dev, int resno)
186{ 209{