diff options
Diffstat (limited to 'xpp/card_global.c')
-rw-r--r-- | xpp/card_global.c | 135 |
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); |