summaryrefslogtreecommitdiff
path: root/linux/drivers/media
diff options
context:
space:
mode:
authorHolger Waechtler <devnull@localhost>2003-06-27 11:10:06 +0000
committerHolger Waechtler <devnull@localhost>2003-06-27 11:10:06 +0000
commit698696017b1949582cd2865bcf4f02ace6fc56dd (patch)
tree2a930045641f79fb404b96c23468542d15f33fc2 /linux/drivers/media
parentbbec8c46962ff58cd76508f46ce105839f944068 (diff)
downloadmediapointer-dvb-s2-698696017b1949582cd2865bcf4f02ace6fc56dd.tar.gz
mediapointer-dvb-s2-698696017b1949582cd2865bcf4f02ace6fc56dd.tar.bz2
flush work queues on deinitialisation, restart feeds in set_mac in work queue
Diffstat (limited to 'linux/drivers/media')
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_compat.h1
-rw-r--r--linux/drivers/media/dvb/dvb-core/dvb_net.c30
2 files changed, 23 insertions, 8 deletions
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_compat.h b/linux/drivers/media/dvb/dvb-core/dvb_compat.h
index 980b4cd85..50e451a7c 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_compat.h
+++ b/linux/drivers/media/dvb/dvb-core/dvb_compat.h
@@ -98,6 +98,7 @@ extern struct page * vmalloc_to_page(void *addr);
#define work_struct tq_struct
#define INIT_WORK(wq,routine,data) INIT_TQUEUE(wq,routine,data)
#define schedule_work(wq) schedule_task(wq)
+#define flush_scheduled_work() flush_scheduled_tasks()
#else
#include <linux/workqueue.h>
#endif
diff --git a/linux/drivers/media/dvb/dvb-core/dvb_net.c b/linux/drivers/media/dvb/dvb-core/dvb_net.c
index 1924ba76d..407e24c89 100644
--- a/linux/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/linux/drivers/media/dvb/dvb-core/dvb_net.c
@@ -57,10 +57,12 @@ struct dvb_net_priv {
#define RX_MODE_MULTI 1
#define RX_MODE_ALL_MULTI 2
#define RX_MODE_PROMISC 3
- struct work_struct wq;
+ struct work_struct set_multicast_list_wq;
+ struct work_struct restart_net_feed_wq;
};
+
/**
* Determine the packet's protocol ID. The rule here is that we
* assume 802.3 if the type field is short enough to be a length.
@@ -359,7 +361,7 @@ static int dvb_set_mc_filter (struct net_device *dev, struct dev_mc_list *mc)
}
-static void tq_set_multicast_list (void *data)
+static void wq_set_multicast_list (void *data)
{
struct net_device *dev = data;
struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
@@ -398,7 +400,7 @@ static void tq_set_multicast_list (void *data)
static void dvb_net_set_multicast_list (struct net_device *dev)
{
struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
- schedule_work(&priv->wq);
+ schedule_work(&priv->set_multicast_list_wq);
}
@@ -410,16 +412,26 @@ static int dvb_net_set_config (struct net_device *dev, struct ifmap *map)
}
-static int dvb_net_set_mac (struct net_device *dev, void *p)
+static void wq_restart_net_feed (void *data)
{
- struct sockaddr *addr=p;
-
- memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+ struct net_device *dev = data;
if (netif_running(dev)) {
dvb_net_feed_stop(dev);
dvb_net_feed_start(dev);
}
+}
+
+
+static int dvb_net_set_mac (struct net_device *dev, void *p)
+{
+ struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
+ struct sockaddr *addr=p;
+
+ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+ if (netif_running(dev))
+ schedule_work(&priv->restart_net_feed_wq);
return 0;
}
@@ -523,7 +535,8 @@ static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid)
priv->pid = pid;
priv->rx_mode = RX_MODE_UNI;
- INIT_WORK(&priv->wq, tq_set_multicast_list, net);
+ INIT_WORK(&priv->set_multicast_list_wq, wq_set_multicast_list, net);
+ INIT_WORK(&priv->restart_net_feed_wq, wq_restart_net_feed, net);
net->base_addr = pid;
@@ -545,6 +558,7 @@ static int dvb_net_remove_if(struct dvb_net *dvbnet, int num)
return -EBUSY;
dvb_net_stop(&dvbnet->device[num]);
+ flush_scheduled_work();
kfree(priv);
unregister_netdev(&dvbnet->device[num]);
dvbnet->state[num]=0;