From d717b83056e5076a64c9471dd85573de409582d7 Mon Sep 17 00:00:00 2001 From: tzafrir Date: Thu, 25 Jan 2007 10:48:33 +0000 Subject: * Xbus protocol version: 2.4 (Zaptel 1.2.12/1.4.0 had 2.3). XPS Init scripts renamed accordingly. * 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. git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.2@1966 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- xpp/xproto.c | 102 +++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 72 insertions(+), 30 deletions(-) (limited to 'xpp/xproto.c') diff --git a/xpp/xproto.c b/xpp/xproto.c index 4c72d3f..5b62494 100644 --- a/xpp/xproto.c +++ b/xpp/xproto.c @@ -55,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 ----------------------------*/ @@ -153,43 +163,45 @@ 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 packet_process(xbus_t *xbus, xpacket_t *pack) { byte op; const xproto_entry_t *xe; xproto_handler_t handler; xproto_table_t *table; xpd_t *xpd; - int xpd_num; int ret = 0; BUG_ON(!pack); - if(!valid_xpd_addr(&pack->content.addr)) { - static int rate_limit = 0; - - if((rate_limit++ % 5003) < 3) - dump_packet("packet_receive -- bad address", pack, print_dbg); + if(!valid_xpd_addr(&pack->addr)) { + if(printk_ratelimit()) + dump_packet("packet_process -- bad address", pack, print_dbg); ret = -EPROTO; goto out; } - op = pack->content.opcode; - xpd_num = XPD_NUM(pack->content.addr); - xpd = xpd_of(xbus, xpd_num); + 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_receive -- 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_receive -- wrong size", pack, print_dbg); + dump_packet("packet_process -- wrong size", pack, print_dbg); + } ret = -EPROTO; goto out; } @@ -198,7 +210,35 @@ int packet_receive(xbus_t *xbus, 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; } @@ -207,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) @@ -317,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); @@ -347,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