From 7b37d36938b44708e642dae2286826f6c3b5e8ac Mon Sep 17 00:00:00 2001 From: sruffell Date: Thu, 4 Dec 2008 23:09:28 +0000 Subject: 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 --- kernel/wctc4xxp/base.c | 76 +++++++++++++++++++++++++++++--------------------- kernel/zttranscode.c | 5 ++-- 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 -- cgit v1.2.3