Compare commits

...

3 Commits

Author SHA1 Message Date
Wendell Thompson
4b242c3f84 Raised E1 pulse level for wcte43x targets 2016-02-15 15:45:51 -06:00
Tzafrir Cohen
8d1f17fc44 dahdi-modules: load and unloads the modules
A script that performs the module loading / unloading instead of the
init script.

Other functionality of the init script is performed by udev hooks. But
manual initiation of modules loading or unloading is still needed on
several occasions.

This script should help enable the removal of the init script from the
DAHDI package.

Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>
2015-11-05 18:11:57 +02:00
Oron Peled
404a67d089 xpp: improve handling of USB sluggishness
* Drop PCM during sluggish events:
  - Drop both rx/tx (was only tx)
  - Drop almost all pcm until sluggishness stops (used to drop only
    single pcm each time).
  - Renamed: "drop_next_pcm" -> "drop_pcm" (to match new semantics)
  - Still allow "keep alive" PCM so Astribank will not reset FXS high-voltage.
    The "sluggish_pcm_keepalive" parameter set the rate (1/50 by default)
  - Added rx/tx drop statistics counters
  - Removed "pcm_tx_drops" (replaced by new statistics counters)

* Also improved format of /proc/xpp/XBUS-*/xpp_usb:
  - Show cummulative number of sluggish events.
  - Clearly show range (in usec) of usb_tx_delay[]

Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>
2015-11-02 10:49:42 +02:00
3 changed files with 132 additions and 21 deletions

72
dahdi-modules Executable file
View File

@@ -0,0 +1,72 @@
#!/bin/sh
MODULES="dahdi"
DAHDI_MODULES_FILE="/etc/dahdi/modules"
usage() {
cat <<EOF
$0: loads / unloads DAHDI kernel modules
Usage: $0 <load|unload>
* load: Loads all modules listed in /etc/dahdi/modules (one per line)
* unload: Unloads the DAHDI modules (all the modules that are dependencies
of $MODULES).
EOF
}
# recursively unload a module and its dependencies, if possible.
# where's modprobe -r when you need it?
# inputs: module to unload.
# returns: the result from
unload_module() {
module="$1"
line=`lsmod 2>/dev/null | grep "^$1 "`
if [ "$line" = '' ]; then return; fi # module was not loaded
set -- $line
# $1: the original module, $2: size, $3: refcount, $4: deps list
mods=`echo $4 | tr , ' '`
ec_modules=""
# xpp_usb keeps the xpds below busy if an xpp hardware is
# connected. Hence must be removed before them:
case "$module" in xpd_*) mods="xpp_usb $mods";; esac
for mod in $mods; do
case "$mod" in
dahdi_echocan_*)
ec_modules="$mod $ec_modules"
;;
*)
# run in a subshell, so it won't step over our vars:
(unload_module $mod)
;;
esac
done
# Now that all the other dependencies are unloaded, we can unload the
# dahdi_echocan modules. The drivers that register spans may keep
# references on the echocan modules before they are unloaded.
for mod in $ec_modules; do
(unload_module $mod)
done
rmmod $module
}
unload_modules() {
for module in "$@"; do
unload_module $module
done
}
load_modules() {
modules=`sed -e 's/#.*$//' $DAHDI_MODULES_FILE 2>/dev/null`
for line in $modules; do
modprobe $line
done
}
case "$1" in
load) load_modules "$@";;
unload) unload_modules $MODULES;;
*) usage;;
esac

View File

@@ -1709,7 +1709,7 @@ static void t43x_configure_e1(struct t43x *wc, int span_idx, int lineconfig)
__t43x_framer_set(wc, fidx, 0x21, 0x1c|cas);
/* Generate pulse mask for E1 */
__t43x_framer_set(wc, fidx, 0x26, 0x74); /* XPM0 */
__t43x_framer_set(wc, fidx, 0x26, 0xb5); /* XPM0 */
__t43x_framer_set(wc, fidx, 0x27, 0x02); /* XPM1 */
__t43x_framer_set(wc, fidx, 0x28, 0x00); /* XPM2 */

View File

