summaryrefslogtreecommitdiff
path: root/xpp/xproto.c
diff options
context:
space:
mode:
authortzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2007-01-25 10:48:33 +0000
committertzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2007-01-25 10:48:33 +0000
commitd717b83056e5076a64c9471dd85573de409582d7 (patch)
treef46ebf64df73d8f513989d29f54e5b22b8bce2a5 /xpp/xproto.c
parenta11cf4664ea4fd14478f88c9118acd0f87ad7008 (diff)
* 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
Diffstat (limited to 'xpp/xproto.c')
-rw-r--r--xpp/xproto.c102
1 files changed, 72 insertions, 30 deletions
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);