Index: 8139too.c =================================================================== RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.4/drivers/net/8139too.c,v retrieving revision 1.1.1.11 diff -u -r1.1.1.11 8139too.c --- 8139too.c 12 Aug 2001 17:52:29 -0000 1.1.1.11 +++ 8139too.c 23 Sep 2001 10:17:02 -0000 @@ -154,6 +154,7 @@ #include #include #include +#include #include #define RTL8139_DRIVER_NAME DRV_NAME " Fast Ethernet driver " DRV_VERSION @@ -588,6 +589,7 @@ struct completion thr_exited; u32 rx_config; struct rtl_extra_stats xstats; + struct semaphore mdio_sem; }; MODULE_AUTHOR ("Jeff Garzik "); @@ -971,6 +973,7 @@ spin_lock_init (&tp->lock); init_waitqueue_head (&tp->thr_wait); init_completion (&tp->thr_exited); + init_MUTEX (&tp->mdio_sem); /* dev is fully set up and ready to use now */ DPRINTK("about to register device named %s (%p)...\n", dev->name, dev); @@ -1627,9 +1630,10 @@ if (signal_pending (current)) break; - rtnl_lock (); + if (down_interruptible (&tp->mdio_sem)) + break; rtl8139_thread_iter (dev, tp, tp->mmio_addr); - rtnl_unlock (); + up (&tp->mdio_sem); } complete_and_exit (&tp->thr_exited, 0); @@ -2212,13 +2216,14 @@ { struct rtl8139_private *tp = dev->priv; struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data; - int rc = 0; + int rc; int phy = tp->phys[0] & 0x3f; DPRINTK ("ENTER\n"); data->phy_id &= 0x1f; data->reg_num &= 0x1f; + rc = -ERESTARTSYS; switch (cmd) { case SIOCETHTOOL: @@ -2231,14 +2236,18 @@ case SIOCGMIIREG: /* Read the specified MII register. */ case SIOCDEVPRIVATE+1: /* binary compat, remove in 2.5 */ + if (down_interruptible (&tp->mdio_sem)) { + goto err_out; + } data->val_out = mdio_read (dev, data->phy_id, data->reg_num); + up (&tp->mdio_sem); break; case SIOCSMIIREG: /* Write the specified MII register */ case SIOCDEVPRIVATE+2: /* binary compat, remove in 2.5 */ if (!capable (CAP_NET_ADMIN)) { rc = -EPERM; - break; + goto err_out; } if (data->phy_id == phy) { @@ -2253,14 +2262,21 @@ case 4: /* tp->advertising = value; */ break; } } + if (down_interruptible (&tp->mdio_sem)) { + goto err_out; + } mdio_write(dev, data->phy_id, data->reg_num, data->val_in); + up (&tp->mdio_sem); break; default: rc = -EOPNOTSUPP; - break; + goto err_out; } + rc = 0; + +err_out: DPRINTK ("EXIT, returning %d\n", rc); return rc; }