Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
void dump_packet(const char *msg, const xpacket_t *packet, bool debug)
{
	byte	op = XPACKET_OP(packet);
	byte	*addr = (byte *)&XPACKET_ADDR(packet);

	if(!debug)
		return;
	printk(KERN_DEBUG "%s: XPD=%1X-%1X%c (0x%X) OP=0x%02X LEN=%d",
			msg,
			XPACKET_ADDR_UNIT(packet),
			XPACKET_ADDR_SUBUNIT(packet),
			(XPACKET_ADDR_SYNC(packet))?'+':' ',
			*addr,
			op,
			XPACKET_LEN(packet));
#if VERBOSE_DEBUG
	{
		int i;
		byte	*p = (byte *)packet;

		printk(" BYTES: ");
		for(i = 0; i < XPACKET_LEN(packet); i++) {
			static int limiter = 0;

			if(i >= sizeof(xpacket_t)) {
				if(limiter < ERR_REPORT_LIMIT) {
					ERR("%s: length overflow i=%d > sizeof(xpacket_t)=%lu\n",
						__FUNCTION__, i+1, (long)sizeof(xpacket_t));
				} else if(limiter == ERR_REPORT_LIMIT) {
					ERR("%s: error packet #%d... squelsh reports.\n",
						__FUNCTION__, limiter);
				}
				limiter++;
				break;
			}
			if (debug)
				printk("%02X ", p[i]);
		}
	}
#endif
	printk("\n");
}
Ejemplo n.º 3
0
static int xframe_receive_cmd(xbus_t *xbus, xframe_t *xframe)
{
	byte		*xframe_end;
	xpacket_t	*pack;
	byte		*p;
	int		len;
	int		ret;

	if(debug & DBG_COMMANDS)
		dump_xframe("RX-CMD", xbus, xframe, DBG_ANY);
	p = xframe->packets;
	xframe_end = p + XFRAME_LEN(xframe);
	do {
		pack = (xpacket_t *)p;
		len = XPACKET_LEN(pack);
		/* Sanity checks */
		if(unlikely(XPACKET_OP(pack) == XPROTO_NAME(GLOBAL,PCM_READ))) {
			static int	rate_limit;

			if((rate_limit++ % 1003) == 0) {
				XBUS_DBG(GENERAL, xbus, "A PCM packet within a Non-PCM xframe\n");
				dump_xframe("In Non-PCM xframe", xbus, xframe, debug);
			}
			ret = -EPROTO;
			goto out;
		}
		p += len;
		if(p > xframe_end || len < RPACKET_HEADERSIZE) {
			static int	rate_limit;

			if((rate_limit++ % 1003) == 0) {
				XBUS_NOTICE(xbus, "Invalid packet length %d\n", len);
				dump_xframe("BAD LENGTH", xbus, xframe, debug);
			}
			ret = -EPROTO;
			goto out;
		}
		ret = packet_process(xbus, pack);
		if(unlikely(ret < 0))
			break;
	} while(p < xframe_end);
out:
	FREE_RECV_XFRAME(xbus, xframe);
	return ret;
}
Ejemplo n.º 4
0
static 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			ret = -EPROTO;

	BUG_ON(!pack);
	if(!valid_xpd_addr(&XPACKET_ADDR(pack))) {
		if(printk_ratelimit()) {
			XBUS_NOTICE(xbus, "%s: from %d%d: bad address.\n",
					__FUNCTION__,
					XPACKET_ADDR_UNIT(pack), XPACKET_ADDR_SUBUNIT(pack));
			dump_packet("packet_process -- bad address", pack, debug);
		}
		goto out;
	}
	op = XPACKET_OP(pack);
	xpd = xpd_byaddr(xbus, XPACKET_ADDR_UNIT(pack), XPACKET_ADDR_SUBUNIT(pack));
	/* XPD may be NULL (e.g: during bus polling */
	xe = xproto_global_entry(op);
	/*-------- Validations -----------*/
	if(!xe) {
		const xproto_table_t *xtable;
		
		if(!xpd) {
			if(printk_ratelimit()) {
				XBUS_NOTICE(xbus, "%s: from %d%d opcode=0x%02X: no such global command.\n",
						__FUNCTION__,
						XPACKET_ADDR_UNIT(pack), XPACKET_ADDR_SUBUNIT(pack), op);
				dump_packet("packet_process -- no such global command", pack, 1);
			}
			goto out;
		}
		xtable = xproto_table(xpd->type);
		if(!xtable) {
			if(printk_ratelimit())
				XPD_ERR(xpd, "%s: no protocol table (type=%d)\n",
					__FUNCTION__,
					xpd->type);
			goto out;
		}
		xe = xproto_card_entry(xtable, op);
		if(!xe) {
			if(printk_ratelimit()) {
				XPD_NOTICE(xpd, "%s: bad command (type=%d,opcode=0x%x)\n",
					__FUNCTION__,
					xpd->type, op);
				dump_packet("packet_process -- bad command", pack, 1);
			}
			goto out;
		}
	}
	table = xe->table;
	BUG_ON(!table);
	if(!table->packet_is_valid(pack)) {
		if(printk_ratelimit()) {
			ERR("xpp: %s: wrong size %d for opcode=0x%02X\n",
					__FUNCTION__, XPACKET_LEN(pack), op);
			dump_packet("packet_process -- wrong size", pack, debug);
		}
		goto out;
	}
	ret = 0;	/* All well */
	handler = xe->handler;
	BUG_ON(!handler);
	XBUS_COUNTER(xbus, RX_BYTES) += XPACKET_LEN(pack);
	handler(xbus, xpd, xe, pack);
