vserver 1.9.5.x5
[linux-2.6.git] / arch / um / drivers / net_kern.c
index c686a39..fe1e79a 100644 (file)
@@ -30,7 +30,9 @@
 #include "irq_user.h"
 #include "irq_kern.h"
 
-static spinlock_t opened_lock = SPIN_LOCK_UNLOCKED;
+#define DRIVER_NAME "uml-netdev"
+
+static DEFINE_SPINLOCK(opened_lock);
 LIST_HEAD(opened);
 
 static int uml_net_rx(struct net_device *dev)
@@ -126,10 +128,6 @@ static int uml_net_open(struct net_device *dev)
        lp->tl.data = (unsigned long) &lp->user;
        netif_start_queue(dev);
 
-       spin_lock(&opened_lock);
-       list_add(&lp->list, &opened);
-       spin_unlock(&opened_lock);
-
        /* clear buffer - it can happen that the host side of the interface
         * is full when we get here.  In this case, new data is never queued,
         * SIGIOs never arrive, and the net never works.
@@ -148,12 +146,11 @@ static int uml_net_close(struct net_device *dev)
        netif_stop_queue(dev);
        spin_lock(&lp->lock);
 
+       free_irq_by_irq_and_dev(dev->irq, dev);
        free_irq(dev->irq, dev);
-       if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
+       if(lp->close != NULL)
+               (*lp->close)(lp->fd, &lp->user);
        lp->fd = -1;
-       spin_lock(&opened_lock);
-       list_del(&lp->list);
-       spin_unlock(&opened_lock);
 
        spin_unlock(&lp->lock);
        return 0;
@@ -251,7 +248,7 @@ static int uml_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
        static const struct ethtool_drvinfo info = {
                .cmd     = ETHTOOL_GDRVINFO,
-               .driver  = "uml virtual ethernet",
+               .driver  = DRIVER_NAME,
                .version = "42",
        };
        void *useraddr;
@@ -285,9 +282,15 @@ void uml_net_user_timer_expire(unsigned long _conn)
 #endif
 }
 
-static spinlock_t devices_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(devices_lock);
 static struct list_head devices = LIST_HEAD_INIT(devices);
 
+static struct device_driver uml_net_driver = {
+       .name  = DRIVER_NAME,
+       .bus   = &platform_bus_type,
+};
+static int driver_registered;
+
 static int eth_configure(int n, void *init, char *mac,
                         struct transport *transport)
 {
@@ -329,6 +332,16 @@ static int eth_configure(int n, void *init, char *mac,
                return 1;
        }
 
+       /* sysfs register */
+       if (!driver_registered) {
+               driver_register(&uml_net_driver);
+               driver_registered = 1;
+       }
+       device->pdev.id = n;
+       device->pdev.name = DRIVER_NAME;
+       platform_device_register(&device->pdev);
+       SET_NETDEV_DEV(dev,&device->pdev.dev);
+
        /* If this name ends up conflicting with an existing registered
         * netdevice, that is OK, register_netdev{,ice}() will notice this
         * and fail.
@@ -396,6 +409,11 @@ static int eth_configure(int n, void *init, char *mac,
 
        if (device->have_mac)
                set_ether_mac(dev, device->mac);
+
+       spin_lock(&opened_lock);
+       list_add(&lp->list, &opened);
+       spin_unlock(&opened_lock);
+
        return(0);
 }
 
@@ -559,6 +577,7 @@ __uml_help(eth_setup,
 "    Configure a network device.\n\n"
 );
 
+#if 0
 static int eth_init(void)
 {
        struct list_head *ele, *next;
@@ -573,8 +592,8 @@ static int eth_init(void)
        
        return(1);
 }
-
 __initcall(eth_init);
+#endif
 
 static int net_config(char *str)
 {
@@ -615,6 +634,7 @@ static int net_remove(char *str)
        if(lp->fd > 0) return(-1);
        if(lp->remove != NULL) (*lp->remove)(&lp->user);
        unregister_netdev(dev);
+       platform_device_unregister(&device->pdev);
 
        list_del(&device->list);
        kfree(device);
@@ -704,7 +724,7 @@ __initcall(uml_net_init);
 static void close_devices(void)
 {
        struct list_head *ele;
-       struct uml_net_private *lp;     
+       struct uml_net_private *lp;
 
        list_for_each(ele, &opened){
                lp = list_entry(ele, struct uml_net_private, list);