summaryrefslogtreecommitdiff
path: root/kernel/xpp/xpp_zap.c
diff options
context:
space:
mode:
authortzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-05-13 21:08:09 +0000
committertzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-05-13 21:08:09 +0000
commitd7e54a785544ac40abc4a88383df3a913ca466e8 (patch)
treeabf630c8372e7c81407172ad31190fa8a617a8ed /kernel/xpp/xpp_zap.c
parent823cf303caf13cc6e4fd2c2173804f0990b29532 (diff)
xpp r5723: Includes, among others:
* New firmware protocol version: 3.0 . * New numbers for the device types: (e.g. in card_init* scripts) - FXS: 1 (was: 3) - FXO: 2 (was: 4) - BRI: 3 (was: 6 for TE, 7 for NT) - PRI: 4 (was: 9) * Init scripts of FXS and FXO modules are now written in Perl as well (be sure to have File::Basename, e.g: perl-modules in Debian). * calibrate_slics merged into init_card_1_30 . * Module parameter print_dbg replaced with debug . Same meaning. * init_fxo_modes removed: content moved into init_card_2_30, verified at build time. * Code tested with sparse. Most warnings were fixed. * Set ZT_SIG_DACS for the bchans in the PRI and BRI modules to not get ignored by ztscan. * Handle null config_desc we get from some crazy USB controllers. * genzaptelconf: Fix reporting of empty slots in list mode. * xpp_blink can now blink a single analog port. * "slics" has been renamed "chipregs". * Fixed a small typo in fpga_load(8). * Fixed bashism in xpp_fxloader. Merged revisions 4264 via svnmerge from http://svn.digium.com/svn/zaptel/branches/1.2 git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.4@4266 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'kernel/xpp/xpp_zap.c')
-rw-r--r--kernel/xpp/xpp_zap.c244
1 files changed, 124 insertions, 120 deletions
diff --git a/kernel/xpp/xpp_zap.c b/kernel/xpp/xpp_zap.c
index afa34e9..5ee7303 100644
--- a/kernel/xpp/xpp_zap.c
+++ b/kernel/xpp/xpp_zap.c
@@ -57,9 +57,9 @@ struct proc_dir_entry *xpp_proc_toplevel = NULL;
#define MAX_QUEUE_LEN 10000
#define DELAY_UNTIL_DIALTONE 3000
-DEF_PARM(int, print_dbg, 0, 0644, "Print DBG statements");
-DEF_PARM_BOOL(zap_autoreg, 0, 0644, "Register spans automatically (1) or not (0)");
-DEF_PARM_BOOL(prefmaster, 0, 0644, "Do we want to be zaptel preferred sync master");
+DEF_PARM(int, debug, 0, 0644, "Print DBG statements");
+static DEF_PARM_BOOL(zap_autoreg, 0, 0644, "Register spans automatically (1) or not (0)");
+static DEF_PARM_BOOL(prefmaster, 0, 0644, "Do we want to be zaptel preferred sync master");
// DEF_ARRAY(int, pcmtx, 4, 0, "Forced PCM values to transmit");
#include "zap_debug.h"
@@ -114,20 +114,14 @@ static int proc_xpd_ztregister_read(char *page, char **start, off_t off, int cou
static int proc_xpd_ztregister_write(struct file *file, const char __user *buffer, unsigned long count, void *data);
static int proc_xpd_blink_read(char *page, char **start, off_t off, int count, int *eof, void *data);
static int proc_xpd_blink_write(struct file *file, const char __user *buffer, unsigned long count, void *data);
-static void xpd_free(xpd_t *xpd);
-static void xpd_free(xpd_t *xpd)
-{
- xbus_t *xbus = NULL;
+/*------------------------- XPD Management -------------------------*/
- if(!xpd)
- return;
- xbus = xpd->xbus;
- if(!xbus)
- return;
- XPD_DBG(DEVICES, xpd, "\n");
+static void xpd_proc_remove(xbus_t *xbus, xpd_t *xpd)
+{
#ifdef CONFIG_PROC_FS
if(xpd->proc_xpd_dir) {
+ chip_proc_remove(xbus, xpd);
if(xpd->proc_xpd_summary) {
XPD_DBG(PROC, xpd, "Removing proc '%s'\n", PROC_XPD_SUMMARY);
remove_proc_entry(PROC_XPD_SUMMARY, xpd->proc_xpd_dir);
@@ -143,96 +137,16 @@ static void xpd_free(xpd_t *xpd)
remove_proc_entry(PROC_XPD_BLINK, xpd->proc_xpd_dir);
xpd->proc_xpd_blink = NULL;
}
- XPD_DBG(PROC, xpd, "Removing proc directory\n");
+ XPD_DBG(PROC, xpd, "Removing %s/%s proc directory\n",
+ xbus->busname, xpd->xpdname);
remove_proc_entry(xpd->xpdname, xbus->proc_xbus_dir);
xpd->proc_xpd_dir = NULL;
}
#endif
- xbus_unregister_xpd(xbus, xpd);
- if(xpd->xproto)
- xproto_put(xpd->xproto);
- xpd->xproto = NULL;
- KZFREE(xpd);
}
-
-/*------------------------- XPD Management -------------------------*/
-
-/*
- * Synchronous part of XPD detection.
- * Called from xbus_poll()
- */
-void card_detected(struct card_desc_struct *card_desc)
+static int xpd_proc_create(xbus_t *xbus, xpd_t *xpd)
{
- xbus_t *xbus;
- xpd_t *xpd = NULL;
- byte type;
- byte subtype;
- int unit;
- int subunit;
- byte rev;
- const xops_t *xops;
- const xproto_table_t *proto_table;
-
-
- BUG_ON(!card_desc);
- BUG_ON(card_desc->magic != CARD_DESC_MAGIC);
- xbus = card_desc->xbus; /* refcount held by xbus_poll() */
- type = card_desc->type;
- subtype = card_desc->subtype;
- unit = card_desc->xpd_addr.unit;
- subunit = card_desc->xpd_addr.subunit;
- rev = card_desc->rev;
- BUG_ON(!xbus);
- xpd = xpd_byaddr(xbus, unit, subunit);
- if(xpd) {
- if(type == XPD_TYPE_NOMODULE) {
- XBUS_NOTICE(xbus, "XPD at %d%d removed\n",
- unit, subunit);
- BUG();
- goto out;
- }
- XPD_NOTICE(xpd, "XPD at %d%d already exists\n",
- unit, subunit);
- goto out;
- }
- if(type == XPD_TYPE_NOMODULE) {
- XBUS_NOTICE(xbus, "XPD at %d%d Missing\n",
- unit, subunit);
- goto out;
- }
- proto_table = xproto_get(type);
- if(!proto_table) {
- XBUS_NOTICE(xbus, "XPD at %d%d: missing protocol table for type=%d. Ignored.\n",
- unit, subunit,
- type);
- goto out;
- }
- xops = &proto_table->xops;
- BUG_ON(!xops);
- xpd = xops->card_new(xbus, unit, subunit, proto_table, subtype, rev);
- if(!xpd) {
- XBUS_NOTICE(xbus, "card_new(%d,%d,%d,%d,%d) failed. Ignored.\n",
- unit, subunit, proto_table->type, subtype, rev);
- xproto_put(proto_table);
- goto err;
- }
- xpd->addr = card_desc->xpd_addr;
- xpd->xbus_idx = XPD_IDX(unit,subunit);
- snprintf(xpd->xpdname, XPD_NAMELEN, "XPD-%1d%1d", unit, subunit);
- xpd->subtype = card_desc->subtype;
- xpd->offhook = card_desc->line_status;
-
- /* For USB-1 disable some channels */
- if(MAX_SEND_SIZE(xbus) < RPACKET_SIZE(GLOBAL, PCM_WRITE)) {
- xpp_line_t no_pcm;
-
- no_pcm = 0x7F | xpd->digital_outputs | xpd->digital_inputs;
- xpd->no_pcm = no_pcm;
- XBUS_NOTICE(xbus, "max xframe size = %d, disabling some PCM channels. no_pcm=0x%04X\n",
- MAX_SEND_SIZE(xbus), xpd->no_pcm);
- }
- xbus_register_xpd(xbus, xpd);
#ifdef CONFIG_PROC_FS
XPD_DBG(PROC, xpd, "Creating proc directory\n");
xpd->proc_xpd_dir = proc_mkdir(xpd->xpdname, xbus->proc_xbus_dir);
@@ -265,24 +179,105 @@ void card_detected(struct card_desc_struct *card_desc)
xpd->proc_xpd_blink->data = xpd;
xpd->proc_xpd_blink->read_proc = proc_xpd_blink_read;
xpd->proc_xpd_blink->write_proc = proc_xpd_blink_write;
-#endif
- if(CALL_XMETHOD(card_init, xbus, xpd) < 0)
+ if(chip_proc_create(xbus, xpd) < 0)
goto err;
- //CALL_XMETHOD(XPD_STATE, xbus, xpd, 0); /* Turn off all channels */
- xpd->card_present = 1;
- CALL_XMETHOD(XPD_STATE, xbus, xpd, 1); /* Turn on all channels */
- XPD_INFO(xpd, "Initialized: %s\n", xpd->type_name);
+#endif
+ return 0;
+err:
+ xpd_proc_remove(xbus, xpd);
+ return -EFAULT;
+}
- if(zap_autoreg)
- zaptel_register_xpd(xpd);
+void xpd_free(xpd_t *xpd)
+{
+ xbus_t *xbus = NULL;
+
+ if(!xpd)
+ return;
+ if(xpd->xproto)
+ xproto_put(xpd->xproto); /* was taken in xpd_alloc() */
+ xpd->xproto = NULL;
+ xbus = xpd->xbus;
+ if(!xbus)
+ return;
+ XPD_DBG(DEVICES, xpd, "\n");
+ xpd_proc_remove(xbus, xpd);
+ xbus_unregister_xpd(xbus, xpd);
+ KZFREE(xpd);
+}
+
+
+__must_check int xpd_common_init(xbus_t *xbus, xpd_t *xpd, int unit, int subunit, int subtype, int subunits)
+{
+ int ret;
+
+ MKADDR(&xpd->addr, unit, subunit);
+ xpd->xbus_idx = XPD_IDX(unit,subunit);
+ snprintf(xpd->xpdname, XPD_NAMELEN, "XPD-%1d%1d", unit, subunit);
+ xpd->subtype = subtype;
+ xpd->subunits = subunits;
+ xpd->offhook = 0;
+
+ /* For USB-1 disable some channels */
+ if(MAX_SEND_SIZE(xbus) < RPACKET_SIZE(GLOBAL, PCM_WRITE)) {
+ xpp_line_t no_pcm;
+
+ no_pcm = 0x7F | xpd->digital_outputs | xpd->digital_inputs;
+ xpd->no_pcm = no_pcm;
+ XBUS_NOTICE(xbus, "max xframe size = %d, disabling some PCM channels. no_pcm=0x%04X\n",
+ MAX_SEND_SIZE(xbus), xpd->no_pcm);
+ }
+ if((ret = xpd_proc_create(xbus, xpd)) < 0)
+ return ret;
+ xbus_register_xpd(xbus, xpd);
+ return 0;
+}
+
+/*
+ * 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:
- KZFREE(card_desc);
- return;
+ return 0;
err:
- xpd_free(xpd);
- goto out;
+ if(xpd)
+ xpd_free(xpd);
+ return ret;
}
+void xpd_post_init(xpd_t *xpd)
+{
+ XPD_DBG(DEVICES, xpd, "\n");
+ if(zap_autoreg)
+ zaptel_register_xpd(xpd);
+}
#ifdef CONFIG_PROC_FS
@@ -306,7 +301,7 @@ static int xpd_read_proc(char *page, char **start, off_t off, int count, int *eo
goto out;
xbus = xpd->xbus;
- len += sprintf(page + len, "%s (%s ,card %s, span %d)\n"
+ len += sprintf(page + len, "%s (%s, card %s, span %d)\n"
"timing_priority: %d\n"
"timer_count: %d span->mainttimer=%d\n"
,
@@ -317,6 +312,7 @@ static int xpd_read_proc(char *page, char **start, off_t off, int count, int *eo
xpd->timer_count, xpd->span.mainttimer
);
len += sprintf(page + len, "Address: U=%d S=%d\n", xpd->addr.unit, xpd->addr.subunit);
+ len += sprintf(page + len, "Subunits: %d\n", xpd->subunits);
len += sprintf(page + len, "Type: %d.%d\n\n", xpd->type, xpd->subtype);
len += sprintf(page + len, "pcm_len=%d\n\n", xpd->pcm_len);
len += sprintf(page + len, "wanted_pcm_mask=0x%04X\n\n", xpd->wanted_pcm_mask);
@@ -426,6 +422,7 @@ xpd_t *xpd_alloc(size_t privsize, const xproto_table_t *proto_table, int channel
size_t alloc_size = sizeof(xpd_t) + privsize;
int type = proto_table->type;
+ BUG_ON(!proto_table);
DBG(DEVICES, "type=%d channels=%d (alloc_size=%zd)\n",
type, channels, alloc_size);
if(channels > CHANNELS_PERXPD) {
@@ -461,6 +458,7 @@ xpd_t *xpd_alloc(size_t privsize, const xproto_table_t *proto_table, int channel
ERR("%s: Unable to allocate channels\n", __FUNCTION__);
goto err;
}
+ xproto_get(type); /* will be returned in xpd_free() */
return xpd;
err:
if(xpd) {
@@ -569,7 +567,7 @@ void update_line_status(xpd_t *xpd, int pos, bool to_offhook)
}
#ifdef CONFIG_PROC_FS
-int proc_xpd_ztregister_read(char *page, char **start, off_t off, int count, int *eof, void *data)
+static int proc_xpd_ztregister_read(char *page, char **start, off_t off, int count, int *eof, void *data)
{
int len = 0;
unsigned long flags;
@@ -615,7 +613,7 @@ static int proc_xpd_ztregister_write(struct file *file, const char __user *buffe
return (ret < 0) ? ret : count;
}
-int proc_xpd_blink_read(char *page, char **start, off_t off, int count, int *eof, void *data)
+static int proc_xpd_blink_read(char *page, char **start, off_t off, int count, int *eof, void *data)
{
int len = 0;
unsigned long flags;
@@ -641,8 +639,9 @@ static int proc_xpd_blink_write(struct file *file, const char __user *buffer, un
{
xpd_t *xpd = data;
char buf[MAX_PROC_WRITE];
- int blink;
- int ret;
+ char *endp;
+ unsigned blink;
+
BUG_ON(!xpd);
if(count >= MAX_PROC_WRITE)
@@ -650,10 +649,12 @@ static int proc_xpd_blink_write(struct file *file, const char __user *buffer, un
if(copy_from_user(buf, buffer, count))
return -EFAULT;
buf[count] = '\0';
- ret = sscanf(buf, "%d", &blink);
- if(ret != 1)
+ if(count > 0 && buf[count-1] == '\n') /* chomp */
+ buf[count-1] = '\0';
+ blink = simple_strtoul(buf, &endp, 0);
+ if(*endp != '\0' || blink > 0xFFFF)
return -EINVAL;
- XPD_DBG(GENERAL, xpd, "%s\n", (blink) ? "blink" : "unblink");
+ XPD_DBG(GENERAL, xpd, "BLINK channels: 0x%X\n", blink);
xpd->blink_mode = blink;
return count;
}
@@ -1020,7 +1021,7 @@ static void do_cleanup(void)
#endif
}
-int __init xpp_zap_init(void)
+static int __init xpp_zap_init(void)
{
int ret = 0;
@@ -1055,16 +1056,19 @@ err:
return ret;
}
-void __exit xpp_zap_cleanup(void)
+static void __exit xpp_zap_cleanup(void)
{
xbus_pcm_shutdown();
xbus_core_shutdown();
do_cleanup();
}
-EXPORT_SYMBOL(print_dbg);
-EXPORT_SYMBOL(card_detected);
+EXPORT_SYMBOL(debug);
+EXPORT_SYMBOL(xpd_common_init);
+EXPORT_SYMBOL(create_xpd);
+EXPORT_SYMBOL(xpd_post_init);
EXPORT_SYMBOL(xpd_alloc);
+EXPORT_SYMBOL(xpd_free);
EXPORT_SYMBOL(xpd_disconnect);
EXPORT_SYMBOL(update_xpd_status);
EXPORT_SYMBOL(update_line_status);