summaryrefslogtreecommitdiff
path: root/xpp/xproto.c
diff options
context:
space:
mode:
authortzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-07-08 00:43:31 +0000
committertzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2006-07-08 00:43:31 +0000
commitec6b220aa7a334ccbd0fcb41d35c66560fc78a11 (patch)
tree8ee3f2338f95b3fa67f8512adb8fe4842643c391 /xpp/xproto.c
parent4e4b79bf56f6477b65973c869e5a8936aea27864 (diff)
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
Diffstat (limited to 'xpp/xproto.c')
-rw-r--r--xpp/xproto.c88
1 files changed, 50 insertions, 38 deletions
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 <oron@actcom.co.il>
- * 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 <linux/module.h>
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;
}