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

Reply via email to