From ec6b220aa7a334ccbd0fcb41d35c66560fc78a11 Mon Sep 17 00:00:00 2001 From: tzafrir Date: Sat, 8 Jul 2006 00:43:31 +0000 Subject: xpp Release 1.1.0 : * FPGA firmware now loaded from PC (for newer models) * Driver for the FXO module (xpd_fxo.ko) * Moved most userspace files to the subdirectory utils (see also next commit) * Explicit license for firmware files * Optionally avoid auto-registration * Registers initializations code is done by a userspace script. * Remove obsolete .inc initialization files (we use user-space init) * Added an install target to the utils dir. * Updated README.Astribank accordingly. * Using RBS signalling, as caller ID did not work well otherwise. * Better handling of USB protocol errors. * Fixed some procfs-related races. * per-card-module ioctls. * fxotune support. * opermode support (set through /etc/default/zaptel for now) * Userspace initialization script can also read registers. * Power calibration works (and implemented in perl) * some fine-tuning to the regster initialization parameters. * Leds turn on before registration and turn off after it. git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.2@1212 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- xpp/xproto.c | 88 ++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 50 insertions(+), 38 deletions(-) (limited to 'xpp/xproto.c') diff --git a/xpp/xproto.c b/xpp/xproto.c index 5a0d5c6..7e6dd56 100644 --- a/xpp/xproto.c +++ b/xpp/xproto.c @@ -1,6 +1,6 @@ /* * Written by Oron Peled - * Copyright (C) 2004-2005, Xorcom + * Copyright (C) 2004-2006, Xorcom * * All rights reserved. * @@ -23,6 +23,8 @@ #include "xpd.h" #include "xproto.h" #include "xpp_zap.h" +#include "xbus-core.h" +#include "zap_debug.h" #include static const char rcsid[] = "$Id$"; @@ -32,26 +34,25 @@ static int packet_process(xbus_t *xbus, int xpd_num, xpacket_t *pack); static const xproto_table_t *xprotocol_tables[XPD_TYPE_NOMODULE]; +#if MAX_UNIT*MAX_SUBUNIT > MAX_XPDS +#error MAX_XPDS is too small +#endif + bool valid_xpd_addr(const xpd_addr_t *addr) { - return ((addr->bank_num & ~0x1) == 0) && ((addr->card_id & ~0x3) == 0); + return ((addr->subunit & ~0x1) == 0) && ((addr->unit & ~0x3) == 0); } int xpd_addr2num(const xpd_addr_t *addr) { BUG_ON(!valid_xpd_addr(addr)); - return addr->bank_num * 4 + addr->card_id; + return addr->unit + addr->subunit * MAX_UNIT; } void xpd_set_addr(xpd_addr_t *addr, int xpd_num) { - if(xpd_num < 4) { - addr->card_id = xpd_num; - addr->bank_num = 0; - } else { - addr->card_id = xpd_num % 4; - addr->bank_num = xpd_num / 4; - } + addr->unit = xpd_num % MAX_UNIT; + addr->subunit = xpd_num / MAX_UNIT; } @@ -75,7 +76,7 @@ const xproto_entry_t *xproto_global_entry(byte opcode) return xe; } -const xproto_handler_t xproto_global_handler(byte opcode) +xproto_handler_t xproto_global_handler(byte opcode) { return xproto_card_handler(&PROTO_TABLE(GLOBAL), opcode); } @@ -87,7 +88,7 @@ const xproto_table_t *xproto_table(xpd_type_t cardtype) return xprotocol_tables[cardtype]; } -const xproto_table_t *get_xproto_table(xpd_type_t cardtype) +const xproto_table_t *xproto_get(xpd_type_t cardtype) { const xproto_table_t *xtable; @@ -95,18 +96,34 @@ const xproto_table_t *get_xproto_table(xpd_type_t cardtype) return NULL; xtable = xprotocol_tables[cardtype]; if(!xtable) { /* Try to load the relevant module */ - int ret = request_module("xpd-type-%d", cardtype); + int ret = request_module(XPD_TYPE_PREFIX "%d", cardtype); if(ret != 0) { NOTICE("%s: Failed to load module for type=%d. exit status=%d.\n", __FUNCTION__, cardtype, ret); - /* Drop through: we may be luck... */ + /* Drop through: we may be lucky... */ } xtable = xprotocol_tables[cardtype]; } + if(xtable) { + BUG_ON(!xtable->owner); + DBG("%s refcount was %d\n", xtable->name, module_refcount(xtable->owner)); + if(!try_module_get(xtable->owner)) { + ERR("%s: try_module_get for %s failed.\n", __FUNCTION__, xtable->name); + return NULL; + } + } return xtable; } -const xproto_handler_t xproto_card_handler(const xproto_table_t *table, byte opcode) +void xproto_put(const xproto_table_t *xtable) +{ + BUG_ON(!xtable); + DBG("%s refcount was %d\n", xtable->name, module_refcount(xtable->owner)); + BUG_ON(module_refcount(xtable->owner) <= 0); + module_put(xtable->owner); +} + +xproto_handler_t xproto_card_handler(const xproto_table_t *table, byte opcode) { const xproto_entry_t *xe; @@ -115,7 +132,7 @@ const xproto_handler_t xproto_card_handler(const xproto_table_t *table, byte opc return xe->handler; } -const xproto_entry_t *find_xproto_entry(xpd_t *xpd, byte opcode) +static const xproto_entry_t *find_xproto_entry(xpd_t *xpd, byte opcode) { const xproto_entry_t *xe; @@ -136,18 +153,6 @@ const xproto_entry_t *find_xproto_entry(xpd_t *xpd, byte opcode) return xe; } -const xops_t *get_xops(xpd_type_t xpd_type) -{ - const xproto_table_t *proto_table; - - if(xpd_type >= XPD_TYPE_NOMODULE) - return NULL; - proto_table = xprotocol_tables[xpd_type]; - if(!proto_table) - return NULL; - return &proto_table->xops; -} - int packet_receive(xbus_t *xbus, xpacket_t *pack) { int xpd_num; @@ -161,7 +166,7 @@ int packet_receive(xbus_t *xbus, xpacket_t *pack) return -EPROTO; } xpd_num = XPD_NUM(pack->content.addr); -#if SOFT_SIMULATOR +#ifdef SOFT_SIMULATOR if(xbus->sim[xpd_num].simulated) { //dump_packet("packet_receive -> simulate", pack, print_dbg); return simulate_xpd(xbus, xpd_num, pack); @@ -189,7 +194,8 @@ static int packet_process(xbus_t *xbus, int xpd_num, xpacket_t *pack) xe = find_xproto_entry(xpd, op); /*-------- Validations -----------*/ if(!xe) { - ERR("xpp: %s -- bad command op=0x%02X\n", __FUNCTION__, op); + 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); ret = -EPROTO; goto out; @@ -221,10 +227,10 @@ void dump_packet(const char *msg, xpacket_t *packet, bool print_dbg) if(!print_dbg) return; - DBG("%s: @0x%1X%1X OP=0x%02X LEN=%d\n", + DBG("%s: U=0x%1X S=0x%1X OP=0x%02X LEN=%d\n", msg, - packet->content.addr.bank_num, - packet->content.addr.card_id, + packet->content.addr.unit, + packet->content.addr.subunit, op, (byte)packet->datalen); #if VERBOSE_DEBUG @@ -256,7 +262,7 @@ const char *xproto_name(xpd_type_t xpd_type) { const xproto_table_t *proto_table; - BUG_ON(xpd_type >= XPD_TYPE(NOMODULE)); + BUG_ON(xpd_type >= XPD_TYPE_NOMODULE); proto_table = xprotocol_tables[xpd_type]; if(!proto_table) return NULL; @@ -278,7 +284,7 @@ int xproto_register(const xproto_table_t *proto_table) BUG_ON(!proto_table); type = proto_table->type; name = proto_table->name; - if(type >= XPD_TYPE(NOMODULE)) { + if(type >= XPD_TYPE_NOMODULE) { NOTICE("%s: Bad xproto type %d\n", __FUNCTION__, type); return -EINVAL; } @@ -290,14 +296,20 @@ int xproto_register(const xproto_table_t *proto_table) CHECK_XOP(card_init); CHECK_XOP(card_remove); CHECK_XOP(card_tick); + CHECK_XOP(card_zaptel_preregistration); + CHECK_XOP(card_zaptel_postregistration); +#ifdef WITH_RBS + CHECK_XOP(card_hooksig); +#else + CHECK_XOP(card_sethook); +#endif + // CHECK_XOP(card_ioctl); // optional method -- call after testing CHECK_XOP(SYNC_SOURCE); CHECK_XOP(PCM_WRITE); CHECK_XOP(CHAN_ENABLE); - CHECK_XOP(CHAN_POWER); CHECK_XOP(CHAN_CID); CHECK_XOP(RING); CHECK_XOP(SETHOOK); - CHECK_XOP(LED); CHECK_XOP(RELAY_OUT); xprotocol_tables[type] = proto_table; @@ -313,7 +325,7 @@ void xproto_unregister(const xproto_table_t *proto_table) type = proto_table->type; name = proto_table->name; DBG("%s (%d)\n", name, type); - if(type >= XPD_TYPE(NOMODULE)) { + if(type >= XPD_TYPE_NOMODULE) { NOTICE("%s: Bad xproto type %s (%d)\n", __FUNCTION__, name, type); return; } -- cgit v1.2.3