From d7e54a785544ac40abc4a88383df3a913ca466e8 Mon Sep 17 00:00:00 2001 From: tzafrir Date: Tue, 13 May 2008 21:08:09 +0000 Subject: 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 --- kernel/xpp/xpp_zap.c | 244 ++++++++++++++++++++++++++------------------------- 1 file changed, 124 insertions(+), 120 deletions(-) (limited to 'kernel/xpp/xpp_zap.c') 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); -- cgit v1.2.3