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
[email protected]
https://lists.berlios.de/mailman/listinfo/bcm43xx-dev