Modify

Opened 9 years ago

Closed 9 years ago

Last modified 8 years ago

#2686 closed defect (fixed)

Resource collisions on bcm4780 using kernel 2.6

Reported by: xaviour Owned by: developers
Priority: normal Milestone: Kamikaze 8.09 RC1
Component: kernel Version:
Keywords: bcm4780 Cc: nbd

Description

Using revision 9538 (or older revisions), looking at the output of dmesg (attached to this ticket) shows that there is a resource collision on the "Broadcom Corporation BCM4704 PCI to SB Bridge". This might be what prevents Linux from enabling the aec62xx IDE controller present on the WL-700gE (see ticket:2516 which should be closed now). Using kernel 2.4, there is no resource collision. The line of interest in the logs is:

PCI: Device 0000:00:00.0 not available because of resource collisions

Comparing the output of "lspci -vv" (attached to this ticket), the following can be noted:

  • With a 2.6 kernel all interrupts are assigned to IRQ6 while with a 2.4 kernel interrupts are assigned to IRQ2-6.
  • The 2.4 kernel places the 4318 wireless device at address 0x40002000 and region 0 of the PCI to SB bridge at address 0x40000000 while the 2.6 kernel places the 4318 wireless device at 0x40000000 and does not even report region 0 of the PCI to SB bridge.

Attachments (5)

dmesg_enable.txt (6.9 KB) - added by xaviour 9 years ago.
Output of dmesg is the aec62xx device is enabled before loading the module
dmesg_noenable.txt (7.7 KB) - added by xaviour 9 years ago.
Output of dmesg is the aec62xx device is not enabled before loading the module
pci_2.4_driver.txt (9.2 KB) - added by xaviour 9 years ago.
Output of lspci --v with a 2.4 kernel and aec62xx driver loaded
pci_2.6_driver.txt (3.9 KB) - added by xaviour 9 years ago.
Output of lspci --v with a 2.6 kernel and aec62xx driver loaded
pci_2.6_nodriver.txt (3.9 KB) - added by xaviour 9 years ago.
Output of lspci --v with a 2.6 kernel and aec62xx driver not loaded

Download all attachments as: .zip

Change History (12)

Changed 9 years ago by xaviour

Output of dmesg is the aec62xx device is enabled before loading the module

Changed 9 years ago by xaviour

Output of dmesg is the aec62xx device is not enabled before loading the module

Changed 9 years ago by xaviour

Output of lspci --v with a 2.4 kernel and aec62xx driver loaded

Changed 9 years ago by xaviour

Output of lspci --v with a 2.6 kernel and aec62xx driver loaded

Changed 9 years ago by xaviour

Output of lspci --v with a 2.6 kernel and aec62xx driver not loaded

comment:1 follow-up: Changed 9 years ago by biblbroks@…

