[zaptel-commits] tzafrir: branch tzafrir/syncing r1480 -
/team/tzafrir/syncing/xpp/xpp_zap.c
zaptel-commits at lists.digium.com
zaptel-commits at lists.digium.com
Sun Sep 24 17:24:14 MST 2006
Author: tzafrir
Date: Sun Sep 24 19:24:13 2006
New Revision: 1480
URL: http://svn.digium.com/view/zaptel?rev=1480&view=rev
Log:
Use the do_sync operation to sync the xpp driver.
* Create a separate dummy XPP_SYNCER span.
* Add "zaptel sync mode" in addition to host sync mode and device sync mode.
* Device will not register as sync master. Added a new kernel parameter to
allow setting that (be_zap_master).
* Small cleanup in the init code.
* Still buggy when zaptel sync master is an Astribank.
Modified:
team/tzafrir/syncing/xpp/xpp_zap.c
Modified: team/tzafrir/syncing/xpp/xpp_zap.c
URL: http://svn.digium.com/view/zaptel/team/tzafrir/syncing/xpp/xpp_zap.c?rev=1480&r1=1479&r2=1480&view=diff
==============================================================================
--- team/tzafrir/syncing/xpp/xpp_zap.c (original)
+++ team/tzafrir/syncing/xpp/xpp_zap.c Sun Sep 24 19:24:13 2006
@@ -67,6 +67,7 @@
DEF_PARM(int, print_dbg, 0, "Print DBG statements");
DEF_PARM(int, max_queue_len, MAX_QUEUE_LEN, "Maximum Queue Length.");
+DEF_PARM(int, be_zap_master, 1, "Should spans ask to be zaptel sync. source? (0) no, (1) yes, (2) only the first in each span.");
DEF_PARM(bool, have_sync_bus, 0, "True if all Astribank(TM) devices are connected via a sync-cable");
DEF_PARM(bool, zap_autoreg, 1, "Register spans automatically (1) or not (0)");
@@ -84,6 +85,30 @@
static int proc_xpd_ztregister_read(char *page, char **start, off_t off, int count, int *eof, void *data);
static int proc_xpd_ztregister_write(struct file *file, const char __user *buffer, unsigned long count, void *data);
static void xpd_free(xpd_t *xpd);
+
+
+struct zt_span xpp_sync_span;
+struct zt_chan xpp_sync_chan;
+
+/* dummy xpd structure for our span, to allow us being a sync source. */
+struct xpd sync_xpd = {
+ .xpdname = "XPPSYNCER",
+ .channels = 0
+};
+
+/* called by the zaptel sync master span from zt_recieve. */
+int syncer_do_sync(struct zt_span *span)
+{
+ static int counter = 1;
+
+ xpp_tick( (unsigned long)&sync_xpd); /* actually do something */
+
+ /* print stats visible in the /proc/zaptel file */
+ if ((counter++ %1000) == 0) {
+ snprintf(xpp_sync_span.desc, MAX_SPANDESC, "ticks: %d", counter);
+ }
+ return 0;
+}
static void external_sync(xpd_t *the_xpd)
{
@@ -134,7 +159,8 @@
xpd_t *the_xpd = (xpd_t *)param;
int i;
int j;
-
+ /* if the_xpd is zaptel sync_master and local sync master is sync_xpd */
+ int sync_master_only_mode = 0;
if(!the_xpd) { /* Called from timer */
#if 0
static int rate_limit = 0;
@@ -143,13 +169,18 @@
#endif
mod_timer(&xpp_timer, jiffies + 1); /* Must be 1KHz rate */
}
+ else if ( (sync_master == &sync_xpd) && zt_is_sync_master(&the_xpd->span)) {
+ sync_master_only_mode = 1; /* continue, but only copy your span */
+ }
else if(the_xpd != sync_master)
return;
+
/* Statistics */
if((xpp_timer_count % SAMPLE_TICKS) == 0) {
xpp_last_jiffies = jiffies;
}
- xpp_timer_count++;
+ if (!sync_master_only_mode)
+ xpp_timer_count++;
for(i = 0; i < MAX_BUSES; i++) {
xbus = xbus_of(i);
@@ -168,11 +199,33 @@
for(j = 0; j < MAX_XPDS; j++) {
xpd_t *xpd = xpd_of(xbus, j);
+ /* sanity checks: no point in syncing if we don't have a hardware
+ * and talk to zaptel
+ */
if(!xpd)
continue;
if(!xpd->card_present)
continue;
+ /* prevent recusrsive calls to sync master. The following two conditions
+ * handle the case where one of our spans is the zaptel sync master,
+ * whereas the syncer span is the xpp sync master.
+ *
+ * The zaptel sync master will run through xpp_tick but only set
+ * zt_recieve for its span. This, in turn, will trigger a call to
+ * the sync functions of spans and specifically cause our syncer span
+ * to call xpp_tick.
+ *
+ * If our syncer span is the zaptel sync source, it will then trigger
+ * a full xpp_tick . But we need to make sure it will not trigger the
+ * tick of itself again.
+ */
+ if(sync_master_only_mode && !zt_is_sync_master(&xpd->span))
+ continue;
+ if((the_xpd == &sync_xpd) && (sync_master == &sync_xpd) &&
+ zt_is_sync_master(&xpd->span))
+ continue;
xpd->timer_count++;
+ /* actions that need doing before actual data copying */
CALL_XMETHOD(card_tick, xbus, xpd);
if(!SPAN_REGISTERED(xpd))
continue;
@@ -690,6 +743,7 @@
len += sprintf(page + len, "# To modify sync source write into this file:\n");
len += sprintf(page + len, "# HOST - For host based sync\n");
+ len += sprintf(page + len, "# ZAPTEL - Sync from zaptel sync master\n");
len += sprintf(page + len, "# 0 0 - XBUS-0/XPD-0 provide sync\n");
len += sprintf(page + len, "# m n - XBUS-m/XPD-n provide sync\n");
if(!sync_master)
@@ -732,6 +786,10 @@
buf[count] = '\0';
if(strncmp("HOST", buf, 4) == 0) {
sync_master_is(NULL);
+ goto out;
+ } else if (strncmp("ZAPTEL", buf, 6) == 0) {
+ //external_sync(&sync_xpd); /* TODO: rename that function? */
+ sync_master_is(&sync_xpd);
goto out;
}
ret = sscanf(buf, "%d %d %d", &xbus_num, &xpd_num, &setit);
@@ -1311,6 +1369,7 @@
xbus_t *xbus;
int cn;
const xops_t *xops;
+ int become_master;
BUG_ON(!xpd);
xops = xpd->xops;
@@ -1353,7 +1412,13 @@
DBG("Registering span of %s.\n", xpd->xpdname);
xpd->xops->card_zaptel_preregistration(xpd, 1);
- if(zt_register(&xpd->span, 1)) {
+ if ( be_zap_master == 0 )
+ become_master = 0;
+ else if (be_zap_master == 1 )
+ become_master = 1;
+ else /* only first XPD in bus will ask to be zaptel master */
+ become_master = (xpd->id == 0);
+ if(zt_register(&xpd->span, become_master )) {
xbus_t *xbus = xpd->xbus;
ERR("%s/%s: Failed to zt_register span\n", xbus->busname, xpd->xpdname);
return -ENODEV;
@@ -1377,8 +1442,17 @@
/*------------------------- Initialization -------------------------*/
+static void __exit xpp_syncer_cleanup(void)
+{
+ if (xpp_sync_span.flags & ZT_FLAG_REGISTERED) {
+ zt_unregister(&xpp_sync_span);
+ }
+}
+
static void do_cleanup(void)
{
+ xbus_core_shutdown();
+ xpp_syncer_cleanup();
if(timer_pending(&xpp_timer))
del_timer_sync(&xpp_timer);
#ifdef CONFIG_PROC_FS
@@ -1392,6 +1466,27 @@
#endif
}
+static int __init xpp_syncer_init(void)
+{
+ int ret;
+
+ /* Modified from ztdummy.c */
+ sprintf(xpp_sync_span.name, "XPP_SYNCER/1");
+ snprintf(xpp_sync_span.desc, MAX_SPANDESC, "ticks: nothing.");
+ sprintf(xpp_sync_chan.name, "XPP_SYNCER/%d/%d", 1, 0);
+ xpp_sync_chan.chanpos = 1;
+ xpp_sync_span.chans = &xpp_sync_chan;
+ xpp_sync_span.channels = 0; /* no channels on our span */
+ xpp_sync_span.deflaw = ZT_LAW_MULAW;
+ init_waitqueue_head(&xpp_sync_span.maintq);
+ xpp_sync_span.do_sync = syncer_do_sync;
+ if ((ret = zt_register(&xpp_sync_span, 0)) < 0) {
+ xpp_syncer_cleanup();
+ return ret;
+ }
+ return 0;
+}
+
int __init xpp_zap_init(void)
{
int ret;
@@ -1426,6 +1521,12 @@
ent->write_proc = proc_sync_write;
ent->data = NULL;
#endif
+ ret = xpp_syncer_init();
+ if(ret) {
+ ERR("xbus_syncer_init failed (%d)\n", ret);
+ do_cleanup();
+ return ret;
+ }
ret = xbus_core_init();
if(ret) {
ERR("xbus_core_init failed (%d)\n", ret);
@@ -1441,7 +1542,6 @@
void __exit xpp_zap_cleanup(void)
{
- xbus_core_shutdown();
do_cleanup();
}
More information about the zaptel-commits
mailing list