summaryrefslogtreecommitdiff
path: root/xpp/card_global.c
diff options
context:
space:
mode:
authortzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2007-12-18 14:31:07 +0000
committertzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2007-12-18 14:31:07 +0000
commitcfd61537b47387b0fb5c8228baad6cec16d8f6e6 (patch)
tree108deea65c09c7c273a9b981f8783efcd433eaea /xpp/card_global.c
parent4391b4a6ee42bdfd8e097c5ee5485e9eb13f19a0 (diff)
xpp r5151:
* xpd_pri: Basically ready. * PCM synchronization changes: - Each Astribank unit ticks independently. Each with its own PLL. - HOST synchronization is gone. Loading of xpp will no longer cause useless 250 ticks per second if you have no Astribank. - Synchronization from the zaptel sync master requires setting ZAPTEL as sync source (xpp_sync ZAPTEL). * rx_tasklet is now a parameter of the module xpp, rather than of xpp_usb. * New FPGA firmware: 5128 (1151) / 5122 (1141, 1131): - Fixes synchronization issues. - PRI module: E1 should now work. * perl module and utilities: - Modules no longer magically scan system on initialization. - Scanning is by calling explicit methods. - "Serial" has been renamed "Label". It is basically unique, but should be modifieble. - Some basic documentation of zaptel perl modules. * Default sort order of zt_registration is back to SORT_CONNCTOR. * zt_registration proc file now shows the number of span registered to if registered. Try: grep . /proc/xpp/XBUS-*/XPD-*/zt_registration * genzaptelconf: Allow using a custom command instead of /etc/init.d/asterisk to start/stop asterisk. * Fixed the typo "Slagish". git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.2@3506 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'xpp/card_global.c')
-rw-r--r--xpp/card_global.c135
1 files changed, 23 insertions, 112 deletions
diff --git a/xpp/card_global.c b/xpp/card_global.c
index 2a8bdd8..a2c4ac0 100644
--- a/xpp/card_global.c
+++ b/xpp/card_global.c
@@ -34,7 +34,6 @@ static const char rcsid[] = "$Id$";
DEF_PARM(charp,initdir, "/usr/share/zaptel", 0644, "The directory of card initialization scripts");
extern int print_dbg;
-static bool pcm_valid(xpd_t *xpd, xpacket_t *pack);
/*---------------- GLOBAL Protocol Commands -------------------------------*/
@@ -53,7 +52,7 @@ static void global_packet_dump(const char *msg, xpacket_t *pack);
DBG(GENERAL, "NO XBUS\n");
return -EINVAL;
}
- XFRAME_NEW(xframe, pack, xbus, GLOBAL, DESC_REQ, xpd_num);
+ XFRAME_NEW_CMD(xframe, pack, xbus, GLOBAL, DESC_REQ, xpd_num);
XBUS_DBG(GENERAL, xbus, "to %1d%1d\n", XBUS_UNIT(xpd_num), XBUS_SUBUNIT(xpd_num));
ret = send_cmd_frame(xbus, xframe);
XBUS_COUNTER(xbus, DESC_REQ)++;
@@ -72,7 +71,7 @@ int xpp_register_request(xbus_t *xbus, xpd_t *xpd,
DBG(REGS, "NO XBUS\n");
return -EINVAL;
}
- XFRAME_NEW(xframe, pack, xbus, GLOBAL, REGISTER_REQUEST, xpd->xbus_idx);
+ XFRAME_NEW_CMD(xframe, pack, xbus, GLOBAL, REGISTER_REQUEST, xpd->xbus_idx);
LINE_DBG(REGS, xpd, chipsel, "%c%c R%02X S%02X %02X %02X\n",
(writing)?'W':'R',
(do_subreg)?'S':'D',
@@ -97,10 +96,15 @@ int xpp_register_request(xbus_t *xbus, xpd_t *xpd,
{
xframe_t *xframe;
xpacket_t *pack;
+ const char *mode_name;
BUG_ON(!xbus);
- XBUS_DBG(SYNC, xbus, "mode=0x%X drift=%d\n", mode, drift);
- XFRAME_NEW(xframe, pack, xbus, GLOBAL, SYNC_SOURCE, 0);
+ if((mode_name = sync_mode_name(mode)) == NULL) {
+ XBUS_ERR(xbus, "SYNC_SOURCE: bad sync_mode=0x%X\n", mode);
+ return -EINVAL;
+ }
+ XBUS_DBG(SYNC, xbus, "%s (0x%X), drift=%d\n", mode_name, mode, drift);
+ XFRAME_NEW_CMD(xframe, pack, xbus, GLOBAL, SYNC_SOURCE, 0);
RPACKET_FIELD(pack, GLOBAL, SYNC_SOURCE, sync_mode) = mode;
RPACKET_FIELD(pack, GLOBAL, SYNC_SOURCE, drift) = drift;
send_cmd_frame(xbus, xframe);
@@ -113,8 +117,8 @@ int xpp_register_request(xbus_t *xbus, xpd_t *xpd,
xpacket_t *pack;
BUG_ON(!xbus);
- XBUS_DBG(SYNC, xbus, "\n");
- XFRAME_NEW(xframe, pack, xbus, GLOBAL, RESET_SYNC_COUNTERS, 0);
+ //XBUS_DBG(SYNC, xbus, "\n");
+ XFRAME_NEW_CMD(xframe, pack, xbus, GLOBAL, RESET_SYNC_COUNTERS, 0);
RPACKET_FIELD(pack, GLOBAL, RESET_SYNC_COUNTERS, mask) = 0x10;
send_cmd_frame(xbus, xframe);
return 0;
@@ -170,81 +174,20 @@ HANDLER_DEF(GLOBAL, REGISTER_REPLY)
return CALL_XMETHOD(card_register_reply, xbus, xpd, reg);
}
-HANDLER_DEF(GLOBAL, PCM_READ)
-{
- struct xpd_addr addr = RPACKET_FIELD(pack, GLOBAL, PCM_READ, head.addr);
- struct timeval now;
- unsigned long sec_diff;
- unsigned long usec_diff;
-
- BUG_ON(!xbus);
- /*
- * FIXME:
- * Only calculate PCM statistics for unit==0, otherwise the data
- * of the PCM packets in the same xframe would clobber each other.
- *
- * This is just a workaround, since the true solution is to handle
- * each PCM frame separately (once the firmware guarantee that PCM
- * frames contain only PCM packets).
- *
- * On PRI we must fix this since the PCM is transmitted in two frames
- * and the following workaround only accounts for the first one.
- */
- if(addr.unit == 0) {
- do_gettimeofday(&now);
- sec_diff = now.tv_sec - xbus->last_rx_sync.tv_sec;
- usec_diff = sec_diff * 1000000 + (now.tv_usec - xbus->last_rx_sync.tv_usec);
- if(unlikely(abs(sec_diff) > 2)) {
- XBUS_DBG(SYNC, xbus, "PCM RX timing restart (sec_diff=%ld)\n", sec_diff);
- } else {
- if(abs(usec_diff - 1000) > TICK_TOLERANCE) {
- static int rate_limit;
-
- if((rate_limit++ % 5003) == 0)
- XBUS_DBG(SYNC, xbus, "Bad PCM RX timing(%d): usec_diff=%ld.\n",
- rate_limit, usec_diff);
- }
- if(usec_diff > xbus->max_rx_sync)
- xbus->max_rx_sync = usec_diff;
- if(usec_diff < xbus->min_rx_sync)
- xbus->min_rx_sync = usec_diff;
- }
- xbus->last_rx_sync = now;
- }
- if(!xpd) {
-#if 0
- notify_bad_xpd(__FUNCTION__, xbus, pack->addr, cmd->name);
-#endif
- return -EPROTO;
- }
- if(!pcm_valid(xpd, pack))
- return -EPROTO;
- XBUS_COUNTER(xbus, RX_PACK_PCM)++;
- CALL_XMETHOD(card_pcm_tospan, xbus, xpd, pack);
- flip_parport_bit(2);
- /*
- * Firmware marks the sync packets.
- * This is out of the loop, so we don't send multiple times
- * for BRI subunits.
- */
- if(addr.sync_master)
- got_sync_from(xpd);
- return 0;
-}
-
HANDLER_DEF(GLOBAL, SYNC_REPLY)
{
- byte mode = RPACKET_FIELD(pack, GLOBAL, SYNC_REPLY, sync_mode);
- byte drift = RPACKET_FIELD(pack, GLOBAL, SYNC_REPLY, drift);
+ byte mode = RPACKET_FIELD(pack, GLOBAL, SYNC_REPLY, sync_mode);
+ byte drift = RPACKET_FIELD(pack, GLOBAL, SYNC_REPLY, drift);
+ const char *mode_name;
BUG_ON(!xbus);
- if(!xpd) {
- notify_bad_xpd(__FUNCTION__, xbus, XPACKET_ADDR(pack), cmd->name);
- return -EPROTO;
+ if((mode_name = sync_mode_name(mode)) == NULL) {
+ XBUS_ERR(xbus, "SYNC_REPLY: bad sync_mode=0x%X\n", mode);
+ return -EINVAL;
}
- XPD_DBG(GENERAL, xpd, "mode=0x%X drift=%d\n", mode, drift);
- dump_packet("SYNC_REPLY", pack, print_dbg);
- xbus->sync_adjustment = (signed char)drift;
+ XBUS_DBG(SYNC, xbus, "%s (0x%X), drift=%d\n", mode_name, mode, drift);
+ //dump_packet("SYNC_REPLY", pack, print_dbg & DBG_SYNC);
+ got_new_syncer(xbus, mode, drift);
return 0;
}
@@ -292,7 +235,6 @@ xproto_table_t PROTO_TABLE(GLOBAL) = {
/* Prototable Card Opcode */
XENTRY( GLOBAL, GLOBAL, NULL_REPLY ),
XENTRY( GLOBAL, GLOBAL, DEV_DESC ),
- XENTRY( GLOBAL, GLOBAL, PCM_READ ),
XENTRY( GLOBAL, GLOBAL, SYNC_REPLY ),
XENTRY( GLOBAL, GLOBAL, ERROR_CODE ),
XENTRY( GLOBAL, GLOBAL, REGISTER_REPLY ),
@@ -316,38 +258,6 @@ static void global_packet_dump(const char *msg, xpacket_t *pack)
DBG(GENERAL, "%s\n", msg);
}
-static bool pcm_valid(xpd_t *xpd, xpacket_t *pack)
-{
- xpp_line_t lines = RPACKET_FIELD(pack, GLOBAL, PCM_READ, lines);
- int i;
- int count = 0;
- uint16_t good_len;
-
- BUG_ON(!pack);
- BUG_ON(XPACKET_OP(pack) != XPROTO_NAME(GLOBAL, PCM_READ));
-/*
- * Don't use for_each_line(xpd, i) here because for BRI it will ignore the channels of the other
- * xpd's in the same unit.
- */
- for (i = 0; i < CHANNELS_PERXPD; i++)
- if(IS_SET(lines, i))
- count++;
- /* FRAMES: include opcode in calculation */
- good_len = RPACKET_HEADERSIZE + sizeof(xpp_line_t) + count * 8;
- if(XPACKET_LEN(pack) != good_len) {
- static int rate_limit = 0;
-
- XPD_COUNTER(xpd, RECV_ERRORS)++;
- if((rate_limit++ % 1000) <= 10) {
- XPD_ERR(xpd, "BAD PCM REPLY: packet_len=%d (should be %d), count=%d\n",
- XPACKET_LEN(pack), good_len, count);
- dump_packet("BAD PCM REPLY", pack, 1);
- }
- return 0;
- }
- return 1;
-}
-
#define MAX_ENV_STR 40
#define MAX_PATH_STR 60
@@ -396,7 +306,7 @@ int run_initialize_registers(xpd_t *xpd)
XPD_NOTICE(xpd, "Cannot initialize. pathname is longer than %d characters.\n", MAX_PATH_STR);
return -E2BIG;
}
- if(!down_read_trylock(&xbus->in_use)) {
+ if(!XBUS_GET(xbus)) {
XBUS_ERR(xbus, "Skipped register initialization. XBUS is going down\n");
return -ENODEV;
}
@@ -421,9 +331,10 @@ int run_initialize_registers(xpd_t *xpd)
}
ret = -EINVAL;
}
- up_read(&xbus->in_use);
+ XBUS_PUT(xbus);
return ret;
}
+EXPORT_SYMBOL(sync_mode_name);
EXPORT_SYMBOL(run_initialize_registers);
EXPORT_SYMBOL(xpp_register_request);