PCI initialization on bcm47xx seems a bit broken.
I recently added a patch that fixes the same resource collision issue for bcm43xx and this might have broken aec62xx.
Try checking out r9534 or earlier and see if it works (but you'll have no WiFi support). We can than work from there.

comment:2 in reply to: ↑ 1 ; follow-up: Changed 9 years ago by xaviour

Replying to biblbroks@sezampro.yu:

Try checking out r9534 or earlier and see if it works (but you'll have no WiFi support). We can than work from there.

The problem was already there in r9285. I actually used a recent version in the hope that your patch (applied in r9535) would improve the situation. It did not but it does not seam to make things worse either.

While I checked for improvements in r9538, I took the time this week-end to get the output of lspci -vv on a 2.4 kernel. It is now possible to do a comparison between a version that is known to work against a version that is known not to work. It should help with debugging.

It is still unclear whether the resource conflict is due to interrupts or to memory mappings.

comment:3 in reply to: ↑ 2 ; follow-up: Changed 9 years ago by biblbroks@…

Replying to xaviour:

Interrupts aren't the problem here because all devices behind BCM4704 bridge share the same interrupt line, even on 2.4 (note that in your 2.4 lspci dump every device on bus 01 has IRQ 2)

I suspect that the reason for aec62xx failing is that its expansion ROM gets mapped on the same address (40000000) as b43 and is thus disabled, because SSB initialization code only does fixups for PCI BARs 0-5, not for EXPANSION ROM BAR. I don't know much about aec62xx, but if the driver relies on this ROM being enabled it will most certainly fail.

Anyway, drop me an e-mail and I'll send you some patches to try out.

comment:4 in reply to: ↑ 3 ; follow-up: Changed 9 years ago by anonymous

Replying to biblbroks@sezampro.yu:

Interrupts aren't the problem here because all devices behind BCM4704 bridge share the same interrupt line, even on 2.4 (note that in your 2.4 lspci dump every device on bus 01 has IRQ 2)

One hypothesis less then.

Replying to biblbroks@sezampro.yu:

I suspect that the reason for aec62xx failing is that its expansion ROM gets mapped on the same address (40000000) as b43 and is thus disabled, because SSB initialization code only does fixups for PCI BARs 0-5, not for EXPANSION ROM BAR. I don't know much about aec62xx, but if the driver relies on this ROM being enabled it will most certainly fail.

Take into account that if I manually enable the aec62xx device and then load the driver

cd /sys/devices/pci0000:00 
for FILE in */enable 
do 
  echo -n 1 > $FILE 
done 
cd - 
insmod aec62xx

Then everything works fine. If you look at "pci_2.6_driver.txt", you will see that the device is enabled (and works fine) while the expansion ROM is disabled.

So I think the aec62xx has nothing to do with the problem. The driver simply fails because the device was not enabled.

About the lack of fixup for the expansion ROM bar, is "ssb_fixup_pcibridge" in "driver_pcicore.c" the function that needs to be fixed?

Anyway, drop me an e-mail and I'll send you some patches to try out.

Sent you an email.

comment:5 in reply to: ↑ 4 Changed 9 years ago by xaviour

Replying to anonymous:

About the lack of fixup for the expansion ROM bar, is "ssb_fixup_pcibridge" in "driver_pcicore.c" the function that needs to be fixed?

It seams to make sense. The fixup function is as follows:

	for (pos = 0; pos < 6; pos++) {
		res = &d->resource[pos];
		if (res->flags & IORESOURCE_IO)
			base = &ssb_pcicore_pcibus_iobase;
		else
			base = &ssb_pcicore_pcibus_membase;
		if (res->end) {
			size = res->end - res->start + 1;
			if (*base & (size - 1))
				*base = (*base + size) & ~(size - 1);
			res->start = *base;
			res->end = res->start + size - 1;
			*base += size;
			pci_write_config_dword(d, PCI_BASE_ADDRESS_0 + (pos << 2), res->start);
		}
		/* Fix up PCI bridge BAR0 only */
		if (d->bus->number == 0 && PCI_SLOT(d->devfn) == 0)
			break;
	}

The functions goes through the official 5 bars. Some devices like the aec62xx support more than 5 bars. So if the code was changed to use "DEVICE_COUNT_RESOURCE" instead of 6 then the extension ROM would be placed somewhere in the memory range. This would make the resource conflict disappear and the device would be enabled normally.

If there any risk in changing "6" to "DEVICE_COUNT_RESOURCE" like the "pcibios_fixup_resources" function is doing it for the PPC architecture in "arch/ppc/kernel/pci.c"?

        for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
                struct resource *res = dev->resource + i;
                if (!res->flags)
                        continue;
                if (res->end == 0xffffffff) {
                        DBG("PCI:%s Resource %d [%016llx-%016llx] is unassigned\n",
                                pci_name(dev), i,
                                (unsigned long long)res->start,
                                (unsigned long long)res->end);
                        res->end -= res->start;
                        res->start = 0;
                        res->flags |= IORESOURCE_UNSET;
                        continue;
                }
                offset = 0;
                if (res->flags & IORESOURCE_MEM) {
                        offset = hose->pci_mem_offset;
                } else if (res->flags & IORESOURCE_IO) {
                        offset = (unsigned long) hose->io_base_virt
                                - isa_io_base;
                }
                if (offset != 0) {
                        res->start += offset;
                        res->end += offset;
#ifdef DEBUG
                        printk("Fixup res %d (%lx) of dev %s: %lx -> %lx\n",
                               i, res->flags, pci_name(dev),
                               res->start - offset, res->start);
#endif
                }
        }

comment:6 Changed 9 years ago by xaviour

So it seams that "ssb_fixup_pcibridge" in "driver_pcicore.c" is doing the fix up only for the bridge as witnessed in the dmesg log:

PCI: fixing up bridge
PCI: Setting latency timer of device 0000:00:00.0 to 64
PCI: Fixing up device 0000:00:00.0

So the hypothesis that the for loop boundary should be increased does not hold. Later on in the log when enable is called manually, the function "pcibios_enable_resources" from "arch/mips/pci/pci.c" is called:

PCI: Enabling device 0000:00:01.0 (0000 -> 0002)
PCI: Fixing up device 0000:00:01.0
PCI: Enabling device 0000:00:02.0 (0000 -> 0003)
PCI: Fixing up device 0000:00:02.0
PCI: Enabling device 0000:00:03.0 (0000 -> 0001)
PCI: Fixing up device 0000:00:03.0
PCI: Enabling device 0000:00:03.1 (0000 -> 0001)
PCI: Fixing up device 0000:00:03.1
PCI: Enabling device 0000:00:03.2 (0000 -> 0002)
PCI: Fixing up device 0000:00:03.2

The comment in the original text of the ticket about region 0 being missing is when using a 2.6 kernel is still valid.

comment:7 Changed 9 years ago by nbd

  • Resolution set to fixed
  • Status changed from new to closed

fixed in [9560]

Add Comment

Modify Ticket

Action
as closed .
The resolution will be deleted. Next status will be 'reopened'.
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.