From 698696017b1949582cd2865bcf4f02ace6fc56dd Mon Sep 17 00:00:00 2001 From: Holger Waechtler Date: Fri, 27 Jun 2003 11:10:06 +0000 Subject: flush work queues on deinitialisation, restart feeds in set_mac in work queue --- linux/drivers/media/dvb/dvb-core/dvb_compat.h | 1 + linux/drivers/media/dvb/dvb-core/dvb_net.c | 30 ++++++++++++++++++++------- 2 files changed, 23 insertions(+), 8 deletions(-) (limited to 'linux/drivers/media') 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 #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; -- cgit v1.2.3