#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)
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.
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;
{
static const struct ethtool_drvinfo info = {
.cmd = ETHTOOL_GDRVINFO,
- .driver = "uml virtual ethernet",
+ .driver = DRIVER_NAME,
.version = "42",
};
void *useraddr;
#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)
{
return 1;
}
+ /* sysfs register */
+ if (!driver_registered) {
+ driver_register(¨_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.
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);
}
" Configure a network device.\n\n"
);
+#if 0
static int eth_init(void)
{
struct list_head *ele, *next;
return(1);
}
-
__initcall(eth_init);
+#endif
static int net_config(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);
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);