Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 03f80cc3 authored by Sebastian Siewior's avatar Sebastian Siewior Committed by David S. Miller
Browse files

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: default avatarSebastian Andrzej Siewior <sebastian@breakpoint.cc>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5fa782c2
Loading
Loading
Loading
Loading
+33 −34
Original line number Diff line number Diff line
@@ -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);