From d8562c778088ff6ab3383df5ceead41eff4bf124 Mon Sep 17 00:00:00 2001 From: tzafrir Date: Thu, 19 Mar 2009 20:08:29 +0000 Subject: xpp: a massive backport from DAHDI. From Xorcom branch-rel-6839-r6908 . Sun Mar 1 2009 Oron Peled - xpp.r6795 * Fix cases where the command_queue overflowed during initialization. - Also add a 'command_queue_length' parameter to xpp.ko * More migrations to sysfs: - Add a 'transport' attribute to our astribank devices which points to the usb device we use. E.g: /sys/bus/astribanks/devices/xbus-00/transport is symlinked to ../../../../../../devices/pci0000:00/0000:00:10.4/usb5/5-4 - Move /proc/xpp/XBUS-??/XPD-??/span to /sys/bus/xpds/devices/??:?:?/span - Migrate from /proc/xpp/sync to: /sys/bus/astribanks/drivers/xppdrv/sync - New 'offhook' attribute in: /sys/bus/xpds/devices/??:?:?/offhook * PRI: change the "timing" priority to match the convention used by other PRI cards -- I.e: lower numbers (not 0) have higher priority. * FXO: - Power denial: create two module parameters instead of hard-coded constants (power_denial_safezone, power_denial_minlen). For sites that get non-standard power-denial signals from central office on offhook. - Don't hangup on power-denial, just notify Dahdi and wait for - Fix caller-id detection for the case central office sends it before first ring without any indication before. Asterisk's desicion. Mon, Dec 8 2008 Oron Peled - xpp.r6430 * PRI: - Match our span clocking priorities (in system.conf) to Digium -- this is a reversal of the previous state. Now lower numbers (greater than 0) are better. - Synchronization fixes for PRI ports other than 0. - Fix T1 CRC for some countries (e.g: China). * FXS: fix bug in VMWI detection if using old asterisk which does not provide ZT_VMWI ioctl(). * FXO: - Improve caller_id_style module parameter. This provide a workaround for countries that send this information without any notification (reverse polarity, ring, etc.) - Don't force on-hook upon power-denial. So, loopstart devices would ignore these as expected. * Implement a flow-control to prevent user space (init_card_* scripts) from pressuring our command queue. git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.4@4631 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- kernel/xpp/xbus-pcm.c | 351 ++++++++++++++++++++++---------------------------- 1 file changed, 157 insertions(+), 194 deletions(-) (limited to 'kernel/xpp/xbus-pcm.c') diff --git a/kernel/xpp/xbus-pcm.c b/kernel/xpp/xbus-pcm.c index ef92a88..4d75a43 100644 --- a/kernel/xpp/xbus-pcm.c +++ b/kernel/xpp/xbus-pcm.c @@ -36,10 +36,6 @@ static const char rcsid[] = "$Id$"; extern int debug; -#ifdef XPP_EC_CHUNK -#include "supress/ec_xpp.h" -DEF_PARM_BOOL(xpp_ec, 0, 0444, "Do we use our own (1) or Zaptel's (0) echo canceller"); -#endif #ifdef OPTIMIZE_CHANMUTE static DEF_PARM_BOOL(optimize_chanmute, 1, 0644, "Optimize by muting inactive channels"); #endif @@ -60,7 +56,7 @@ static struct xpp_ticker zaptel_ticker; */ static struct xpp_ticker *ref_ticker = NULL; static spinlock_t ref_ticker_lock = SPIN_LOCK_UNLOCKED; -static bool force_zaptel_sync = 0; /* from "/proc/xpp/sync" */ +static bool force_zaptel_sync = 0; /* from /sys/bus/astribanks/drivers/xppdrv/sync */ static xbus_t *global_ticker; static struct xpp_ticker global_ticks_series; @@ -84,13 +80,26 @@ static unsigned int zaptel_tick_count = 0; static void send_drift(xbus_t *xbus, int drift); +static void ticker_set_cycle(struct xpp_ticker *ticker, int cycle) +{ + unsigned long flags; + + spin_lock_irqsave(&ticker->lock, flags); + if(cycle < SYNC_ADJ_QUICK) + cycle = SYNC_ADJ_QUICK; + if(cycle > SYNC_ADJ_SLOW) + cycle = SYNC_ADJ_SLOW; + ticker->cycle = cycle; + spin_unlock_irqrestore(&ticker->lock, flags); +} + static void xpp_ticker_init(struct xpp_ticker *ticker) { memset(ticker, 0, sizeof(*ticker)); + spin_lock_init(&ticker->lock); do_gettimeofday(&ticker->last_sample.tv); ticker->first_sample = ticker->last_sample; - ticker->cycle = SYNC_ADJ_QUICK; - spin_lock_init(&ticker->lock); + ticker_set_cycle(ticker, SYNC_ADJ_QUICK); } static int xpp_ticker_step(struct xpp_ticker *ticker, const struct timeval *t) @@ -131,7 +140,7 @@ static inline void xbus_drift_clear(xbus_t *xbus) driftinfo_recalc(driftinfo); driftinfo->calc_drift = 0; - xbus->ticker.cycle = SYNC_ADJ_QUICK; + ticker_set_cycle(&xbus->ticker, SYNC_ADJ_QUICK); } void xpp_drift_init(xbus_t *xbus) @@ -168,18 +177,23 @@ static void xpp_drift_step(xbus_t *xbus, const struct timeval *tv) spin_lock_irqsave(&driftinfo->lock, flags); cycled = xpp_ticker_step(&xbus->ticker, tv); - if(ref_ticker && syncer && xbus->sync_mode == SYNC_MODE_PLL) { + if(ref_ticker && ref_ticker != &xbus->ticker && syncer && xbus->sync_mode == SYNC_MODE_PLL) { int new_delta_tick = ticker->count - ref_ticker->count; int lost_ticks = new_delta_tick - driftinfo->delta_tick; driftinfo->delta_tick = new_delta_tick; if(lost_ticks) { + static int rate_limit; + driftinfo->lost_ticks++; driftinfo->lost_tick_count += abs(lost_ticks); - XBUS_DBG(SYNC, xbus, "Lost %d tick%s\n", - lost_ticks, - (abs(lost_ticks) > 1) ? "s": ""); - ticker->cycle = SYNC_ADJ_QUICK; + + if((rate_limit++ % 1003) == 0) { + XBUS_DBG(SYNC, xbus, "Lost %d tick%s\n", + lost_ticks, + (abs(lost_ticks) > 1) ? "s": ""); + } + ticker_set_cycle(ticker, SYNC_ADJ_QUICK); if(abs(lost_ticks) > 100) ticker->count = ref_ticker->count; } else { @@ -198,13 +212,15 @@ static void xpp_drift_step(xbus_t *xbus, const struct timeval *tv) */ if(usec_delta > 0 && xbus->sync_adjustment > -SYNC_ADJ_MAX) { XBUS_DBG(SYNC, xbus, "Pullback usec_delta=%ld\n", usec_delta); + driftinfo->kicks_down++; send_drift(xbus, -SYNC_ADJ_MAX); /* emergency push */ } if(usec_delta < 0 && xbus->sync_adjustment < SYNC_ADJ_MAX) { XBUS_DBG(SYNC, xbus, "Pushback usec_delta=%ld\n", usec_delta); + driftinfo->kicks_up++; send_drift(xbus, SYNC_ADJ_MAX); /* emergency push */ } - ticker->cycle = SYNC_ADJ_QUICK; + ticker_set_cycle(ticker, SYNC_ADJ_QUICK); nofix = 1; } else { /* good data, use it */ @@ -228,15 +244,13 @@ static void xpp_drift_step(xbus_t *xbus, const struct timeval *tv) offset = driftinfo->calc_drift + factor; /* for large median, push some more */ if(abs(driftinfo->median) >= 300) { /* more than 2 usb uframes */ - ticker->cycle = SYNC_ADJ_QUICK; + ticker_set_cycle(ticker, SYNC_ADJ_QUICK); XBUS_NOTICE(xbus, "Back to quick: median=%d\n", driftinfo->median); } } else { - ticker->cycle += 500; - if(ticker->cycle >= SYNC_ADJ_SLOW) - ticker->cycle = SYNC_ADJ_SLOW; + //ticker_set_cycle(ticker, ticker->cycle + 500); } driftinfo->calc_drift = offset; XBUS_DBG(SYNC, xbus, @@ -275,16 +289,30 @@ const char *sync_mode_name(enum sync_mode mode) static void xpp_set_syncer(xbus_t *xbus, bool on) { + unsigned long flags; + + spin_lock_irqsave(&ref_ticker_lock, flags); + if(!xbus) { /* Special case, no more syncers */ + DBG(SYNC, "No more syncers\n"); + syncer = NULL; + if(ref_ticker != &zaptel_ticker) + ref_ticker = NULL; + goto out; + } if(syncer != xbus && on) { XBUS_DBG(SYNC, xbus, "New syncer\n"); syncer = xbus; } else if(syncer == xbus && !on) { XBUS_DBG(SYNC, xbus, "Lost syncer\n"); syncer = NULL; + if(ref_ticker != &zaptel_ticker) + ref_ticker = NULL; } else XBUS_DBG(SYNC, xbus, "ignore %s (current syncer: %s)\n", (on)?"ON":"OFF", (syncer) ? syncer->busname : "NO-SYNC"); +out: + spin_unlock_irqrestore(&ref_ticker_lock, flags); } static void xbus_command_timer(unsigned long param) @@ -314,6 +342,7 @@ void xbus_set_command_timer(xbus_t *xbus, bool on) XBUS_DBG(SYNC, xbus, "del_timer\n"); del_timer(&xbus->command_timer); } + xbus->self_ticking = ! on; } /* @@ -323,33 +352,30 @@ void got_new_syncer(xbus_t *xbus, enum sync_mode mode, int drift) { unsigned long flags; - XBUS_DBG(SYNC, xbus, "Mode %s (%d), drift=%d (pcm_rx_counter=%d)\n", - sync_mode_name(mode), mode, drift, atomic_read(&xbus->pcm_rx_counter)); spin_lock_irqsave(&xbus->lock, flags); xbus->sync_adjustment = (signed char)drift; if(xbus->sync_mode == mode) { - XBUS_DBG(SYNC, xbus, "Already in mode '%s'. Ignored\n", sync_mode_name(mode)); + /* XBUS_DBG(SYNC, xbus, "Already in mode '%s'. Ignored\n", sync_mode_name(mode)); */ goto out; } + XBUS_DBG(SYNC, xbus, "Mode %s (%d), drift=%d (pcm_rx_counter=%d)\n", + sync_mode_name(mode), mode, drift, atomic_read(&xbus->pcm_rx_counter)); switch(mode) { case SYNC_MODE_AB: xbus->sync_mode = mode; xbus_set_command_timer(xbus, 0); - xbus->self_ticking = 1; xpp_set_syncer(xbus, 1); global_ticker = xbus; break; case SYNC_MODE_PLL: xbus->sync_mode = mode; xbus_set_command_timer(xbus, 0); - xbus->self_ticking = 1; xpp_set_syncer(xbus, 0); global_ticker = xbus; break; case SYNC_MODE_NONE: /* lost sync source */ xbus->sync_mode = mode; xbus_set_command_timer(xbus, 1); - xbus->self_ticking = 0; xpp_set_syncer(xbus, 0); break; case SYNC_MODE_QUERY: /* ignore */ @@ -366,6 +392,9 @@ void xbus_request_sync(xbus_t *xbus, enum sync_mode mode) BUG_ON(!xbus); XBUS_DBG(SYNC, xbus, "sent request (mode=%d)\n", mode); CALL_PROTO(GLOBAL, SYNC_SOURCE, xbus, NULL, mode, 0); + if(mode == SYNC_MODE_NONE) { + xbus_set_command_timer(xbus, 1); + } } static void reset_sync_counters(void) @@ -374,7 +403,7 @@ static void reset_sync_counters(void) //DBG(SYNC, "%d\n", atomic_read(&xpp_tick_counter)); for(i = 0; i < MAX_BUSES; i++) { - xbus_t *xbus = get_xbus(i); + xbus_t *xbus = xbus_num(i); if(!xbus) continue; @@ -384,20 +413,15 @@ static void reset_sync_counters(void) * - Or maybe they didn't answer us in the first place (e.g: wrong firmware version, etc). */ - if (TRANSPORT_RUNNING(xbus) && xbus->self_ticking) { - if(XBUS_GET(xbus)) { + if(xbus->self_ticking) { + if(XBUS_IS(xbus, DISCONNECTED)) { + XBUS_DBG(GENERAL, xbus, + "Dropped packet. Is shutting down.\n"); + } else { /* Reset sync LEDs once in a while */ CALL_PROTO(GLOBAL, RESET_SYNC_COUNTERS, xbus, NULL); - XBUS_PUT(xbus); - } else { - static int rate_limit; - - if((rate_limit++ % 1003) == 0) - XBUS_DBG(GENERAL, xbus, - "Dropped packet. Is shutting down. (%d)\n", rate_limit); } } - put_xbus(xbus); } } @@ -448,14 +472,8 @@ int zaptel_sync_tick(struct zt_span *span, int is_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++; + if((rate_limit++ % 1003) == 0) + XPD_NOTICE(xpd, "Is a ZAPTEL sync master: ignore sync from ZAPTEL\n"); goto noop; } /* Now we know for sure someone else is zaptel sync master */ @@ -464,7 +482,7 @@ int zaptel_sync_tick(struct zt_span *span, int is_master) if((rate_limit++ % 5003) == 0) XBUS_DBG(SYNC, syncer, - "Already a syncer, ignore ZAPTEL sync\n"); + "is a SYNCer: ignore sync from ZAPTEL\n"); goto noop; } /* ignore duplicate calls from all our registered spans */ @@ -491,12 +509,15 @@ noop: * if new_syncer is NULL, than we move all to SYNC_MODE_PLL * for ZAPTEL sync. */ -static void update_sync_master(xbus_t *new_syncer) +static void update_sync_master(xbus_t *new_syncer, bool force_zaptel) { - const char *msg = (force_zaptel_sync) ? "ZAPTEL" : "NO-SYNC"; + const char *msg; int i; unsigned long flags; + WARN_ON(new_syncer && force_zaptel); /* Ambigous */ + force_zaptel_sync = force_zaptel; + msg = (force_zaptel_sync) ? "ZAPTEL" : "NO-SYNC"; DBG(SYNC, "%s => %s\n", (syncer) ? syncer->busname : msg, (new_syncer) ? new_syncer->busname : msg); @@ -504,6 +525,12 @@ static void update_sync_master(xbus_t *new_syncer) * This global locking protects: * - The ref_ticker so it won't be used while we change it. * - The xbus_drift_clear() from corrupting driftinfo data. + * It's important to set ref_ticker now: + * - We cannot make the new xbus a syncer yet (until we get + * a reply from AB). Maybe it's still not self_ticking, so + * we must keep the timer for the command_queue to function. + * - However, we must not send drift commands to it, because + * they'll revert it to PLL instead of AB. */ spin_lock_irqsave(&ref_ticker_lock, flags); if(syncer) @@ -524,16 +551,15 @@ static void update_sync_master(xbus_t *new_syncer) DBG(SYNC, "stop unwanted syncers\n"); /* Shut all down except the wanted sync master */ for(i = 0; i < MAX_BUSES; i++) { - xbus_t *xbus = get_xbus(i); + xbus_t *xbus = xbus_num(i); if(!xbus) continue; - if(TRANSPORT_RUNNING(xbus) && xbus != new_syncer) { + if(!XBUS_IS(xbus, DISCONNECTED) && xbus != new_syncer) { if(xbus->self_ticking) xbus_request_sync(xbus, SYNC_MODE_PLL); else XBUS_DBG(SYNC, xbus, "Not self_ticking yet. Ignore\n"); } - put_xbus(xbus); } } @@ -541,39 +567,41 @@ void elect_syncer(const char *msg) { int i; int j; - uint timing_priority = 0; + uint timing_priority = INT_MAX; xpd_t *best_xpd = NULL; xbus_t *the_xbus = NULL; for(i = 0; i < MAX_BUSES; i++) { - xbus_t *xbus = get_xbus(i); + xbus_t *xbus = xbus_num(i); if(!xbus) continue; - if(!the_xbus) - the_xbus = xbus; - if (TRANSPORT_RUNNING(xbus)) { + if(XBUS_IS(xbus, READY)) { + if(!the_xbus) + the_xbus = xbus; /* First candidate */ for(j = 0; j < MAX_XPDS; j++) { xpd_t *xpd = xpd_of(xbus, j); if(!xpd || !xpd->card_present) continue; - if(xpd->timing_priority > timing_priority) { + if(xpd->timing_priority > 0 && xpd->timing_priority < timing_priority) { timing_priority = xpd->timing_priority; best_xpd = xpd; } } } - put_xbus(xbus); } if(best_xpd) { the_xbus = best_xpd->xbus; XPD_DBG(SYNC, best_xpd, "%s: elected with priority %d\n", msg, timing_priority); } else if(the_xbus) { XBUS_DBG(SYNC, the_xbus, "%s: elected\n", msg); - } else + } else { DBG(SYNC, "%s: No more syncers\n", msg); + xpp_set_syncer(NULL, 0); + the_xbus = NULL; + } if(the_xbus != syncer) - update_sync_master(the_xbus); + update_sync_master(the_xbus, force_zaptel_sync); } /* @@ -640,35 +668,10 @@ void fill_beep(u_char *buf, int num, int duration) memcpy(buf, snd, ZT_CHUNKSIZE); } -#ifdef XPP_EC_CHUNK -/* - * Taken from zaptel.c - */ -static inline void xpp_ec_chunk(struct zt_chan *chan, unsigned char *rxchunk, const unsigned char *txchunk) -{ - int16_t rxlin; - int x; - unsigned long flags; - - /* Perform echo cancellation on a chunk if necessary */ - if (!chan->ec) - return; - spin_lock_irqsave(&chan->lock, flags); - for (x=0;xec, ZT_XLAW(txchunk[x], chan), rxlin); - rxchunk[x] = ZT_LIN2X((int)rxlin, chan); - } - spin_unlock_irqrestore(&chan->lock, flags); -} -#endif - static void do_ec(xpd_t *xpd) { -#ifdef WITH_ECHO_SUPPRESSION - int i; + int i; - /* FIXME: need to Echo cancel double buffered data */ for (i = 0;i < xpd->span.channels; i++) { struct zt_chan *chan = XPD_CHAN(xpd, i); @@ -676,17 +679,10 @@ static void do_ec(xpd_t *xpd) continue; if(!IS_SET(xpd->wanted_pcm_mask, i)) /* No ec for unwanted PCM */ continue; -#ifdef XPP_EC_CHUNK - /* even if defined, parameterr xpp_ec can override at run-time */ - if (xpp_ec) - xpp_ec_chunk(chan, chan->readchunk, xpd->ec_chunk2[i]); - else -#endif - zt_ec_chunk(chan, chan->readchunk, xpd->ec_chunk2[i]); + zt_ec_chunk(chan, chan->readchunk, xpd->ec_chunk2[i]); memcpy(xpd->ec_chunk2[i], xpd->ec_chunk1[i], ZT_CHUNKSIZE); memcpy(xpd->ec_chunk1[i], chan->writechunk, ZT_CHUNKSIZE); } -#endif } #if 0 @@ -711,29 +707,6 @@ int (*hooksig)(struct zt_chan *chan, zt_txsig_t hookstate); int (*sethook)(struct zt_chan *chan, int hookstate); #endif -int xpp_echocan(struct zt_chan *chan, int len) -{ -#ifdef XPP_EC_CHUNK - if(len == 0) { /* shut down */ - /* zaptel calls this also during channel initialization */ - if(chan->ec) { - xpp_echo_can_free(chan->ec); - } - return 0; - } - if(chan->ec) { - ERR("%s: Trying to override an existing EC (%p)\n", __FUNCTION__, chan->ec); - return -EINVAL; - } - chan->ec = xpp_echo_can_create(len, 0); - if(!chan->ec) { - ERR("%s: Failed creating xpp EC (len=%d)\n", __FUNCTION__, len); - return -EINVAL; - } -#endif - return 0; -} - static bool pcm_valid(xpd_t *xpd, xpacket_t *pack) { xpp_line_t lines = RPACKET_FIELD(pack, GLOBAL, PCM_READ, lines); @@ -776,7 +749,7 @@ static inline void pcm_frame_out(xbus_t *xbus, xframe_t *xframe) spin_lock_irqsave(&xbus->lock, flags); do_gettimeofday(&now); - if(unlikely(disable_pcm || !TRANSPORT_RUNNING(xbus))) + if(unlikely(disable_pcm || !XBUS_IS(xbus, READY))) goto dropit; if(XPACKET_ADDR_SYNC((xpacket_t *)xframe->packets)) { usec = usec_diff(&now, &xbus->last_tx_sync); @@ -1124,7 +1097,50 @@ void xframe_receive_pcm(xbus_t *xbus, xframe_t *xframe) xbus->xbus_frag_count++; } -#ifdef CONFIG_PROC_FS +int exec_sync_command(const char *buf, size_t count) +{ + int ret = count; + int xbusno; + xbus_t *xbus; + + if(strncmp("ZAPTEL", buf, 6) == 0) { /* Ignore the newline */ + DBG(SYNC, "ZAPTEL"); + update_sync_master(NULL, 1); + } else if(sscanf(buf, "SYNC=%d", &xbusno) == 1) { + DBG(SYNC, "SYNC=%d\n", xbusno); + if((xbus = xbus_num(xbusno)) == NULL) { + ERR("No bus %d exists\n", xbusno); + return -ENXIO; + } + update_sync_master(xbus, 0); + } else if(sscanf(buf, "QUERY=%d", &xbusno) == 1) { + DBG(SYNC, "QUERY=%d\n", xbusno); + if((xbus = xbus_num(xbusno)) == NULL) { + ERR("No bus %d exists\n", xbusno); + return -ENXIO; + } + CALL_PROTO(GLOBAL, SYNC_SOURCE, xbus, NULL, SYNC_MODE_QUERY, 0); + } else { + ERR("%s: cannot parse '%s'\n", __FUNCTION__, buf); + ret = -EINVAL; + } + return ret; +} + +int fill_sync_string(char *buf, size_t count) +{ + int len = 0; + + if(!syncer) { + len += snprintf(buf, count, "%s\n", + (force_zaptel_sync) ? "ZAPTEL" : "NO-SYNC"); + } else + len += snprintf(buf, count, "SYNC=%02d\n", syncer->num); + return len; +} + +#ifdef OLD_PROC +#ifdef CONFIG_PROC_FS static int proc_sync_read(char *page, char **start, off_t off, int count, int *eof, void *data) { int len = 0; @@ -1133,17 +1149,13 @@ static int proc_sync_read(char *page, char **start, off_t off, int count, int *e unsigned long usec; do_gettimeofday(&now); + NOTICE("%s: DEPRECATED: %s[%d] read from /proc interface instead of /sys\n", + __FUNCTION__, current->comm, current->tgid); len += sprintf(page + len, "# To modify sync source write into this file:\n"); len += sprintf(page + len, "# ZAPTEL - Another zaptel device provide sync\n"); len += sprintf(page + len, "# SYNC=nn - XBUS-nn provide sync\n"); len += sprintf(page + len, "# QUERY=nn - Query XBUS-nn for sync information (DEBUG)\n"); - if(!syncer) { - if(force_zaptel_sync) - len += sprintf(page + len, "ZAPTEL\n"); - else - len += sprintf(page + len, "NO-SYNC\n"); - } else - len += sprintf(page + len, "SYNC=%02d\n", syncer->num); + len += fill_sync_string(page + len, PAGE_SIZE - len); #ifdef ZAPTEL_SYNC_TICK if(force_zaptel_sync) { len += sprintf(page + len, @@ -1177,86 +1189,31 @@ static int proc_sync_read(char *page, char **start, off_t off, int count, int *e static int proc_sync_write(struct file *file, const char __user *buffer, unsigned long count, void *data) { char buf[MAX_PROC_WRITE]; - int xbus_num; - int xpd_num; - xbus_t *xbus; - xpd_t *xpd; // DBG(SYNC, "%s: count=%ld\n", __FUNCTION__, count); + NOTICE("%s: DEPRECATED: %s[%d] write to /proc interface instead of /sys\n", + __FUNCTION__, current->comm, current->tgid); if(count >= MAX_PROC_WRITE) return -EINVAL; if(copy_from_user(buf, buffer, count)) return -EFAULT; buf[count] = '\0'; - if(strncmp("ZAPTEL", buf, 6) == 0) { - DBG(SYNC, "ZAPTEL\n"); - force_zaptel_sync=1; - update_sync_master(NULL); - } else if(sscanf(buf, "SYNC=%d", &xbus_num) == 1) { - DBG(SYNC, "SYNC=%d\n", xbus_num); - if((xbus = get_xbus(xbus_num)) == NULL) { - ERR("No bus %d exists\n", xbus_num); - return -ENXIO; - } - update_sync_master(xbus); - put_xbus(xbus); - } else if(sscanf(buf, "QUERY=%d", &xbus_num) == 1) { - DBG(SYNC, "QUERY=%d\n", xbus_num); - if((xbus = get_xbus(xbus_num)) == NULL) { - ERR("No bus %d exists\n", xbus_num); - return -ENXIO; - } - CALL_PROTO(GLOBAL, SYNC_SOURCE, xbus, NULL, SYNC_MODE_QUERY, 0); - put_xbus(xbus); - } else if(sscanf(buf, "%d %d", &xbus_num, &xpd_num) == 2) { - NOTICE("Using deprecated syntax to update %s file\n", - PROC_SYNC); - if(xpd_num != 0) { - ERR("Currently can only set sync for XPD #0\n"); - return -EINVAL; - } - if((xbus = get_xbus(xbus_num)) == NULL) { - ERR("No bus %d exists\n", xbus_num); - return -ENXIO; - } - if((xpd = xpd_of(xbus, xpd_num)) == NULL) { - XBUS_ERR(xbus, "No xpd %d exists\n", xpd_num); - put_xbus(xbus); - return -ENXIO; - } - update_sync_master(xbus); - put_xbus(xbus); - } else { - ERR("%s: cannot parse '%s'\n", __FUNCTION__, buf); - count = -EINVAL; - } - return count; + return exec_sync_command(buf, count); } static struct proc_dir_entry *top; #endif +#endif /* OLD_PROC */ int xbus_pcm_init(struct proc_dir_entry *toplevel) { int ret = 0; -#ifdef CONFIG_PROC_FS - struct proc_dir_entry *ent; -#endif #ifdef OPTIMIZE_CHANMUTE INFO("FEATURE: with CHANMUTE optimization (%sactivated)\n", (optimize_chanmute)?"":"de"); #endif -#ifdef WITH_ECHO_SUPPRESSION - INFO("FEATURE: with ECHO_SUPPRESSION\n"); -#else - INFO("FEATURE: without ECHO_SUPPRESSION\n"); -#endif - if(xpp_ec) - INFO("FEATURE: with XPP_EC_CHUNK\n"); - else - INFO("FEATURE: without XPP_EC_CHUNK\n"); #ifdef ZAPTEL_SYNC_TICK INFO("FEATURE: with sync_tick() from ZAPTEL\n"); #else @@ -1264,34 +1221,40 @@ int xbus_pcm_init(struct proc_dir_entry *toplevel) #endif xpp_ticker_init(&global_ticks_series); xpp_ticker_init(&zaptel_ticker); -#ifdef CONFIG_PROC_FS - top = toplevel; - ent = create_proc_entry(PROC_SYNC, 0644, top); - if(!ent) { - ret = -EFAULT; - goto err; +#ifdef OLD_PROC +#ifdef CONFIG_PROC_FS + { + struct proc_dir_entry *ent; + + top = toplevel; + ent = create_proc_entry(PROC_SYNC, 0644, top); + if(ent) { + ent->read_proc = proc_sync_read; + ent->write_proc = proc_sync_write; + ent->data = NULL; + } else { + ret = -EFAULT; + } } - ent->read_proc = proc_sync_read; - ent->write_proc = proc_sync_write; - ent->data = NULL; #endif -err: +#endif /* OLD_PROC */ return ret; } void xbus_pcm_shutdown(void) { +#ifdef OLD_PROC #ifdef CONFIG_PROC_FS DBG(GENERAL, "Removing '%s' from proc\n", PROC_SYNC); remove_proc_entry(PROC_SYNC, top); #endif +#endif /* OLD_PROC */ } EXPORT_SYMBOL(xbus_request_sync); EXPORT_SYMBOL(got_new_syncer); EXPORT_SYMBOL(elect_syncer); -EXPORT_SYMBOL(xpp_echocan); #ifdef ZAPTEL_SYNC_TICK EXPORT_SYMBOL(zaptel_sync_tick); #endif -- cgit v1.2.3