diff options
author | Shaun Ruffell <sruffell@digium.com> | 2010-02-08 23:22:25 +0000 |
---|---|---|
committer | Shaun Ruffell <sruffell@digium.com> | 2010-02-08 23:22:25 +0000 |
commit | de76afabf2e413a149ae0ef0477bd64e71b3bc0d (patch) | |
tree | 43acbc68c3550d417024d37b4e0ad43d02eaf7fb /drivers/dahdi/voicebus | |
parent | 4e67fd27670cf690cdb2d4f8560e31c9670dedb3 (diff) |
voicebus: Reset own bits when a soft underrun is detected.
If a combination of softunderun results in descriptors that aren't owned being
skipped in the vb_recover_tx_descriptor_list, it's possible for processing to
stop on a descriptor that isn't owned.
git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@8010 a0bf4364-ded3-4de4-8d8a-66a801d63aff
Diffstat (limited to 'drivers/dahdi/voicebus')
-rw-r--r-- | drivers/dahdi/voicebus/voicebus.c | 46 |
1 files changed, 36 insertions, 10 deletions
diff --git a/drivers/dahdi/voicebus/voicebus.c b/drivers/dahdi/voicebus/voicebus.c index 913b62c..d68c1f3 100644 --- a/drivers/dahdi/voicebus/voicebus.c +++ b/drivers/dahdi/voicebus/voicebus.c @@ -1134,6 +1134,27 @@ static inline void vb_set_all_tx_owned(struct voicebus *vb) } /** + * vb_reset_tx_owned() - Reset the OWN bits on descriptors from tail to head. + * + * When there is a softunderun, this function will cleanup what should be the + * idle buffers that we do not expect to be in progress. + * + */ +static void vb_reset_tx_owned(struct voicebus *vb) +{ + struct voicebus_descriptor_list *dl = &vb->txd; + struct voicebus_descriptor *d; + unsigned int tail = dl->tail; + + while (tail != dl->head) { + d = vb_descriptor(dl, tail); + SET_OWNED(d); + ++tail; + tail &= DRING_MASK; + } +} + +/** * __vb_get_default_behind_count() - Returns how many idle buffers are loaded in tx fifo. * * These buffers are going to be set, but the AN983 does not clear the owned @@ -1336,16 +1357,21 @@ static void vb_deferred(struct voicebus *vb) * descriptor ring. Otherwise it's possible to take so much time * printing the dmesg output that we lose the lead that we got on the * hardware, resulting in a hard underrun condition. */ - if (unlikely(softunderrun && - !test_bit(LATENCY_LOCKED, &vb->flags) && printk_ratelimit())) { - if (vb->max_latency != vb->min_tx_buffer_count) { - dev_info(&vb->pdev->dev, "Missed interrupt. " - "Increasing latency to %d ms in order to " - "compensate.\n", vb->min_tx_buffer_count); - } else { - dev_info(&vb->pdev->dev, "ERROR: Unable to service " - "card within %d ms and unable to further " - "increase latency.\n", vb->max_latency); + if (unlikely(softunderrun)) { + vb_reset_tx_owned(vb); + if (!test_bit(LATENCY_LOCKED, &vb->flags) && + printk_ratelimit()) { + if (vb->max_latency != vb->min_tx_buffer_count) { + dev_info(&vb->pdev->dev, "Missed interrupt. " + "Increasing latency to %d ms in " + "order to compensate.\n", + vb->min_tx_buffer_count); + } else { + dev_info(&vb->pdev->dev, "ERROR: Unable to " + "service card within %d ms and " + "unable to further increase " + "latency.\n", vb->max_latency); + } } } |