From cc599ab08d6f58a2d5e57db4150e2f9efe1112b8 Mon Sep 17 00:00:00 2001 From: tzafrir Date: Fri, 9 Feb 2007 19:12:55 +0000 Subject: Merged revisions 2123-2124 via svnmerge from https://origsvn.digium.com/svn/zaptel/branches/1.4 ........ r2123 | tzafrir | 2007-02-08 02:05:17 +0200 (Thu, 08 Feb 2007) | 27 lines Branch 1.4 is back in sync (currently: xorcom rev. 3332): * Performance improvements for multi-XPD (span) devices. * Astribank BRI driver (in next commit). * Changes under /proc: - XBUS and XPD numbers have two digits. - Every script wildcard should be replaced from XBUS-? to XBUS-[0-9]* - Added /proc/xpp/XBUS-*/XPD-*/blink: echo 1 to start and 0 to stop. * Several countries (South Africa, UAE, anybody else) require a shorter ring delay. Adjust FXO reg 0x17 (23)'s bits 0:2 to 011. * Use tasklets to move most of the interrupt PCM copying out of the interrupt. * Debugfs-based code to dump data to userspace (used to debug BRI D channel). * Pretend every 2.6.9 actually has later RHEL's typedefs. * fpga_load supports /dev/bus/usb . * Fixed physical order sorting in genzaptelconf. * Reverse polarity and power denial detection. * A short led flash at registration time. * Add a real version of the xpp modules to them (independent of the Zaptel version). * Update our line status even when not registered. * Fixed a false SIG_CHANGED when inserting or removing cable to FXO. * Fixed compilation fixes for 2.6.20 (Bug #8982) * A cleaner fix for the bool changes of 2.6.19 . * Automatically detect echo_can_state_t at debug time. * Automaitcally set XPP_DEBUGFS (depending on debugfs) at compile time. * Bug-fixes to zaptel-helper. Moved to xpp/utils . * Xbus protocol version: 2.4 (Zaptel 1.2.12/1.4.0 had 2.3). XPS Init scripts renamed accordingly. ........ r2124 | tzafrir | 2007-02-08 02:30:56 +0200 (Thu, 08 Feb 2007) | 1 line Now 'chans' is used after all. ........ git-svn-id: http://svn.digium.com/svn/zaptel/trunk@2144 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- xpp/xproto.c | 125 +++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 75 insertions(+), 50 deletions(-) (limited to 'xpp/xproto.c') diff --git a/xpp/xproto.c b/xpp/xproto.c index ebd9bba..5b62494 100644 --- a/xpp/xproto.c +++ b/xpp/xproto.c @@ -31,7 +31,6 @@ static const char rcsid[] = "$Id$"; extern int print_dbg; -static int packet_process(xbus_t *xbus, int xpd_num, xpacket_t *pack); static const xproto_table_t *xprotocol_tables[XPD_TYPE_NOMODULE]; @@ -56,6 +55,16 @@ void xpd_set_addr(xpd_addr_t *addr, int xpd_num) addr->subunit = (xpd_num >> UNIT_BITS) & BITMASK(SUBUNIT_BITS); } +xpd_t *xpd_by_addr(const xbus_t *xbus, int unit, int subunit) +{ + xpd_addr_t addr; + int xpd_num; + + addr.unit = unit; + addr.subunit = subunit; + xpd_num = xpd_addr2num(&addr); + return xpd_of(xbus, xpd_num); +} /*---------------- General Protocol Management ----------------------------*/ @@ -154,32 +163,7 @@ static const xproto_entry_t *find_xproto_entry(xpd_t *xpd, byte opcode) return xe; } -int packet_receive(xbus_t *xbus, xpacket_t *pack) -{ - int xpd_num; - - if(!valid_xpd_addr(&pack->content.addr)) { - static int rate_limit = 0; - - if((rate_limit++ % 5003) < 3) - dump_packet("bad address", pack, print_dbg); - xbus->ops->packet_free(xbus, pack); - return -EPROTO; - } - xpd_num = XPD_NUM(pack->content.addr); -#ifdef SOFT_SIMULATOR - if(xbus->sim[xpd_num].simulated) { - //dump_packet("packet_receive -> simulate", pack, print_dbg); - return simulate_xpd(xbus, xpd_num, pack); - } else -#endif - { - //dump_packet("packet_receive -> process", pack, print_dbg); - return packet_process(xbus, xpd_num, pack); - } -} - -static int packet_process(xbus_t *xbus, int xpd_num, xpacket_t *pack) +int packet_process(xbus_t *xbus, xpacket_t *pack) { byte op; const xproto_entry_t *xe; @@ -189,24 +173,35 @@ static int packet_process(xbus_t *xbus, int xpd_num, xpacket_t *pack) int ret = 0; BUG_ON(!pack); - op = pack->content.opcode; - xpd_num = XPD_NUM(pack->content.addr); - xpd = xpd_of(xbus, xpd_num); + if(!valid_xpd_addr(&pack->addr)) { + if(printk_ratelimit()) + dump_packet("packet_process -- bad address", pack, print_dbg); + ret = -EPROTO; + goto out; + } + op = pack->opcode; + xpd = xpd_by_addr(xbus, pack->addr.unit, pack->addr.subunit); + /* XPD may be NULL (e.g: during bus polling */ xe = find_xproto_entry(xpd, op); /*-------- Validations -----------*/ if(!xe) { - ERR("xpp: %s: %s unit #%d: bad command op=0x%02X\n", - __FUNCTION__, xbus->busname, xpd_num, op); - dump_packet("packet_process -- bad command", pack, print_dbg); + if(printk_ratelimit()) { + ERR("xpp: %s: %s/%d-%d: bad command op=0x%02X\n", + __FUNCTION__, xbus->busname, + pack->addr.unit, pack->addr.subunit, op); + dump_packet("packet_process -- bad command", pack, print_dbg); + } ret = -EPROTO; goto out; } table = xe->table; BUG_ON(!table); if(!table->packet_is_valid(pack)) { - ERR("xpp: %s: wrong size %d for op=0x%02X\n", + if(printk_ratelimit()) { + ERR("xpp: %s: wrong size %d for op=0x%02X\n", __FUNCTION__, pack->datalen, op); - dump_packet("packet_process -- wrong size", pack, print_dbg); + dump_packet("packet_process -- wrong size", pack, print_dbg); + } ret = -EPROTO; goto out; } @@ -215,7 +210,35 @@ static int packet_process(xbus_t *xbus, int xpd_num, xpacket_t *pack) XBUS_COUNTER(xbus, RX_BYTES) += pack->datalen; handler(xbus, xpd, xe, pack); out: - xbus->ops->packet_free(xbus, pack); + return ret; +} + +int xframe_receive(xbus_t *xbus, xframe_t *xframe) +{ + byte *p; + byte *xpacket_start; + byte *xframe_end; + int ret = 0; + static int rate_limit; + + if(print_dbg == 2 && ((rate_limit++ % 1003) == 0)) + dump_xframe("RCV_PCM", xbus, xframe); + p = xpacket_start = xframe->packets; + xframe_end = xpacket_start + XFRAME_LEN(xframe); + do { + xpacket_t *pack = (xpacket_t *)p; + int len = pack->datalen; + + p += len; + if(p > xframe_end) { + ERR("%s: Invalid packet length %d\n", __FUNCTION__, len); + ret = -EPROTO; + goto out; + } + packet_process(xbus, pack); + } while(p < xframe_end); +out: + xbus->ops->xframe_free(xbus, xframe); return ret; } @@ -224,41 +247,45 @@ out: void dump_packet(const char *msg, xpacket_t *packet, bool print_dbg) { - byte op = packet->content.opcode; - byte *addr = (byte *)&packet->content.addr; + byte op = packet->opcode; + byte *addr = (byte *)&packet->addr; if(!print_dbg) return; - DBG("%s: XPD=%1X-%1X (0x%X) OP=0x%02X LEN=%d\n", + DBG("%s: XPD=%1X-%1X (0x%X) OP=0x%02X LEN=%d", msg, - packet->content.addr.unit, - packet->content.addr.subunit, + packet->addr.unit, + packet->addr.subunit, *addr, op, (byte)packet->datalen); #if VERBOSE_DEBUG { int i; - byte *p = packet->content.data; + byte *p = (byte *)packet; + if (print_dbg) + printk(" BYTES: "); for(i = 0; i < packet->datalen; i++) { static int limiter = 0; - if(i >= sizeof(xpacket_raw_t)) { + if(i >= sizeof(xpacket_t)) { if(limiter < ERR_REPORT_LIMIT) { - ERR("%s: length overflow i=%d > sizeof(xpacket_raw_t)=%d\n", - __FUNCTION__, i+1, sizeof(xpacket_raw_t)); + ERR("%s: length overflow i=%d > sizeof(xpacket_t)=%d\n", + __FUNCTION__, i+1, sizeof(xpacket_t)); } else if(limiter == ERR_REPORT_LIMIT) { ERR("%s: error packet #%d... squelsh reports.\n", - __FUNCTION__, limiter); + __FUNCTION__, limiter); } limiter++; break; } - DBG(" %2d> %02X\n", i+1, p[i]); + if (print_dbg) + printk("%02X ", p[i]); } } #endif + printk("\n"); } void dump_reg_cmd(const char msg[], reg_cmd_t *regcmd) @@ -334,9 +361,7 @@ int xproto_register(const xproto_table_t *proto_table) CHECK_XOP(card_hooksig); // CHECK_XOP(card_ioctl); // optional method -- call after testing CHECK_XOP(SYNC_SOURCE); - CHECK_XOP(PCM_WRITE); CHECK_XOP(XPD_STATE); - CHECK_XOP(CHAN_CID); CHECK_XOP(RING); CHECK_XOP(RELAY_OUT); @@ -364,7 +389,7 @@ void xproto_unregister(const xproto_table_t *proto_table) EXPORT_SYMBOL(dump_packet); EXPORT_SYMBOL(dump_reg_cmd); -EXPORT_SYMBOL(packet_receive); +EXPORT_SYMBOL(xframe_receive); EXPORT_SYMBOL(valid_xpd_addr); EXPORT_SYMBOL(xpd_addr2num); EXPORT_SYMBOL(xpd_set_addr); -- cgit v1.2.3