summaryrefslogtreecommitdiff
path: root/xpp/card_global.c
diff options
context:
space:
mode:
authortzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-11-30 21:46:11 +0000
committertzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-11-30 21:46:11 +0000
commit9e81e78446308a27fd157ca7943a25457c59075d (patch)
tree37a1e55a7b3c364b1b525ddb2fa00c247ef561c1 /xpp/card_global.c
parent4c1daa46b5a30fec3c37558e9d02a8d616c88eda (diff)
r2817@boole: oron | 2006-11-28 13:39:47 +0200
Maintenance branch for asterisk-1.2.x git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.2@1666 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'xpp/card_global.c')
-rw-r--r--xpp/card_global.c41
1 files changed, 26 insertions, 15 deletions
diff --git a/xpp/card_global.c b/xpp/card_global.c
index 4740eab..22456bc 100644
--- a/xpp/card_global.c
+++ b/xpp/card_global.c
@@ -30,15 +30,6 @@
static const char rcsid[] = "$Id$";
DEF_PARM(charp,initdir, "/usr/share/zaptel", "The directory of card initialization scripts");
-/*
- * BRI: Temporary software workaround for firmware limitation:
- * - The BRI firmware count PCM channel number globally across subunits.
- * - The module parameter 'bri_pcmshift' enables us to cheat and shift
- * each B-channel, 4 bits for each subsequent subunit.
- * - Eventually, this should be fixed in the firmware, otherwise we won't
- * handle PRI (all the space we have is 32bits).
- */
-DEF_PARM(bool,bri_pcmshift, 1, "TESTING: shift bri PCM bits by subunit number");
extern int print_dbg;
static bool pcm_valid(xpd_t *xpd, xpacket_t *pack);
@@ -94,7 +85,11 @@ static void global_packet_dump(const char *msg, xpacket_t *pack);
}
buf += ZT_CHUNKSIZE;
}
- if(bri_pcmshift) { /* workaround for pcm problem in BRI */
+ /*
+ * BRI: Software workaround for firmware limitation.
+ * The BRI firmware count PCM channel number globally across subunits.
+ */
+ if(xpd->type == XPD_TYPE_BRI_NT || xpd->type == XPD_TYPE_BRI_TE) {
lines = lines << (xpd->addr.subunit * 4);
RPACKET_FIELD(pack, GLOBAL, PCM_WRITE, lines) = lines;
}
@@ -153,17 +148,22 @@ HANDLER_DEF(GLOBAL, DEV_DESC)
card_desc->type = type;
card_desc->rev = rev;
card_desc->xpd_addr = xpd_addr;
+ DBG("%s: xpd=%d-%d type=%d rev=%d line_status=0x%04X\n",
+ xbus->busname, xpd_addr.unit, xpd_addr.subunit, type, rev, line_status);
spin_lock_irqsave(&xbus->lock, flags);
- DBG("xpd=%d-%d type=%d rev=%d line_status=0x%04X\n",
- xpd_addr.unit, xpd_addr.subunit, type, rev, line_status);
if(type == XPD_TYPE_NOMODULE)
XBUS_COUNTER(xbus, DEV_DESC_EMPTY)++;
else
XBUS_COUNTER(xbus, DEV_DESC_FULL)++;
atomic_inc(&xbus->count_poll_answers);
- wake_up(&xbus->wait_for_polls);
list_add_tail(&card_desc->card_list, &xbus->poll_results);
spin_unlock_irqrestore(&xbus->lock, flags);
+ /*
+ * wake_up only after exiting our critical section.
+ * We suspect that otherwise a spinlock nesting may occur
+ * and cause a panic (if spinlock debugging is compiled in).
+ */
+ wake_up(&xbus->wait_for_polls);
return 0;
}
@@ -176,6 +176,7 @@ HANDLER_DEF(GLOBAL, PCM_READ)
volatile u_char *r;
unsigned long flags;
int i;
+ xpp_line_t old_lines = lines;
BUG_ON(!xbus);
if(!xpd) {
@@ -188,11 +189,20 @@ HANDLER_DEF(GLOBAL, PCM_READ)
}
// DBG("lines=0x%04X\n", lines);
- if(bri_pcmshift) { /* workaround for pcm problem in BRI */
+ /*
+ * BRI: Software workaround for firmware limitation.
+ * The BRI firmware count PCM channel number globally across subunits.
+ */
+ if(xpd->type == XPD_TYPE_BRI_NT || xpd->type == XPD_TYPE_BRI_TE) {
lines = (lines >> (xpd->addr.subunit * 4)) & 0x7;
RPACKET_FIELD(pack, GLOBAL, PCM_WRITE, lines) = lines;
}
if(!pcm_valid(xpd, pack)) {
+ static int rate_limit;
+
+ if((rate_limit++ % 5001) == 0)
+ ERR("%s/%s: old_lines=0x%04X lines=0x%04X subunit=%d\n",
+ xpd->xbus->busname, xpd->xpdname, old_lines, lines, xpd->addr.subunit);
return -EPROTO;
}
spin_lock_irqsave(&xpd->lock, flags);
@@ -313,7 +323,8 @@ static bool pcm_valid(xpd_t *xpd, xpacket_t *pack)
XPD_COUNTER(xpd, RECV_ERRORS)++;
if((rate_limit++ % 1000) <= 10) {
- ERR("BAD PCM REPLY: pack->datalen=%d, count=%d\n", pack->datalen, count);
+ ERR("%s/%s: BAD PCM REPLY: pack->datalen=%d, count=%d\n",
+ xpd->xbus->busname, xpd->xpdname, pack->datalen, count);
dump_packet("BAD PCM REPLY", pack, 1);
}
return 0;