int zaptel_sync_tick(struct zt_span *span, int is_master) { xpd_t *xpd = span->pvt; static int redundant_ticks; /* for extra spans */ struct timeval now; if(!force_zaptel_sync) goto noop; do_gettimeofday(&now); BUG_ON(!xpd); /* * Detect if any of our spans is zaptel sync master */ if(is_master) { static int rate_limit; if(xpd->xbus != syncer && ((rate_limit % 1003) == 0)) { XPD_ERR(xpd, "Zaptel master, but syncer=%s\n", xpd->xbus->busname); } if((rate_limit % 5003) == 0) XPD_NOTICE(xpd, "Zaptel master: ignore ZAPTEL sync\n"); rate_limit++; goto noop; } /* Now we know for sure someone else is zaptel sync master */ if(syncer) { static int rate_limit; if((rate_limit++ % 5003) == 0) XBUS_DBG(SYNC, syncer, "Already a syncer, ignore ZAPTEL sync\n"); goto noop; } /* ignore duplicate calls from all our registered spans */ if((redundant_ticks++ % total_registered_spans()) != 0) { #if 0 static int rate_limit; if((rate_limit++ % 1003) < 16) XPD_NOTICE(xpd, "boop (%d)\n", zaptel_tick_count); #endif goto noop; } xpp_ticker_step(&zaptel_ticker, &now); zaptel_tick_count++; //flip_parport_bit(1); return 0; noop: return 0; /* No auto sync from zaptel */ }
/* * Synchronous part of XPD detection. * Called from xbus_poll() */ int create_xpd(xbus_t *xbus, const xproto_table_t *proto_table, int unit, int subunit, byte type, byte subtype, int subunits, byte port_dir) { xpd_t *xpd = NULL; bool to_phone; int ret = -EINVAL; BUG_ON(type == XPD_TYPE_NOMODULE); to_phone = BIT(subunit) & port_dir; BUG_ON(!xbus); xpd = xpd_byaddr(xbus, unit, subunit); if(xpd) { XPD_NOTICE(xpd, "XPD at %d%d already exists\n", unit, subunit); goto out; } xpd = proto_table->xops.card_new(xbus, unit, subunit, proto_table, subtype, subunits, to_phone); if(!xpd) { XBUS_NOTICE(xbus, "card_new(%d,%d,%d,%d,%d) failed. Ignored.\n", unit, subunit, proto_table->type, subtype, to_phone); goto err; } out: return 0; err: if(xpd) xpd_free(xpd); return ret; }
static DEVICE_ATTR_WRITER(chipregs_store, dev, buf, count) { xpd_t *xpd; const char *p; char tmp[MAX_PROC_WRITE]; int i; int ret; BUG_ON(!dev); xpd = dev_to_xpd(dev); //XPD_DBG(GENERAL, xpd, "%s\n", buf); if (!xpd) return -ENODEV; p = buf; while ((p - buf) < count) { i = strcspn(p, "\r\n"); if (i > 0) { if (i >= MAX_PROC_WRITE) { XPD_NOTICE(xpd, "Command too long (%d chars)\n", i); return -E2BIG; } memcpy(tmp, p, i); tmp[i] = '\0'; ret = parse_chip_command(xpd, tmp); if (ret < 0) { XPD_NOTICE(xpd, "Failed writing command: '%s'\n", tmp); return ret; } } p += i + 1; /* Don't flood command_queue */ if (xframe_queue_count(&xpd->xbus->command_queue) > 5) msleep(6); } return count; }
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; }