diff options
author | Sebastian Siewior <sebastian@breakpoint.cc> | 2010-04-28 05:57:01 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-04-28 17:32:03 -0400 |
commit | 03f80cc3f24e1dcdbdba081ed5daf5575aac6180 (patch) | |
tree | 3f9297e38b66cc500d46be9d6bed0fef13c18f41 /drivers/net/sb1250-mac.c | |
parent | 5fa782c2f5ef6c2e4f04d3e228412c9b4a4c8809 (diff) |
net/sb1250: register mdio bus in probe
"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>
Diffstat (limited to 'drivers/net/sb1250-mac.c')
-rw-r--r-- | drivers/net/sb1250-mac.c | 67 |
1 files changed, 33 insertions, 34 deletions
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c index 9944e5d662c0..04efc0c1bda9 100644 --- a/drivers/net/sb1250-mac.c +++ b/drivers/net/sb1250-mac.c | |||
@@ -2353,17 +2353,36 @@ static int sbmac_init(struct platform_device *pldev, long long base) | |||
2353 | 2353 | ||
2354 | sc->mii_bus = mdiobus_alloc(); | 2354 | sc->mii_bus = mdiobus_alloc(); |
2355 | if (sc->mii_bus == NULL) { | 2355 | if (sc->mii_bus == NULL) { |
2356 | sbmac_uninitctx(sc); | 2356 | err = -ENOMEM; |
2357 | return -ENOMEM; | 2357 | goto uninit_ctx; |
2358 | } | 2358 | } |
2359 | 2359 | ||
2360 | sc->mii_bus->name = sbmac_mdio_string; | ||
2361 | snprintf(sc->mii_bus->id, MII_BUS_ID_SIZE, "%x", idx); | ||
2362 | sc->mii_bus->priv = sc; | ||
2363 | sc->mii_bus->read = sbmac_mii_read; | ||
2364 | sc->mii_bus->write = sbmac_mii_write; | ||
2365 | sc->mii_bus->irq = sc->phy_irq; | ||
2366 | for (i = 0; i < PHY_MAX_ADDR; ++i) | ||
2367 | sc->mii_bus->irq[i] = SBMAC_PHY_INT; | ||
2368 | |||
2369 | sc->mii_bus->parent = &pldev->dev; | ||
2370 | /* | ||
2371 | * Probe PHY address | ||
2372 | */ | ||
2373 | err = mdiobus_register(sc->mii_bus); | ||
2374 | if (err) { | ||
2375 | printk(KERN_ERR "%s: unable to register MDIO bus\n", | ||
2376 | dev->name); | ||
2377 | goto free_mdio; | ||
2378 | } | ||
2379 | dev_set_drvdata(&pldev->dev, sc->mii_bus); | ||
2380 | |||
2360 | err = register_netdev(dev); | 2381 | err = register_netdev(dev); |
2361 | if (err) { | 2382 | if (err) { |
2362 | printk(KERN_ERR "%s.%d: unable to register netdev\n", | 2383 | printk(KERN_ERR "%s.%d: unable to register netdev\n", |
2363 | sbmac_string, idx); | 2384 | sbmac_string, idx); |
2364 | mdiobus_free(sc->mii_bus); | 2385 | goto unreg_mdio; |
2365 | sbmac_uninitctx(sc); | ||
2366 | return err; | ||
2367 | } | 2386 | } |
2368 | 2387 | ||
2369 | pr_info("%s.%d: registered as %s\n", sbmac_string, idx, dev->name); | 2388 | 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) | |||
2379 | pr_info("%s: SiByte Ethernet at 0x%08Lx, address: %pM\n", | 2398 | pr_info("%s: SiByte Ethernet at 0x%08Lx, address: %pM\n", |
2380 | dev->name, base, eaddr); | 2399 | dev->name, base, eaddr); |
2381 | 2400 | ||
2382 | sc->mii_bus->name = sbmac_mdio_string; | ||
2383 | snprintf(sc->mii_bus->id, MII_BUS_ID_SIZE, "%x", idx); | ||
2384 | sc->mii_bus->priv = sc; | ||
2385 | sc->mii_bus->read = sbmac_mii_read; | ||
2386 | sc->mii_bus->write = sbmac_mii_write; | ||
2387 | sc->mii_bus->irq = sc->phy_irq; | ||
2388 | for (i = 0; i < PHY_MAX_ADDR; ++i) | ||
2389 | sc->mii_bus->irq[i] = SBMAC_PHY_INT; | ||
2390 | |||
2391 | sc->mii_bus->parent = &pldev->dev; | ||
2392 | dev_set_drvdata(&pldev->dev, sc->mii_bus); | ||
2393 | |||
2394 | return 0; | 2401 | return 0; |
2402 | unreg_mdio: | ||
2403 | mdiobus_unregister(sc->mii_bus); | ||
2404 | dev_set_drvdata(&pldev->dev, NULL); | ||
2405 | free_mdio: | ||
2406 | mdiobus_free(sc->mii_bus); | ||
2407 | uninit_ctx: | ||
2408 | sbmac_uninitctx(sc); | ||
2409 | return err; | ||
2395 | } | 2410 | } |
2396 | 2411 | ||
2397 | 2412 | ||
@@ -2417,16 +2432,6 @@ static int sbmac_open(struct net_device *dev) | |||
2417 | goto out_err; | 2432 | goto out_err; |
2418 | } | 2433 | } |
2419 | 2434 | ||
2420 | /* | ||
2421 | * Probe PHY address | ||
2422 | */ | ||
2423 | err = mdiobus_register(sc->mii_bus); | ||
2424 | if (err) { | ||
2425 | printk(KERN_ERR "%s: unable to register MDIO bus\n", | ||
2426 | dev->name); | ||
2427 | goto out_unirq; | ||
2428 | } | ||
2429 | |||
2430 | sc->sbm_speed = sbmac_speed_none; | 2435 | sc->sbm_speed = sbmac_speed_none; |
2431 | sc->sbm_duplex = sbmac_duplex_none; | 2436 | sc->sbm_duplex = sbmac_duplex_none; |
2432 | sc->sbm_fc = sbmac_fc_none; | 2437 | sc->sbm_fc = sbmac_fc_none; |
@@ -2457,11 +2462,7 @@ static int sbmac_open(struct net_device *dev) | |||
2457 | return 0; | 2462 | return 0; |
2458 | 2463 | ||
2459 | out_unregister: | 2464 | out_unregister: |
2460 | mdiobus_unregister(sc->mii_bus); | ||
2461 | |||
2462 | out_unirq: | ||
2463 | free_irq(dev->irq, dev); | 2465 | free_irq(dev->irq, dev); |
2464 | |||
2465 | out_err: | 2466 | out_err: |
2466 | return err; | 2467 | return err; |
2467 | } | 2468 | } |
@@ -2650,9 +2651,6 @@ static int sbmac_close(struct net_device *dev) | |||
2650 | 2651 | ||
2651 | phy_disconnect(sc->phy_dev); | 2652 | phy_disconnect(sc->phy_dev); |
2652 | sc->phy_dev = NULL; | 2653 | sc->phy_dev = NULL; |
2653 | |||
2654 | mdiobus_unregister(sc->mii_bus); | ||
2655 | |||
2656 | free_irq(dev->irq, dev); | 2654 | free_irq(dev->irq, dev); |
2657 | 2655 | ||
2658 | sbdma_emptyring(&(sc->sbm_txdma)); | 2656 | sbdma_emptyring(&(sc->sbm_txdma)); |
@@ -2760,6 +2758,7 @@ static int __exit sbmac_remove(struct platform_device *pldev) | |||
2760 | 2758 | ||
2761 | unregister_netdev(dev); | 2759 | unregister_netdev(dev); |
2762 | sbmac_uninitctx(sc); | 2760 | sbmac_uninitctx(sc); |
2761 | mdiobus_unregister(sc->mii_bus); | ||
2763 | mdiobus_free(sc->mii_bus); | 2762 | mdiobus_free(sc->mii_bus); |
2764 | iounmap(sc->sbm_base); | 2763 | iounmap(sc->sbm_base); |
2765 | free_netdev(dev); | 2764 | free_netdev(dev); |