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); xpd->proc_xpd_summary = NULL; } if(xpd->proc_xpd_ztregister) { XPD_DBG(PROC, xpd, "Removing proc '%s'\n", PROC_XPD_ZTREGISTER); remove_proc_entry(PROC_XPD_ZTREGISTER, xpd->proc_xpd_dir); xpd->proc_xpd_ztregister = NULL; } if(xpd->proc_xpd_blink) { XPD_DBG(PROC, xpd, "Removing proc '%s'\n", PROC_XPD_BLINK); remove_proc_entry(PROC_XPD_BLINK, xpd->proc_xpd_dir); xpd->proc_xpd_blink = NULL; } 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 }
static int fxo_proc_create(xbus_t *xbus, xpd_t *xpd) { struct FXO_priv_data *priv; BUG_ON(!xpd); priv = xpd->priv; #ifdef CONFIG_PROC_FS XPD_DBG(PROC, xpd, "Creating FXO_INFO file\n"); priv->fxo_info = create_proc_read_entry(PROC_FXO_INFO_FNAME, 0444, xpd->proc_xpd_dir, proc_fxo_info_read, xpd); if (!priv->fxo_info) { XPD_ERR(xpd, "Failed to create proc file '%s'\n", PROC_FXO_INFO_FNAME); fxo_proc_remove(xbus, xpd); return -EINVAL; } SET_PROC_DIRENTRY_OWNER(priv->fxo_info); #ifdef WITH_METERING XPD_DBG(PROC, xpd, "Creating Metering tone file\n"); priv->meteringfile = create_proc_read_entry(PROC_METERING_FNAME, 0444, xpd->proc_xpd_dir, proc_xpd_metering_read, xpd); if (!priv->meteringfile) { XPD_ERR(xpd, "Failed to create proc file '%s'\n", PROC_METERING_FNAME); fxo_proc_remove(xbus, xpd); return -EINVAL; } SET_PROC_DIRENTRY_OWNER(priv->meteringfile); #endif #endif return 0; }
/* * This function is used by FXS/FXO. The pcm_mask argument signifies * channels which should be *added* to the automatic calculation. * Normally, this argument is 0. * * The caller should spinlock the XPD before calling it. */ void __pcm_recompute(xpd_t *xpd, xpp_line_t pcm_mask) { int i; int line_count = 0; XPD_DBG(SIGNAL, xpd, "pcm_mask=0x%X\n", pcm_mask); /* Add/remove all the trivial cases */ pcm_mask |= xpd->offhook; pcm_mask |= xpd->cid_on; pcm_mask &= ~xpd->digital_signalling; /* No PCM in D-Channels */ pcm_mask &= ~xpd->digital_inputs; pcm_mask &= ~xpd->digital_outputs; for_each_line(xpd, i) if(IS_SET(pcm_mask, i)) line_count++; /* * FIXME: Workaround a bug in sync code of the Astribank. * Send dummy PCM for sync. */ if(xpd->addr.unit == 0 && pcm_mask == 0) { pcm_mask = BIT(0); line_count = 1; } xpd->pcm_len = (line_count) ? RPACKET_HEADERSIZE + sizeof(xpp_line_t) + line_count * ZT_CHUNKSIZE : 0L; xpd->wanted_pcm_mask = pcm_mask; }
static void fxo_proc_remove(xbus_t *xbus, xpd_t *xpd) { struct FXO_priv_data *priv; BUG_ON(!xpd); priv = xpd->priv; XPD_DBG(PROC, xpd, "\n"); #ifdef CONFIG_PROC_FS #ifdef WITH_METERING if (priv->meteringfile) { XPD_DBG(PROC, xpd, "Removing xpd metering tone file\n"); remove_proc_entry(PROC_METERING_FNAME, xpd->proc_xpd_dir); priv->meteringfile = NULL; } #endif if (priv->fxo_info) { XPD_DBG(PROC, xpd, "Removing xpd FXO_INFO file\n"); remove_proc_entry(PROC_FXO_INFO_FNAME, xpd->proc_xpd_dir); priv->fxo_info = NULL; } #endif }
/* * For backward compatibility with old dahdi-tools * Remove after dahdi_registration is upgraded */ static DEVICE_ATTR_WRITER(span_store, dev, buf, count) { xpd_t *xpd; int dahdi_reg; int ret; BUG_ON(!dev); xpd = dev_to_xpd(dev); if (!xpd) return -ENODEV; ret = sscanf(buf, "%d", &dahdi_reg); if (ret != 1) return -EINVAL; if (!XBUS_IS(xpd->xbus, READY)) return -ENODEV; XPD_DBG(DEVICES, xpd, "%s -- deprecated (should use pinned-spans)\n", (dahdi_reg) ? "register" : "unregister"); if (xbus_is_registered(xpd->xbus)) { if (dahdi_reg) { XPD_DBG(DEVICES, xpd, "already registered %s. Ignored.\n", xpd->xbus->busname); } else { xbus_unregister_dahdi_device(xpd->xbus); } } else { if (!dahdi_reg) { XPD_DBG(DEVICES, xpd, "already unregistered %s. Ignored.\n", xpd->xbus->busname); } else { xbus_register_dahdi_device(xpd->xbus); } } return count; }
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); }
static int xpd_proc_create(xbus_t *xbus, xpd_t *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); if(!xpd->proc_xpd_dir) { XPD_ERR(xpd, "Failed to create proc directory\n"); goto err; } xpd->proc_xpd_summary = create_proc_read_entry(PROC_XPD_SUMMARY, 0444, xpd->proc_xpd_dir, xpd_read_proc, xpd); if(!xpd->proc_xpd_summary) { XPD_ERR(xpd, "Failed to create proc file '%s'\n", PROC_XPD_SUMMARY); goto err; } xpd->proc_xpd_summary->owner = THIS_MODULE; xpd->proc_xpd_ztregister = create_proc_entry(PROC_XPD_ZTREGISTER, 0644, xpd->proc_xpd_dir); if (!xpd->proc_xpd_ztregister) { XPD_ERR(xpd, "Failed to create proc file '%s'\n", PROC_XPD_ZTREGISTER); goto err; } xpd->proc_xpd_ztregister->owner = THIS_MODULE; xpd->proc_xpd_ztregister->data = xpd; xpd->proc_xpd_ztregister->read_proc = proc_xpd_ztregister_read; xpd->proc_xpd_ztregister->write_proc = proc_xpd_ztregister_write; xpd->proc_xpd_blink = create_proc_entry(PROC_XPD_BLINK, 0644, xpd->proc_xpd_dir); if (!xpd->proc_xpd_blink) { XPD_ERR(xpd, "Failed to create proc file '%s'\n", PROC_XPD_BLINK); goto err; } xpd->proc_xpd_blink->owner = THIS_MODULE; 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; if(chip_proc_create(xbus, xpd) < 0) goto err; #endif return 0; err: xpd_proc_remove(xbus, xpd); return -EFAULT; }
static DEVICE_ATTR_WRITER(blink_store, dev, buf, count) { xpd_t *xpd; char *endp; unsigned long blink; BUG_ON(!dev); xpd = dev_to_xpd(dev); //XPD_DBG(GENERAL, xpd, "%s\n", buf); if (!xpd) return -ENODEV; blink = simple_strtoul(buf, &endp, 0); if (*endp != '\0' && *endp != '\n' && *endp != '\r') return -EINVAL; if (blink > 0xFFFF) return -EINVAL; XPD_DBG(GENERAL, xpd, "BLINK channels: 0x%lX\n", blink); xpd->blink_mode = blink; return count; }
void elect_syncer(const char *msg) { int i; int j; uint timing_priority = 0; xpd_t *best_xpd = NULL; xbus_t *the_xbus = NULL; for(i = 0; i < MAX_BUSES; i++) { xbus_t *xbus = get_xbus(i); if(!xbus) continue; if(!the_xbus) the_xbus = xbus; if (TRANSPORT_RUNNING(xbus)) { 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) { 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 DBG(SYNC, "%s: No more syncers\n", msg); if(the_xbus != syncer) update_sync_master(the_xbus); }
/* * For backward compatibility with old dahdi-tools * Remove after dahdi_registration is upgraded */ static DEVICE_ATTR_WRITER(span_store, dev, buf, count) { xpd_t *xpd; int dahdi_reg; int ret; BUG_ON(!dev); xpd = dev_to_xpd(dev); if (!xpd) return -ENODEV; ret = sscanf(buf, "%d", &dahdi_reg); if (ret != 1) return -EINVAL; if (!XBUS_IS(xpd->xbus, READY)) return -ENODEV; XPD_DBG(DEVICES, xpd, "%s -- deprecated (should use assigned-spans)\n", (dahdi_reg) ? "register" : "unregister"); if (dahdi_reg) xbus_register_dahdi_device(xpd->xbus); else xbus_unregister_dahdi_device(xpd->xbus); return count; }
void xpd_post_init(xpd_t *xpd) { XPD_DBG(DEVICES, xpd, "\n"); if(dahdi_autoreg) dahdi_register_xpd(xpd); }