out:
	return ret;
}
Ejemplo n.º 5
0
static int copy_pcm_tospan(xbus_t *xbus, xframe_t *xframe)
{
	byte		*xframe_end;
	xpacket_t	*pack;
	byte		*p;
	int		ret = -EPROTO;	/* Assume error */

	if(debug & DBG_PCM)
		dump_xframe("RX_XFRAME_PCM", xbus, xframe, debug);
	/* handle content */

	p = xframe->packets;
	xframe_end = p + XFRAME_LEN(xframe);
	do {
		int		len;
		xpd_t		*xpd;

		pack = (xpacket_t *)p;
		len = XPACKET_LEN(pack);
		/* Sanity checks */
		if(unlikely(XPACKET_OP(pack) != XPROTO_NAME(GLOBAL,PCM_READ))) {
			static int	rate_limit;

			if((rate_limit++ % 1003) == 0) {
				XBUS_NOTICE(xbus,
					"%s: Non-PCM packet within a PCM xframe. (%d)\n",
					__FUNCTION__, rate_limit);
				dump_xframe("In PCM xframe", xbus, xframe, debug);
			}
			goto out;
		}
		p += len;
		if(p > xframe_end || len < RPACKET_HEADERSIZE) {
			static int	rate_limit;

			if((rate_limit++ % 1003) == 0) {
				XBUS_NOTICE(xbus,
					"%s: Invalid packet length %d. (%d)\n",
					__FUNCTION__, len, rate_limit);
				dump_xframe("BAD LENGTH", xbus, xframe, debug);
			}
			goto out;
		}
		xpd = xpd_byaddr(xbus, XPACKET_ADDR_UNIT(pack), XPACKET_ADDR_SUBUNIT(pack));
		if(unlikely(!xpd)) {
			static int	rate_limit;

			if((rate_limit++ % 1003) == 0) {
				notify_bad_xpd(__FUNCTION__, xbus, XPACKET_ADDR(pack), "RECEIVE PCM");
				dump_xframe("Unknown XPD addr", xbus, xframe, debug);
			}
			goto out;
		}
		if(!pcm_valid(xpd, pack))
			goto out;
		if(SPAN_REGISTERED(xpd)) {
			XBUS_COUNTER(xbus, RX_PACK_PCM)++;
			CALL_XMETHOD(card_pcm_tospan, xbus, xpd, pack);
		}
	} while(p < xframe_end);
	ret = 0;	/* all good */
	XBUS_COUNTER(xbus, RX_XFRAME_PCM)++;
out:
	FREE_RECV_XFRAME(xbus, xframe);
	return ret;
}