PHYLIB: Locking fixes for PHY I/O potentially sleeping
[safe/jmp/linux-2.6] / drivers / net / phy / mdio_bus.c
index b31ce27..6e9f619 100644 (file)
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 
-/* mdiobus_register 
+/**
+ * mdiobus_register - bring up all the PHYs on a given bus and attach them to bus
+ * @bus: target mii_bus
  *
- * description: Called by a bus driver to bring up all the PHYs
- *   on a given bus, and attach them to the bus
+ * Description: Called by a bus driver to bring up all the PHYs
+ *   on a given bus, and attach them to the bus.
+ *
+ * Returns 0 on success or < 0 on error.
  */
 int mdiobus_register(struct mii_bus *bus)
 {
        int i;
        int err = 0;
 
-       spin_lock_init(&bus->mdio_lock);
+       mutex_init(&bus->mdio_lock);
 
        if (NULL == bus || NULL == bus->name ||
                        NULL == bus->read ||
@@ -87,9 +91,12 @@ int mdiobus_register(struct mii_bus *bus)
 
                        err = device_register(&phydev->dev);
 
-                       if (err)
+                       if (err) {
                                printk(KERN_ERR "phy %d failed to register\n",
                                                i);
+                               phy_device_free(phydev);
+                               phydev = NULL;
+                       }
                }
 
                bus->phy_map[i] = phydev;
@@ -106,25 +113,27 @@ void mdiobus_unregister(struct mii_bus *bus)
        int i;
 
        for (i = 0; i < PHY_MAX_ADDR; i++) {
-               if (bus->phy_map[i]) {
+               if (bus->phy_map[i])
                        device_unregister(&bus->phy_map[i]->dev);
-                       kfree(bus->phy_map[i]);
-               }
        }
 }
 EXPORT_SYMBOL(mdiobus_unregister);
 
-/* mdio_bus_match
+/**
+ * mdio_bus_match - determine if given PHY driver supports the given PHY device
+ * @dev: target PHY device
+ * @drv: given PHY driver
  *
- * description: Given a PHY device, and a PHY driver, return 1 if
- *   the driver supports the device.  Otherwise, return 0
+ * Description: Given a PHY device, and a PHY driver, return 1 if
+ *   the driver supports the device.  Otherwise, return 0.
  */
 static int mdio_bus_match(struct device *dev, struct device_driver *drv)
 {
        struct phy_device *phydev = to_phy_device(dev);
        struct phy_driver *phydrv = to_phy_driver(drv);
 
-       return (phydrv->phy_id == (phydev->phy_id & phydrv->phy_id_mask));
+       return ((phydrv->phy_id & phydrv->phy_id_mask) ==
+               (phydev->phy_id & phydrv->phy_id_mask));
 }
 
 /* Suspend and resume.  Copied from platform_suspend and