summaryrefslogtreecommitdiff
path: root/xpp/xproto.c
diff options
context:
space:
mode:
Diffstat (limited to 'xpp/xproto.c')
-rw-r--r--xpp/xproto.c125
1 files changed, 75 insertions, 50 deletions
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);