diff options
Diffstat (limited to 'arch/x86/pci')
-rw-r--r-- | arch/x86/pci/acpi.c | 11 | ||||
-rw-r--r-- | arch/x86/pci/common.c | 63 | ||||
-rw-r--r-- | arch/x86/pci/i386.c | 38 | ||||
-rw-r--r-- | arch/x86/pci/pcbios.c | 72 | ||||
-rw-r--r-- | arch/x86/pci/pci.h | 4 |
5 files changed, 6 insertions, 182 deletions
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 378136fb5044..2664cb3fc96c 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c | |||
@@ -151,7 +151,7 @@ adjust_transparent_bridge_resources(struct pci_bus *bus) | |||
151 | 151 | ||
152 | static void | 152 | static void |
153 | get_current_resources(struct acpi_device *device, int busnum, | 153 | get_current_resources(struct acpi_device *device, int busnum, |
154 | struct pci_bus *bus) | 154 | int domain, struct pci_bus *bus) |
155 | { | 155 | { |
156 | struct pci_root_info info; | 156 | struct pci_root_info info; |
157 | size_t size; | 157 | size_t size; |
@@ -168,10 +168,10 @@ get_current_resources(struct acpi_device *device, int busnum, | |||
168 | if (!info.res) | 168 | if (!info.res) |
169 | goto res_alloc_fail; | 169 | goto res_alloc_fail; |
170 | 170 | ||
171 | info.name = kmalloc(12, GFP_KERNEL); | 171 | info.name = kmalloc(16, GFP_KERNEL); |
172 | if (!info.name) | 172 | if (!info.name) |
173 | goto name_alloc_fail; | 173 | goto name_alloc_fail; |
174 | sprintf(info.name, "PCI Bus #%02x", busnum); | 174 | sprintf(info.name, "PCI Bus %04x:%02x", domain, busnum); |
175 | 175 | ||
176 | info.res_num = 0; | 176 | info.res_num = 0; |
177 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource, | 177 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource, |
@@ -247,7 +247,7 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do | |||
247 | #endif | 247 | #endif |
248 | 248 | ||
249 | if (bus && (pci_probe & PCI_USE__CRS)) | 249 | if (bus && (pci_probe & PCI_USE__CRS)) |
250 | get_current_resources(device, busnum, bus); | 250 | get_current_resources(device, busnum, domain, bus); |
251 | 251 | ||
252 | return bus; | 252 | return bus; |
253 | } | 253 | } |
@@ -278,8 +278,7 @@ static int __init pci_acpi_init(void) | |||
278 | printk(KERN_INFO "PCI: Routing PCI interrupts for all devices because \"pci=routeirq\" specified\n"); | 278 | printk(KERN_INFO "PCI: Routing PCI interrupts for all devices because \"pci=routeirq\" specified\n"); |
279 | for_each_pci_dev(dev) | 279 | for_each_pci_dev(dev) |
280 | acpi_pci_irq_enable(dev); | 280 | acpi_pci_irq_enable(dev); |
281 | } else | 281 | } |
282 | printk(KERN_INFO "PCI: If a device doesn't work, try \"pci=routeirq\". If it helps, post a report\n"); | ||
283 | 282 | ||
284 | #ifdef CONFIG_X86_IO_APIC | 283 | #ifdef CONFIG_X86_IO_APIC |
285 | if (acpi_ioapic) | 284 | if (acpi_ioapic) |
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index 7b6e3bb9b28c..75fcc29ecf52 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c | |||
@@ -77,59 +77,6 @@ int pcibios_scanned; | |||
77 | */ | 77 | */ |
78 | DEFINE_SPINLOCK(pci_config_lock); | 78 | DEFINE_SPINLOCK(pci_config_lock); |
79 | 79 | ||
80 | /* | ||
81 | * Several buggy motherboards address only 16 devices and mirror | ||
82 | * them to next 16 IDs. We try to detect this `feature' on all | ||
83 | * primary buses (those containing host bridges as they are | ||
84 | * expected to be unique) and remove the ghost devices. | ||
85 | */ | ||
86 | |||
87 | static void __devinit pcibios_fixup_ghosts(struct pci_bus *b) | ||
88 | { | ||
89 | struct list_head *ln, *mn; | ||
90 | struct pci_dev *d, *e; | ||
91 | int mirror = PCI_DEVFN(16,0); | ||
92 | int seen_host_bridge = 0; | ||
93 | int i; | ||
94 | |||
95 | DBG("PCI: Scanning for ghost devices on bus %d\n", b->number); | ||
96 | list_for_each(ln, &b->devices) { | ||
97 | d = pci_dev_b(ln); | ||
98 | if ((d->class >> 8) == PCI_CLASS_BRIDGE_HOST) | ||
99 | seen_host_bridge++; | ||
100 | for (mn=ln->next; mn != &b->devices; mn=mn->next) { | ||
101 | e = pci_dev_b(mn); | ||
102 | if (e->devfn != d->devfn + mirror || | ||
103 | e->vendor != d->vendor || | ||
104 | e->device != d->device || | ||
105 | e->class != d->class) | ||
106 | continue; | ||
107 | for(i=0; i<PCI_NUM_RESOURCES; i++) | ||
108 | if (e->resource[i].start != d->resource[i].start || | ||
109 | e->resource[i].end != d->resource[i].end || | ||
110 | e->resource[i].flags != d->resource[i].flags) | ||
111 | continue; | ||
112 | break; | ||
113 | } | ||
114 | if (mn == &b->devices) | ||
115 | return; | ||
116 | } | ||
117 | if (!seen_host_bridge) | ||
118 | return; | ||
119 | printk(KERN_WARNING "PCI: Ignoring ghost devices on bus %02x\n", b->number); | ||
120 | |||
121 | ln = &b->devices; | ||
122 | while (ln->next != &b->devices) { | ||
123 | d = pci_dev_b(ln->next); | ||
124 | if (d->devfn >= mirror) { | ||
125 | list_del(&d->global_list); | ||
126 | list_del(&d->bus_list); | ||
127 | kfree(d); | ||
128 | } else | ||
129 | ln = ln->next; | ||
130 | } | ||
131 | } | ||
132 | |||
133 | static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) | 80 | static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) |
134 | { | 81 | { |
135 | struct resource *rom_r = &dev->resource[PCI_ROM_RESOURCE]; | 82 | struct resource *rom_r = &dev->resource[PCI_ROM_RESOURCE]; |
@@ -152,7 +99,6 @@ void __devinit pcibios_fixup_bus(struct pci_bus *b) | |||
152 | { | 99 | { |
153 | struct pci_dev *dev; | 100 | struct pci_dev *dev; |
154 | 101 | ||
155 | pcibios_fixup_ghosts(b); | ||
156 | pci_read_bridge_bases(b); | 102 | pci_read_bridge_bases(b); |
157 | list_for_each_entry(dev, &b->devices, bus_list) | 103 | list_for_each_entry(dev, &b->devices, bus_list) |
158 | pcibios_fixup_device_resources(dev); | 104 | pcibios_fixup_device_resources(dev); |
@@ -427,10 +373,6 @@ static int __init pcibios_init(void) | |||
427 | 373 | ||
428 | if (pci_bf_sort >= pci_force_bf) | 374 | if (pci_bf_sort >= pci_force_bf) |
429 | pci_sort_breadthfirst(); | 375 | pci_sort_breadthfirst(); |
430 | #ifdef CONFIG_PCI_BIOS | ||
431 | if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT)) | ||
432 | pcibios_sort(); | ||
433 | #endif | ||
434 | return 0; | 376 | return 0; |
435 | } | 377 | } |
436 | 378 | ||
@@ -455,9 +397,6 @@ char * __devinit pcibios_setup(char *str) | |||
455 | } else if (!strcmp(str, "nobios")) { | 397 | } else if (!strcmp(str, "nobios")) { |
456 | pci_probe &= ~PCI_PROBE_BIOS; | 398 | pci_probe &= ~PCI_PROBE_BIOS; |
457 | return NULL; | 399 | return NULL; |
458 | } else if (!strcmp(str, "nosort")) { | ||
459 | pci_probe |= PCI_NO_SORT; | ||
460 | return NULL; | ||
461 | } else if (!strcmp(str, "biosirq")) { | 400 | } else if (!strcmp(str, "biosirq")) { |
462 | pci_probe |= PCI_BIOS_IRQ_SCAN; | 401 | pci_probe |= PCI_BIOS_IRQ_SCAN; |
463 | return NULL; | 402 | return NULL; |
@@ -527,7 +466,7 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) | |||
527 | { | 466 | { |
528 | int err; | 467 | int err; |
529 | 468 | ||
530 | if ((err = pcibios_enable_resources(dev, mask)) < 0) | 469 | if ((err = pci_enable_resources(dev, mask)) < 0) |
531 | return err; | 470 | return err; |
532 | 471 | ||
533 | if (!dev->msi_enabled) | 472 | if (!dev->msi_enabled) |
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index 2ead72363077..94f6c73a53d0 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c | |||
@@ -241,44 +241,6 @@ void __init pcibios_resource_survey(void) | |||
241 | */ | 241 | */ |
242 | fs_initcall(pcibios_assign_resources); | 242 | fs_initcall(pcibios_assign_resources); |
243 | 243 | ||
244 | int pcibios_enable_resources(struct pci_dev *dev, int mask) | ||
245 | { | ||
246 | u16 cmd, old_cmd; | ||
247 | int idx; | ||
248 | struct resource *r; | ||
249 | |||
250 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | ||
251 | old_cmd = cmd; | ||
252 | for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) { | ||
253 | /* Only set up the requested stuff */ | ||
254 | if (!(mask & (1 << idx))) | ||
255 | continue; | ||
256 | |||
257 | r = &dev->resource[idx]; | ||
258 | if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM))) | ||
259 | continue; | ||
260 | if ((idx == PCI_ROM_RESOURCE) && | ||
261 | (!(r->flags & IORESOURCE_ROM_ENABLE))) | ||
262 | continue; | ||
263 | if (!r->start && r->end) { | ||
264 | printk(KERN_ERR "PCI: Device %s not available " | ||
265 | "because of resource %d collisions\n", | ||
266 | pci_name(dev), idx); | ||
267 | return -EINVAL; | ||
268 | } | ||
269 | if (r->flags & IORESOURCE_IO) | ||
270 | cmd |= PCI_COMMAND_IO; | ||
271 | if (r->flags & IORESOURCE_MEM) | ||
272 | cmd |= PCI_COMMAND_MEMORY; | ||
273 | } | ||
274 | if (cmd != old_cmd) { | ||
275 | printk("PCI: Enabling device %s (%04x -> %04x)\n", | ||
276 | pci_name(dev), old_cmd, cmd); | ||
277 | pci_write_config_word(dev, PCI_COMMAND, cmd); | ||
278 | } | ||
279 | return 0; | ||
280 | } | ||
281 | |||
282 | /* | 244 | /* |
283 | * If we set up a device for bus mastering, we need to check the latency | 245 | * If we set up a device for bus mastering, we need to check the latency |
284 | * timer as certain crappy BIOSes forget to set it properly. | 246 | * timer as certain crappy BIOSes forget to set it properly. |
diff --git a/arch/x86/pci/pcbios.c b/arch/x86/pci/pcbios.c index 2f7109ac4c15..37472fc6f729 100644 --- a/arch/x86/pci/pcbios.c +++ b/arch/x86/pci/pcbios.c | |||
@@ -152,28 +152,6 @@ static int __devinit check_pcibios(void) | |||
152 | return 0; | 152 | return 0; |
153 | } | 153 | } |
154 | 154 | ||
155 | static int __devinit pci_bios_find_device (unsigned short vendor, unsigned short device_id, | ||
156 | unsigned short index, unsigned char *bus, unsigned char *device_fn) | ||
157 | { | ||
158 | unsigned short bx; | ||
159 | unsigned short ret; | ||
160 | |||
161 | __asm__("lcall *(%%edi); cld\n\t" | ||
162 | "jc 1f\n\t" | ||
163 | "xor %%ah, %%ah\n" | ||
164 | "1:" | ||
165 | : "=b" (bx), | ||
166 | "=a" (ret) | ||
167 | : "1" (PCIBIOS_FIND_PCI_DEVICE), | ||
168 | "c" (device_id), | ||
169 | "d" (vendor), | ||
170 | "S" ((int) index), | ||
171 | "D" (&pci_indirect)); | ||
172 | *bus = (bx >> 8) & 0xff; | ||
173 | *device_fn = bx & 0xff; | ||
174 | return (int) (ret & 0xff00) >> 8; | ||
175 | } | ||
176 | |||
177 | static int pci_bios_read(unsigned int seg, unsigned int bus, | 155 | static int pci_bios_read(unsigned int seg, unsigned int bus, |
178 | unsigned int devfn, int reg, int len, u32 *value) | 156 | unsigned int devfn, int reg, int len, u32 *value) |
179 | { | 157 | { |
@@ -364,55 +342,6 @@ static struct pci_raw_ops * __devinit pci_find_bios(void) | |||
364 | } | 342 | } |
365 | 343 | ||
366 | /* | 344 | /* |
367 | * Sort the device list according to PCI BIOS. Nasty hack, but since some | ||
368 | * fool forgot to define the `correct' device order in the PCI BIOS specs | ||
369 | * and we want to be (possibly bug-to-bug ;-]) compatible with older kernels | ||
370 | * which used BIOS ordering, we are bound to do this... | ||
371 | */ | ||
372 | |||
373 | void __devinit pcibios_sort(void) | ||
374 | { | ||
375 | LIST_HEAD(sorted_devices); | ||
376 | struct list_head *ln; | ||
377 | struct pci_dev *dev, *d; | ||
378 | int idx, found; | ||
379 | unsigned char bus, devfn; | ||
380 | |||
381 | DBG("PCI: Sorting device list...\n"); | ||
382 | while (!list_empty(&pci_devices)) { | ||
383 | ln = pci_devices.next; | ||
384 | dev = pci_dev_g(ln); | ||
385 | idx = found = 0; | ||
386 | while (pci_bios_find_device(dev->vendor, dev->device, idx, &bus, &devfn) == PCIBIOS_SUCCESSFUL) { | ||
387 | idx++; | ||
388 | list_for_each(ln, &pci_devices) { | ||
389 | d = pci_dev_g(ln); | ||
390 | if (d->bus->number == bus && d->devfn == devfn) { | ||
391 | list_move_tail(&d->global_list, &sorted_devices); | ||
392 | if (d == dev) | ||
393 | found = 1; | ||
394 | break; | ||
395 | } | ||
396 | } | ||
397 | if (ln == &pci_devices) { | ||
398 | printk(KERN_WARNING "PCI: BIOS reporting unknown device %02x:%02x\n", bus, devfn); | ||
399 | /* | ||
400 | * We must not continue scanning as several buggy BIOSes | ||
401 | * return garbage after the last device. Grr. | ||
402 | */ | ||
403 | break; | ||
404 | } | ||
405 | } | ||
406 | if (!found) { | ||
407 | printk(KERN_WARNING "PCI: Device %s not found by BIOS\n", | ||
408 | pci_name(dev)); | ||
409 | list_move_tail(&dev->global_list, &sorted_devices); | ||
410 | } | ||
411 | } | ||
412 | list_splice(&sorted_devices, &pci_devices); | ||
413 | } | ||
414 | |||
415 | /* | ||
416 | * BIOS Functions for IRQ Routing | 345 | * BIOS Functions for IRQ Routing |
417 | */ | 346 | */ |
418 | 347 | ||
@@ -495,7 +424,6 @@ void __init pci_pcbios_init(void) | |||
495 | { | 424 | { |
496 | if ((pci_probe & PCI_PROBE_BIOS) | 425 | if ((pci_probe & PCI_PROBE_BIOS) |
497 | && ((raw_pci_ops = pci_find_bios()))) { | 426 | && ((raw_pci_ops = pci_find_bios()))) { |
498 | pci_probe |= PCI_BIOS_SORT; | ||
499 | pci_bios_present = 1; | 427 | pci_bios_present = 1; |
500 | } | 428 | } |
501 | } | 429 | } |
diff --git a/arch/x86/pci/pci.h b/arch/x86/pci/pci.h index 3431518d921a..c4bddaeff619 100644 --- a/arch/x86/pci/pci.h +++ b/arch/x86/pci/pci.h | |||
@@ -19,8 +19,6 @@ | |||
19 | #define PCI_PROBE_MASK 0x000f | 19 | #define PCI_PROBE_MASK 0x000f |
20 | #define PCI_PROBE_NOEARLY 0x0010 | 20 | #define PCI_PROBE_NOEARLY 0x0010 |
21 | 21 | ||
22 | #define PCI_NO_SORT 0x0100 | ||
23 | #define PCI_BIOS_SORT 0x0200 | ||
24 | #define PCI_NO_CHECKS 0x0400 | 22 | #define PCI_NO_CHECKS 0x0400 |
25 | #define PCI_USE_PIRQ_MASK 0x0800 | 23 | #define PCI_USE_PIRQ_MASK 0x0800 |
26 | #define PCI_ASSIGN_ROMS 0x1000 | 24 | #define PCI_ASSIGN_ROMS 0x1000 |
@@ -44,7 +42,6 @@ enum pci_bf_sort_state { | |||
44 | extern unsigned int pcibios_max_latency; | 42 | extern unsigned int pcibios_max_latency; |
45 | 43 | ||
46 | void pcibios_resource_survey(void); | 44 | void pcibios_resource_survey(void); |
47 | int pcibios_enable_resources(struct pci_dev *, int); | ||
48 | 45 | ||
49 | /* pci-pc.c */ | 46 | /* pci-pc.c */ |
50 | 47 | ||
@@ -101,7 +98,6 @@ extern int pci_direct_probe(void); | |||
101 | extern void pci_direct_init(int type); | 98 | extern void pci_direct_init(int type); |
102 | extern void pci_pcbios_init(void); | 99 | extern void pci_pcbios_init(void); |
103 | extern void pci_mmcfg_init(int type); | 100 | extern void pci_mmcfg_init(int type); |
104 | extern void pcibios_sort(void); | ||
105 | 101 | ||
106 | /* pci-mmconfig.c */ | 102 | /* pci-mmconfig.c */ |
107 | 103 | ||