Michael, The patch below fixes the problem of the kernel oops associated with having a dangling USB core on a chip using a PCIe interface. The patch should also fix problems associated with having extra 802.11 cores.
I still have a problem in that bcm43xx_mac80211 will not unload with this patch - the machine crashes, but I wanted to get your feedback before degugging that issue. Larry ====================== Index: wireless-mb/drivers/ssb/scan.c =================================================================== --- wireless-mb.orig/drivers/ssb/scan.c +++ wireless-mb/drivers/ssb/scan.c @@ -255,6 +255,8 @@ int ssb_bus_scan(struct ssb_bus *bus, int dev_i, i; struct ssb_device *dev; int nr_80211_cores = 0; + int usb_core_found = 0; + int pci_core_found = 0; mmio = ssb_ioremap(bus, baseaddr); if (!mmio) @@ -317,6 +319,7 @@ int ssb_bus_scan(struct ssb_bus *bus, bus->mmio = mmio; } + bus->core_ignore_flags = 0; /* Fetch basic information about each core/device */ for (i = 0, dev_i = 0; i < bus->nr_devices; i++) { err = scan_switchcore(bus, i); @@ -346,6 +349,7 @@ int ssb_bus_scan(struct ssb_bus *bus, if (!we_support_multiple_80211_cores(bus)) { ssb_dprintk(KERN_INFO PFX "Ignoring additional " "802.11 core\n"); + bus->core_ignore_flags |= (1 <<i); continue; } } @@ -355,6 +359,7 @@ int ssb_bus_scan(struct ssb_bus *bus, if (bus->extif.dev) { ssb_printk(KERN_WARNING PFX "WARNING: Multiple EXTIFs found\n"); + bus->core_ignore_flags |= (1 <<i); break; } bus->extif.dev = dev; @@ -364,6 +369,7 @@ int ssb_bus_scan(struct ssb_bus *bus, if (bus->chipco.dev) { ssb_printk(KERN_WARNING PFX "WARNING: Multiple ChipCommon found\n"); + bus->core_ignore_flags |= (1 <<i); break; } bus->chipco.dev = dev; @@ -374,6 +380,7 @@ int ssb_bus_scan(struct ssb_bus *bus, if (bus->mipscore.dev) { ssb_printk(KERN_WARNING PFX "WARNING: Multiple MIPS cores found\n"); + bus->core_ignore_flags |= (1 <<i); break; } bus->mipscore.dev = dev; @@ -381,15 +388,20 @@ int ssb_bus_scan(struct ssb_bus *bus, break; case SSB_DEV_PCI: case SSB_DEV_PCIE: + pci_core_found = 1; #ifdef CONFIG_SSB_DRIVER_PCICORE if (bus->pcicore.dev) { ssb_printk(KERN_WARNING PFX "WARNING: Multiple PCI(E) cores found\n"); + bus->core_ignore_flags |= (1 <<i); break; } bus->pcicore.dev = dev; #endif /* CONFIG_SSB_DRIVER_PCICORE */ break; + case SSB_DEV_USB11_HOST: + case SSB_DEV_USB20_HOST: + usb_core_found = i; default: break; } @@ -397,7 +409,11 @@ int ssb_bus_scan(struct ssb_bus *bus, dev_i++; } bus->nr_devices = dev_i; - + if (pci_core_found && usb_core_found) { + ssb_printk(KERN_WARNING PFX + "WARNING: USB Host ignored\n"); + bus->core_ignore_flags |= (1 << usb_core_found); + } err = 0; out: return err; Index: wireless-mb/include/linux/ssb/ssb.h =================================================================== --- wireless-mb.orig/include/linux/ssb/ssb.h +++ wireless-mb/include/linux/ssb/ssb.h @@ -323,6 +323,8 @@ struct ssb_bus { struct ssb_mipscore mipscore; /* The EXTif-core device (if available). */ struct ssb_extif extif; + /* A word with flags for each core to ignore. */ + u16 core_ignore_flags; /* Internal. */ struct list_head list; Index: wireless-mb/drivers/ssb/core.c =================================================================== --- wireless-mb.orig/drivers/ssb/core.c +++ wireless-mb/drivers/ssb/core.c @@ -160,6 +160,8 @@ int ssb_devices_freeze(struct ssb_bus *b pm_message_t state = PMSG_FREEZE; for (i = 0; i < bus->nr_devices; i++) { + if (bus->core_ignore_flags & (1 <<i)) + continue; dev = &(bus->devices[i]); if (!dev->dev->driver) continue; @@ -182,6 +184,8 @@ int ssb_devices_thaw(struct ssb_bus *bus int i; for (i = 0; i < bus->nr_devices; i++) { + if (bus->core_ignore_flags & (1 <<i)) + continue; dev = &(bus->devices[i]); if (!dev->dev->driver) continue; @@ -297,6 +301,8 @@ static void ssb_devices_unregister(struc int i; for (i = bus->nr_devices - 1; i >= 0; i--) { + if (bus->core_ignore_flags & (1 <<i)) + continue; sdev = &(bus->devices[i]); if (sdev->dev) device_unregister(sdev->dev); @@ -329,6 +335,8 @@ static int ssb_devices_register(struct s int dev_idx = 0; for (i = 0; i < bus->nr_devices; i++) { + if (bus->core_ignore_flags & (1 <<i)) + continue; sdev = &(bus->devices[i]); /* We don't register SSB-system devices to the kernel, _______________________________________________ Bcm43xx-dev mailing list Bcm43xx-dev@lists.berlios.de https://lists.berlios.de/mailman/listinfo/bcm43xx-dev