[PATCH 1/3] PAL: Support of the fixed PHY
Michael Buesch
mb at bu3sch.de
Thu Jun 22 06:48:27 EST 2006
On Wednesday 21 June 2006 18:09, Vitaly Bordug wrote:
> +static int fixed_mdio_update_regs(struct fixed_info *fixed)
> +{
> + u16 *regs = fixed->regs;
> + u16 bmsr = 0;
> + u16 bmcr = 0;
> +
> + if(!regs) {
> + printk(KERN_ERR "%s: regs not set up", __FUNCTION__);
> + return -1;
-EINVAL perhaps?
> +static int fixed_mdio_register_device(int number, int speed, int duplex)
> +{
> + struct mii_bus *new_bus;
> + struct fixed_info *fixed;
> + struct phy_device *phydev;
> + int err = 0;
> +
> + struct device* dev = kzalloc(sizeof(struct device), GFP_KERNEL);
> +
> + if (NULL == dev)
> + return -EINVAL;
-ENOMEM here.
> + new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL);
> +
> + if (NULL == new_bus) {
> + kfree(dev);
> + return -ENOMEM;
> + }
> + fixed = fixed_ptr = kzalloc(sizeof(struct fixed_info), GFP_KERNEL);
> +
> + if (NULL == fixed) {
> + kfree(dev);
> + kfree(new_bus);
> + return -ENOMEM;
> + }
> +
> + fixed->regs = kzalloc(MII_REGS_NUM*sizeof(int), GFP_KERNEL);
> +
> + if (NULL == fixed->regs) {
> + kfree(dev);
> + kfree(new_bus);
> + kfree (fixed);
> + return -ENOMEM;
> + }
> +
> + fixed->regs_num = MII_REGS_NUM;
> + fixed->phy_status.speed = speed;
> + fixed->phy_status.duplex = duplex;
> + fixed->phy_status.link = 1;
> +
> + new_bus->name = "Fixed MII Bus",
> + new_bus->read = &fixed_mii_read,
> + new_bus->write = &fixed_mii_write,
> + new_bus->reset = &fixed_mii_reset,
> +
> + /*set up workspace*/
> + fixed_mdio_update_regs(fixed);
> + new_bus->priv = fixed;
> +
> + new_bus->dev = dev;
> + dev_set_drvdata(dev, new_bus);
> +
> + /* create phy_device and register it on the mdio bus */
> + phydev = phy_device_create(new_bus, 0, 0);
> +
> + /*
> + Put the phydev pointer into the fixed pack so that bus read/write code could be able
> + to access for instance attached netdev. Well it doesn't have to do so, only in case
> + of utilizing user-specified link-update...
> + */
> + fixed->phydev = phydev;
> +
> + if (IS_ERR(phydev)) {
> + err = PTR_ERR(-ENOMEM);
> + goto bus_register_fail;
> + }
> +
> + phydev->irq = -1;
> + phydev->dev.bus = &mdio_bus_type;
> +
> + if(number)
> + snprintf(phydev->dev.bus_id, BUS_ID_SIZE,
> + "fixed_%d@%d:%d", number, speed, duplex);
> + else
> + snprintf(phydev->dev.bus_id, BUS_ID_SIZE,
> + "fixed@%d:%d", speed, duplex);
> + phydev->bus = new_bus;
> +
> + err = device_register(&phydev->dev);
> + if(err) {
> + printk(KERN_ERR "Phy %s failed to register\n",
> + phydev->dev.bus_id);
> + goto bus_register_fail;
> + }
> +
> + /*
> + the mdio bus has phy_id match... In order not to do it
> + artificially, we are binding the driver here by hand;
> + it will be the same
> + for all the fixed phys anyway.
> + */
> + down_write(&phydev->dev.bus->subsys.rwsem);
> +
> + phydev->dev.driver = &fixed_mdio_driver.driver;
> +
> + err = phydev->dev.driver->probe(&phydev->dev);
> + if(err < 0) {
> + printk(KERN_ERR "Phy %s: problems with fixed driver\n",
> + phydev->dev.bus_id);
> + up_write(&phydev->dev.bus->subsys.rwsem);
> + goto bus_register_fail;
Probably need some additional error unwinding code.
Of doesn't device_register() have to be reverted?
What about phy_device_create()?
> + }
> +
> + device_bind_driver(&phydev->dev);
> + up_write(&phydev->dev.bus->subsys.rwsem);
> +
> + return 0;
> +
> +bus_register_fail:
> + kfree(dev);
> + kfree (fixed);
> + kfree(new_bus);
> +
> + return err;
> +}
--
Greetings Michael.
More information about the Linuxppc-embedded
mailing list