summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsruffell <sruffell@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-12-04 23:09:28 +0000
committersruffell <sruffell@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-12-04 23:09:28 +0000
commit7b37d36938b44708e642dae2286826f6c3b5e8ac (patch)
treedf78681a3e795d87d0554a903030263065ba7935
parentef7bbab6bcc4cef87bfa733964113262cc53b545 (diff)
Service the transmit descriptor ring before the receive descriptor ring so
that commands that are still sitting on the transmit descriptor ring are not completed twice. git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.4@4593 5390a7c7-147a-4af0-8ec9-7488f05a26cb
-rw-r--r--kernel/wctc4xxp/base.c76
-rw-r--r--kernel/zttranscode.c5
2 files changed, 46 insertions, 35 deletions
diff --git a/kernel/wctc4xxp/base.c b/kernel/wctc4xxp/base.c
index 4b22299..cfa0d30 100644
--- a/kernel/wctc4xxp/base.c
+++ b/kernel/wctc4xxp/base.c
@@ -1977,43 +1977,13 @@ wctc4xxp_receiveprep(struct wcdte *wc, struct tcb *cmd)
}
}
-static inline void service_dte(struct wcdte *wc)
+static inline void service_tx_ring(struct wcdte *wc)
{
struct tcb *cmd;
-
- /*
- * Process the received packets
- */
- while((cmd = wctc4xxp_retrieve(wc->rxd))) {
- struct tcb *newcmd;
-
- wctc4xxp_net_capture_cmd(wc, cmd);
-
- if(!(newcmd = __alloc_cmd(ALLOC_FLAGS, 0))) {
- DTE_PRINTK(ERR, "Out of memory in %s.\n", __FUNCTION__);
- } else {
- if (newcmd->data_len < MAX_FRAME_SIZE) {
- newcmd->data = kmalloc(MAX_FRAME_SIZE, ALLOC_FLAGS);
- if (!newcmd->data) {
- DTE_PRINTK(ERR, "out of memory in %s " \
- "again.\n", __FUNCTION__);
- }
- newcmd->data_len = MAX_FRAME_SIZE;
- }
- if (wctc4xxp_submit(wc->rxd, newcmd)) {
- DTE_PRINTK(ERR, "Failed submit in %s\n", __FUNCTION__);
- free_cmd(newcmd);
- }
- wctc4xxp_receive_demand_poll(wc);
- }
- wctc4xxp_receiveprep(wc, cmd);
- }
- wctc4xxp_receive_demand_poll(wc);
-
/*
* Process the transmit packets
*/
- while((cmd = wctc4xxp_retrieve(wc->txd))) {
+ while ((cmd = wctc4xxp_retrieve(wc->txd))) {
if (!(cmd->flags & (__WAIT_FOR_ACK | __WAIT_FOR_RESPONSE))) {
/* If we're not waiting for an ACK or Response from
* the DTE, this message should not be sitting on any
@@ -2043,6 +2013,45 @@ static inline void service_dte(struct wcdte *wc)
}
}
+static inline void service_rx_ring(struct wcdte *wc)
+{
+ struct tcb *cmd;
+ /*
+ * Process the received packets
+ */
+ while ((cmd = wctc4xxp_retrieve(wc->rxd))) {
+ struct tcb *newcmd;
+
+ wctc4xxp_net_capture_cmd(wc, cmd);
+
+ if(!(newcmd = __alloc_cmd(ALLOC_FLAGS, 0))) {
+ DTE_PRINTK(ERR, "Out of memory in %s.\n", __FUNCTION__);
+ } else {
+ if (newcmd->data_len < MAX_FRAME_SIZE) {
+ newcmd->data = kmalloc(MAX_FRAME_SIZE, ALLOC_FLAGS);
+ if (!newcmd->data) {
+ DTE_PRINTK(ERR, "out of memory in %s " \
+ "again.\n", __FUNCTION__);
+ }
+ newcmd->data_len = MAX_FRAME_SIZE;
+ }
+ if (wctc4xxp_submit(wc->rxd, newcmd)) {
+ DTE_PRINTK(ERR, "Failed submit in %s\n", __FUNCTION__);
+ free_cmd(newcmd);
+ }
+ wctc4xxp_receive_demand_poll(wc);
+ }
+ wctc4xxp_receiveprep(wc, cmd);
+ }
+ wctc4xxp_receive_demand_poll(wc);
+}
+
+static inline void service_dte(struct wcdte *wc)
+{
+ service_tx_ring(wc);
+ service_rx_ring(wc);
+}
+
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
static void deferred_work_func(void *param)
@@ -2834,6 +2843,9 @@ wctc4xxp_watchdog(unsigned long data)
LIST_HEAD(cmds_to_retry);
const int MAX_RETRIES = 5;
+ /* Check for any commands that have completed transmission. */
+ service_tx_ring(wc);
+
spin_lock(&wc->cmd_list_lock);
/* Go through the list of messages that are waiting for responses from
* the DTE, and complete or retry any that have timed out. */
diff --git a/kernel/zttranscode.c b/kernel/zttranscode.c
index 5462da8..70ba2e1 100644
--- a/kernel/zttranscode.c
+++ b/kernel/zttranscode.c
@@ -179,8 +179,7 @@ static int zt_tc_release(struct inode *inode, struct file *file)
/* Find a free channel on the transcoder and mark it busy. */
static inline struct zt_transcoder_channel *
-get_free_channel(struct zt_transcoder *tc)
-
+get_free_channel(struct zt_transcoder *tc, const struct zt_transcoder_formats *fmts)
{
struct zt_transcoder_channel *chan;
int i;
@@ -225,7 +224,7 @@ __find_free_channel(struct list_head *list, const struct zt_transcoder_formats *
/* We found a transcoder that can handle our formats.
* Now look for an available channel. */
match = 1;
- if ((chan = get_free_channel(tc))) {
+ if ((chan = get_free_channel(tc, fmts))) {
/* transcoder tc has a free channel. In order
* to spread the load among available
* transcoders (when there are more than one