@@ -49,7 +49,9 @@ static DEF_PARM(int, debug, 0, 0644, "Print DBG statements");
static DEF_PARM(int, usb1, 0, 0644, "Allow using USB 1.1 interfaces");
static DEF_PARM(uint, tx_sluggish, 2000, 0644, "A sluggish transmit (usec)");
static DEF_PARM(uint, drop_pcm_after, 6, 0644,
"Number of consecutive tx_sluggish to drop a PCM frame");
"Number of consecutive tx_sluggish to start dropping PCM");
static DEF_PARM(uint, sluggish_pcm_keepalive, 50, 0644,
"During sluggish -- Keep-alive PCM (1 every #)");
#include "dahdi_debug.h"
@@ -117,6 +119,8 @@ enum {
XUSB_N_TX_FRAMES,
XUSB_N_RX_ERRORS,
XUSB_N_TX_ERRORS,
XUSB_N_RX_DROPS,
XUSB_N_TX_DROPS,
XUSB_N_RCV_ZERO_LEN,
};
@@ -127,8 +131,14 @@ enum {
static struct xusb_counters {
char *name;
} xusb_counters[] = {
C_(RX_FRAMES), C_(TX_FRAMES), C_(RX_ERRORS), C_(TX_ERRORS),
C_(RCV_ZERO_LEN),};
C_(RX_FRAMES),
C_(TX_FRAMES),
C_(RX_ERRORS),
C_(TX_ERRORS),
C_(RX_DROPS),
C_(TX_DROPS),
C_(RCV_ZERO_LEN),
};
#undef C_
@@ -194,8 +204,7 @@ struct xusb {
unsigned int max_tx_delay;
uint usb_tx_delay[NUM_BUCKETS];
uint sluggish_debounce;
bool drop_next_pcm; /* due to sluggishness */
atomic_t pcm_tx_drops;
bool drop_pcm; /* due to sluggishness */
atomic_t usb_sluggish_count;
const char *manufacturer;
@@ -400,12 +409,23 @@ static int xframe_send_pcm(xbus_t *xbus, xframe_t *xframe)
BUG_ON(!xframe);
xusb = xusb_of(xbus);
BUG_ON(!xusb);
if (xusb->drop_next_pcm) {
FREE_SEND_XFRAME(xbus, xframe); /* return to pool */
xusb->drop_next_pcm = 0;
return -EIO;
if (xusb->drop_pcm) {
static int rate_limit;
if ((rate_limit++ % 1000) == 0)
XUSB_ERR(xusb, "Sluggish USB: drop tx-pcm (%d)\n",
rate_limit);
/* Let trickle of TX-PCM, so Astribank will not reset */
if (sluggish_pcm_keepalive &&
((rate_limit % sluggish_pcm_keepalive) != 0)) {
XUSB_COUNTER(xusb, TX_DROPS)++;
goto err;
}
}
return do_send_xframe(xbus, xframe);
err:
FREE_SEND_XFRAME(xbus, xframe); /* return to pool */
return -EIO;
}
/*
@@ -674,7 +694,6 @@ static int xusb_probe(struct usb_interface *interface,
sema_init(&xusb->sem, 1);
atomic_set(&xusb->pending_writes, 0);
atomic_set(&xusb->pending_reads, 0);
atomic_set(&xusb->pcm_tx_drops, 0);
atomic_set(&xusb->usb_sluggish_count, 0);
xusb->udev = udev;
xusb->interface = interface;
@@ -878,7 +897,6 @@ static void xpp_send_callback(USB_PASS_CB(urb))
i = NUM_BUCKETS - 1;
xusb->usb_tx_delay[i]++;
if (unlikely(usec > tx_sluggish)) {
atomic_inc(&xusb->usb_sluggish_count);
if (xusb->sluggish_debounce++ > drop_pcm_after) {
static int rate_limit;
@@ -888,12 +906,14 @@ static void xpp_send_callback(USB_PASS_CB(urb))
"Sluggish USB. Dropping next PCM frame "
"(pending_writes=%d)\n",
writes);
atomic_inc(&xusb->pcm_tx_drops);
xusb->drop_next_pcm = 1;
atomic_inc(&xusb->usb_sluggish_count);
xusb->drop_pcm = 1;
xusb->sluggish_debounce = 0;
}
} else
} else {
xusb->sluggish_debounce = 0;
xusb->drop_pcm = 0;
}
/* sync/async unlink faults aren't errors */
if (urb->status
&& !(urb->status == -ENOENT || urb->status == -ECONNRESET)) {
@@ -956,6 +976,26 @@ static void xpp_receive_callback(USB_PASS_CB(urb))
// if (debug)
// dump_xframe("USB_FRAME_RECEIVE", xbus, xframe, debug);
XUSB_COUNTER(xusb, RX_FRAMES)++;
if (xusb->drop_pcm) {
/* some protocol analysis */
static int rate_limit;
xpacket_t *pack = (xpacket_t *)(xframe->packets);
bool is_pcm = XPACKET_IS_PCM(pack);
if (is_pcm) {
if ((rate_limit++ % 1000) == 0)
XUSB_ERR(xusb,
"Sluggish USB: drop rx-pcm (%d)\n",
rate_limit);
/* Let trickle of RX-PCM, so Astribank will not reset */
if (sluggish_pcm_keepalive &&
((rate_limit % sluggish_pcm_keepalive)
!= 0)) {
XUSB_COUNTER(xusb, RX_DROPS)++;
goto err;
}
}
}
/* Send UP */
xbus_receive_xframe(xbus, xframe);
end:
@@ -1061,17 +1101,16 @@ static int xusb_read_proc_show(struct seq_file *sfile, void *data)
stamp_last_pcm_read, accumulate_diff);
#endif
memcpy(usb_tx_delay, xusb->usb_tx_delay, sizeof(usb_tx_delay));
seq_printf(sfile, "usb_tx_delay[%d,%d,%d]: ", USEC_BUCKET,
BUCKET_START, NUM_BUCKETS);
seq_printf(sfile, "usb_tx_delay[%dus - %dus]: ",
USEC_BUCKET * BUCKET_START,
USEC_BUCKET * NUM_BUCKETS);
for (i = BUCKET_START; i < NUM_BUCKETS; i++) {
seq_printf(sfile, "%6d ", usb_tx_delay[i]);
if (i == mark_limit)
seq_printf(sfile, "| ");
}
seq_printf(sfile, "\nPCM_TX_DROPS: %5d (sluggish: %d)\n",
atomic_read(&xusb->pcm_tx_drops),
atomic_read(&xusb->usb_sluggish_count)
);
seq_printf(sfile, "\nSluggish events: %d\n",
atomic_read(&xusb->usb_sluggish_count));
seq_printf(sfile, "\nCOUNTERS:\n");
for (i = 0; i < XUSB_COUNTER_MAX; i++) {
seq_printf(sfile, "\t%-15s = %d\n", xusb_counters[i].name,