aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/probe.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/probe.c')
-rw-r--r--drivers/pci/probe.c87
1 files changed, 41 insertions, 46 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 9ab492f21f86..795c9026d55f 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -68,21 +68,6 @@ static int __init pcibus_class_init(void)
68} 68}
69postcore_initcall(pcibus_class_init); 69postcore_initcall(pcibus_class_init);
70 70
71/*
72 * Translate the low bits of the PCI base
73 * to the resource type
74 */
75static inline unsigned int pci_calc_resource_flags(unsigned int flags)
76{
77 if (flags & PCI_BASE_ADDRESS_SPACE_IO)
78 return IORESOURCE_IO;
79
80 if (flags & PCI_BASE_ADDRESS_MEM_PREFETCH)
81 return IORESOURCE_MEM | IORESOURCE_PREFETCH;
82
83 return IORESOURCE_MEM;
84}
85
86static u64 pci_size(u64 base, u64 maxbase, u64 mask) 71static u64 pci_size(u64 base, u64 maxbase, u64 mask)
87{ 72{
88 u64 size = mask & maxbase; /* Find the significant bits */ 73 u64 size = mask & maxbase; /* Find the significant bits */
@@ -101,18 +86,39 @@ static u64 pci_size(u64 base, u64 maxbase, u64 mask)
101 return size; 86 return size;
102} 87}
103 88
104static inline enum pci_bar_type decode_bar(struct resource *res, u32 bar) 89static inline unsigned long decode_bar(struct pci_dev *dev, u32 bar)
105{ 90{
91 u32 mem_type;
92 unsigned long flags;
93
106 if ((bar & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) { 94 if ((bar & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) {
107 res->flags = bar & ~PCI_BASE_ADDRESS_IO_MASK; 95 flags = bar & ~PCI_BASE_ADDRESS_IO_MASK;
108 return pci_bar_io; 96 flags |= IORESOURCE_IO;
97 return flags;
109 } 98 }
110 99
111 res->flags = bar & ~PCI_BASE_ADDRESS_MEM_MASK; 100 flags = bar & ~PCI_BASE_ADDRESS_MEM_MASK;
101 flags |= IORESOURCE_MEM;
102 if (flags & PCI_BASE_ADDRESS_MEM_PREFETCH)
103 flags |= IORESOURCE_PREFETCH;
112 104
113 if (res->flags & PCI_BASE_ADDRESS_MEM_TYPE_64) 105 mem_type = bar & PCI_BASE_ADDRESS_MEM_TYPE_MASK;
114 return pci_bar_mem64; 106 switch (mem_type) {
115 return pci_bar_mem32; 107 case PCI_BASE_ADDRESS_MEM_TYPE_32:
108 break;
109 case PCI_BASE_ADDRESS_MEM_TYPE_1M:
110 dev_info(&dev->dev, "1M mem BAR treated as 32-bit BAR\n");
111 break;
112 case PCI_BASE_ADDRESS_MEM_TYPE_64:
113 flags |= IORESOURCE_MEM_64;
114 break;
115 default:
116 dev_warn(&dev->dev,
117 "mem unknown type %x treated as 32-bit BAR\n",
118 mem_type);
119 break;
120 }
121 return flags;
116} 122}
117 123
118/** 124/**
@@ -165,9 +171,9 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
165 l = 0; 171 l = 0;
166 172
167 if (type == pci_bar_unknown) { 173 if (type == pci_bar_unknown) {
168 type = decode_bar(res, l); 174 res->flags = decode_bar(dev, l);
169 res->flags |= pci_calc_resource_flags(l) | IORESOURCE_SIZEALIGN; 175 res->flags |= IORESOURCE_SIZEALIGN;
170 if (type == pci_bar_io) { 176 if (res->flags & IORESOURCE_IO) {
171 l &= PCI_BASE_ADDRESS_IO_MASK; 177 l &= PCI_BASE_ADDRESS_IO_MASK;
172 mask = PCI_BASE_ADDRESS_IO_MASK & (u32) IO_SPACE_LIMIT; 178 mask = PCI_BASE_ADDRESS_IO_MASK & (u32) IO_SPACE_LIMIT;
173 } else { 179 } else {
@@ -180,7 +186,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
180 mask = (u32)PCI_ROM_ADDRESS_MASK; 186 mask = (u32)PCI_ROM_ADDRESS_MASK;
181 } 187 }
182 188
183 if (type == pci_bar_mem64) { 189 if (res->flags & IORESOURCE_MEM_64) {
184 u64 l64 = l; 190 u64 l64 = l;
185 u64 sz64 = sz; 191 u64 sz64 = sz;
186 u64 mask64 = mask | (u64)~0 << 32; 192 u64 mask64 = mask | (u64)~0 << 32;
@@ -204,7 +210,6 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
204 goto fail; 210 goto fail;
205 } 211 }
206 212
207 res->flags |= IORESOURCE_MEM_64;
208 if ((sizeof(resource_size_t) < 8) && l) { 213 if ((sizeof(resource_size_t) < 8) && l) {
209 /* Address above 32-bit boundary; disable the BAR */ 214 /* Address above 32-bit boundary; disable the BAR */
210 pci_write_config_dword(dev, pos, 0); 215 pci_write_config_dword(dev, pos, 0);
@@ -230,7 +235,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
230 } 235 }
231 236
232 out: 237 out:
233 return (type == pci_bar_mem64) ? 1 : 0; 238 return (res->flags & IORESOURCE_MEM_64) ? 1 : 0;
234 fail: 239 fail:
235 res->flags = 0; 240 res->flags = 0;
236 goto out; 241 goto out;
@@ -284,10 +289,6 @@ static void __devinit pci_read_bridge_io(struct pci_bus *child)
284 if (!res->end) 289 if (!res->end)
285 res->end = limit + 0xfff; 290 res->end = limit + 0xfff;
286 dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); 291 dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res);
287 } else {
288 dev_printk(KERN_DEBUG, &dev->dev,
289 " bridge window [io %#06lx-%#06lx] (disabled)\n",
290 base, limit);
291 } 292 }
292} 293}
293 294
@@ -308,10 +309,6 @@ static void __devinit pci_read_bridge_mmio(struct pci_bus *child)
308 res->start = base; 309 res->start = base;
309 res->end = limit + 0xfffff; 310 res->end = limit + 0xfffff;
310 dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); 311 dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res);
311 } else {
312 dev_printk(KERN_DEBUG, &dev->dev,
313 " bridge window [mem %#010lx-%#010lx] (disabled)\n",
314 base, limit + 0xfffff);
315 } 312 }
316} 313}
317 314
@@ -359,10 +356,6 @@ static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child)
359 res->start = base; 356 res->start = base;
360 res->end = limit + 0xfffff; 357 res->end = limit + 0xfffff;
361 dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); 358 dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res);
362 } else {
363 dev_printk(KERN_DEBUG, &dev->dev,
364 " bridge window [mem %#010lx-%#010lx pref] (disabled)\n",
365 base, limit + 0xfffff);
366 } 359 }
367} 360}
368 361
@@ -725,12 +718,14 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
725 pci_write_config_word(dev, PCI_STATUS, 0xffff); 718 pci_write_config_word(dev, PCI_STATUS, 0xffff);
726 719
727 /* Prevent assigning a bus number that already exists. 720 /* Prevent assigning a bus number that already exists.
728 * This can happen when a bridge is hot-plugged */ 721 * This can happen when a bridge is hot-plugged, so in
729 if (pci_find_bus(pci_domain_nr(bus), max+1)) 722 * this case we only re-scan this bus. */
730 goto out; 723 child = pci_find_bus(pci_domain_nr(bus), max+1);
731 child = pci_add_new_bus(bus, dev, ++max); 724 if (!child) {
732 if (!child) 725 child = pci_add_new_bus(bus, dev, ++max);
733 goto out; 726 if (!child)
727 goto out;
728 }
734 buses = (buses & 0xff000000) 729 buses = (buses & 0xff000000)
735 | ((unsigned int)(child->primary) << 0) 730 | ((unsigned int)(child->primary) << 0)
736 | ((unsigned int)(child->secondary) << 8) 731 | ((unsigned int)(child->secondary) << 8)