]> err.no Git - linux-2.6/blobdiff - arch/um/drivers/net_kern.c
[PATCH] uml: assign random MACs to interfaces if necessary
[linux-2.6] / arch / um / drivers / net_kern.c
index 8c7279bb353bc52848b4e930000af5cd98376b7e..684a1ef93c87e888fae13ad8989f399b0fe39501 100644 (file)
 #include "irq_user.h"
 #include "irq_kern.h"
 
+static inline void set_ether_mac(struct net_device *dev, unsigned char *addr)
+{
+       memcpy(dev->dev_addr, addr, ETH_ALEN);
+}
+
 #define DRIVER_NAME "uml-netdev"
 
 static DEFINE_SPINLOCK(opened_lock);
@@ -109,8 +114,6 @@ static int uml_net_open(struct net_device *dev)
        struct uml_net_private *lp = dev->priv;
        int err;
 
-       spin_lock(&lp->lock);
-
        if(lp->fd >= 0){
                err = -ENXIO;
                goto out;
@@ -128,7 +131,7 @@ static int uml_net_open(struct net_device *dev)
        }
 
        err = um_request_irq(dev->irq, lp->fd, IRQ_READ, uml_net_interrupt,
-                            SA_INTERRUPT | SA_SHIRQ, dev->name, dev);
+                            IRQF_DISABLED | IRQF_SHARED, dev->name, dev);
        if(err != 0){
                printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err);
                err = -ENETUNREACH;
@@ -144,8 +147,6 @@ static int uml_net_open(struct net_device *dev)
         */
        while((err = uml_net_rx(dev)) > 0) ;
 
-       spin_unlock(&lp->lock);
-
        spin_lock(&opened_lock);
        list_add(&lp->list, &opened);
        spin_unlock(&opened_lock);
@@ -155,7 +156,6 @@ out_close:
        if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
        lp->fd = -1;
 out:
-       spin_unlock(&lp->lock);
        return err;
 }
 
@@ -164,15 +164,12 @@ static int uml_net_close(struct net_device *dev)
        struct uml_net_private *lp = dev->priv;
        
        netif_stop_queue(dev);
-       spin_lock(&lp->lock);
 
        free_irq(dev->irq, dev);
        if(lp->close != NULL)
                (*lp->close)(lp->fd, &lp->user);
        lp->fd = -1;
 
-       spin_unlock(&lp->lock);
-
        spin_lock(&opened_lock);
        list_del(&lp->list);
        spin_unlock(&opened_lock);
@@ -241,9 +238,9 @@ static int uml_net_set_mac(struct net_device *dev, void *addr)
        struct uml_net_private *lp = dev->priv;
        struct sockaddr *hwaddr = addr;
 
-       spin_lock(&lp->lock);
-       memcpy(dev->dev_addr, hwaddr->sa_data, ETH_ALEN);
-       spin_unlock(&lp->lock);
+       spin_lock_irq(&lp->lock);
+       set_ether_mac(dev, hwaddr->sa_data);
+       spin_unlock_irq(&lp->lock);
 
        return(0);
 }
@@ -253,7 +250,7 @@ static int uml_net_change_mtu(struct net_device *dev, int new_mtu)
        struct uml_net_private *lp = dev->priv;
        int err = 0;
 
-       spin_lock(&lp->lock);
+       spin_lock_irq(&lp->lock);
 
        new_mtu = (*lp->set_mtu)(new_mtu, &lp->user);
        if(new_mtu < 0){
@@ -264,7 +261,7 @@ static int uml_net_change_mtu(struct net_device *dev, int new_mtu)
        dev->mtu = new_mtu;
 
  out:
-       spin_unlock(&lp->lock);
+       spin_unlock_irq(&lp->lock);
        return err;
 }
 
@@ -564,12 +561,13 @@ static int eth_setup(char *str)
        int n, err;
 
        err = eth_parse(str, &n, &str);
-       if(err) return(1);
+       if(err)
+               return 1;
 
-       new = alloc_bootmem(sizeof(new));
+       new = alloc_bootmem(sizeof(*new));
        if (new == NULL){
                printk("eth_init : alloc_bootmem failed\n");
-               return(1);
+               return 1;
        }
 
        INIT_LIST_HEAD(&new->list);
@@ -577,7 +575,7 @@ static int eth_setup(char *str)
        new->init = str;
 
        list_add_tail(&new->list, &eth_cmd_line);
-       return(1);
+       return 1;
 }
 
 __setup("eth", eth_setup);
@@ -755,7 +753,8 @@ int setup_etheraddr(char *str, unsigned char *addr)
        int i;
 
        if(str == NULL)
-               return(0);
+               goto random;
+
        for(i=0;i<6;i++){
                addr[i] = simple_strtoul(str, &end, 16);
                if((end == str) ||
@@ -763,7 +762,7 @@ int setup_etheraddr(char *str, unsigned char *addr)
                        printk(KERN_ERR 
                               "setup_etheraddr: failed to parse '%s' "
                               "as an ethernet address\n", str);
-                       return(0);
+                       goto random;
                }
                str = end + 1;
        }
@@ -771,9 +770,15 @@ int setup_etheraddr(char *str, unsigned char *addr)
                printk(KERN_ERR 
                       "Attempt to assign a broadcast ethernet address to a "
                       "device disallowed\n");
-               return(0);
+               goto random;
        }
-       return(1);
+       return 1;
+
+random:
+       addr[0] = 0xfe;
+       addr[1] = 0xfd;
+       random_mac(addr);
+       return 1;
 }
 
 void dev_ip_addr(void *d, unsigned char *bin_buf)
@@ -790,13 +795,6 @@ void dev_ip_addr(void *d, unsigned char *bin_buf)
        memcpy(bin_buf, &in->ifa_address, sizeof(in->ifa_address));
 }
 
-void set_ether_mac(void *d, unsigned char *addr)
-{
-       struct net_device *dev = d;
-
-       memcpy(dev->dev_addr, addr, ETH_ALEN);  
-}
-
 struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra)
 {
        if((skb != NULL) && (skb_tailroom(skb) < extra)){
@@ -834,7 +832,7 @@ int dev_netmask(void *d, void *m)
        struct net_device *dev = d;
        struct in_device *ip = dev->ip_ptr;
        struct in_ifaddr *in;
-       __u32 *mask_out = m;
+       __be32 *mask_out = m;
 
        if(ip == NULL) 
                return(1);