From aa5c973611550c503cf534181e44b9e3f1113ffb Mon Sep 17 00:00:00 2001 From: Shaun Ruffell Date: Wed, 20 Oct 2010 12:23:16 +0000 Subject: [PATCH] dahdi: Atomically set/test if channel has associated network device. Push all tests for the DAHDI_FLAGBIT_NETDEV flag behind a 'dahdi_have_netdev' function so if CONFIG_DAHDI_NET is not defined the compiler can just remove all the flag tests. Also, makes sure that the bit is checked / set atomically. (closes issue #9379) Signed-off-by: Shaun Ruffell Acked-by: Kinsey Moore Acked-by: Russ Meyerriecks git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@9444 a0bf4364-ded3-4de4-8d8a-66a801d63aff --- drivers/dahdi/dahdi-base.c | 35 +++++++++++++++++++---------------- drivers/dahdi/tor2.c | 2 +- drivers/dahdi/wct1xxp.c | 2 +- drivers/dahdi/wct4xxp/base.c | 2 +- drivers/dahdi/wcte11xp.c | 2 +- drivers/dahdi/wcte12xp/base.c | 2 +- include/dahdi/kernel.h | 18 +++++++++++++++++- 7 files changed, 41 insertions(+), 22 deletions(-) diff --git a/drivers/dahdi/dahdi-base.c b/drivers/dahdi/dahdi-base.c index 6134192..7e28c52 100644 --- a/drivers/dahdi/dahdi-base.c +++ b/drivers/dahdi/dahdi-base.c @@ -1730,7 +1730,7 @@ static int dahdi_net_open(hdlc_device *hdlc) module_printk(KERN_NOTICE, "%s is already open!\n", ms->name); return -EBUSY; } - if (!(ms->flags & DAHDI_FLAG_NETDEV)) { + if (!dahdi_have_netdev(ms)) { module_printk(KERN_NOTICE, "%s is not a net device!\n", ms->name); return -EINVAL; } @@ -1791,7 +1791,7 @@ static void dahdi_net_close(hdlc_device *hdlc) return; #endif } - if (!(ms->flags & DAHDI_FLAG_NETDEV)) { + if (!dahdi_have_netdev(ms)) { #ifdef NEW_HDLC_INTERFACE module_printk(KERN_NOTICE, "dahdi_net_stop: %s is not a net device!\n", ms->name); return 0; @@ -2067,7 +2067,7 @@ static void dahdi_chan_unreg(struct dahdi_chan *chan) release_echocan(chan->ec_factory); #ifdef CONFIG_DAHDI_NET - if (chan->flags & DAHDI_FLAG_NETDEV) { + if (dahdi_have_netdev(chan)) { unregister_hdlc_device(chan->hdlcnetdev->netdev); free_netdev(chan->hdlcnetdev->netdev); kfree(chan->hdlcnetdev); @@ -2823,7 +2823,7 @@ static int dahdi_specchan_open(struct file *file) if (chan && chan->sig) { /* Make sure we're not already open, a net device, or a slave device */ - if (chan->flags & DAHDI_FLAG_NETDEV) + if (dahdi_have_netdev(chan)) res = -EBUSY; else if (chan->master != chan) res = -EBUSY; @@ -4234,7 +4234,7 @@ static int dahdi_ioctl_chanconfig(struct file *file, unsigned long data) } spin_lock_irqsave(&chan->lock, flags); #ifdef CONFIG_DAHDI_NET - if (chan->flags & DAHDI_FLAG_NETDEV) { + if (dahdi_have_netdev(chan)) { if (ztchan_to_dev(chan)->flags & IFF_UP) { spin_unlock_irqrestore(&chan->lock, flags); module_printk(KERN_WARNING, "Can't switch HDLC net mode on channel %s, since current interface is up\n", chan->name); @@ -4246,7 +4246,7 @@ static int dahdi_ioctl_chanconfig(struct file *file, unsigned long data) free_netdev(chan->hdlcnetdev->netdev); kfree(chan->hdlcnetdev); chan->hdlcnetdev = NULL; - chan->flags &= ~DAHDI_FLAG_NETDEV; + clear_bit(DAHDI_FLAGBIT_NETDEV, &chan->flags); } #else if (ch.sigtype == DAHDI_SIG_HDLCNET) { @@ -4368,7 +4368,7 @@ static int dahdi_ioctl_chanconfig(struct file *file, unsigned long data) res = -1; } if (!res) - chan->flags |= DAHDI_FLAG_NETDEV; + set_bit(DAHDI_FLAGBIT_NETDEV, &chan->flags); } else { module_printk(KERN_NOTICE, "Unable to allocate netdev: out of memory\n"); res = -1; @@ -4377,7 +4377,7 @@ static int dahdi_ioctl_chanconfig(struct file *file, unsigned long data) #endif if ((chan->sig == DAHDI_SIG_HDLCNET) && (chan == newmaster) && - !(chan->flags & DAHDI_FLAG_NETDEV)) + !dahdi_have_netdev(chan)) module_printk(KERN_NOTICE, "Unable to register HDLC device for channel %s\n", chan->name); if (!res) { /* Setup default law */ @@ -6770,7 +6770,8 @@ in the read or iomux call, etc). That is why the write and iomux calls start with an infinite loop that gets broken out of upon an active condition, otherwise keeps sleeping and looking. The part in this code got "optimized" out in the later versions, and is put back now. */ - if (!(ms->flags & (DAHDI_FLAG_NETDEV | DAHDI_FLAG_PPP))) { + if (!(ms->flags & DAHDI_FLAG_PPP) || + !dahdi_have_netdev(ms)) { wake_up_interruptible(&ms->writebufq); wake_up_interruptible(&ms->sel); if (ms->iomask & DAHDI_IOMUX_WRITE) @@ -6780,7 +6781,7 @@ out in the later versions, and is put back now. */ if (ms->flags & DAHDI_FLAG_HDLC) fasthdlc_tx_frame_nocheck(&ms->txhdlc); #ifdef CONFIG_DAHDI_NET - if (ms->flags & DAHDI_FLAG_NETDEV) + if (dahdi_have_netdev(ms)) netif_wake_queue(ztchan_to_dev(ms)); #endif #ifdef CONFIG_DAHDI_PPP @@ -7819,7 +7820,8 @@ static inline void __putbuf_chunk(struct dahdi_chan *ss, unsigned char *rxb, int module_printk(KERN_NOTICE, "EOF, len is %d\n", ms->readn[ms->inreadbuf]); #endif #if defined(CONFIG_DAHDI_NET) || defined(CONFIG_DAHDI_PPP) - if (ms->flags & (DAHDI_FLAG_NETDEV | DAHDI_FLAG_PPP)) { + if ((ms->flags & DAHDI_FLAG_PPP) || + dahdi_have_netdev(ms)) { #ifdef CONFIG_DAHDI_NET #endif /* CONFIG_DAHDI_NET */ /* Our network receiver logic is MUCH @@ -7841,7 +7843,7 @@ static inline void __putbuf_chunk(struct dahdi_chan *ss, unsigned char *rxb, int memcpy(skb->data, ms->readbuf[ms->inreadbuf], ms->readn[ms->inreadbuf]); skb_put(skb, ms->readn[ms->inreadbuf]); #ifdef CONFIG_DAHDI_NET - if (ms->flags & DAHDI_FLAG_NETDEV) { + if (dahdi_have_netdev(ms)) { struct net_device_stats *stats = hdlc_stats(ms->hdlcnetdev->netdev); stats->rx_packets++; stats->rx_bytes += ms->readn[ms->inreadbuf]; @@ -7850,7 +7852,7 @@ static inline void __putbuf_chunk(struct dahdi_chan *ss, unsigned char *rxb, int } else { #ifdef CONFIG_DAHDI_NET - if (ms->flags & DAHDI_FLAG_NETDEV) { + if (dahdi_have_netdev(ms)) { struct net_device_stats *stats = hdlc_stats(ms->hdlcnetdev->netdev); stats->rx_dropped++; } @@ -7948,7 +7950,7 @@ that the waitqueue is empty. */ ms->infcs = PPP_INITFCS; #ifdef CONFIG_DAHDI_NET - if (ms->flags & DAHDI_FLAG_NETDEV) { + if (dahdi_have_netdev(ms)) { struct net_device_stats *stats = hdlc_stats(ms->hdlcnetdev->netdev); stats->rx_errors++; if (abort == DAHDI_EVENT_OVERRUN) @@ -7973,7 +7975,7 @@ that the waitqueue is empty. */ } else /* No place to receive -- drop on the floor */ break; #ifdef CONFIG_DAHDI_NET - if (skb && (ms->flags & DAHDI_FLAG_NETDEV)) + if (skb && dahdi_have_netdev(ms)) #ifdef NEW_HDLC_INTERFACE { #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) @@ -8157,7 +8159,8 @@ int dahdi_hdlc_getbuf(struct dahdi_chan *ss, unsigned char *bufptr, unsigned int if (ss->inwritebuf < 0) ss->inwritebuf = oldbuf; - if (!(ss->flags & (DAHDI_FLAG_NETDEV | DAHDI_FLAG_PPP))) { + if (!(ss->flags & DAHDI_FLAG_PPP) || + !dahdi_have_netdev(ss)) { wake_up_interruptible(&ss->writebufq); wake_up_interruptible(&ss->sel); if ((ss->iomask & DAHDI_IOMUX_WRITE) && (res >= 0)) diff --git a/drivers/dahdi/tor2.c b/drivers/dahdi/tor2.c index f30f9f7..93e0dbd 100644 --- a/drivers/dahdi/tor2.c +++ b/drivers/dahdi/tor2.c @@ -1397,7 +1397,7 @@ DAHDI_IRQ_HANDLER(tor2_intr) /* go thru all chans, and count # open */ for (n = 0, k = 0; k < tor->tspans[i].dahdi_span.channels; k++) { if (((tor->chans[i][k])->flags & DAHDI_FLAG_OPEN) || - ((tor->chans[i][k])->flags & DAHDI_FLAG_NETDEV)) + dahdi_have_netdev(tor->chans[i][k])) n++; } /* if none open, set alarm condition */ diff --git a/drivers/dahdi/wct1xxp.c b/drivers/dahdi/wct1xxp.c index 76b038f..e5ed794 100644 --- a/drivers/dahdi/wct1xxp.c +++ b/drivers/dahdi/wct1xxp.c @@ -1072,7 +1072,7 @@ static void t1xxp_check_alarms(struct t1xxp *wc) if (wc->span.lineconfig & DAHDI_CONFIG_NOTOPEN) { for (x=0,j=0;x < wc->span.channels;x++) if ((wc->chans[x]->flags & DAHDI_FLAG_OPEN) || - (wc->chans[x]->flags & DAHDI_FLAG_NETDEV)) + dahdi_have_netdev(wc->chans[x])) j++; if (!j) alarms |= DAHDI_ALARM_NOTOPEN; diff --git a/drivers/dahdi/wct4xxp/base.c b/drivers/dahdi/wct4xxp/base.c index d04fce2..7cc44bc 100644 --- a/drivers/dahdi/wct4xxp/base.c +++ b/drivers/dahdi/wct4xxp/base.c @@ -3158,7 +3158,7 @@ static void t4_check_alarms(struct t4 *wc, int span) if (ts->span.lineconfig & DAHDI_CONFIG_NOTOPEN) { for (x=0,j=0;x < ts->span.channels;x++) if ((ts->span.chans[x]->flags & DAHDI_FLAG_OPEN) || - (ts->span.chans[x]->flags & DAHDI_FLAG_NETDEV)) + dahdi_have_netdev(ts->span.chans[x])) j++; if (!j) alarms |= DAHDI_ALARM_NOTOPEN; diff --git a/drivers/dahdi/wcte11xp.c b/drivers/dahdi/wcte11xp.c index 3a1eef2..bb50cd9 100644 --- a/drivers/dahdi/wcte11xp.c +++ b/drivers/dahdi/wcte11xp.c @@ -1247,7 +1247,7 @@ static void t1_check_alarms(struct t1 *wc) if (wc->span.lineconfig & DAHDI_CONFIG_NOTOPEN) { for (x=0,j=0;x < wc->span.channels;x++) if ((wc->span.chans[x]->flags & DAHDI_FLAG_OPEN) || - (wc->span.chans[x]->flags & DAHDI_FLAG_NETDEV)) + dahdi_have_netdev(wc->span.chans[x])) j++; if (!j) alarms |= DAHDI_ALARM_NOTOPEN; diff --git a/drivers/dahdi/wcte12xp/base.c b/drivers/dahdi/wcte12xp/base.c index edb7848..be0e54f 100644 --- a/drivers/dahdi/wcte12xp/base.c +++ b/drivers/dahdi/wcte12xp/base.c @@ -1723,7 +1723,7 @@ static inline void t1_check_alarms(struct t1 *wc) if (wc->span.lineconfig & DAHDI_CONFIG_NOTOPEN) { for (x=0,j=0;x < wc->span.channels;x++) if ((wc->span.chans[x]->flags & DAHDI_FLAG_OPEN) || - (wc->span.chans[x]->flags & DAHDI_FLAG_NETDEV)) + dahdi_have_netdev(wc->span.chans[x])) j++; if (!j) alarms |= DAHDI_ALARM_NOTOPEN; diff --git a/include/dahdi/kernel.h b/include/dahdi/kernel.h index 6edddbd..cf9ee3c 100644 --- a/include/dahdi/kernel.h +++ b/include/dahdi/kernel.h @@ -692,7 +692,9 @@ enum { DAHDI_FLAGBIT_MFDECODE = 3, /*!< Channel supports native MFr2 decode */ DAHDI_FLAGBIT_ECHOCANCEL= 4, /*!< Channel supports native echo cancellation */ DAHDI_FLAGBIT_HDLC = 5, /*!< Perform HDLC */ +#ifdef CONFIG_DAHDI_NET DAHDI_FLAGBIT_NETDEV = 6, /*!< Send to network */ +#endif DAHDI_FLAGBIT_CLEAR = 8, /*!< Clear channel */ DAHDI_FLAGBIT_AUDIO = 9, /*!< Audio mode channel */ DAHDI_FLAGBIT_OPEN = 10, /*!< Channel is open */ @@ -708,6 +710,20 @@ enum { DAHDI_FLAGBIT_HDLC56 = 20, /*!< Sets the given channel (if in HDLC mode) to use 56K HDLC instead of 64K */ }; +#ifdef CONFIG_DAHDI_NET +/** + * have_netdev() - Return true if a channel has an associated network device. + * @chan: Then channel to check. + * + */ +static inline int dahdi_have_netdev(const struct dahdi_chan *chan) +{ + return test_bit(DAHDI_FLAGBIT_NETDEV, &chan->flags); +} +#else +static inline int dahdi_have_netdev(const struct dahdi_chan *chan) { return 0; } +#endif + struct dahdi_count { __u32 fe; /*!< Framing error counter */ __u32 cv; /*!< Coding violations counter */ @@ -740,7 +756,7 @@ struct dahdi_count { #define DAHDI_FLAG_ECHOCANCEL DAHDI_FLAG(ECHOCANCEL) #define DAHDI_FLAG_HDLC DAHDI_FLAG(HDLC) -#define DAHDI_FLAG_NETDEV DAHDI_FLAG(NETDEV) +/* #define DAHDI_FLAG_NETDEV DAHDI_FLAG(NETDEV) */ #define DAHDI_FLAG_CLEAR DAHDI_FLAG(CLEAR) #define DAHDI_FLAG_AUDIO DAHDI_FLAG(AUDIO)