net/sb1250: register mdio bus in probe
authorSebastian Siewior <sebastian@breakpoint.cc>
Wed, 28 Apr 2010 09:57:01 +0000 (09:57 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 28 Apr 2010 21:32:03 +0000 (14:32 -0700)
"ifconfig eth0 up && ifconfig eth0 down" triggers:
| kobject (a8000000cfa5a480): tried to init an initialized object, something is seriously wrong.
| Call Trace:
| [<ffffffff8010aabc>] dump_stack+0x8/0x34
| [<ffffffff80293128>] kobject_init+0xe8/0xf0
| [<ffffffff802d922c>] device_initialize+0x2c/0x98
| [<ffffffff802d9cfc>] device_register+0x14/0x28
| [<ffffffff80312cd4>] mdiobus_register+0xdc/0x1e0
| [<ffffffff80314cf0>] sbmac_open+0x58/0x220
| [<ffffffff803519bc>] __dev_open+0x11c/0x180
| [<ffffffff8034d578>] __dev_change_flags+0x120/0x180
| [<ffffffff80351848>] dev_change_flags+0x20/0x78
| [<ffffffff803a753c>] devinet_ioctl+0x7cc/0x820
| [<ffffffff80339ac8>] sock_do_ioctl+0x38/0x90
| [<ffffffff8033a258>] compat_sock_ioctl_trans+0x408/0x1030
| [<ffffffff8033af30>] compat_sock_ioctl+0xb0/0xd0
| [<ffffffff80208b08>] compat_sys_ioctl+0xa0/0x18b8
| [<ffffffff80102f94>] handle_sys+0x114/0x130
|
| sb1250-mac-mdio: probed

mdiobus_register() calls device_register() which initializes the kobj of
the device. mdiobus_unregister() calls only device_del() so we have one
reference left. That one is leaving with mdiobus_free() which is only
called on remove.
Since I don't see any reason why mdiobus_register()/mdiobus_unregister()
should happen in ->open()/->close() I move them to probe & exit.

Signed-off-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/sb1250-mac.c

index 9944e5d662c0fff7d975cce45bb708301512aa67..04efc0c1bda93b95bfbd840c7778d8a57ac2c5ad 100644 (file)
@@ -2353,17 +2353,36 @@ static int sbmac_init(struct platform_device *pldev, long long base)
 
        sc->mii_bus = mdiobus_alloc();
        if (sc->mii_bus == NULL) {
-               sbmac_uninitctx(sc);
-               return -ENOMEM;
+               err = -ENOMEM;
+               goto uninit_ctx;
        }
 
+       sc->mii_bus->name = sbmac_mdio_string;
+       snprintf(sc->mii_bus->id, MII_BUS_ID_SIZE, "%x", idx);
+       sc->mii_bus->priv = sc;
+       sc->mii_bus->read = sbmac_mii_read;
+       sc->mii_bus->write = sbmac_mii_write;
+       sc->mii_bus->irq = sc->phy_irq;
+       for (i = 0; i < PHY_MAX_ADDR; ++i)
+               sc->mii_bus->irq[i] = SBMAC_PHY_INT;
+
+       sc->mii_bus->parent = &pldev->dev;
+       /*
+        * Probe PHY address
+        */
+       err = mdiobus_register(sc->mii_bus);
+       if (err) {
+               printk(KERN_ERR "%s: unable to register MDIO bus\n",
+                      dev->name);
+               goto free_mdio;
+       }
+       dev_set_drvdata(&pldev->dev, sc->mii_bus);
+
        err = register_netdev(dev);
        if (err) {
                printk(KERN_ERR "%s.%d: unable to register netdev\n",
                       sbmac_string, idx);
-               mdiobus_free(sc->mii_bus);
-               sbmac_uninitctx(sc);
-               return err;
+               goto unreg_mdio;
        }
 
        pr_info("%s.%d: registered as %s\n", sbmac_string, idx, dev->name);
@@ -2379,19 +2398,15 @@ static int sbmac_init(struct platform_device *pldev, long long base)
        pr_info("%s: SiByte Ethernet at 0x%08Lx, address: %pM\n",
               dev->name, base, eaddr);
 
-       sc->mii_bus->name = sbmac_mdio_string;
-       snprintf(sc->mii_bus->id, MII_BUS_ID_SIZE, "%x", idx);
-       sc->mii_bus->priv = sc;
-       sc->mii_bus->read = sbmac_mii_read;
-       sc->mii_bus->write = sbmac_mii_write;
-       sc->mii_bus->irq = sc->phy_irq;
-       for (i = 0; i < PHY_MAX_ADDR; ++i)
-               sc->mii_bus->irq[i] = SBMAC_PHY_INT;
-
-       sc->mii_bus->parent = &pldev->dev;
-       dev_set_drvdata(&pldev->dev, sc->mii_bus);
-
        return 0;
+unreg_mdio:
+       mdiobus_unregister(sc->mii_bus);
+       dev_set_drvdata(&pldev->dev, NULL);
+free_mdio:
+       mdiobus_free(sc->mii_bus);
+uninit_ctx:
+       sbmac_uninitctx(sc);
+       return err;
 }
 
 
@@ -2417,16 +2432,6 @@ static int sbmac_open(struct net_device *dev)
                goto out_err;
        }
 
-       /*
-        * Probe PHY address
-        */
-       err = mdiobus_register(sc->mii_bus);
-       if (err) {
-               printk(KERN_ERR "%s: unable to register MDIO bus\n",
-                      dev->name);
-               goto out_unirq;
-       }
-
        sc->sbm_speed = sbmac_speed_none;
        sc->sbm_duplex = sbmac_duplex_none;
        sc->sbm_fc = sbmac_fc_none;
@@ -2457,11 +2462,7 @@ static int sbmac_open(struct net_device *dev)
        return 0;
 
 out_unregister:
-       mdiobus_unregister(sc->mii_bus);
-
-out_unirq:
        free_irq(dev->irq, dev);
-
 out_err:
        return err;
 }
@@ -2650,9 +2651,6 @@ static int sbmac_close(struct net_device *dev)
 
        phy_disconnect(sc->phy_dev);
        sc->phy_dev = NULL;
-
-       mdiobus_unregister(sc->mii_bus);
-
        free_irq(dev->irq, dev);
 
        sbdma_emptyring(&(sc->sbm_txdma));
@@ -2760,6 +2758,7 @@ static int __exit sbmac_remove(struct platform_device *pldev)
 
        unregister_netdev(dev);
        sbmac_uninitctx(sc);
+       mdiobus_unregister(sc->mii_bus);
        mdiobus_free(sc->mii_bus);
        iounmap(sc->sbm_base);
        free_netdev(dev);