summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatteo <matteo@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2003-03-14 06:00:34 +0000
committermatteo <matteo@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2003-03-14 06:00:34 +0000
commitb7171ef3ad852bec92c85aeb388c3454c44d9ab8 (patch)
tree7ce7b23f9685cdb8eb1b64fbd1e988bbf4ba3831
parentcddcc315433c262a54bbe769d281a0b9c0526d55 (diff)
Fri Mar 14 07:00:01 CET 2003
git-svn-id: http://svn.digium.com/svn/zaptel/trunk@153 5390a7c7-147a-4af0-8ec9-7488f05a26cb
-rwxr-xr-xwcusb.c6
-rwxr-xr-xzaptel.c91
-rwxr-xr-xzaptel.h6
3 files changed, 77 insertions, 26 deletions
diff --git a/wcusb.c b/wcusb.c
index 5bed63b..96be5ae 100755
--- a/wcusb.c
+++ b/wcusb.c
@@ -98,9 +98,9 @@ static alpha indirect_regs[] =
{23,"PULSE_ENVEL",0x2000},
{24,"PULSE_X",0x2000},
{25,"PULSE_Y",0x0000},
-{26,"RECV_DIGITAL_GAIN",0x4000}, // playback volume set lower
-//{26,"RECV_DIGITAL_GAIN",0x2000}, // playback volume set lower
-{27,"XMIT_DIGITAL_GAIN",0x4000},
+//{26,"RECV_DIGITAL_GAIN",0x4000}, // playback volume set lower
+{26,"RECV_DIGITAL_GAIN",0x2000}, // playback volume set lower
+{27,"XMIT_DIGITAL_GAIN",0x8000},
{28,"LOOP_CLOSE_TRES",0x1000},
{29,"RING_TRIP_TRES",0x3600},
{30,"COMMON_MIN_TRES",0x1000},
diff --git a/zaptel.c b/zaptel.c
index ad11786..1fdfa62 100755
--- a/zaptel.c
+++ b/zaptel.c
@@ -800,7 +800,7 @@ static void reset_conf(struct zt_chan *chan)
static void close_channel(struct zt_chan *chan)
{
- unsigned int flags;
+ unsigned long flags;
void *rxgain = NULL;
echo_can_state_t *ec = NULL;
int oldconf;
@@ -871,6 +871,8 @@ static void close_channel(struct zt_chan *chan)
#ifdef CONFIG_ZAPATA_PPP
if (ppp) {
+ tasklet_kill(&chan->ppp_calls);
+ skb_queue_purge(&chan->ppp_rq);
ppp_unregister_channel(ppp);
kfree(ppp);
}
@@ -1040,7 +1042,7 @@ static int zt_chan_reg(struct zt_chan *chan)
{
int x;
int res=0;
- unsigned int flags;
+ unsigned long flags;
write_lock_irqsave(&chan_lock, flags);
for (x=1;x<ZT_MAX_CHANNELS;x++) {
@@ -1293,7 +1295,9 @@ static int zt_ppp_xmit(struct ppp_channel *ppp, struct sk_buff *skb)
spin_unlock_irqrestore(&ss->lock, flags);
if (retval) {
/* Get rid of the SKB if we're returning non-zero */
- dev_kfree_skb_any(skb);
+ /* N.B. this is called in process or BH context so
+ dev_kfree_skb is OK. */
+ dev_kfree_skb(skb);
}
return retval;
}
@@ -1313,7 +1317,7 @@ static struct ppp_channel_ops ztppp_ops =
static void zt_chan_unreg(struct zt_chan *chan)
{
int x;
- unsigned int flags;
+ unsigned long flags;
write_lock_irqsave(&chan_lock, flags);
if (chan->flags & ZT_FLAG_REGISTERED) {
chans[chan->channo] = NULL;
@@ -1362,7 +1366,7 @@ static ssize_t zt_chan_read(struct file *file, char *usrbuf, size_t count, int u
int amnt;
int res, rv;
int oldbuf,x;
- unsigned int flags;
+ unsigned long flags;
if (!chan)
return -EINVAL;
if (count < 1)
@@ -1436,7 +1440,7 @@ static ssize_t zt_chan_read(struct file *file, char *usrbuf, size_t count, int u
static ssize_t zt_chan_write(struct file *file, const char *usrbuf, size_t count, int unit)
{
- unsigned int flags;
+ unsigned long flags;
struct zt_chan *chan = chans[unit];
int res, amnt, oldbuf, rv,x;
if (!chan)
@@ -1688,7 +1692,7 @@ static int zt_hangup(struct zt_chan *chan)
static int initialize_channel(struct zt_chan *chan)
{
int res;
- unsigned int flags;
+ unsigned long flags;
void *rxgain=NULL;
echo_can_state_t *ec=NULL;
if ((res = zt_reallocbufs(chan, ZT_DEFAULT_BLOCKSIZE, ZT_DEFAULT_NUM_BUFS)))
@@ -2216,7 +2220,7 @@ static int zt_common_ioctl(struct inode *node, struct file *file, unsigned int c
struct zt_chan *chan,mychan;
int i,j;
struct zt_params param;
- unsigned int flags;
+ unsigned long flags;
switch(cmd) {
case ZT_GET_PARAMS: /* get channel timing parameters */
@@ -2490,7 +2494,7 @@ static int zt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cmd
struct zt_chan *newmaster;
struct zt_dialparams tdp;
struct zt_maintinfo maint;
- unsigned int flags;
+ unsigned long flags;
int rv;
switch(cmd) {
@@ -2763,7 +2767,7 @@ static int zt_chanandpseudo_ioctl(struct inode *inode, struct file *file, unsign
struct zt_bufferinfo bi;
struct zt_confinfo conf;
struct zt_ring_cadence cad;
- unsigned int flags;
+ unsigned long flags;
int i, j, k, rv;
int ret, c;
@@ -3205,10 +3209,37 @@ static int zt_chanandpseudo_ioctl(struct inode *inode, struct file *file, unsign
return 0;
}
+#ifdef CONFIG_ZAPATA_PPP
+/*
+ * This is called at softirq (BH) level when there are calls
+ * we need to make to the ppp_generic layer. We do it this
+ * way because the ppp_generic layer functions may not be called
+ * at interrupt level.
+ */
+static void do_ppp_calls(unsigned long data)
+{
+ struct zt_chan *chan = (struct zt_chan *) data;
+ struct sk_buff *skb;
+
+ if (!chan->ppp)
+ return;
+ if (chan->do_ppp_wakeup) {
+ chan->do_ppp_wakeup = 0;
+ ppp_output_wakeup(chan->ppp);
+ }
+ while ((skb = skb_dequeue(&chan->ppp_rq)) != NULL)
+ ppp_input(chan->ppp, skb);
+ if (chan->do_ppp_error) {
+ chan->do_ppp_error = 0;
+ ppp_input_error(chan->ppp, 0);
+ }
+}
+#endif
+
static int zt_chan_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long data, int unit)
{
struct zt_chan *chan = chans[unit];
- unsigned int flags;
+ unsigned long flags;
int j, rv;
int ret;
echo_can_state_t *ec, *tec;
@@ -3241,6 +3272,10 @@ static int zt_chan_ioctl(struct inode *inode, struct file *file, unsigned int cm
chan->ppp->ops = &ztppp_ops;
chan->ppp->mtu = ZT_DEFAULT_MTU_MRU;
chan->ppp->hdrlen = 0;
+ skb_queue_head_init(&chan->ppp_rq);
+ chan->do_ppp_wakeup = 0;
+ tasklet_init(&chan->ppp_calls, do_ppp_calls,
+ (unsigned long)chan);
if ((ret = zt_reallocbufs(chan, ZT_DEFAULT_MTU_MRU, ZT_DEFAULT_NUM_BUFS))) {
kfree(chan->ppp);
chan->ppp = NULL;
@@ -3271,9 +3306,12 @@ static int zt_chan_ioctl(struct inode *inode, struct file *file, unsigned int cm
} else {
chan->flags &= ~(ZT_FLAG_PPP | ZT_FLAG_HDLC | ZT_FLAG_FCS);
if (chan->ppp) {
- ppp_unregister_channel(chan->ppp);
- kfree(chan->ppp);
+ struct ppp_channel *ppp = chan->ppp;
chan->ppp = NULL;
+ tasklet_kill(&chan->ppp_calls);
+ skb_queue_purge(&chan->ppp_rq);
+ ppp_unregister_channel(ppp);
+ kfree(ppp);
}
}
#else
@@ -4018,7 +4056,8 @@ out in the later versions, and is put back now. */
#endif
#ifdef CONFIG_ZAPATA_PPP
if (ms->flags & ZT_FLAG_PPP) {
- ppp_output_wakeup(ms->ppp);
+ ms->do_ppp_wakeup = 1;
+ tasklet_schedule(&ms->ppp_calls);
}
#endif
}
@@ -4658,7 +4697,10 @@ static inline void zt_putbuf_chunk(struct zt_chan *ss, unsigned char *rxb)
/* Drop the FCS */
ms->readn[ms->inreadbuf] -= 2;
/* Allocate an SKB */
- skb = dev_alloc_skb(ms->readn[ms->inreadbuf]);
+#ifdef CONFIG_ZAPATA_PPP
+ if (!ms->do_ppp_error)
+#endif
+ skb = dev_alloc_skb(ms->readn[ms->inreadbuf]);
if (skb) {
/* XXX Get rid of this memcpy XXX */
memcpy(skb->data, ms->readbuf[ms->inreadbuf], ms->readn[ms->inreadbuf]);
@@ -4670,14 +4712,14 @@ static inline void zt_putbuf_chunk(struct zt_chan *ss, unsigned char *rxb)
#endif
#ifdef CONFIG_ZAPATA_PPP
if (ms->flags & ZT_FLAG_PPP) {
- printk("Would call ppp_input_error\n");
-#if 1
- ppp_input_error(ms->ppp, 0);
-#endif
+ abort = ZT_EVENT_OVERRUN;
}
#endif
#if 1
- printk("Memory squeeze, dropped one\n");
+#ifdef CONFIG_ZAPATA_PPP
+ if (!ms->do_ppp_error)
+#endif
+ printk("Memory squeeze, dropped one\n");
#endif
}
}
@@ -4744,7 +4786,8 @@ out in the later versions, and is put back now. */
#endif
#ifdef CONFIG_ZAPATA_PPP
if (ms->flags & ZT_FLAG_PPP) {
- ppp_input_error(ms->ppp, 0);
+ ms->do_ppp_error = 1;
+ tasklet_schedule(&ms->ppp_calls);
} else
#endif
@@ -4773,8 +4816,10 @@ out in the later versions, and is put back now. */
if (tmp)
printk("Received invalid SKB (%02x, %02x)\n", tmp[0], tmp[1]);
dev_kfree_skb_irq(skb);
- } else
- ppp_input(ms->ppp, skb);
+ } else {
+ skb_queue_tail(&ms->ppp_rq, skb);
+ tasklet_schedule(&ms->ppp_calls);
+ }
}
#endif
}
diff --git a/zaptel.h b/zaptel.h
index f6614aa..9a2f9a3 100755
--- a/zaptel.h
+++ b/zaptel.h
@@ -36,6 +36,8 @@
#endif
#ifdef CONFIG_ZAPATA_PPP
#include <linux/ppp_channel.h>
+#include <linux/skbuff.h>
+#include <linux/interrupt.h>
#endif
#include <linux/fs.h>
@@ -801,6 +803,10 @@ struct zt_chan {
#endif
#ifdef CONFIG_ZAPATA_PPP
struct ppp_channel *ppp;
+ struct tasklet_struct ppp_calls;
+ int do_ppp_wakeup;
+ int do_ppp_error;
+ struct sk_buff_head ppp_rq;
#endif
spinlock_t lock;
char name[40]; /* Name */