diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-09 21:41:42 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-09 21:41:42 -0500 |
commit | 977127174a7dff52d17faeeb4c4949a54221881f (patch) | |
tree | b05b9d18a1256d7ed97bdfb537213a8d70ccca57 /drivers/pci/probe.c | |
parent | 80c0531514516e43ae118ddf38424e06e5c3cb3c (diff) | |
parent | 93b47684f60cf25e8cefe19a21d94aa0257fdf36 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6
Diffstat (limited to 'drivers/pci/probe.c')
-rw-r--r-- | drivers/pci/probe.c | 49 |
1 files changed, 44 insertions, 5 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index fce2cb2112d8..adfad4fd6a13 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -264,8 +264,10 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) | |||
264 | 264 | ||
265 | if (base <= limit) { | 265 | if (base <= limit) { |
266 | res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO; | 266 | res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO; |
267 | res->start = base; | 267 | if (!res->start) |
268 | res->end = limit + 0xfff; | 268 | res->start = base; |
269 | if (!res->end) | ||
270 | res->end = limit + 0xfff; | ||
269 | } | 271 | } |
270 | 272 | ||
271 | res = child->resource[1]; | 273 | res = child->resource[1]; |
@@ -431,7 +433,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max | |||
431 | { | 433 | { |
432 | struct pci_bus *child; | 434 | struct pci_bus *child; |
433 | int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS); | 435 | int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS); |
434 | u32 buses, i; | 436 | u32 buses, i, j = 0; |
435 | u16 bctl; | 437 | u16 bctl; |
436 | 438 | ||
437 | pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses); | 439 | pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses); |
@@ -541,10 +543,29 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max | |||
541 | * as cards with a PCI-to-PCI bridge can be | 543 | * as cards with a PCI-to-PCI bridge can be |
542 | * inserted later. | 544 | * inserted later. |
543 | */ | 545 | */ |
544 | for (i=0; i<CARDBUS_RESERVE_BUSNR; i++) | 546 | for (i=0; i<CARDBUS_RESERVE_BUSNR; i++) { |
547 | struct pci_bus *parent = bus; | ||
545 | if (pci_find_bus(pci_domain_nr(bus), | 548 | if (pci_find_bus(pci_domain_nr(bus), |
546 | max+i+1)) | 549 | max+i+1)) |
547 | break; | 550 | break; |
551 | while (parent->parent) { | ||
552 | if ((!pcibios_assign_all_busses()) && | ||
553 | (parent->subordinate > max) && | ||
554 | (parent->subordinate <= max+i)) { | ||
555 | j = 1; | ||
556 | } | ||
557 | parent = parent->parent; | ||
558 | } | ||
559 | if (j) { | ||
560 | /* | ||
561 | * Often, there are two cardbus bridges | ||
562 | * -- try to leave one valid bus number | ||
563 | * for each one. | ||
564 | */ | ||
565 | i /= 2; | ||
566 | break; | ||
567 | } | ||
568 | } | ||
548 | max += i; | 569 | max += i; |
549 | pci_fixup_parent_subordinate_busnr(child, max); | 570 | pci_fixup_parent_subordinate_busnr(child, max); |
550 | } | 571 | } |
@@ -559,6 +580,22 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max | |||
559 | 580 | ||
560 | sprintf(child->name, (is_cardbus ? "PCI CardBus #%02x" : "PCI Bus #%02x"), child->number); | 581 | sprintf(child->name, (is_cardbus ? "PCI CardBus #%02x" : "PCI Bus #%02x"), child->number); |
561 | 582 | ||
583 | while (bus->parent) { | ||
584 | if ((child->subordinate > bus->subordinate) || | ||
585 | (child->number > bus->subordinate) || | ||
586 | (child->number < bus->number) || | ||
587 | (child->subordinate < bus->number)) { | ||
588 | printk(KERN_WARNING "PCI: Bus #%02x (-#%02x) may be " | ||
589 | "hidden behind%s bridge #%02x (-#%02x)%s\n", | ||
590 | child->number, child->subordinate, | ||
591 | bus->self->transparent ? " transparent" : " ", | ||
592 | bus->number, bus->subordinate, | ||
593 | pcibios_assign_all_busses() ? " " : | ||
594 | " (try 'pci=assign-busses')"); | ||
595 | } | ||
596 | bus = bus->parent; | ||
597 | } | ||
598 | |||
562 | return max; | 599 | return max; |
563 | } | 600 | } |
564 | 601 | ||
@@ -571,6 +608,7 @@ static void pci_read_irq(struct pci_dev *dev) | |||
571 | unsigned char irq; | 608 | unsigned char irq; |
572 | 609 | ||
573 | pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq); | 610 | pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq); |
611 | dev->pin = irq; | ||
574 | if (irq) | 612 | if (irq) |
575 | pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); | 613 | pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); |
576 | dev->irq = irq; | 614 | dev->irq = irq; |
@@ -624,6 +662,7 @@ static int pci_setup_device(struct pci_dev * dev) | |||
624 | /* The PCI-to-PCI bridge spec requires that subtractive | 662 | /* The PCI-to-PCI bridge spec requires that subtractive |
625 | decoding (i.e. transparent) bridge must have programming | 663 | decoding (i.e. transparent) bridge must have programming |
626 | interface code of 0x01. */ | 664 | interface code of 0x01. */ |
665 | pci_read_irq(dev); | ||
627 | dev->transparent = ((dev->class & 0xff) == 1); | 666 | dev->transparent = ((dev->class & 0xff) == 1); |
628 | pci_read_bases(dev, 2, PCI_ROM_ADDRESS1); | 667 | pci_read_bases(dev, 2, PCI_ROM_ADDRESS1); |
629 | break; | 668 | break; |
@@ -678,7 +717,7 @@ static void pci_release_dev(struct device *dev) | |||
678 | * reading the dword at 0x100 which must either be 0 or a valid extended | 717 | * reading the dword at 0x100 which must either be 0 or a valid extended |
679 | * capability header. | 718 | * capability header. |
680 | */ | 719 | */ |
681 | static int pci_cfg_space_size(struct pci_dev *dev) | 720 | int pci_cfg_space_size(struct pci_dev *dev) |
682 | { | 721 | { |
683 | int pos; | 722 | int pos; |
684 | u32 status; | 723 | u32 status; |