summaryrefslogtreecommitdiff
path: root/xpp/xbus-sysfs.c
diff options
context:
space:
mode:
authortzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-03-06 22:54:16 +0000
committertzafrir <tzafrir@5390a7c7-147a-4af0-8ec9-7488f05a26cb>2008-03-06 22:54:16 +0000
commit3b3d8f7b1186f672e16cd7e4ded2f405ec43cb1c (patch)
tree5e592d92e3030b4eb28cab7585f769dbbeab2d74 /xpp/xbus-sysfs.c
parent07b404b68141bc981adbc1f5a00cbe90116fb9c1 (diff)
xpp.r5512:
* Build: - Zaptel >= 1.4.9 is migrating to storing kernel stuff in zaptel/kernel/* - We conditionally use old/new directory scheme: In xpp/Kbuild and xpp/utils/Makefile use ZAP_KERNEL variable, so it's not confused with ZAPTEL_DIR (which appears in zaptel/Makefile as well). - Fix compile warnings on 64 bit systems. - Compile fixes for kernel-2.6.24 * UDEV: - /etc/udev/rules.d/xpp.rules now uses XPP_INIT_DIR to find astribank_hook. - astribank_hook: Modify to do nothing. Add some documentation. * Autoconfiguration -- zapconf: - Don't fail zapconf et.al. if no config file was found. - Skip the 'IRQ Missing:' line in /proc/zaptel/nnn for wcte1xp(?). - Add some newer Digium cards to our hardware inventory. - Partially handle cases where the /proc/zaptel strings does not contain info about E1/T1/J1 or NT/TE. * Better SYNC: - Finer tuning of PLL (New firmware). - Change calculation algorithm of sync offset. It now copes better with the variance in USB frame reception timing. - Statistics: . The view of results was moved from /proc/xpp/XBUS-*/summary to a new /sys/bus/astribanks/devices/xbus-*/timing and enhanced. . A new xpp_timing script shows all astribanks. . A new write only /sys/bus/astribanks/devices/xbus-*/cls is used to clear statistics. Eventually, clearing of XBUS related statistics should be done here. One that was migrated is the clearing of 'PCM [TR]X:' numbers currently appearing in /proc/xpp/XBUS-*/summary (they should be moved too later). - Shorten the strings representation sync_mode ("SYNC_MODE_AB" -> "AB") adapted their use in printk and /proc so the text is clear. - Added a command line parameter xpp.disable_pll_sync to stop all adjustments command to AB (calculations still continue as usual). * PRI: - 4 port support - set clocking master span via ztcfg, like other zaptel devices. * FXO: - Fix false hangups in some countries (voltage fluctuations). - Some countries send caller-id before first ring. Added code to handle caller-id PCM pass through according to a new command line parameter (xpd_fxo.caller_id_style). - No longer sends an event on zt_open. See #12160 . * Misc: - Adapt to zaptel-1.4.8 and above ztscan: added fields returend by new ZT_SPANSTAT_V2 ioctl() - Document sysfs and waitfor_xpds. - Miscelaneous optimizations and bugfixes. - Remove deprecated pcm_tasklet parameter. The rx_tasklet parameter has replaced it a long time ago. - Add RX_CMD counter to /proc/xpp/XBUS-*/summary - Unclutter some of the usb disconnect messages. - xpp_usb: minor preformance improvements in receive. Expose the number of pending receive URB's in /proc/xpp/XBUS-*/xpp_usb git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.2@3952 5390a7c7-147a-4af0-8ec9-7488f05a26cb
Diffstat (limited to 'xpp/xbus-sysfs.c')
-rw-r--r--xpp/xbus-sysfs.c174
1 files changed, 162 insertions, 12 deletions
diff --git a/xpp/xbus-sysfs.c b/xpp/xbus-sysfs.c
index d45058e..04bc24e 100644
--- a/xpp/xbus-sysfs.c
+++ b/xpp/xbus-sysfs.c
@@ -58,11 +58,15 @@ extern int print_dbg;
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
-#define DEVICE_ATTR_FUNC(name,dev,buf) \
+#define DEVICE_ATTR_READER(name,dev,buf) \
ssize_t name(struct device *dev, struct device_attribute *attr, char *buf)
+#define DEVICE_ATTR_WRITER(name,dev,buf, count) \
+ ssize_t name(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
#else
-#define DEVICE_ATTR_FUNC(name,dev,buf) \
+#define DEVICE_ATTR_READER(name,dev,buf) \
ssize_t name(struct device *dev, char *buf)
+#define DEVICE_ATTR_WRITER(name,dev,buf, count) \
+ ssize_t name(struct device *dev, const char *buf, size_t count)
#endif
/*--------- Sysfs Bus handling ----*/
@@ -88,32 +92,62 @@ static int xpp_bus_hotplug(struct device *dev, char **envp, int envnum, char *bu
}
#else
+#define XBUS_VAR_BLOCK \
+ do { \
+ XBUS_ADD_UEVENT_VAR("XPP_INIT_DIR=%s", initdir); \
+ XBUS_ADD_UEVENT_VAR("XBUS_NUM=%02d", xbus->num); \
+ XBUS_ADD_UEVENT_VAR("XBUS_NAME=%s", xbus->busname); \
+ } while(0)
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
#define XBUS_ADD_UEVENT_VAR(fmt, val...) \
do { \
int err = add_uevent_var(envp, num_envp, &i, \
buffer, buffer_size, &len, \
fmt, val); \
if (err) \
- return err; \
+ return err; \
} while (0)
static int xpp_bus_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
{
- xbus_t *xbus;
- int i = 0;
- int len = 0;
+ xbus_t *xbus;
+ int i = 0;
+ int len = 0;
+ extern char *initdir;
if(!dev)
return -ENODEV;
xbus = dev_to_xbus(dev);
DBG(GENERAL, "bus_id=%s xbus=%s\n", dev->bus_id, xbus->busname);
- XBUS_ADD_UEVENT_VAR("XBUS_NUM=%02d", xbus->num);
- XBUS_ADD_UEVENT_VAR("XBUS_NAME=%s", xbus->busname);
+ XBUS_VAR_BLOCK;
envp[i] = NULL;
return 0;
}
+#else
+#define XBUS_ADD_UEVENT_VAR(fmt, val...) \
+ do { \
+ int err = add_uevent_var(kenv, fmt, val); \
+ if (err) \
+ return err; \
+ } while (0)
+
+static int xpp_bus_uevent(struct device *dev, struct kobj_uevent_env *kenv)
+{
+ xbus_t *xbus;
+ extern char *initdir;
+
+ if(!dev)
+ return -ENODEV;
+ xbus = dev_to_xbus(dev);
+ DBG(GENERAL, "bus_id=%s xbus=%s\n", dev->bus_id, xbus->busname);
+ XBUS_VAR_BLOCK;
+ return 0;
+}
#endif
+#endif /* OLD_HOPLUG_SUPPORT */
+
static void xpp_bus_release(struct device *dev)
{
DBG(GENERAL, "\n");
@@ -185,17 +219,17 @@ void unregister_xpp_bus(void)
}
/*--------- Sysfs Device handling ----*/
-static DEVICE_ATTR_FUNC(connector_show, dev, buf)
+static DEVICE_ATTR_READER(connector_show, dev, buf)
{
xbus_t *xbus;
int ret;
xbus = dev_to_xbus(dev);
- ret = snprintf(buf, PAGE_SIZE, "%s\n", xbus->busdesc);
+ ret = snprintf(buf, PAGE_SIZE, "%s\n", xbus->location);
return ret;
}
-static DEVICE_ATTR_FUNC(label_show, dev, buf)
+static DEVICE_ATTR_READER(label_show, dev, buf)
{
xbus_t *xbus;
int ret;
@@ -205,7 +239,7 @@ static DEVICE_ATTR_FUNC(label_show, dev, buf)
return ret;
}
-static DEVICE_ATTR_FUNC(status_show, dev, buf)
+static DEVICE_ATTR_READER(status_show, dev, buf)
{
xbus_t *xbus;
int ret;
@@ -215,9 +249,103 @@ static DEVICE_ATTR_FUNC(status_show, dev, buf)
return ret;
}
+static DEVICE_ATTR_READER(timing_show, dev, buf)
+{
+ xbus_t *xbus;
+ struct xpp_drift *driftinfo;
+ int len = 0;
+ struct timeval now;
+
+ do_gettimeofday(&now);
+ xbus = dev_to_xbus(dev);
+ driftinfo = &xbus->drift;
+ len += snprintf(buf + len, PAGE_SIZE - len, "DRIFT: %-3s", sync_mode_name(xbus->sync_mode));
+ if(xbus->sync_mode == SYNC_MODE_PLL) {
+ len += snprintf(buf + len, PAGE_SIZE - len,
+ " %5d: jitter %4d median %4d calc_drift %3d lost (%4d,%4d) : ",
+ xbus->ticker.cycle,
+ driftinfo->jitter, driftinfo->median,
+ driftinfo->calc_drift,
+ driftinfo->lost_ticks, driftinfo->lost_tick_count);
+ len += snprintf(buf + len, PAGE_SIZE - len,
+ "DRIFT %3d %ld sec ago",
+ xbus->sync_adjustment,
+ (xbus->pll_updated_at == 0) ? 0 : now.tv_sec - xbus->pll_updated_at);
+ }
+ len += snprintf(buf + len, PAGE_SIZE - len, "\n");
+ return len;
+}
+
+#ifdef SAMPLE_TICKS
+/*
+ * tick sampling: Measure offset from reference ticker:
+ * - Recording start when writing to:
+ * /sys/bus/astribanks/devices/xbus-??/samples
+ * - Recording ends when filling SAMPLE_SIZE ticks
+ * - Results are read from the same sysfs file.
+ * - Trying to read/write during recording, returns -EBUSY.
+ */
+static DEVICE_ATTR_READER(samples_show, dev, buf)
+{
+ xbus_t *xbus;
+ int len = 0;
+ int i;
+
+ xbus = dev_to_xbus(dev);
+ if(xbus->sample_running)
+ return -EBUSY;
+ for(i = 0; i < SAMPLE_SIZE; i++) {
+ if(len > PAGE_SIZE - 20)
+ break;
+ len += snprintf(buf + len, PAGE_SIZE - len, "%d\n", xbus->sample_ticks[i]);
+ }
+ return len;
+}
+
+static DEVICE_ATTR_WRITER(samples_store, dev, buf, count)
+{
+ xbus_t *xbus;
+
+ xbus = dev_to_xbus(dev);
+ if(xbus->sample_running)
+ return -EBUSY;
+ memset(xbus->sample_ticks, 0, sizeof(*xbus->sample_ticks));
+ xbus->sample_pos = 0;
+ xbus->sample_running = 1;
+ return count;
+}
+#endif
+
+/*
+ * Clear statistics
+ */
+static DEVICE_ATTR_WRITER(cls_store, dev, buf, count)
+{
+ xbus_t *xbus;
+ struct xpp_drift *driftinfo;
+
+ xbus = dev_to_xbus(dev);
+ driftinfo = &xbus->drift;
+ driftinfo->lost_ticks = 0;
+ driftinfo->lost_tick_count = 0;
+ xbus->min_tx_sync = INT_MAX;
+ xbus->max_tx_sync = 0;
+ xbus->min_rx_sync = INT_MAX;
+ xbus->max_rx_sync = 0;
+#ifdef SAMPLE_TICKS
+ memset(xbus->sample_ticks, 0, sizeof(*xbus->sample_ticks));
+#endif
+ return count;
+}
+
static DEVICE_ATTR(connector, S_IRUGO, connector_show, NULL);
static DEVICE_ATTR(label, S_IRUGO, label_show, NULL);
static DEVICE_ATTR(status, S_IRUGO, status_show, NULL);
+static DEVICE_ATTR(timing, S_IRUGO, timing_show, NULL);
+static DEVICE_ATTR(cls, S_IWUSR, NULL, cls_store);
+#ifdef SAMPLE_TICKS
+static DEVICE_ATTR(samples, S_IWUSR | S_IRUGO, samples_show, samples_store);
+#endif
void xbus_sysfs_remove(xbus_t *xbus)
{
@@ -227,6 +355,11 @@ void xbus_sysfs_remove(xbus_t *xbus)
XBUS_DBG(GENERAL, xbus, "\n");
astribank = &xbus->astribank;
BUG_ON(!astribank);
+#ifdef SAMPLE_TICKS
+ device_remove_file(&xbus->astribank, &dev_attr_samples);
+#endif
+ device_remove_file(&xbus->astribank, &dev_attr_cls);
+ device_remove_file(&xbus->astribank, &dev_attr_timing);
device_remove_file(&xbus->astribank, &dev_attr_status);
device_remove_file(&xbus->astribank, &dev_attr_label);
device_remove_file(&xbus->astribank, &dev_attr_connector);
@@ -268,6 +401,23 @@ int xbus_sysfs_create(xbus_t *xbus)
XBUS_ERR(xbus, "%s: device_create_file failed: %d\n", __FUNCTION__, ret);
goto out;
}
+ ret = device_create_file(astribank, &dev_attr_timing);
+ if(ret) {
+ XBUS_ERR(xbus, "%s: device_create_file failed: %d\n", __FUNCTION__, ret);
+ goto out;
+ }
+ ret = device_create_file(astribank, &dev_attr_cls);
+ if(ret) {
+ XBUS_ERR(xbus, "%s: device_create_file failed: %d\n", __FUNCTION__, ret);
+ goto out;
+ }
+#ifdef SAMPLE_TICKS
+ ret = device_create_file(astribank, &dev_attr_samples);
+ if(ret) {
+ XBUS_ERR(xbus, "%s: device_create_file failed: %d\n", __FUNCTION__, ret);
+ goto out;
+ }
+#endif
out:
return ret;
}