diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c index 09d1de90297cffed136e874adce70644486ff131..d0b656a517d3864c2abc9e965ebc2d68199af849 100644 --- a/arch/um/drivers/daemon_user.c +++ b/arch/um/drivers/daemon_user.c @@ -123,7 +123,7 @@ static int connect_to_switch(struct daemon_data *pri) return err; } -static void daemon_user_init(void *data, void *dev) +static int daemon_user_init(void *data, void *dev) { struct daemon_data *pri = data; struct timeval tv; @@ -146,7 +146,10 @@ static void daemon_user_init(void *data, void *dev) if(pri->fd < 0){ kfree(pri->local_addr); pri->local_addr = NULL; + return pri->fd; } + + return 0; } static int daemon_open(void *data) diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c index cfaa2cc43139a1d3a9fe8bc1f1f6cc8705771fa5..0f64d9467286169742ba41df30c4f07d6da1efe0 100644 --- a/arch/um/drivers/mcast_user.c +++ b/arch/um/drivers/mcast_user.c @@ -42,12 +42,13 @@ static struct sockaddr_in *new_addr(char *addr, unsigned short port) return sin; } -static void mcast_user_init(void *data, void *dev) +static int mcast_user_init(void *data, void *dev) { struct mcast_data *pri = data; pri->mcast_addr = new_addr(pri->addr, pri->port); pri->dev = dev; + return 0; } static void mcast_remove(void *data) diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 859303730b2f9faed861b1bc3252b4ddc284d65c..ac746fb5d10f897f751b8249f48020ac3e2ce943 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -325,8 +325,8 @@ static struct platform_driver uml_net_driver = { }; static int driver_registered; -static int eth_configure(int n, void *init, char *mac, - struct transport *transport) +static void eth_configure(int n, void *init, char *mac, + struct transport *transport) { struct uml_net *device; struct net_device *dev; @@ -339,16 +339,12 @@ static int eth_configure(int n, void *init, char *mac, device = kzalloc(sizeof(*device), GFP_KERNEL); if (device == NULL) { printk(KERN_ERR "eth_configure failed to allocate uml_net\n"); - return(1); + return; } INIT_LIST_HEAD(&device->list); device->index = n; - spin_lock(&devices_lock); - list_add(&device->list, &devices); - spin_unlock(&devices_lock); - setup_etheraddr(mac, device->mac); printk(KERN_INFO "Netdevice %d ", n); @@ -360,7 +356,7 @@ static int eth_configure(int n, void *init, char *mac, dev = alloc_etherdev(size); if (dev == NULL) { printk(KERN_ERR "eth_configure: failed to allocate device\n"); - return 1; + goto out_free_device; } lp = dev->priv; @@ -376,7 +372,8 @@ static int eth_configure(int n, void *init, char *mac, } device->pdev.id = n; device->pdev.name = DRIVER_NAME; - platform_device_register(&device->pdev); + if(platform_device_register(&device->pdev)) + goto out_free_netdev; SET_NETDEV_DEV(dev,&device->pdev.dev); /* If this name ends up conflicting with an existing registered @@ -386,31 +383,12 @@ static int eth_configure(int n, void *init, char *mac, snprintf(dev->name, sizeof(dev->name), "eth%d", n); device->dev = dev; + /* + * These just fill in a data structure, so there's no failure + * to be worried about. + */ (*transport->kern->init)(dev, init); - dev->mtu = transport->user->max_packet; - dev->open = uml_net_open; - dev->hard_start_xmit = uml_net_start_xmit; - dev->stop = uml_net_close; - dev->get_stats = uml_net_get_stats; - dev->set_multicast_list = uml_net_set_multicast_list; - dev->tx_timeout = uml_net_tx_timeout; - dev->set_mac_address = uml_net_set_mac; - dev->change_mtu = uml_net_change_mtu; - dev->ethtool_ops = ¨_net_ethtool_ops; - dev->watchdog_timeo = (HZ >> 1); - dev->irq = UM_ETH_IRQ; - - rtnl_lock(); - err = register_netdevice(dev); - rtnl_unlock(); - if (err) { - device->dev = NULL; - /* XXX: should we call ->remove() here? */ - free_netdev(dev); - return 1; - } - /* lp.user is the first four bytes of the transport data, which * has already been initialized. This structure assignment will * overwrite that, so we make sure that .user gets overwritten with @@ -438,12 +416,45 @@ static int eth_configure(int n, void *init, char *mac, lp->tl.function = uml_net_user_timer_expire; memcpy(lp->mac, device->mac, sizeof(lp->mac)); - if (transport->user->init) - (*transport->user->init)(&lp->user, dev); + if ((transport->user->init != NULL) && + ((*transport->user->init)(&lp->user, dev) != 0)) + goto out_unregister; set_ether_mac(dev, device->mac); + dev->mtu = transport->user->max_packet; + dev->open = uml_net_open; + dev->hard_start_xmit = uml_net_start_xmit; + dev->stop = uml_net_close; + dev->get_stats = uml_net_get_stats; + dev->set_multicast_list = uml_net_set_multicast_list; + dev->tx_timeout = uml_net_tx_timeout; + dev->set_mac_address = uml_net_set_mac; + dev->change_mtu = uml_net_change_mtu; + dev->ethtool_ops = ¨_net_ethtool_ops; + dev->watchdog_timeo = (HZ >> 1); + dev->irq = UM_ETH_IRQ; - return 0; + rtnl_lock(); + err = register_netdevice(dev); + rtnl_unlock(); + if (err) + goto out_undo_user_init; + + spin_lock(&devices_lock); + list_add(&device->list, &devices); + spin_unlock(&devices_lock); + + return; + +out_undo_user_init: + if (transport->user->init != NULL) + (*transport->user->remove)(&lp->user); +out_unregister: + platform_device_unregister(&device->pdev); +out_free_netdev: + free_netdev(dev); +out_free_device: ; + kfree(device); } static struct uml_net *find_device(int n) diff --git a/arch/um/drivers/pcap_user.c b/arch/um/drivers/pcap_user.c index a1747dc0ff6fbcf3cffe12ec5ba5caf12a23bd90..dc0a903ef9a6fa547032bc1d7bbdfb70c7c3013f 100644 --- a/arch/um/drivers/pcap_user.c +++ b/arch/um/drivers/pcap_user.c @@ -18,7 +18,7 @@ #define PCAP_FD(p) (*(int *)(p)) -static void pcap_user_init(void *data, void *dev) +static int pcap_user_init(void *data, void *dev) { struct pcap_data *pri = data; pcap_t *p; @@ -28,11 +28,12 @@ static void pcap_user_init(void *data, void *dev) if(p == NULL){ printk("pcap_user_init : pcap_open_live failed - '%s'\n", errors); - return; + return -EINVAL; } pri->dev = dev; pri->pcap = p; + return 0; } static int pcap_open(void *data) diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c index 7eddacc53b6ec2168a581685b4e11bf6523eeedf..329c072d17d152872e23938c3f49c6658502efb5 100644 --- a/arch/um/drivers/slip_user.c +++ b/arch/um/drivers/slip_user.c @@ -17,11 +17,12 @@ #include "os.h" #include "um_malloc.h" -void slip_user_init(void *data, void *dev) +static int slip_user_init(void *data, void *dev) { struct slip_data *pri = data; pri->dev = dev; + return 0; } static int set_up_tty(int fd) diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c index ce5e85d1de3d8029ca968033d2d66117de66abcf..f0a40abc8abffcc4fa8cae86560a5a3c2970ba0b 100644 --- a/arch/um/drivers/slirp_user.c +++ b/arch/um/drivers/slirp_user.c @@ -15,11 +15,12 @@ #include "slip_common.h" #include "os.h" -void slirp_user_init(void *data, void *dev) +static int slirp_user_init(void *data, void *dev) { struct slirp_data *pri = data; pri->dev = dev; + return 0; } struct slirp_pre_exec_data { diff --git a/arch/um/include/net_user.h b/arch/um/include/net_user.h index 19f207cd70fe4b3bf6ed33dee917a58622055d9a..cfe7c50634b9dd45a88a9d77bbe04dd8643fb9ff 100644 --- a/arch/um/include/net_user.h +++ b/arch/um/include/net_user.h @@ -14,7 +14,7 @@ #define UML_NET_VERSION (4) struct net_user_info { - void (*init)(void *, void *); + int (*init)(void *, void *); int (*open)(void *); void (*close)(int, void *); void (*remove)(void *); diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c index f3ad0dac7cdc32cf73970b093c4e61ae2f7d287a..2cc2d3ea2e6d8a5c684dc7c105baa7f296b96636 100644 --- a/arch/um/os-Linux/drivers/ethertap_user.c +++ b/arch/um/os-Linux/drivers/ethertap_user.c @@ -24,11 +24,12 @@ #define MAX_PACKET ETH_MAX_PACKET -void etap_user_init(void *data, void *dev) +static int etap_user_init(void *data, void *dev) { struct ethertap_data *pri = data; pri->dev = dev; + return 0; } struct addr_change { diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c index ab63fb6f999230d48fe04f616976a58d55ce44fa..506ef09d83a0f215e6db90ad7663bca954b397b0 100644 --- a/arch/um/os-Linux/drivers/tuntap_user.c +++ b/arch/um/os-Linux/drivers/tuntap_user.c @@ -24,11 +24,12 @@ #define MAX_PACKET ETH_MAX_PACKET -void tuntap_user_init(void *data, void *dev) +static int tuntap_user_init(void *data, void *dev) { struct tuntap_data *pri = data; pri->dev = dev; + return 0; } static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask,