Compare commits
35 Commits
v2.6.0-rc1
...
v2.6.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0a58eef031 | ||
|
|
07a8698f77 | ||
|
|
6f2a52b764 | ||
|
|
b91ec305be | ||
|
|
afe3702873 | ||
|
|
892e49c356 | ||
|
|
9fd76d93c9 | ||
|
|
6706b03d9d | ||
|
|
2ae396112a | ||
|
|
b6f3466607 | ||
|
|
9ce15dc967 | ||
|
|
2b11667c47 | ||
|
|
6b6d047241 | ||
|
|
2983075256 | ||
|
|
b43c7f02a0 | ||
|
|
990af593a5 | ||
|
|
654486dc24 | ||
|
|
6d1713c2c0 | ||
|
|
da149b0d4d | ||
|
|
06961f8605 | ||
|
|
2a3a074f33 | ||
|
|
c4616c6c86 | ||
|
|
244c9bd254 | ||
|
|
cc7c73c4d8 | ||
|
|
66eb65dda7 | ||
|
|
1372573e68 | ||
|
|
1e22667c31 | ||
|
|
8bcab23272 | ||
|
|
1a79cb4fdc | ||
|
|
bc7c111d7e | ||
|
|
4b58524565 | ||
|
|
6ed54cc7e3 | ||
|
|
09e46f2213 | ||
|
|
875c1ec3b6 | ||
|
|
382125f880 |
@@ -6,6 +6,7 @@ obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_DYNAMIC_ETH) += dahdi_dynamic_eth.o
|
||||
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_DYNAMIC_ETHMF) += dahdi_dynamic_ethmf.o
|
||||
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_TRANSCODE) += dahdi_transcode.o
|
||||
|
||||
ifdef CONFIG_PCI
|
||||
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCT4XXP) += wct4xxp/
|
||||
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTC4XXP) += wctc4xxp/
|
||||
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTDM24XXP) += wctdm24xxp/
|
||||
@@ -20,6 +21,7 @@ obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTE11XP) += wcte11xp.o
|
||||
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCFXO) += wcfxo.o
|
||||
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_TOR2) += tor2.o
|
||||
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_PCIRADIO) += pciradio.o
|
||||
endif
|
||||
|
||||
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_XPP) += xpp/
|
||||
|
||||
|
||||
@@ -2150,6 +2150,8 @@ static unsigned long _chan_cleanup(struct dahdi_chan *pos, unsigned long data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct file_operations nodev_fops;
|
||||
|
||||
static void dahdi_chan_unreg(struct dahdi_chan *chan)
|
||||
{
|
||||
unsigned long flags;
|
||||
@@ -2164,6 +2166,11 @@ static void dahdi_chan_unreg(struct dahdi_chan *chan)
|
||||
"%s: surprise removal: chan %d\n",
|
||||
__func__, chan->channo);
|
||||
chan->file->private_data = NULL;
|
||||
chan->file->f_op = &nodev_fops;
|
||||
/*
|
||||
* From now on, any file_operations for this device
|
||||
* would call the nodev_fops methods.
|
||||
*/
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&chan->lock, flags);
|
||||
@@ -2240,14 +2247,12 @@ static ssize_t dahdi_chan_read(struct file *file, char __user *usrbuf,
|
||||
count &= 0xffff;
|
||||
|
||||
if (unlikely(!chan)) {
|
||||
/* We would typically be here because of surprise hardware
|
||||
* removal or driver unbinding while a user space application
|
||||
* has a channel open. Most telephony applications are run at
|
||||
* elevated priorities so this sleep can prevent the high
|
||||
* priority threads from consuming the CPU if they're not
|
||||
* expecting surprise device removal.
|
||||
/*
|
||||
* This should never happen. Surprise device removal
|
||||
* should lead us to the nodev_* file_operations
|
||||
*/
|
||||
msleep(5);
|
||||
module_printk(KERN_ERR, "%s: NODEV\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@@ -2363,14 +2368,12 @@ static ssize_t dahdi_chan_write(struct file *file, const char __user *usrbuf,
|
||||
count &= 0xffff;
|
||||
|
||||
if (unlikely(!chan)) {
|
||||
/* We would typically be here because of surprise hardware
|
||||
* removal or driver unbinding while a user space application
|
||||
* has a channel open. Most telephony applications are run at
|
||||
* elevated priorities so this sleep can prevent the high
|
||||
* priority threads from consuming the CPU if they're not
|
||||
* expecting surprise device removal.
|
||||
/*
|
||||
* This should never happen. Surprise device removal
|
||||
* should lead us to the nodev_* file_operations
|
||||
*/
|
||||
msleep(5);
|
||||
module_printk(KERN_ERR, "%s: NODEV\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@@ -4877,7 +4880,7 @@ static int dahdi_ioctl_startup(struct file *file, unsigned long data)
|
||||
__dahdi_find_master_span();
|
||||
}
|
||||
put_span(s);
|
||||
return 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
static int dahdi_ioctl_shutdown(unsigned long data)
|
||||
@@ -5500,13 +5503,12 @@ static int dahdi_ioctl_iomux(struct file *file, unsigned long data)
|
||||
wait_result = 0;
|
||||
prepare_to_wait(&chan->waitq, &wait, TASK_INTERRUPTIBLE);
|
||||
if (unlikely(!chan->file->private_data)) {
|
||||
static int rate_limit;
|
||||
|
||||
if ((rate_limit++ % 1000) == 0)
|
||||
module_printk(KERN_NOTICE,
|
||||
"%s: (%d) nodev\n",
|
||||
__func__, rate_limit);
|
||||
/*
|
||||
* This should never happen. Surprise device removal
|
||||
* should lead us to the nodev_* file_operations
|
||||
*/
|
||||
msleep(5);
|
||||
module_printk(KERN_ERR, "%s: NODEV\n", __func__);
|
||||
ret = -ENODEV;
|
||||
break;
|
||||
}
|
||||
@@ -6647,6 +6649,9 @@ static void
|
||||
set_spanno_and_basechan(struct dahdi_span *span, u32 spanno, u32 basechan)
|
||||
{
|
||||
int i;
|
||||
dahdi_dev_dbg(ASSIGN, span->parent->dev.parent,
|
||||
"set: spanno=%d, basechan=%d (span->channels=%d)\n",
|
||||
spanno, basechan, span->channels);
|
||||
span->spanno = spanno;
|
||||
for (i = 0; i < span->channels; ++i)
|
||||
span->chans[i]->channo = basechan + i;
|
||||
@@ -6668,6 +6673,8 @@ static int _assign_spanno_and_basechan(struct dahdi_span *span)
|
||||
unsigned int spanno = 1;
|
||||
unsigned int basechan = 1;
|
||||
|
||||
dahdi_dev_dbg(ASSIGN, span->parent->dev.parent,
|
||||
"assign: channels=%d\n", span->channels);
|
||||
list_for_each_entry(pos, &span_list, spans_node) {
|
||||
|
||||
if (pos->spanno <= spanno) {
|
||||
@@ -6686,6 +6693,9 @@ static int _assign_spanno_and_basechan(struct dahdi_span *span)
|
||||
basechan = pos->chans[0]->channo + pos->channels;
|
||||
}
|
||||
|
||||
dahdi_dev_dbg(ASSIGN, span->parent->dev.parent,
|
||||
"good: spanno=%d, basechan=%d (span->channels=%d)\n",
|
||||
spanno, basechan, span->channels);
|
||||
set_spanno_and_basechan(span, spanno, basechan);
|
||||
return 0;
|
||||
}
|
||||
@@ -6733,14 +6743,20 @@ _check_spanno_and_basechan(struct dahdi_span *span, u32 spanno, u32 basechan)
|
||||
struct dahdi_span *pos;
|
||||
unsigned int next_channo;
|
||||
|
||||
dahdi_dev_dbg(ASSIGN, span->parent->dev.parent,
|
||||
"check: spanno=%d, basechan=%d (span->channels=%d)\n",
|
||||
spanno, basechan, span->channels);
|
||||
list_for_each_entry(pos, &span_list, spans_node) {
|
||||
|
||||
next_channo = _get_next_channo(pos);
|
||||
dahdi_dev_dbg(ASSIGN, span->parent->dev.parent,
|
||||
"pos: spanno=%d channels=%d (next_channo=%d)\n",
|
||||
pos->spanno, pos->channels, next_channo);
|
||||
|
||||
if (pos->spanno <= spanno) {
|
||||
if (basechan < next_channo + pos->channels) {
|
||||
/* Requested basechan breaks channel sorting */
|
||||
dev_info(span->parent->dev.parent,
|
||||
dev_notice(span->parent->dev.parent,
|
||||
"[%d] basechan (%d) is too low for wanted span %d\n",
|
||||
local_spanno(span), basechan, spanno);
|
||||
return -EINVAL;
|
||||
@@ -6751,13 +6767,19 @@ _check_spanno_and_basechan(struct dahdi_span *span, u32 spanno, u32 basechan)
|
||||
if (next_channo == -1)
|
||||
break;
|
||||
|
||||
if ((basechan + span->channels) < next_channo)
|
||||
if ((basechan + span->channels) <= next_channo)
|
||||
break;
|
||||
|
||||
/* Cannot fit the span into the requested location. Abort. */
|
||||
dev_notice(span->parent->dev.parent,
|
||||
"cannot fit span %d (basechan=%d) into requested location\n",
|
||||
spanno, basechan);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dahdi_dev_dbg(ASSIGN, span->parent->dev.parent,
|
||||
"good: spanno=%d, basechan=%d (span->channels=%d)\n",
|
||||
spanno, basechan, span->channels);
|
||||
set_spanno_and_basechan(span, spanno, basechan);
|
||||
return 0;
|
||||
}
|
||||
@@ -6851,10 +6873,10 @@ static int _dahdi_assign_span(struct dahdi_span *span, unsigned int spanno,
|
||||
unsigned int x;
|
||||
|
||||
if (!span || !span->ops || !span->ops->owner)
|
||||
return -EINVAL;
|
||||
return -EFAULT;
|
||||
|
||||
if (test_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags)) {
|
||||
dev_info(span->parent->dev.parent,
|
||||
dev_notice(span->parent->dev.parent,
|
||||
"local span %d is already assigned span %d "
|
||||
"with base channel %d\n", local_spanno(span), span->spanno,
|
||||
span->chans[0]->channo);
|
||||
@@ -6864,8 +6886,11 @@ static int _dahdi_assign_span(struct dahdi_span *span, unsigned int spanno,
|
||||
if (span->ops->enable_hw_preechocan ||
|
||||
span->ops->disable_hw_preechocan) {
|
||||
if ((NULL == span->ops->enable_hw_preechocan) ||
|
||||
(NULL == span->ops->disable_hw_preechocan))
|
||||
return -EINVAL;
|
||||
(NULL == span->ops->disable_hw_preechocan)) {
|
||||
dev_notice(span->parent->dev.parent,
|
||||
"span with inconsistent enable/disable hw_preechocan");
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
if (!span->deflaw) {
|
||||
@@ -7002,6 +7027,9 @@ static int _dahdi_register_device(struct dahdi_device *ddev,
|
||||
list_for_each_entry(s, &ddev->spans, device_node)
|
||||
ret = _dahdi_assign_span(s, 0, 0, 1);
|
||||
|
||||
if (ret)
|
||||
dahdi_sysfs_unregister_device(ddev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -9145,12 +9173,12 @@ static unsigned int dahdi_timer_poll(struct file *file, struct poll_table_struct
|
||||
ret |= POLLPRI;
|
||||
spin_unlock_irqrestore(&dahdi_timer_lock, flags);
|
||||
} else {
|
||||
static int rate_limit;
|
||||
|
||||
if ((rate_limit++ % 1000) == 0)
|
||||
module_printk(KERN_NOTICE, "%s: (%d) nodev\n",
|
||||
__func__, rate_limit);
|
||||
/*
|
||||
* This should never happen. Surprise device removal
|
||||
* should lead us to the nodev_* file_operations
|
||||
*/
|
||||
msleep(5);
|
||||
module_printk(KERN_ERR, "%s: NODEV\n", __func__);
|
||||
return POLLERR | POLLHUP | POLLRDHUP | POLLNVAL | POLLPRI;
|
||||
}
|
||||
return ret;
|
||||
@@ -9165,12 +9193,12 @@ dahdi_chan_poll(struct file *file, struct poll_table_struct *wait_table)
|
||||
unsigned long flags;
|
||||
|
||||
if (unlikely(!c)) {
|
||||
static int rate_limit;
|
||||
|
||||
if ((rate_limit++ % 1000) == 0)
|
||||
module_printk(KERN_NOTICE, "%s: (%d) nodev\n",
|
||||
__func__, rate_limit);
|
||||
msleep(20);
|
||||
/*
|
||||
* This should never happen. Surprise device removal
|
||||
* should lead us to the nodev_* file_operations
|
||||
*/
|
||||
msleep(5);
|
||||
module_printk(KERN_ERR, "%s: NODEV\n", __func__);
|
||||
return POLLERR | POLLHUP | POLLRDHUP | POLLNVAL | POLLPRI;
|
||||
}
|
||||
|
||||
@@ -9807,6 +9835,97 @@ static const struct file_operations dahdi_fops = {
|
||||
.poll = dahdi_poll,
|
||||
};
|
||||
|
||||
/*
|
||||
* DAHDI stability should not depend on the calling process behaviour.
|
||||
* In case of suprise device removal, we should be able to return
|
||||
* sane results (-ENODEV) even after the underlying device was released.
|
||||
*
|
||||
* This should be OK even if the calling process (hint, hint Asterisk)
|
||||
* ignores the system calls return value.
|
||||
*
|
||||
* We simply use dummy file_operations to implement this.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Common behaviour called from all other nodev_*() file_operations
|
||||
*/
|
||||
static int nodev_common(const char msg[])
|
||||
{
|
||||
if (printk_ratelimit()) {
|
||||
module_printk(KERN_NOTICE,
|
||||
"nodev: %s: process %d still calling\n",
|
||||
msg, current->tgid);
|
||||
}
|
||||
msleep(5);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static ssize_t nodev_chan_read(struct file *file, char __user *usrbuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
return nodev_common("read");
|
||||
}
|
||||
|
||||
static ssize_t nodev_chan_write(struct file *file, const char __user *usrbuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
return nodev_common("write");
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
nodev_chan_poll(struct file *file, struct poll_table_struct *wait_table)
|
||||
{
|
||||
return nodev_common("poll");
|
||||
}
|
||||
|
||||
static long
|
||||
nodev_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long data)
|
||||
{
|
||||
switch (cmd) {
|
||||
case DAHDI_GETEVENT: /* Get event on queue */
|
||||
/*
|
||||
* Hint the bugger that the channel is gone for good
|
||||
*/
|
||||
put_user(DAHDI_EVENT_REMOVED, (int __user *)data);
|
||||
break;
|
||||
}
|
||||
return nodev_common("ioctl");
|
||||
}
|
||||
|
||||
#ifndef HAVE_UNLOCKED_IOCTL
|
||||
static int nodev_ioctl(struct inode *inode, struct file *file,
|
||||
unsigned int cmd, unsigned long data)
|
||||
{
|
||||
return nodev_unlocked_ioctl(file, cmd, data);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_COMPAT_IOCTL
|
||||
static long nodev_ioctl_compat(struct file *file, unsigned int cmd,
|
||||
unsigned long data)
|
||||
{
|
||||
if (cmd == DAHDI_SFCONFIG)
|
||||
return -ENOTTY; /* Not supported yet */
|
||||
|
||||
return nodev_unlocked_ioctl(file, cmd, data);
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct file_operations nodev_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
#ifdef HAVE_UNLOCKED_IOCTL
|
||||
.unlocked_ioctl = nodev_unlocked_ioctl,
|
||||
#ifdef HAVE_COMPAT_IOCTL
|
||||
.compat_ioctl = nodev_ioctl_compat,
|
||||
#endif
|
||||
#else
|
||||
.ioctl = nodev_ioctl,
|
||||
#endif
|
||||
.read = nodev_chan_read,
|
||||
.write = nodev_chan_write,
|
||||
.poll = nodev_chan_poll,
|
||||
};
|
||||
|
||||
static const struct file_operations dahdi_chan_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = dahdi_open,
|
||||
|
||||
@@ -590,8 +590,10 @@ dahdi_device_assign_span(struct device *dev, struct device_attribute *attr,
|
||||
|
||||
ret = sscanf(buf, "%u:%u:%u", &local_span_number, &desired_spanno,
|
||||
&desired_basechanno);
|
||||
if (ret != 3)
|
||||
if (ret != 3) {
|
||||
dev_notice(dev, "badly formatted input (should be <num>:<num>:<num>)\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (desired_spanno && !desired_basechanno) {
|
||||
dev_notice(dev, "Must set span number AND base chan number\n");
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#ifndef _GPAKCUST_H /* prevent multiple inclusion */
|
||||
#define _GPAKCUST_H
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
@@ -373,7 +373,7 @@ struct t4 {
|
||||
int needed_latency;
|
||||
|
||||
#ifdef VPM_SUPPORT
|
||||
struct vpm450m *vpm450m;
|
||||
struct vpm450m *vpm;
|
||||
#endif
|
||||
struct spi_state st;
|
||||
};
|
||||
@@ -410,7 +410,7 @@ static inline unsigned int ports_on_framer(const struct t4 *wc)
|
||||
}
|
||||
|
||||
#ifdef VPM_SUPPORT
|
||||
static void t4_vpm450_init(struct t4 *wc);
|
||||
static void t4_vpm_init(struct t4 *wc);
|
||||
|
||||
static void echocan_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec);
|
||||
|
||||
@@ -819,12 +819,12 @@ static inline void t4_oct_out(struct t4 *wc, const unsigned int addr, const unsi
|
||||
spin_unlock_irqrestore(&wc->reglock, flags);
|
||||
}
|
||||
|
||||
static void t4_check_vpm450(struct t4 *wc)
|
||||
static void t4_check_vpm(struct t4 *wc)
|
||||
{
|
||||
int channel, tone, start, span;
|
||||
|
||||
if (vpm450m_checkirq(wc->vpm450m)) {
|
||||
while(vpm450m_getdtmf(wc->vpm450m, &channel, &tone, &start)) {
|
||||
if (vpm450m_checkirq(wc->vpm)) {
|
||||
while(vpm450m_getdtmf(wc->vpm, &channel, &tone, &start)) {
|
||||
span = channel & 0x3;
|
||||
channel >>= 2;
|
||||
if (!has_e1_span(wc))
|
||||
@@ -1080,7 +1080,7 @@ unsigned int oct_get_reg(void *data, unsigned int reg)
|
||||
|
||||
static const char *__t4_echocan_name(struct t4 *wc)
|
||||
{
|
||||
if (wc->vpm450m) {
|
||||
if (wc->vpm) {
|
||||
if (wc->numspans == 2)
|
||||
return vpmoct064_name;
|
||||
else if (wc->numspans == 4)
|
||||
@@ -1108,7 +1108,7 @@ static int t4_echocan_create(struct dahdi_chan *chan,
|
||||
const struct dahdi_echocan_ops *ops;
|
||||
const struct dahdi_echocan_features *features;
|
||||
|
||||
if (!vpmsupport || !wc->vpm450m)
|
||||
if (!vpmsupport || !wc->vpm)
|
||||
return -ENODEV;
|
||||
|
||||
ops = &vpm_ec_ops;
|
||||
@@ -1127,7 +1127,7 @@ static int t4_echocan_create(struct dahdi_chan *chan,
|
||||
|
||||
channel = has_e1_span(wc) ? chan->chanpos : chan->chanpos + 4;
|
||||
|
||||
if (wc->vpm450m) {
|
||||
if (wc->vpm) {
|
||||
if (is_octal(wc))
|
||||
channel = channel << 3;
|
||||
else
|
||||
@@ -1138,7 +1138,7 @@ static int t4_echocan_create(struct dahdi_chan *chan,
|
||||
"Channel is %d, Span is %d, offset is %d "
|
||||
"length %d\n", wc->num, chan->chanpos,
|
||||
chan->span->offset, channel, ecp->tap_length);
|
||||
vpm450m_setec(wc->vpm450m, channel, ecp->tap_length);
|
||||
vpm450m_setec(wc->vpm, channel, ecp->tap_length);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1152,7 +1152,7 @@ static void echocan_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec
|
||||
|
||||
channel = has_e1_span(wc) ? chan->chanpos : chan->chanpos + 4;
|
||||
|
||||
if (wc->vpm450m) {
|
||||
if (wc->vpm) {
|
||||
if (is_octal(wc))
|
||||
channel = channel << 3;
|
||||
else
|
||||
@@ -1163,7 +1163,7 @@ static void echocan_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec
|
||||
"Channel is %d, Span is %d, offset is %d "
|
||||
"length 0\n", wc->num, chan->chanpos,
|
||||
chan->span->offset, channel);
|
||||
vpm450m_setec(wc->vpm450m, channel, 0);
|
||||
vpm450m_setec(wc->vpm, channel, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1209,7 +1209,7 @@ static int t4_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long dat
|
||||
case DAHDI_TONEDETECT:
|
||||
if (get_user(j, (__user int *) data))
|
||||
return -EFAULT;
|
||||
if (!wc->vpm450m)
|
||||
if (!wc->vpm)
|
||||
return -ENOSYS;
|
||||
if (j && (vpmdtmfsupport == 0))
|
||||
return -ENOSYS;
|
||||
@@ -1226,7 +1226,7 @@ static int t4_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long dat
|
||||
if (!has_e1_span(wc))
|
||||
channel += (4 << 3);
|
||||
channel |= chan->span->offset;
|
||||
vpm450m_setdtmf(wc->vpm450m, channel, j & DAHDI_TONEDETECT_ON,
|
||||
vpm450m_setdtmf(wc->vpm, channel, j & DAHDI_TONEDETECT_ON,
|
||||
j & DAHDI_TONEDETECT_MUTE);
|
||||
return 0;
|
||||
#endif
|
||||
@@ -2786,6 +2786,39 @@ static void __t4_configure_e1(struct t4 *wc, int unit, int lineconfig)
|
||||
wc->numspans, unit + 1, framing, line, crc4);
|
||||
}
|
||||
|
||||
/**
|
||||
* t4_check_for_interrupts - Return 0 if the card is generating interrupts.
|
||||
* @wc: The card to check.
|
||||
*
|
||||
* If the card is not generating interrupts, this function will also place all
|
||||
* the spans on the card into red alarm.
|
||||
*
|
||||
*/
|
||||
static int t4_check_for_interrupts(struct t4 *wc)
|
||||
{
|
||||
unsigned int starting_intcount = wc->intcount;
|
||||
unsigned long stop_time = jiffies + HZ*2;
|
||||
unsigned long flags;
|
||||
int x;
|
||||
|
||||
msleep(20);
|
||||
spin_lock_irqsave(&wc->reglock, flags);
|
||||
while (starting_intcount == wc->intcount) {
|
||||
spin_unlock_irqrestore(&wc->reglock, flags);
|
||||
if (time_after(jiffies, stop_time)) {
|
||||
for (x = 0; x < wc->numspans; x++)
|
||||
wc->tspans[x]->span.alarms = DAHDI_ALARM_RED;
|
||||
dev_err(&wc->dev->dev, "Interrupts not detected.\n");
|
||||
return -EIO;
|
||||
}
|
||||
msleep(100);
|
||||
spin_lock_irqsave(&wc->reglock, flags);
|
||||
}
|
||||
spin_unlock_irqrestore(&wc->reglock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int t4_startup(struct file *file, struct dahdi_span *span)
|
||||
{
|
||||
#ifdef SUPPORT_GEN1
|
||||
@@ -2847,7 +2880,7 @@ static int t4_startup(struct file *file, struct dahdi_span *span)
|
||||
/* Start DMA, enabling DMA interrupts on read only */
|
||||
wc->dmactrl |= (ts->spanflags & FLAG_2NDGEN) ? 0xc0000000 : 0xc0000003;
|
||||
#ifdef VPM_SUPPORT
|
||||
wc->dmactrl |= (wc->vpm450m) ? T4_VPM_PRESENT : 0;
|
||||
wc->dmactrl |= (wc->vpm) ? T4_VPM_PRESENT : 0;
|
||||
#endif
|
||||
/* Seed interrupt register */
|
||||
__t4_pci_out(wc, WC_INTR, 0x0c);
|
||||
@@ -2908,6 +2941,11 @@ static int t4_startup(struct file *file, struct dahdi_span *span)
|
||||
"Source\n", span->spanno);
|
||||
}
|
||||
|
||||
if (!alreadyrunning) {
|
||||
if (t4_check_for_interrupts(wc))
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (debug)
|
||||
dev_info(&wc->dev->dev, "Completed startup!\n");
|
||||
clear_bit(T4_IGNORE_LATENCY, &wc->checkflag);
|
||||
@@ -3903,12 +3941,12 @@ static void t4_isr_bh(unsigned long data)
|
||||
}
|
||||
}
|
||||
#ifdef VPM_SUPPORT
|
||||
if (wc->vpm450m) {
|
||||
if (wc->vpm) {
|
||||
if (test_and_clear_bit(T4_CHECK_VPM, &wc->checkflag)) {
|
||||
/* How stupid is it that the octasic can't generate an
|
||||
* interrupt when there's a tone, in spite of what
|
||||
* their documentation says? */
|
||||
t4_check_vpm450(wc);
|
||||
t4_check_vpm(wc);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -4082,7 +4120,7 @@ DAHDI_IRQ_HANDLER(t4_interrupt_gen2)
|
||||
}
|
||||
|
||||
#ifdef VPM_SUPPORT
|
||||
if (wc->vpm450m && vpmdtmfsupport) {
|
||||
if (wc->vpm && vpmdtmfsupport) {
|
||||
/* How stupid is it that the octasic can't generate an
|
||||
* interrupt when there's a tone, in spite of what their
|
||||
* documentation says? */
|
||||
@@ -4127,7 +4165,7 @@ static int t4_reset_dma(struct t4 *wc)
|
||||
t4_pci_out(wc, WC_INTR, 0);
|
||||
#ifdef VPM_SUPPORT
|
||||
wc->dmactrl = 0xc0000000 | (1 << 29) |
|
||||
((wc->vpm450m) ? T4_VPM_PRESENT : 0);
|
||||
((wc->vpm) ? T4_VPM_PRESENT : 0);
|
||||
#else
|
||||
wc->dmactrl = 0xc0000000 | (1 << 29);
|
||||
#endif
|
||||
@@ -4139,7 +4177,7 @@ static int t4_reset_dma(struct t4 *wc)
|
||||
#endif
|
||||
|
||||
#ifdef VPM_SUPPORT
|
||||
static void t4_vpm450_init(struct t4 *wc)
|
||||
static void t4_vpm_init(struct t4 *wc)
|
||||
{
|
||||
int laws[8] = { 0, };
|
||||
int x;
|
||||
@@ -4185,7 +4223,15 @@ static void t4_vpm450_init(struct t4 *wc)
|
||||
laws[x] = 1;
|
||||
}
|
||||
|
||||
switch ((vpm_capacity = get_vpm450m_capacity(wc))) {
|
||||
vpm_capacity = get_vpm450m_capacity(wc);
|
||||
if (vpm_capacity != wc->numspans * 32) {
|
||||
dev_info(&wc->dev->dev, "Disabling VPMOCT%03d. TE%dXXP"\
|
||||
" requires a VPMOCT%03d", vpm_capacity,
|
||||
wc->numspans, wc->numspans*32);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (vpm_capacity) {
|
||||
case 64:
|
||||
#if defined(HOTPLUG_FIRMWARE)
|
||||
if ((request_firmware(&firmware, oct064_firmware, &wc->dev->dev) != 0) ||
|
||||
@@ -4249,7 +4295,7 @@ static void t4_vpm450_init(struct t4 *wc)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(wc->vpm450m = init_vpm450m(wc, laws, wc->numspans, firmware))) {
|
||||
if (!(wc->vpm = init_vpm450m(wc, laws, wc->numspans, firmware))) {
|
||||
dev_notice(&wc->dev->dev, "VPM450: Failed to initialize\n");
|
||||
if (firmware != &embedded_firmware)
|
||||
release_firmware(firmware);
|
||||
@@ -4842,19 +4888,21 @@ static int t4_hardware_init_1(struct t4 *wc, unsigned int cardflags)
|
||||
|
||||
/* TE820 Auth Check */
|
||||
if (is_octal(wc)) {
|
||||
unsigned long stop = jiffies + HZ;
|
||||
uint32_t donebit;
|
||||
|
||||
donebit = t4_pci_in(wc, WC_LEDS2);
|
||||
t4_pci_out(wc, WC_LEDS2, WC_SET_AUTH);
|
||||
|
||||
msleep(1000);
|
||||
|
||||
donebit = t4_pci_in(wc, WC_LEDS2);
|
||||
if (!(donebit & WC_GET_AUTH)) {
|
||||
/* Encryption check failed, stop operation */
|
||||
dev_info(&wc->dev->dev, "Failed encryption check. "\
|
||||
"Unloading driver.\n");
|
||||
return -EIO;
|
||||
while (!(donebit & WC_GET_AUTH)) {
|
||||
if (time_after(jiffies, stop)) {
|
||||
/* Encryption check failed, stop operation */
|
||||
dev_info(&wc->dev->dev,
|
||||
"Failed encryption check. "
|
||||
"Unloading driver.\n");
|
||||
return -EIO;
|
||||
}
|
||||
msleep(20);
|
||||
donebit = t4_pci_in(wc, WC_LEDS2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5180,11 +5228,11 @@ t4_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
t4_gpio_setdir(wc, (0xff), (0xff));
|
||||
|
||||
#ifdef VPM_SUPPORT
|
||||
if (!wc->vpm450m) {
|
||||
t4_vpm450_init(wc);
|
||||
wc->dmactrl |= (wc->vpm450m) ? T4_VPM_PRESENT : 0;
|
||||
if (!wc->vpm) {
|
||||
t4_vpm_init(wc);
|
||||
wc->dmactrl |= (wc->vpm) ? T4_VPM_PRESENT : 0;
|
||||
t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
|
||||
if (wc->vpm450m)
|
||||
if (wc->vpm)
|
||||
set_span_devicetype(wc);
|
||||
}
|
||||
#endif
|
||||
@@ -5260,10 +5308,10 @@ static void _t4_remove_one(struct t4 *wc)
|
||||
t4_hardware_stop(wc);
|
||||
|
||||
#ifdef VPM_SUPPORT
|
||||
/* Release vpm450m */
|
||||
if (wc->vpm450m)
|
||||
release_vpm450m(wc->vpm450m);
|
||||
wc->vpm450m = NULL;
|
||||
/* Release vpm */
|
||||
if (wc->vpm)
|
||||
release_vpm450m(wc->vpm);
|
||||
wc->vpm = NULL;
|
||||
#endif
|
||||
/* Unregister spans */
|
||||
|
||||
|
||||
@@ -474,6 +474,7 @@ wctc4xxp_skb_to_cmd(struct wcdte *wc, const struct sk_buff *skb)
|
||||
return cmd;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)
|
||||
static void
|
||||
wctc4xxp_net_set_multi(struct net_device *netdev)
|
||||
{
|
||||
@@ -481,6 +482,15 @@ wctc4xxp_net_set_multi(struct net_device *netdev)
|
||||
DTE_DEBUG(DTE_DEBUG_GENERAL, "%s promiscuity:%d\n",
|
||||
__func__, netdev->promiscuity);
|
||||
}
|
||||
#else
|
||||
static void
|
||||
wctc4xxp_set_rx_mode(struct net_device *netdev)
|
||||
{
|
||||
struct wcdte *wc = wcdte_from_netdev(netdev);
|
||||
DTE_DEBUG(DTE_DEBUG_GENERAL, "%s promiscuity:%d\n",
|
||||
__func__, netdev->promiscuity);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
wctc4xxp_net_up(struct net_device *netdev)
|
||||
@@ -644,7 +654,11 @@ wctc4xxp_net_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
|
||||
|
||||
#ifdef HAVE_NET_DEVICE_OPS
|
||||
static const struct net_device_ops wctc4xxp_netdev_ops = {
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)
|
||||
.ndo_set_multicast_list = &wctc4xxp_net_set_multi,
|
||||
#else
|
||||
.ndo_set_rx_mode = &wctc4xxp_set_rx_mode,
|
||||
#endif
|
||||
.ndo_open = &wctc4xxp_net_up,
|
||||
.ndo_stop = &wctc4xxp_net_down,
|
||||
.ndo_start_xmit = &wctc4xxp_net_hard_start_xmit,
|
||||
|
||||
@@ -2256,20 +2256,16 @@ wctdm_fxs_hooksig(struct wctdm *wc, struct wctdm_module *const mod,
|
||||
switch (txsig) {
|
||||
case DAHDI_TXSIG_ONHOOK:
|
||||
switch (get_dahdi_chan(wc, mod)->sig) {
|
||||
case DAHDI_SIG_EM:
|
||||
case DAHDI_SIG_FXOKS:
|
||||
case DAHDI_SIG_FXOLS:
|
||||
x = fxs->idletxhookstate;
|
||||
break;
|
||||
case DAHDI_SIG_FXOGS:
|
||||
x = (POLARITY_XOR(fxs)) ?
|
||||
SLIC_LF_RING_OPEN :
|
||||
SLIC_LF_TIP_OPEN;
|
||||
break;
|
||||
case DAHDI_SIG_EM:
|
||||
case DAHDI_SIG_FXOKS:
|
||||
case DAHDI_SIG_FXOLS:
|
||||
default:
|
||||
WARN_ONCE(1, "%x is an invalid signaling state for "
|
||||
"an FXS module.\n",
|
||||
get_dahdi_chan(wc, mod)->sig);
|
||||
x = fxs->idletxhookstate;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -4937,8 +4933,30 @@ static void wctdm_back_out_gracefully(struct wctdm *wc)
|
||||
{
|
||||
int i;
|
||||
unsigned long flags;
|
||||
struct vpmadt032 *vpm;
|
||||
LIST_HEAD(local_list);
|
||||
|
||||
spin_lock_irqsave(&wc->reglock, flags);
|
||||
if (wc->not_ready) {
|
||||
wc->not_ready--;
|
||||
spin_unlock_irqrestore(&wc->reglock, flags);
|
||||
while (wctdm_wait_for_ready(wc))
|
||||
schedule();
|
||||
spin_lock_irqsave(&wc->reglock, flags);
|
||||
}
|
||||
spin_unlock_irqrestore(&wc->reglock, flags);
|
||||
|
||||
if (wc->vpmadt032) {
|
||||
flush_workqueue(wc->vpmadt032->wq);
|
||||
clear_bit(VPM150M_ACTIVE, &wc->vpmadt032->control);
|
||||
flush_workqueue(wc->vpmadt032->wq);
|
||||
spin_lock_irqsave(&wc->reglock, flags);
|
||||
vpm = wc->vpmadt032;
|
||||
wc->vpmadt032 = NULL;
|
||||
spin_unlock_irqrestore(&wc->reglock, flags);
|
||||
vpmadt032_free(vpm);
|
||||
}
|
||||
|
||||
voicebus_release(&wc->vb);
|
||||
#ifdef CONFIG_VOICEBUS_ECREFERENCE
|
||||
for (i = 0; i < ARRAY_SIZE(wc->ec_reference); ++i) {
|
||||
@@ -5716,7 +5734,6 @@ __wctdm_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
if (is_hx8(wc)) {
|
||||
ret = hx8_check_firmware(wc);
|
||||
if (ret) {
|
||||
voicebus_release(&wc->vb);
|
||||
wctdm_back_out_gracefully(wc);
|
||||
return -EIO;
|
||||
}
|
||||
@@ -5992,6 +6009,8 @@ static void __devexit wctdm_remove_one(struct pci_dev *pdev)
|
||||
schedule();
|
||||
}
|
||||
|
||||
flush_scheduled_work();
|
||||
|
||||
/* shut down any BRI modules */
|
||||
for (i = 0; i < wc->mods_per_board; i += 4) {
|
||||
if (wc->mods[i].type == BRI)
|
||||
|
||||
@@ -35,6 +35,10 @@
|
||||
|
||||
static const char rcsid[] = "$Id$";
|
||||
|
||||
#ifndef DAHDI_SIG_HARDHDLC
|
||||
#error Cannot build BRI without HARDHDLC supprt
|
||||
#endif
|
||||
|
||||
static DEF_PARM(int, debug, 0, 0644, "Print DBG statements"); /* must be before dahdi_debug.h */
|
||||
static DEF_PARM(uint, poll_interval, 500, 0644, "Poll channel state interval in milliseconds (0 - disable)");
|
||||
static DEF_PARM_BOOL(nt_keepalive, 1, 0644, "Force BRI_NT to keep trying connection");
|
||||
@@ -129,22 +133,7 @@ typedef union {
|
||||
#define REG30_LOST 3 /* in polls */
|
||||
#define DCHAN_LOST 15000 /* in ticks */
|
||||
|
||||
#ifdef CONFIG_DAHDI_BRI_DCHANS
|
||||
#define BRI_DCHAN_SIGCAP ( \
|
||||
DAHDI_SIG_EM | \
|
||||
DAHDI_SIG_CLEAR | \
|
||||
DAHDI_SIG_FXSLS | \
|
||||
DAHDI_SIG_FXSGS | \
|
||||
DAHDI_SIG_FXSKS | \
|
||||
DAHDI_SIG_FXOLS | \
|
||||
DAHDI_SIG_FXOGS | \
|
||||
DAHDI_SIG_FXOKS | \
|
||||
DAHDI_SIG_CAS | \
|
||||
DAHDI_SIG_SF \
|
||||
)
|
||||
#else
|
||||
#define BRI_DCHAN_SIGCAP DAHDI_SIG_HARDHDLC
|
||||
#endif
|
||||
#define BRI_BCHAN_SIGCAP (DAHDI_SIG_CLEAR | DAHDI_SIG_DACS)
|
||||
|
||||
#define IS_NT(xpd) (PHONEDEV(xpd).direction == TO_PHONE)
|
||||
@@ -218,13 +207,7 @@ struct BRI_priv_data {
|
||||
/*
|
||||
* D-Chan: buffers + extra state info.
|
||||
*/
|
||||
#ifdef CONFIG_DAHDI_BRI_DCHANS
|
||||
int dchan_r_idx;
|
||||
byte dchan_rbuf[DCHAN_BUFSIZE];
|
||||
#else
|
||||
atomic_t hdlc_pending;
|
||||
#endif
|
||||
byte dchan_tbuf[DCHAN_BUFSIZE];
|
||||
bool txframe_begin;
|
||||
|
||||
uint tick_counter;
|
||||
@@ -438,22 +421,6 @@ static void nt_activation(xpd_t *xpd, bool on)
|
||||
/*
|
||||
* D-Chan receive
|
||||
*/
|
||||
static void bri_hdlc_abort(xpd_t *xpd, struct dahdi_chan *dchan, int event)
|
||||
{
|
||||
struct BRI_priv_data *priv;
|
||||
|
||||
priv = xpd->priv;
|
||||
BUG_ON(!priv);
|
||||
#ifdef CONFIG_DAHDI_BRI_DCHANS
|
||||
if(debug & DBG_COMMANDS)
|
||||
dump_hex_buf(xpd, "D-Chan(abort) RX: dchan_rbuf",
|
||||
priv->dchan_rbuf, priv->dchan_r_idx);
|
||||
priv->dchan_r_idx = 0;
|
||||
#else
|
||||
dahdi_hdlc_abort(dchan, event);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int bri_check_stat(xpd_t *xpd, struct dahdi_chan *dchan, byte *buf, int len)
|
||||
{
|
||||
struct BRI_priv_data *priv;
|
||||
@@ -461,21 +428,11 @@ static int bri_check_stat(xpd_t *xpd, struct dahdi_chan *dchan, byte *buf, int l
|
||||
|
||||
priv = xpd->priv;
|
||||
BUG_ON(!priv);
|
||||
#ifdef CONFIG_DAHDI_BRI_DCHANS
|
||||
if(priv->dchan_r_idx < 4) {
|
||||
XPD_NOTICE(xpd, "D-Chan RX short frame (dchan_r_idx=%d)\n",
|
||||
priv->dchan_r_idx);
|
||||
dump_hex_buf(xpd, "D-Chan RX: current packet", buf, len);
|
||||
bri_hdlc_abort(xpd, dchan, DAHDI_EVENT_ABORT);
|
||||
return -EPROTO;
|
||||
}
|
||||
#else
|
||||
if(len <= 0) {
|
||||
XPD_NOTICE(xpd, "D-Chan RX DROP: short frame (len=%d)\n", len);
|
||||
bri_hdlc_abort(xpd, dchan, DAHDI_EVENT_ABORT);
|
||||
dahdi_hdlc_abort(dchan, DAHDI_EVENT_ABORT);
|
||||
return -EPROTO;
|
||||
}
|
||||
#endif
|
||||
status = buf[len-1];
|
||||
if(status) {
|
||||
int event = DAHDI_EVENT_ABORT;
|
||||
@@ -487,132 +444,12 @@ static int bri_check_stat(xpd_t *xpd, struct dahdi_chan *dchan, byte *buf, int l
|
||||
event = DAHDI_EVENT_BADFCS;
|
||||
}
|
||||
dump_hex_buf(xpd, "D-Chan RX: current packet", buf, len);
|
||||
bri_hdlc_abort(xpd, dchan, event);
|
||||
dahdi_hdlc_abort(dchan, event);
|
||||
return -EPROTO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bri_hdlc_putbuf(xpd_t *xpd, struct dahdi_chan *dchan,
|
||||
unsigned char *buf, int len)
|
||||
{
|
||||
#ifdef CONFIG_DAHDI_BRI_DCHANS
|
||||
struct BRI_priv_data *priv;
|
||||
byte *dchan_buf;
|
||||
byte *dst;
|
||||
int idx;
|
||||
|
||||
priv = xpd->priv;
|
||||
BUG_ON(!priv);
|
||||
dchan_buf = dchan->readchunk;
|
||||
idx = priv->dchan_r_idx;
|
||||
if(idx + len >= DCHAN_BUFSIZE) {
|
||||
XPD_ERR(xpd, "D-Chan RX overflow: %d\n", idx);
|
||||
dump_hex_buf(xpd, " current packet", buf, len);
|
||||
dump_hex_buf(xpd, " dchan_buf", dchan_buf, idx);
|
||||
return -ENOSPC;
|
||||
}
|
||||
dst = dchan_buf + idx;
|
||||
idx += len;
|
||||
priv->dchan_r_idx = idx;
|
||||
memcpy(dst, buf, len);
|
||||
#else
|
||||
dahdi_hdlc_putbuf(dchan, buf, len);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bri_hdlc_finish(xpd_t *xpd, struct dahdi_chan *dchan)
|
||||
{
|
||||
struct BRI_priv_data *priv;
|
||||
|
||||
priv = xpd->priv;
|
||||
BUG_ON(!priv);
|
||||
#ifdef CONFIG_DAHDI_BRI_DCHANS
|
||||
dchan->bytes2receive = priv->dchan_r_idx - 1;
|
||||
dchan->eofrx = 1;
|
||||
#else
|
||||
dahdi_hdlc_finish(dchan);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DAHDI_BRI_DCHANS
|
||||
static int rx_dchan(xpd_t *xpd, reg_cmd_t *regcmd)
|
||||
{
|
||||
struct BRI_priv_data *priv;
|
||||
byte *src;
|
||||
byte *dst;
|
||||
byte *dchan_buf;
|
||||
struct dahdi_chan *dchan;
|
||||
uint len;
|
||||
bool eoframe;
|
||||
int idx;
|
||||
int ret = 0;
|
||||
|
||||
src = REG_XDATA(regcmd);
|
||||
len = regcmd->bytes;
|
||||
eoframe = regcmd->eoframe;
|
||||
if(len <= 0)
|
||||
return 0;
|
||||
if(!SPAN_REGISTERED(xpd)) /* Nowhere to copy data */
|
||||
return 0;
|
||||
BUG_ON(!xpd);
|
||||
priv = xpd->priv;
|
||||
BUG_ON(!priv);
|
||||
xbus = xpd->xbus;
|
||||
dchan = XPD_CHAN(xpd, 2);
|
||||
if(!IS_OFFHOOK(xpd, 2)) { /* D-chan is used? */
|
||||
static int rate_limit;
|
||||
|
||||
if((rate_limit++ % 1000) == 0)
|
||||
XPD_DBG(SIGNAL, xpd, "D-Chan unused\n");
|
||||
dchan->bytes2receive = 0;
|
||||
dchan->bytes2transmit = 0;
|
||||
goto out;
|
||||
}
|
||||
dchan_buf = dchan->readchunk;
|
||||
idx = priv->dchan_r_idx;
|
||||
if(idx + len >= DCHAN_BUFSIZE) {
|
||||
XPD_ERR(xpd, "D-Chan RX overflow: %d\n", idx);
|
||||
dump_hex_buf(xpd, " current packet", src, len);
|
||||
dump_hex_buf(xpd, " dchan_buf", dchan_buf, idx);
|
||||
ret = -ENOSPC;
|
||||
if(eoframe)
|
||||
goto drop;
|
||||
goto out;
|
||||
}
|
||||
dst = dchan_buf + idx;
|
||||
idx += len;
|
||||
priv->dchan_r_idx = idx;
|
||||
memcpy(dst, src, len);
|
||||
if(!eoframe)
|
||||
goto out;
|
||||
if(idx < 4) {
|
||||
XPD_NOTICE(xpd, "D-Chan RX short frame (idx=%d)\n", idx);
|
||||
dump_hex_buf(xpd, "D-Chan RX: current packet", src, len);
|
||||
dump_hex_buf(xpd, "D-Chan RX: chan_buf", dchan_buf, idx);
|
||||
ret = -EPROTO;
|
||||
goto drop;
|
||||
}
|
||||
if((ret = bri_check_stat(xpd, dchan, dchan_buf, idx)) < 0)
|
||||
goto drop;
|
||||
if(debug)
|
||||
dump_dchan_packet(xpd, 0, dchan_buf, idx /* - 3 */); /* Print checksum? */
|
||||
/*
|
||||
* Tell Dahdi that we received idx-1 bytes. They include the data and a 2-byte checksum.
|
||||
* The last byte (that we don't pass on) is 0 if the checksum is correct. If it were wrong,
|
||||
* we would drop the packet in the "if(dchan_buf[idx-1])" above.
|
||||
*/
|
||||
dchan->bytes2receive = idx - 1;
|
||||
dchan->eofrx = 1;
|
||||
priv->dchan_rx_counter++;
|
||||
priv->dchan_norx_ticks = 0;
|
||||
drop:
|
||||
priv->dchan_r_idx = 0;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
static int rx_dchan(xpd_t *xpd, reg_cmd_t *regcmd)
|
||||
{
|
||||
struct BRI_priv_data *priv;
|
||||
@@ -638,16 +475,10 @@ static int rx_dchan(xpd_t *xpd, reg_cmd_t *regcmd)
|
||||
|
||||
if((rate_limit++ % 1000) == 0)
|
||||
XPD_DBG(SIGNAL, xpd, "D-Chan unused\n");
|
||||
#ifdef CONFIG_DAHDI_BRI_DCHANS
|
||||
dchan->bytes2receive = 0;
|
||||
dchan->bytes2transmit = 0;
|
||||
#endif
|
||||
goto out;
|
||||
}
|
||||
XPD_DBG(GENERAL, xpd, "D-Chan RX: eoframe=%d len=%d\n", eoframe, len);
|
||||
ret = bri_hdlc_putbuf(xpd, dchan, src, (eoframe) ? len - 1 : len);
|
||||
if(ret < 0)
|
||||
goto out;
|
||||
dahdi_hdlc_putbuf(dchan, src, (eoframe) ? len - 1 : len);
|
||||
if(!eoframe)
|
||||
goto out;
|
||||
if((ret = bri_check_stat(xpd, dchan, src, len)) < 0)
|
||||
@@ -657,18 +488,16 @@ static int rx_dchan(xpd_t *xpd, reg_cmd_t *regcmd)
|
||||
* The last byte (that we don't pass on) is 0 if the checksum is correct. If it were wrong,
|
||||
* we would drop the packet in the "if(src[len-1])" above.
|
||||
*/
|
||||
bri_hdlc_finish(xpd, dchan);
|
||||
dahdi_hdlc_finish(dchan);
|
||||
priv->dchan_rx_counter++;
|
||||
priv->dchan_norx_ticks = 0;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* D-Chan transmit
|
||||
*/
|
||||
#ifndef CONFIG_DAHDI_BRI_DCHANS
|
||||
/* DAHDI calls this when it has data it wants to send to the HDLC controller */
|
||||
static void bri_hdlc_hard_xmit(struct dahdi_chan *chan)
|
||||
{
|
||||
@@ -683,86 +512,129 @@ static void bri_hdlc_hard_xmit(struct dahdi_chan *chan)
|
||||
atomic_inc(&priv->hdlc_pending);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int bri_hdlc_getbuf(struct dahdi_chan *dchan, unsigned char *buf,
|
||||
unsigned int *size)
|
||||
static int send_dchan_frame(xpd_t *xpd, xframe_t *xframe, bool is_eof)
|
||||
{
|
||||
int len = *size;
|
||||
int eoframe;
|
||||
|
||||
#ifdef CONFIG_DAHDI_BRI_DCHANS
|
||||
len = dchan->bytes2transmit; /* dchan's hdlc package len */
|
||||
if(len > *size)
|
||||
len = *size; /* Silent truncation */
|
||||
eoframe = dchan->eoftx; /* dchan's end of frame */
|
||||
dchan->bytes2transmit = 0;
|
||||
dchan->eoftx = 0;
|
||||
dchan->bytes2receive = 0;
|
||||
dchan->eofrx = 0;
|
||||
#else
|
||||
eoframe = dahdi_hdlc_getbuf(dchan, buf, &len);
|
||||
#endif
|
||||
*size = len;
|
||||
return eoframe;
|
||||
}
|
||||
|
||||
static int tx_dchan(xpd_t *xpd)
|
||||
{
|
||||
struct BRI_priv_data *priv;
|
||||
struct dahdi_chan *dchan;
|
||||
int len;
|
||||
int eoframe;
|
||||
int ret;
|
||||
struct BRI_priv_data *priv;
|
||||
int ret;
|
||||
|
||||
XPD_DBG(COMMANDS, xpd, "eoframe=%d\n", is_eof);
|
||||
priv = xpd->priv;
|
||||
BUG_ON(!priv);
|
||||
#ifndef CONFIG_DAHDI_BRI_DCHANS
|
||||
if(atomic_read(&priv->hdlc_pending) == 0)
|
||||
return 0;
|
||||
#endif
|
||||
if(!SPAN_REGISTERED(xpd) || !(PHONEDEV(xpd).span.flags & DAHDI_FLAG_RUNNING))
|
||||
return 0;
|
||||
dchan = XPD_CHAN(xpd, 2);
|
||||
len = ARRAY_SIZE(priv->dchan_tbuf);
|
||||
if(len > MULTIBYTE_MAX_LEN)
|
||||
len = MULTIBYTE_MAX_LEN;
|
||||
eoframe = bri_hdlc_getbuf(dchan, priv->dchan_tbuf, &len);
|
||||
if(len <= 0)
|
||||
return 0; /* Nothing to transmit on D channel */
|
||||
if(len > MULTIBYTE_MAX_LEN) {
|
||||
XPD_ERR(xpd, "%s: len=%d. need to split. Unimplemented.\n", __FUNCTION__, len);
|
||||
dump_hex_buf(xpd, "D-Chan TX:", priv->dchan_tbuf, len);
|
||||
return -EINVAL;
|
||||
}
|
||||
if(!test_bit(HFC_L1_ACTIVATED, &priv->l1_flags) && !test_bit(HFC_L1_ACTIVATING, &priv->l1_flags)) {
|
||||
if (!test_bit(HFC_L1_ACTIVATED, &priv->l1_flags)
|
||||
&& !test_bit(HFC_L1_ACTIVATING, &priv->l1_flags)) {
|
||||
XPD_DBG(SIGNAL, xpd, "Want to transmit: Kick D-Channel transmiter\n");
|
||||
if(! IS_NT(xpd))
|
||||
if (!IS_NT(xpd))
|
||||
te_activation(xpd, 1);
|
||||
else
|
||||
nt_activation(xpd, 1);
|
||||
}
|
||||
if(debug)
|
||||
dump_dchan_packet(xpd, 1, priv->dchan_tbuf, len);
|
||||
if(eoframe)
|
||||
priv->txframe_begin = 1;
|
||||
else
|
||||
priv->txframe_begin = 0;
|
||||
XPD_DBG(COMMANDS, xpd, "eoframe=%d len=%d\n", eoframe, len);
|
||||
ret = send_multibyte_request(xpd->xbus, xpd->addr.unit, xpd->addr.subunit,
|
||||
eoframe, priv->dchan_tbuf, len);
|
||||
if(ret < 0)
|
||||
XPD_NOTICE(xpd, "%s: failed sending xframe\n", __FUNCTION__);
|
||||
if(eoframe) {
|
||||
#ifndef CONFIG_DAHDI_BRI_DCHANS
|
||||
dump_xframe("send_dchan_frame", xpd->xbus, xframe, debug);
|
||||
ret = send_cmd_frame(xpd->xbus, xframe);
|
||||
if (ret < 0)
|
||||
XPD_ERR(xpd, "%s: failed sending xframe\n", __func__);
|
||||
if (is_eof) {
|
||||
atomic_dec(&priv->hdlc_pending);
|
||||
#endif
|
||||
priv->dchan_tx_counter++;
|
||||
}
|
||||
priv->txframe_begin = 1;
|
||||
} else
|
||||
priv->txframe_begin = 0;
|
||||
priv->dchan_notx_ticks = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill a single multibyte REGISTER_REQUEST
|
||||
*/
|
||||
static void fill_multibyte(xpd_t *xpd, xpacket_t *pack, bool eoframe,
|
||||
char *buf, int len)
|
||||
{
|
||||
reg_cmd_t *reg_cmd;
|
||||
char *p;
|
||||
|
||||
XPACKET_INIT(pack, GLOBAL, REGISTER_REQUEST, xpd->xbus_idx, 0, 0);
|
||||
XPACKET_LEN(pack) = RPACKET_SIZE(GLOBAL, REGISTER_REQUEST);
|
||||
reg_cmd = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REQUEST, reg_cmd);
|
||||
reg_cmd->bytes = len;
|
||||
reg_cmd->is_multibyte = 1;
|
||||
reg_cmd->portnum = xpd->addr.subunit;
|
||||
reg_cmd->eoframe = eoframe;
|
||||
p = REG_XDATA(reg_cmd);
|
||||
memcpy(p, buf, len);
|
||||
if (debug)
|
||||
dump_dchan_packet(xpd, 1, p, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Transmit available D-Channel frames
|
||||
*
|
||||
* - FPGA firmware expect to get this as a sequence of REGISTER_REQUEST
|
||||
* multibyte commands.
|
||||
* - The payload of each command is limited to MULTIBYTE_MAX_LEN bytes.
|
||||
* - We batch several REGISTER_REQUEST packets into a single xframe.
|
||||
* - The xframe is terminated when we get a bri "end of frame"
|
||||
* or when the xframe is full (should not happen).
|
||||
*/
|
||||
static int tx_dchan(xpd_t *xpd)
|
||||
{
|
||||
struct BRI_priv_data *priv;
|
||||
xframe_t *xframe;
|
||||
xpacket_t *pack;
|
||||
int packet_count;
|
||||
int eoframe;
|
||||
int ret;
|
||||
|
||||
priv = xpd->priv;
|
||||
BUG_ON(!priv);
|
||||
if (atomic_read(&priv->hdlc_pending) == 0)
|
||||
return 0;
|
||||
if (!SPAN_REGISTERED(xpd) ||
|
||||
!(PHONEDEV(xpd).span.flags & DAHDI_FLAG_RUNNING))
|
||||
return 0;
|
||||
/* Allocate frame */
|
||||
xframe = ALLOC_SEND_XFRAME(xpd->xbus);
|
||||
if (!xframe) {
|
||||
XPD_NOTICE(xpd, "%s: failed to allocate new xframe\n",
|
||||
__func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
for (packet_count = 0, eoframe = 0; !eoframe; packet_count++) {
|
||||
int packet_len = RPACKET_SIZE(GLOBAL, REGISTER_REQUEST);
|
||||
char buf[MULTIBYTE_MAX_LEN];
|
||||
int len = MULTIBYTE_MAX_LEN;
|
||||
|
||||
/* Reserve packet */
|
||||
pack = xframe_next_packet(xframe, packet_len);
|
||||
if (!pack) {
|
||||
BUG_ON(!packet_count);
|
||||
/*
|
||||
* A split. Send what we currently have.
|
||||
*/
|
||||
XPD_NOTICE(xpd,
|
||||
"%s: xframe is full (%d packets)\n",
|
||||
__func__, packet_count);
|
||||
break;
|
||||
}
|
||||
/* Get data from DAHDI */
|
||||
eoframe = dahdi_hdlc_getbuf(XPD_CHAN(xpd, 2), buf, &len);
|
||||
if (len <= 0) {
|
||||
/*
|
||||
* Already checked priv->hdlc_pending,
|
||||
* should never get here.
|
||||
*/
|
||||
if (printk_ratelimit())
|
||||
XPD_ERR(xpd,
|
||||
"%s: hdlc_pending, but nothing to transmit?\n",
|
||||
__func__);
|
||||
FREE_SEND_XFRAME(xpd->xbus, xframe);
|
||||
return -EINVAL;
|
||||
}
|
||||
BUG_ON(len > MULTIBYTE_MAX_LEN);
|
||||
fill_multibyte(xpd, pack, eoframe != 0, buf, len);
|
||||
}
|
||||
return send_dchan_frame(xpd, xframe, eoframe != 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*---------------- BRI: Methods -------------------------------------------*/
|
||||
|
||||
static void bri_proc_remove(xbus_t *xbus, xpd_t *xpd)
|
||||
@@ -853,9 +725,7 @@ static const struct dahdi_span_ops BRI_span_ops = {
|
||||
.chanconfig = bri_chanconfig,
|
||||
.startup = bri_startup,
|
||||
.shutdown = bri_shutdown,
|
||||
#ifndef CONFIG_DAHDI_BRI_DCHANS
|
||||
.hdlc_hard_xmit = bri_hdlc_hard_xmit,
|
||||
#endif
|
||||
.open = xpp_open,
|
||||
.close = xpp_close,
|
||||
.hooksig = xpp_hooksig, /* Only with RBS bits */
|
||||
@@ -904,19 +774,7 @@ static int BRI_card_dahdi_preregistration(xpd_t *xpd, bool on)
|
||||
cur_chan->sigcap = BRI_DCHAN_SIGCAP;
|
||||
clear_bit(DAHDI_FLAGBIT_HDLC, &cur_chan->flags);
|
||||
priv->txframe_begin = 1;
|
||||
#ifdef CONFIG_DAHDI_BRI_DCHANS
|
||||
priv->dchan_r_idx = 0;
|
||||
set_bit(DAHDI_FLAGBIT_BRIDCHAN, &cur_chan->flags);
|
||||
/* Setup big buffers for D-Channel rx/tx */
|
||||
cur_chan->readchunk = priv->dchan_rbuf;
|
||||
cur_chan->writechunk = priv->dchan_tbuf;
|
||||
|
||||
cur_chan->maxbytes2transmit = MULTIBYTE_MAX_LEN;
|
||||
cur_chan->bytes2transmit = 0;
|
||||
cur_chan->bytes2receive = 0;
|
||||
#else
|
||||
atomic_set(&priv->hdlc_pending, 0);
|
||||
#endif
|
||||
} else {
|
||||
cur_chan->sigcap = BRI_BCHAN_SIGCAP;
|
||||
}
|
||||
@@ -1146,15 +1004,6 @@ static int BRI_card_open(xpd_t *xpd, lineno_t pos)
|
||||
static int BRI_card_close(xpd_t *xpd, lineno_t pos)
|
||||
{
|
||||
/* Clear D-Channel pending data */
|
||||
#ifdef CONFIG_DAHDI_BRI_DCHANS
|
||||
struct dahdi_chan *chan = XPD_CHAN(xpd, pos);
|
||||
|
||||
/* Clear D-Channel pending data */
|
||||
chan->bytes2receive = 0;
|
||||
chan->eofrx = 0;
|
||||
chan->bytes2transmit = 0;
|
||||
chan->eoftx = 0;
|
||||
#endif
|
||||
if(pos == 2) {
|
||||
LINE_DBG(SIGNAL, xpd, pos, "ONHOOK the whole span\n");
|
||||
BIT_CLR(PHONEDEV(xpd).offhook_state, 0);
|
||||
@@ -1202,6 +1051,8 @@ static int bri_spanconfig(struct file *file, struct dahdi_span *span,
|
||||
framingstr, codingstr, crcstr,
|
||||
lc->lineconfig,
|
||||
lc->sync);
|
||||
PHONEDEV(xpd).timing_priority = lc->sync;
|
||||
elect_syncer("BRI-spanconfig");
|
||||
/*
|
||||
* FIXME: validate
|
||||
*/
|
||||
@@ -1253,9 +1104,6 @@ static int bri_startup(struct file *file, struct dahdi_span *span)
|
||||
*
|
||||
* Don't Get Mad, Get Even: Now we override dahdi :-)
|
||||
*/
|
||||
#ifdef CONFIG_DAHDI_BRI_DCHANS
|
||||
set_bit(DAHDI_FLAGBIT_BRIDCHAN, &dchan->flags);
|
||||
#endif
|
||||
clear_bit(DAHDI_FLAGBIT_HDLC, &dchan->flags);
|
||||
}
|
||||
return 0;
|
||||
@@ -1429,6 +1277,18 @@ static void BRI_card_pcm_tospan(xpd_t *xpd, xpacket_t *pack)
|
||||
}
|
||||
}
|
||||
|
||||
static int BRI_timing_priority(xpd_t *xpd)
|
||||
{
|
||||
struct BRI_priv_data *priv;
|
||||
|
||||
priv = xpd->priv;
|
||||
BUG_ON(!priv);
|
||||
if (priv->layer1_up)
|
||||
return PHONEDEV(xpd).timing_priority;
|
||||
XPD_DBG(SYNC, xpd, "No timing priority (no layer1)\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
int BRI_echocancel_timeslot(xpd_t *xpd, int pos)
|
||||
{
|
||||
return xpd->addr.subunit * 4 + pos;
|
||||
@@ -1696,7 +1556,7 @@ static const struct phoneops bri_phoneops = {
|
||||
.card_pcm_recompute = BRI_card_pcm_recompute,
|
||||
.card_pcm_fromspan = BRI_card_pcm_fromspan,
|
||||
.card_pcm_tospan = BRI_card_pcm_tospan,
|
||||
.card_timing_priority = generic_timing_priority,
|
||||
.card_timing_priority = BRI_timing_priority,
|
||||
.echocancel_timeslot = BRI_echocancel_timeslot,
|
||||
.echocancel_setmask = BRI_echocancel_setmask,
|
||||
.card_ioctl = BRI_card_ioctl,
|
||||
@@ -1776,9 +1636,6 @@ static int proc_bri_info_read(char *page, char **start, off_t off, int count, in
|
||||
} else {
|
||||
len += sprintf(page + len, "(dead)\n");
|
||||
}
|
||||
#ifndef CONFIG_DAHDI_BRI_DCHANS
|
||||
len += sprintf(page + len, "hdlc_pending=%d\n", atomic_read(&priv->hdlc_pending));
|
||||
#endif
|
||||
len += sprintf(page + len, "dchan_notx_ticks: %d\n", priv->dchan_notx_ticks);
|
||||
len += sprintf(page + len, "dchan_norx_ticks: %d\n", priv->dchan_norx_ticks);
|
||||
len += sprintf(page + len, "LED: %-10s = %d\n", "GREEN", priv->ledstate[GREEN_LED]);
|
||||
@@ -1798,22 +1655,6 @@ static int proc_bri_info_read(char *page, char **start, off_t off, int count, in
|
||||
}
|
||||
#endif
|
||||
|
||||
static DRIVER_ATTR_READER(dchan_hardhdlc_show, drv,buf)
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
#if defined(CONFIG_DAHDI_BRI_DCHANS)
|
||||
len += sprintf(buf + len, "0\n");
|
||||
#elif defined(DAHDI_SIG_HARDHDLC)
|
||||
len += sprintf(buf + len, "1\n");
|
||||
#else
|
||||
#error Cannot build BRI without BRISTUFF or HARDHDLC supprt
|
||||
#endif
|
||||
return len;
|
||||
}
|
||||
|
||||
static DRIVER_ATTR(dchan_hardhdlc,S_IRUGO,dchan_hardhdlc_show,NULL);
|
||||
|
||||
static int bri_xpd_probe(struct device *dev)
|
||||
{
|
||||
xpd_t *xpd;
|
||||
@@ -1856,18 +1697,7 @@ static int __init card_bri_startup(void)
|
||||
|
||||
if((ret = xpd_driver_register(&bri_driver.driver)) < 0)
|
||||
return ret;
|
||||
ret = driver_create_file(&bri_driver.driver, &driver_attr_dchan_hardhdlc);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
INFO("revision %s\n", XPP_VERSION);
|
||||
#if defined(CONFIG_DAHDI_BRI_DCHANS)
|
||||
INFO("FEATURE: WITH BRISTUFF\n");
|
||||
#elif defined(DAHDI_SIG_HARDHDLC)
|
||||
INFO("FEATURE: WITH HARDHDLC\n");
|
||||
#else
|
||||
#error Cannot build BRI without BRISTUFF or HARDHDLC supprt
|
||||
#endif
|
||||
|
||||
xproto_register(&PROTO_TABLE(BRI));
|
||||
return 0;
|
||||
}
|
||||
@@ -1876,7 +1706,6 @@ static void __exit card_bri_cleanup(void)
|
||||
{
|
||||
DBG(GENERAL, "\n");
|
||||
xproto_unregister(&PROTO_TABLE(BRI));
|
||||
driver_remove_file(&bri_driver.driver, &driver_attr_dchan_hardhdlc);
|
||||
xpd_driver_unregister(&bri_driver.driver);
|
||||
}
|
||||
|
||||
|
||||
@@ -134,6 +134,7 @@ struct FXS_priv_data {
|
||||
xpp_line_t want_dtmf_events; /* what dahdi want */
|
||||
xpp_line_t want_dtmf_mute; /* what dahdi want */
|
||||
xpp_line_t prev_key_down; /* DTMF down sets the bit */
|
||||
xpp_line_t neon_blinking;
|
||||
struct timeval prev_key_time[CHANNELS_PERXPD];
|
||||
int led_counter[NUM_LEDS][CHANNELS_PERXPD];
|
||||
int ohttimer[CHANNELS_PERXPD];
|
||||
@@ -564,12 +565,16 @@ static int FXS_card_dahdi_postregistration(xpd_t *xpd, bool on)
|
||||
*/
|
||||
static void __do_mute_dtmf(xpd_t *xpd, int pos, bool muteit)
|
||||
{
|
||||
struct FXS_priv_data *priv;
|
||||
|
||||
priv = xpd->priv;
|
||||
LINE_DBG(SIGNAL, xpd, pos, "%s\n", (muteit) ? "MUTE" : "UNMUTE");
|
||||
if(muteit)
|
||||
BIT_SET(PHONEDEV(xpd).mute_dtmf, pos);
|
||||
else
|
||||
BIT_CLR(PHONEDEV(xpd).mute_dtmf, pos);
|
||||
CALL_PHONE_METHOD(card_pcm_recompute, xpd, 0); /* already spinlocked */
|
||||
/* already spinlocked */
|
||||
CALL_PHONE_METHOD(card_pcm_recompute, xpd, priv->search_fsk_pattern);
|
||||
}
|
||||
|
||||
static int set_vm_led_mode(xbus_t *xbus, xpd_t *xpd, int pos,
|
||||
@@ -584,6 +589,7 @@ static int set_vm_led_mode(xbus_t *xbus, xpd_t *xpd, int pos,
|
||||
if (VMWI_NEON(priv, pos) && msg_waiting) {
|
||||
/* A write to register 0x40 will now turn on/off the VM led */
|
||||
LINE_DBG(SIGNAL, xpd, pos, "NEON\n");
|
||||
BIT_SET(priv->neon_blinking, pos);
|
||||
ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x16, 0xE8, 0x03);
|
||||
ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x15, 0xEF, 0x7B);
|
||||
ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x14, 0x9F, 0x00);
|
||||
@@ -618,6 +624,7 @@ static int set_vm_led_mode(xbus_t *xbus, xpd_t *xpd, int pos,
|
||||
} else {
|
||||
/* A write to register 0x40 will now turn on/off the ringer */
|
||||
LINE_DBG(SIGNAL, xpd, pos, "RINGER\n");
|
||||
BIT_CLR(priv->neon_blinking, pos);
|
||||
|
||||
ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x16, 0x00, 0x00);
|
||||
ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x15, 0x77, 0x01);
|
||||
@@ -877,7 +884,8 @@ static int FXS_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd, unsigned long a
|
||||
if (IS_SET(PHONEDEV(xpd).digital_inputs | PHONEDEV(xpd).digital_outputs, pos))
|
||||
return 0; /* Nothing to do */
|
||||
oht_pcm(xpd, pos, 1); /* Get ready of VMWI FSK tones */
|
||||
if(priv->lasttxhook[pos] == FXS_LINE_POL_ACTIVE) {
|
||||
if (priv->lasttxhook[pos] == FXS_LINE_POL_ACTIVE ||
|
||||
IS_SET(priv->neon_blinking, pos)) {
|
||||
priv->ohttimer[pos] = val;
|
||||
priv->idletxhookstate[pos] = FXS_LINE_POL_OHTRANS;
|
||||
vmwi_search(xpd, pos, 1);
|
||||
@@ -940,10 +948,25 @@ static int FXS_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd, unsigned long a
|
||||
case DAHDI_SETPOLARITY:
|
||||
if (get_user(val, (int __user *)arg))
|
||||
return -EFAULT;
|
||||
/* Can't change polarity while ringing or when open */
|
||||
/*
|
||||
* Asterisk may send us this if chan_dahdi config
|
||||
* has "hanguponpolarityswitch=yes" to notify
|
||||
* that the other side has hanged up.
|
||||
*
|
||||
* This has no effect on normal phone (but we may
|
||||
* be connected to another FXO equipment).
|
||||
* note that this chan_dahdi settings has different
|
||||
* meaning for FXO, where it signals polarity
|
||||
* reversal *detection* logic.
|
||||
*
|
||||
* It seems that sometimes we get this from
|
||||
* asterisk in wrong state (e.g: while ringing).
|
||||
* In these cases, silently ignore it.
|
||||
*/
|
||||
if (priv->lasttxhook[pos] == FXS_LINE_RING || priv->lasttxhook[pos] == FXS_LINE_OPEN) {
|
||||
LINE_ERR(xpd, pos, "DAHDI_SETPOLARITY: %s Cannot change when lasttxhook=0x%X\n",
|
||||
(val)?"ON":"OFF", priv->lasttxhook[pos]);
|
||||
LINE_DBG(SIGNAL, xpd, pos,
|
||||
"DAHDI_SETPOLARITY: %s Cannot change when lasttxhook=0x%X\n",
|
||||
(val)?"ON":"OFF", priv->lasttxhook[pos]);
|
||||
return -EINVAL;
|
||||
}
|
||||
LINE_DBG(SIGNAL, xpd, pos, "DAHDI_SETPOLARITY: %s\n", (val)?"ON":"OFF");
|
||||
@@ -1045,7 +1068,8 @@ static void handle_linefeed(xpd_t *xpd)
|
||||
priv = xpd->priv;
|
||||
BUG_ON(!priv);
|
||||
for_each_line(xpd, i) {
|
||||
if (priv->lasttxhook[i] == FXS_LINE_RING) {
|
||||
if (priv->lasttxhook[i] == FXS_LINE_RING &&
|
||||
!IS_SET(priv->neon_blinking, i)) {
|
||||
/* RINGing, prepare for OHT */
|
||||
priv->ohttimer[i] = OHT_TIMER;
|
||||
priv->idletxhookstate[i] = FXS_LINE_POL_OHTRANS;
|
||||
@@ -1499,11 +1523,13 @@ static int proc_fxs_info_read(char *page, char **start, off_t off, int count, in
|
||||
spin_lock_irqsave(&xpd->lock, flags);
|
||||
priv = xpd->priv;
|
||||
BUG_ON(!priv);
|
||||
len += sprintf(page + len, "%-8s %-10s %-10s %-10s\n",
|
||||
len += sprintf(page + len, "%-8s %-10s %-10s %-10s %-10s %-10s\n",
|
||||
"Channel",
|
||||
"idletxhookstate",
|
||||
"lasttxhook",
|
||||
"ohttimer"
|
||||
"ohttimer",
|
||||
"neon_blinking",
|
||||
"search_fsk_pattern"
|
||||
);
|
||||
for_each_line(xpd, i) {
|
||||
char pref;
|
||||
@@ -1514,12 +1540,14 @@ static int proc_fxs_info_read(char *page, char **start, off_t off, int count, in
|
||||
pref = 'I';
|
||||
else
|
||||
pref = ' ';
|
||||
len += sprintf(page + len, "%c%7d %10d %10d %10d\n",
|
||||
len += sprintf(page + len, "%c%7d %10d %10d %10d %10d %10d\n",
|
||||
pref,
|
||||
i,
|
||||
priv->idletxhookstate[i],
|
||||
priv->lasttxhook[i],
|
||||
priv->ohttimer[i]
|
||||
priv->ohttimer[i],
|
||||
IS_SET(priv->neon_blinking, i),
|
||||
IS_SET(priv->search_fsk_pattern, i)
|
||||
);
|
||||
}
|
||||
len += sprintf(page + len, "\n");
|
||||
|
||||
@@ -40,6 +40,36 @@ extern int debug;
|
||||
|
||||
/*---------------- GLOBAL PROC handling -----------------------------------*/
|
||||
|
||||
static int send_magic_request(xbus_t *xbus,
|
||||
unsigned unit, xportno_t portno, bool eoftx)
|
||||
{
|
||||
xframe_t *xframe;
|
||||
xpacket_t *pack;
|
||||
reg_cmd_t *reg_cmd;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Zero length multibyte is legal and has special meaning for the
|
||||
* firmware:
|
||||
* eoftx==1: Start sending us D-channel packets.
|
||||
* eoftx==0: Stop sending us D-channel packets.
|
||||
*/
|
||||
XFRAME_NEW_CMD(xframe, pack, xbus, GLOBAL, REGISTER_REQUEST, unit);
|
||||
reg_cmd = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REQUEST, reg_cmd);
|
||||
reg_cmd->bytes = 0;
|
||||
reg_cmd->is_multibyte = 1;
|
||||
reg_cmd->portnum = portno;
|
||||
reg_cmd->eoframe = eoftx;
|
||||
PORT_DBG(REGS, xbus, unit, portno, "Magic Packet (eoftx=%d)\n", eoftx);
|
||||
if (debug & DBG_REGS)
|
||||
dump_xframe(__func__, xbus, xframe, debug);
|
||||
ret = send_cmd_frame(xbus, xframe);
|
||||
if (ret < 0)
|
||||
PORT_ERR(xbus, unit, portno,
|
||||
"%s: failed sending xframe\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int parse_hexbyte(const char *buf)
|
||||
{
|
||||
char *endp;
|
||||
@@ -155,8 +185,8 @@ static int execute_chip_command(xpd_t *xpd, const int argc, char *argv[])
|
||||
addr_mode, argc - argno);
|
||||
goto out;
|
||||
}
|
||||
ret = send_multibyte_request(xpd->xbus, xpd->addr.unit, portno,
|
||||
addr_mode == 'm', NULL, 0);
|
||||
ret = send_magic_request(xpd->xbus, xpd->addr.unit, portno,
|
||||
addr_mode == 'm');
|
||||
goto out;
|
||||
}
|
||||
/* Normal (non-Magic) register commands */
|
||||
@@ -370,44 +400,6 @@ int xpp_register_request(xbus_t *xbus, xpd_t *xpd, xportno_t portno,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int send_multibyte_request(xbus_t *xbus,
|
||||
unsigned unit, xportno_t portno,
|
||||
bool eoftx, byte *buf, unsigned len)
|
||||
{
|
||||
xframe_t *xframe;
|
||||
xpacket_t *pack;
|
||||
reg_cmd_t *reg_cmd;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Zero length multibyte is legal and has special meaning for the
|
||||
* firmware:
|
||||
* eoftx==1: Start sending us D-channel packets.
|
||||
* eoftx==0: Stop sending us D-channel packets.
|
||||
*/
|
||||
if(len > MULTIBYTE_MAX_LEN) {
|
||||
PORT_ERR(xbus, unit, portno, "%s: len=%d is too long. dropping.\n", __FUNCTION__, len);
|
||||
return -EINVAL;
|
||||
}
|
||||
XFRAME_NEW_CMD(xframe, pack, xbus, GLOBAL, REGISTER_REQUEST, unit);
|
||||
reg_cmd = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REQUEST, reg_cmd);
|
||||
reg_cmd->bytes = len;
|
||||
reg_cmd->is_multibyte = 1;
|
||||
reg_cmd->portnum = portno;
|
||||
reg_cmd->eoframe = eoftx;
|
||||
if(len > 0) {
|
||||
memcpy(REG_XDATA(reg_cmd), (byte *)buf, len);
|
||||
} else {
|
||||
PORT_DBG(REGS, xbus, unit, portno, "Magic Packet (eoftx=%d)\n", eoftx);
|
||||
}
|
||||
if(debug & DBG_REGS)
|
||||
dump_xframe(__FUNCTION__, xbus, xframe, debug);
|
||||
ret = send_cmd_frame(xbus, xframe);
|
||||
if(ret < 0)
|
||||
PORT_ERR(xbus, unit, portno, "%s: failed sending xframe\n", __FUNCTION__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* The XPD parameter is totaly ignored by the driver and firmware as well.
|
||||
*/
|
||||
@@ -752,4 +744,3 @@ err:
|
||||
EXPORT_SYMBOL(sync_mode_name);
|
||||
EXPORT_SYMBOL(run_initialize_registers);
|
||||
EXPORT_SYMBOL(xpp_register_request);
|
||||
EXPORT_SYMBOL(send_multibyte_request);
|
||||
|
||||
@@ -1034,6 +1034,17 @@ static int pri_lineconfig(xpd_t *xpd, int lineconfig)
|
||||
}
|
||||
#endif
|
||||
if(force_cas) {
|
||||
if(priv->pri_protocol == PRI_PROTO_E1) {
|
||||
int rs1 = 0x0B;
|
||||
|
||||
/*
|
||||
* Set correct X1-X3 bits in the E1 CAS MFAS
|
||||
* They are unused in E1 and should be 1
|
||||
*/
|
||||
XPD_DBG(GENERAL, xpd, "%s: rs1(0x%02X) = 0x%02X\n",
|
||||
__FUNCTION__, REG_RS1_E, rs1);
|
||||
write_subunit(xpd, REG_RS1_E, rs1);
|
||||
}
|
||||
xsp |= REG_XSP_E_CASEN; /* Same as REG_FMR5_T_EIBR for T1 */
|
||||
}
|
||||
XPD_DBG(GENERAL, xpd, "%s: xsp(0x%02X) = 0x%02X\n", __FUNCTION__, REG_XSP_E, xsp);
|
||||
@@ -1467,14 +1478,17 @@ static int PRI_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd, unsigned long a
|
||||
return -ENODEV;
|
||||
chan = XPD_CHAN(xpd, pos);
|
||||
switch (cmd) {
|
||||
/*
|
||||
* Asterisk may send FXS type ioctl()'s to us:
|
||||
* - Some are sent to everybody (DAHDI_TONEDETECT)
|
||||
* - Some are sent because we may be in CAS mode
|
||||
* (FXS signalling)
|
||||
* Ignore them.
|
||||
*/
|
||||
case DAHDI_TONEDETECT:
|
||||
/*
|
||||
* Asterisk call all span types with this (FXS specific)
|
||||
* call. Silently ignore it.
|
||||
*/
|
||||
LINE_DBG(SIGNAL, xpd, pos, "PRI: TONEDETECT (%s)\n",
|
||||
(chan->flags & DAHDI_FLAG_AUDIO) ?
|
||||
"AUDIO" : "SILENCE");
|
||||
"AUDIO" : "SILENCE");
|
||||
return -ENOTTY;
|
||||
case DAHDI_ONHOOKTRANSFER:
|
||||
LINE_DBG(SIGNAL, xpd, pos, "PRI: ONHOOKTRANSFER\n");
|
||||
@@ -1485,6 +1499,10 @@ static int PRI_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd, unsigned long a
|
||||
case DAHDI_VMWI_CONFIG:
|
||||
LINE_DBG(SIGNAL, xpd, pos, "PRI: VMWI_CONFIG\n");
|
||||
return -ENOTTY;
|
||||
case DAHDI_SETPOLARITY:
|
||||
LINE_DBG(SIGNAL, xpd, pos, "PRI: SETPOLARITY\n");
|
||||
return -ENOTTY;
|
||||
/* report on really bad ioctl()'s */
|
||||
default:
|
||||
report_bad_ioctl(THIS_MODULE->name, xpd, pos, cmd);
|
||||
return -ENOTTY;
|
||||
@@ -2243,7 +2261,43 @@ static DEVICE_ATTR_READER(pri_protocol_show, dev, buf)
|
||||
return len;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(pri_protocol, S_IRUGO, pri_protocol_show, NULL);
|
||||
static DEVICE_ATTR_WRITER(pri_protocol_store, dev, buf, count)
|
||||
{
|
||||
xpd_t *xpd;
|
||||
enum pri_protocol new_protocol = PRI_PROTO_0;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
BUG_ON(!dev);
|
||||
xpd = dev_to_xpd(dev);
|
||||
XPD_DBG(GENERAL, xpd, "%s\n", buf);
|
||||
if (!xpd)
|
||||
return -ENODEV;
|
||||
i = strcspn(buf, " \r\n");
|
||||
if (i != 2) {
|
||||
XPD_NOTICE(xpd,
|
||||
"Protocol name '%s' has %d characters (should be 2). Ignored.\n",
|
||||
buf, i);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (strnicmp(buf, "E1", 2) == 0)
|
||||
new_protocol = PRI_PROTO_E1;
|
||||
else if (strnicmp(buf, "T1", 2) == 0)
|
||||
new_protocol = PRI_PROTO_T1;
|
||||
else if (strnicmp(buf, "J1", 2) == 0)
|
||||
new_protocol = PRI_PROTO_J1;
|
||||
else {
|
||||
XPD_NOTICE(xpd,
|
||||
"Unknown PRI protocol '%s' (should be E1|T1|J1). Ignored.\n",
|
||||
buf);
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = set_pri_proto(xpd, new_protocol);
|
||||
return (ret < 0) ? ret : count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(pri_protocol, S_IRUGO | S_IWUSR, pri_protocol_show,
|
||||
pri_protocol_store);
|
||||
|
||||
static DEVICE_ATTR_READER(pri_localloop_show, dev, buf)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# $Id: PIC_TYPE_1.hex 9732 2011-08-24 19:13:55Z dima $
|
||||
# $Id: PIC_TYPE_1.hex 9841 2011-09-08 17:00:23Z dima $
|
||||
#
|
||||
:03000000A1EA4A28
|
||||
:03000100C41C41DB
|
||||
@@ -31,8 +31,8 @@
|
||||
:03001B00D00D0005
|
||||
:03001C00A17A17AF
|
||||
:03001D0080080058
|
||||
:03001E00C0710BA3
|
||||
:03001F0016603830
|
||||
:03001E00C0010B13
|
||||
:03001F0019A038ED
|
||||
:03002000743C0627
|
||||
:03002100A26D804D
|
||||
:03002200C01024E7
|
||||
@@ -42,451 +42,445 @@
|
||||
:03002600C03030B7
|
||||
:0300270018C901F4
|
||||
:030028006432043B
|
||||
:03002900A4C03040
|
||||
:03002900A4A03060
|
||||
:03002A0020C901E9
|
||||
:03002B007432022A
|
||||
:03002C00AFA03052
|
||||
:03002D0020990116
|
||||
:03002E00021C8031
|
||||
:03002F00C40FFFFC
|
||||
:03003000D8016490
|
||||
:03003100024C106E
|
||||
:03003200C00FFFFD
|
||||
:0300330002215057
|
||||
:03003400201D0884
|
||||
:030035000306B906
|
||||
:03003600901D100A
|
||||
:0300370020402244
|
||||
:03003800030201BF
|
||||
:03003900901030F4
|
||||
:03003A0020290179
|
||||
:03003B00030204B9
|
||||
:03003C00901030F1
|
||||
:03003D00C11901E5
|
||||
:03003E00190202A2
|
||||
:03003F00643030FA
|
||||
:03004000A45901BF
|
||||
:03004100C22800D2
|
||||
:030042001902148C
|
||||
:03004300743E7098
|
||||
:03004400A483088A
|
||||
:03004500209308FD
|
||||
:030046001253084A
|
||||
:03004700A4B30857
|
||||
:03004800209027DE
|
||||
:03004900FFF800BD
|
||||
:03004A00165C0041
|
||||
:03004B00AFA0392A
|
||||
:03004C00209038C9
|
||||
:03004D00145C0739
|
||||
:03004E00643D40CE
|
||||
:03004F00A8C03412
|
||||
:03005000209C08E9
|
||||
:0300510002103862
|
||||
:03005200C40219CC
|
||||
:03005300D80E07BD
|
||||
:0300540002402047
|
||||
:03005500C0036085
|
||||
:0300560002236022
|
||||
:0300570020136013
|
||||
:030058000303603F
|
||||
:03005900901C10E8
|
||||
:03005A002040380B
|
||||
:03005B0003021984
|
||||
:03005C00901E07EC
|
||||
:03005D002021203F
|
||||
:03005E00030C1080
|
||||
:03005F009011807D
|
||||
:03006000C11E704E
|
||||
:0300610019074339
|
||||
:03006200643A728B
|
||||
:03006300A68C0266
|
||||
:03006400C2218036
|
||||
:03006500190E076A
|
||||
:03006600743643AA
|
||||
:03006700A8CA75AF
|
||||
:03006800209C03D6
|
||||
:0300690002118001
|
||||
:03006A00C44E077A
|
||||
:03006B00D8064371
|
||||
:03006C00024A75D0
|
||||
:03006D00C00C04C0
|
||||
:03006E00022180EC
|
||||
:03006F00201E0749
|
||||
:0300700003064341
|
||||
:03007100901A756D
|
||||
:03007200204C011E
|
||||
:030073000300384F
|
||||
:03007400901A746B
|
||||
:03007500202C1824
|
||||
:030076000300384C
|
||||
:03007700901219CB
|
||||
:03007800210E0F47
|
||||
:03007900E0303D37
|
||||
:03007A00743C00D3
|
||||
:03007B00C040384A
|
||||
:03007C00190C025A
|
||||
:03007D007481800B
|
||||
:03007E00A8CE0702
|
||||
:03007F00C0474334
|
||||
:03008000FFFA85FF
|
||||
:03008100150C3F1C
|
||||
:03008200643031B6
|
||||
:03008300A87C1640
|
||||
:03008400209A922D
|
||||
:0300850013EC0376
|
||||
:03008600A8A180AE
|
||||
:03008700209E07B1
|
||||
:03008800FFF7433C
|
||||
:0300890017EA8EE5
|
||||
:03008A0021ECFF67
|
||||
:03008B00035031EE
|
||||
:03008C00C14C184C
|
||||
:03008D00D80A92FC
|
||||
:03008E00024C031E
|
||||
:03008F00C000317D
|
||||
:03009000022C122D
|
||||
:03009100201A92A0
|
||||
:0300920003003C2C
|
||||
:03009300901E0FAD
|
||||
:0300940020409D6C
|
||||
:030095000307035B
|
||||
:03009600901A9C21
|
||||
:03009700202C0F0B
|
||||
:03009800030FFF54
|
||||
:0300990090115C67
|
||||
:03009A0021011D24
|
||||
:03009B00E01A9DCB
|
||||
:03009C0002721CD1
|
||||
:03009D00C18030EF
|
||||
:03009E00D80E0F6A
|
||||
:03009F0002403CE0
|
||||
:0300A000C00C028F
|
||||
:0300A10002203901
|
||||
:0300A200201C001F
|
||||
:0300A3000300391E
|
||||
:0300A400901C802D
|
||||
:0300A500204024D4
|
||||
:0300A600030C0840
|
||||
:0300A700901104B1
|
||||
:0300A800202039DC
|
||||
:0300A900030C0045
|
||||
:0300AA009010397A
|
||||
:0300AB00210C0025
|
||||
:0300AC0003B02678
|
||||
:0300AD00C140252A
|
||||
:0300AE0002403ECF
|
||||
:0300AF00C0102B53
|
||||
:0300B000022C031C
|
||||
:0300B10020102CF0
|
||||
:0300B200030C40FC
|
||||
:0300B30090103971
|
||||
:0300B4002047D909
|
||||
:0300B500030AB487
|
||||
:0300B600901C009B
|
||||
:0300B700207208AC
|
||||
:0300B80003003012
|
||||
:0300B9009019019A
|
||||
:0300BA0021AC80F6
|
||||
:0300BB0014120814
|
||||
:0300BC0070703031
|
||||
:0300BD00AC09018A
|
||||
:0300BE00181C40CB
|
||||
:0300BF00AC303929
|
||||
:0300C00069BC0117
|
||||
:0300C100AFA037B6
|
||||
:0300C200F00C60DF
|
||||
:0300C3002282C8CE
|
||||
:0300C400643AC3D8
|
||||
:0300C500AFAC00DD
|
||||
:0300C6001BA03745
|
||||
:0300C700C106D996
|
||||
:0300C800FFFACC70
|
||||
:0300C90017B6F96E
|
||||
:0300CA0021ABCF98
|
||||
:0300CB00141AC73D
|
||||
:0300CC0064394252
|
||||
:0300CD00AD0C0275
|
||||
:0300CE00C10180ED
|
||||
:0300CF0013BE0756
|
||||
:0300D000C507431E
|
||||
:0300D100039AEDA2
|
||||
:0300D200799C0610
|
||||
:0300D300AD2195C7
|
||||
:0300D40020B7430F
|
||||
:0300D500D00AED61
|
||||
:0300D6000387D3CA
|
||||
:0300D700219AED7E
|
||||
:0300D800E07C06C3
|
||||
:0300D900348187E8
|
||||
:0300DA0034874325
|
||||
:0300DB00348ADE86
|
||||
:0300DC00348C035E
|
||||
:0300DD00030AEB28
|
||||
:0300DE00206C078C
|
||||
:0300DF00348187E2
|
||||
:0300E0003487431F
|
||||
:0300E100348AE47A
|
||||
:0300E200348C015A
|
||||
:0300E300D05AEB05
|
||||
:0300E400031C03F7
|
||||
:0300E500C00187D0
|
||||
:0300E600032743AA
|
||||
:0300E700033AEAEF
|
||||
:0300E800C70C0042
|
||||
:0300E900039AEB8C
|
||||
:0300EA00C5020745
|
||||
:0300EB0003902758
|
||||
:0300EC00C18AFACC
|
||||
:0300ED00030C06FB
|
||||
:0300EE00C00195B9
|
||||
:0300EF00031643B2
|
||||
:0300F00021BAFA38
|
||||
:0300F100032C01DC
|
||||
:0300F200C001C783
|
||||
:0300F30003309C3B
|
||||
:0300F400C7070338
|
||||
:0300F500039AFA71
|
||||
:0300F600C50CFF37
|
||||
:0300F70003902251
|
||||
:0300F800C400271A
|
||||
:0300F900039B6204
|
||||
:0300FA00369C0031
|
||||
:0300FB00C016F339
|
||||
:0300FC001E6CFF78
|
||||
:0300FD0021C021FE
|
||||
:0300FE00086C018A
|
||||
:0300FF0074302436
|
||||
:03010000A1E90A68
|
||||
:030101000266B3E0
|
||||
:03010200C02B8986
|
||||
:03010300FFFC01FD
|
||||
:0301040016B02F03
|
||||
:03010500C0221500
|
||||
:0301060023E6D31A
|
||||
:03010700743D80C4
|
||||
:0301080012B0240E
|
||||
:0301090020B2170A
|
||||
:03010A000380224D
|
||||
:03010B00C44C06DB
|
||||
:03010C00039195C7
|
||||
:03010D00C40743E1
|
||||
:03010E00039B51FF
|
||||
:03010F00C006D354
|
||||
:03011000023B515E
|
||||
:03011100ABECE074
|
||||
:03011200B12157C1
|
||||
:03011300000643A0
|
||||
:03011400000B518C
|
||||
:03011500000C00DB
|
||||
:030116000007B728
|
||||
:03011700000C05D4
|
||||
:030118000007D706
|
||||
:03011900000C10C7
|
||||
:03011A000007F7E4
|
||||
:03011B00000C02D3
|
||||
:03011C00000027B9
|
||||
:03011D00000C10C3
|
||||
:03011E00000D02CF
|
||||
:03011F00000FFFCF
|
||||
:0301200000014299
|
||||
:030121000006973E
|
||||
:03012200000D02CB
|
||||
:030123000006379C
|
||||
:03012400000D10BB
|
||||
:03012500000022B5
|
||||
:03012600000C804A
|
||||
:03012700000124B0
|
||||
:03012800000C02C6
|
||||
:0301290000018052
|
||||
:03012A00000E07BD
|
||||
:03012B0000074387
|
||||
:03012C00000B3F86
|
||||
:03012D00000C05BE
|
||||
:03012E0000014786
|
||||
:03012F0000064384
|
||||
:03013000000B3F82
|
||||
:03013100000C01BE
|
||||
:0301320000018148
|
||||
:030133000007437F
|
||||
:03013400000B3885
|
||||
:03013500000C10AB
|
||||
:03013600000021A5
|
||||
:03013700000B3F7B
|
||||
:03013800000C10A8
|
||||
:0301390000018141
|
||||
:03013A0000074378
|
||||
:03013B00000B3F77
|
||||
:03013C00000C2094
|
||||
:03013D000000219E
|
||||
:03013E00000B3F74
|
||||
:03013F00000201BA
|
||||
:03002C00AE803073
|
||||
:03002D00C4090102
|
||||
:03002E00D80C806B
|
||||
:03002F00024FFF7E
|
||||
:03003000C00164A8
|
||||
:03003100022C108E
|
||||
:03003200209FFF0D
|
||||
:0300330003015076
|
||||
:03003400901D0814
|
||||
:030035002046B9A9
|
||||
:03003600030D10A7
|
||||
:0300370090102204
|
||||
:0300380020220182
|
||||
:0300390003003091
|
||||
:03003A0090190119
|
||||
:03003B00C11204EB
|
||||
:03003C0019003078
|
||||
:03003D0064390122
|
||||
:03003E00A43202E7
|
||||
:03003F00C22030AC
|
||||
:030040001909019A
|
||||
:0300410074380010
|
||||
:03004200A46214A1
|
||||
:03004300209E708C
|
||||
:030044001253084C
|
||||
:03004500A4930879
|
||||
:03004600209308FC
|
||||
:03004700FFF308BC
|
||||
:0300480016502728
|
||||
:03004900AE88007E
|
||||
:03004A00209C00F7
|
||||
:03004B0014503915
|
||||
:03004C00643038E5
|
||||
:03004D00A8603F69
|
||||
:03004E00C40C07D8
|
||||
:03004F00D80D4089
|
||||
:0300500002403437
|
||||
:03005100C00C08D8
|
||||
:0300520002203851
|
||||
:03005300209219DF
|
||||
:03005400030E0791
|
||||
:03005500901020E8
|
||||
:03005600204360E4
|
||||
:0300570003036040
|
||||
:03005800901360A2
|
||||
:0300590020236001
|
||||
:03005A00030C1084
|
||||
:03005B00901038CA
|
||||
:03005C00C11219B5
|
||||
:03005D00190E0772
|
||||
:03005E00643120EA
|
||||
:03005F00A64C109C
|
||||
:03006000C221803A
|
||||
:03006100190E7005
|
||||
:03006200743743AD
|
||||
:03006300A86A7315
|
||||
:03006400C44C0287
|
||||
:03006500D801803F
|
||||
:03006600024E0740
|
||||
:03006700C006438D
|
||||
:03006800022A76F3
|
||||
:03006900209C03D5
|
||||
:03006A000301800F
|
||||
:03006B00901E07DD
|
||||
:03006C00204643E8
|
||||
:03006D00030A760D
|
||||
:03006E00901C04DF
|
||||
:03006F00202180CD
|
||||
:03007000030E0775
|
||||
:03007100901643A3
|
||||
:03007200210A76EA
|
||||
:03007300E03C016D
|
||||
:03007400743038AD
|
||||
:03007500C04A7509
|
||||
:03007600190C184A
|
||||
:030077007480385A
|
||||
:03007800A8621962
|
||||
:03007900C04E0F67
|
||||
:03007A00FFF03D57
|
||||
:03007B00150C0061
|
||||
:03007C00643038B5
|
||||
:03007D00A81C02BA
|
||||
:03007E002091804E
|
||||
:03007F0013EE0776
|
||||
:03008000A847434B
|
||||
:03008100209A863C
|
||||
:03008200FFFC3F41
|
||||
:0300830017E03152
|
||||
:0300840021EC1656
|
||||
:03008500035A9388
|
||||
:03008600C14C0367
|
||||
:03008700D801801D
|
||||
:03008800024E071E
|
||||
:03008900C007436A
|
||||
:03008A00022A8FB8
|
||||
:03008B00209CFFB7
|
||||
:03008C000300313D
|
||||
:03008D00901C18AC
|
||||
:03008E00204A9372
|
||||
:03008F00030C035C
|
||||
:030090009010319C
|
||||
:03009100202C120E
|
||||
:03009200030A93CB
|
||||
:0300930090103C8E
|
||||
:03009400210E0F2B
|
||||
:0300950002709D59
|
||||
:03009600C147035C
|
||||
:03009700024A9D7D
|
||||
:03009800209C0F9A
|
||||
:03009900030FFF53
|
||||
:03009A0090115C66
|
||||
:03009B0020411DE4
|
||||
:03009C00030A9EB6
|
||||
:03009D0090121CA2
|
||||
:03009E002070309F
|
||||
:03009F00030E0F3E
|
||||
:0300A00090103C81
|
||||
:0300A100C18C020D
|
||||
:0300A200D800394A
|
||||
:0300A300024C000C
|
||||
:0300A400C0003960
|
||||
:0300A500022C80AA
|
||||
:0300A60020902483
|
||||
:0300A700030C083F
|
||||
:0300A800901104B0
|
||||
:0300A900204039BB
|
||||
:0300AA00030C0044
|
||||
:0300AB0090103979
|
||||
:0300AC00202C0005
|
||||
:0300AD0003003A13
|
||||
:0300AE009010258A
|
||||
:0300AF0021003EEF
|
||||
:0300B00003B02B6F
|
||||
:0300B100707C035D
|
||||
:0300B200AB602C14
|
||||
:0300B300209C404E
|
||||
:0300B40013F0390D
|
||||
:0300B500ABE7D9DD
|
||||
:0300B600209AB5D8
|
||||
:0300B70015FC0035
|
||||
:0300B800643208A7
|
||||
:0300B900AE8030E6
|
||||
:0300BA0069B90120
|
||||
:0300BB00AE8C8088
|
||||
:0300BC0020920887
|
||||
:0300BD001BF03005
|
||||
:0300BE00C5090170
|
||||
:0300BF00039C405F
|
||||
:0300C000799039FB
|
||||
:0300C100AC06D9B1
|
||||
:0300C20020BAC69B
|
||||
:0300C300D006F96B
|
||||
:0300C400038BC9E2
|
||||
:0300C500219AC1BC
|
||||
:0300C600E079429C
|
||||
:0300C700348C0274
|
||||
:0300C80034818000
|
||||
:0300C900348E076B
|
||||
:0300CA0034874335
|
||||
:0300CB00030AE73E
|
||||
:0300CC0021AC065E
|
||||
:0300CD00348195E6
|
||||
:0300CE0034874331
|
||||
:0300CF00348AE789
|
||||
:0300D0003487D39F
|
||||
:0300D100D05AE71B
|
||||
:0300D200031C0606
|
||||
:0300D300C00187E2
|
||||
:0300D400032743BC
|
||||
:0300D500033AD813
|
||||
:0300D600C70C0351
|
||||
:0300D700039AE5A4
|
||||
:0300D800C50C074D
|
||||
:0300D90003918709
|
||||
:0300DA00C1874398
|
||||
:0300DB00030ADE37
|
||||
:0300DC00C00C0154
|
||||
:0300DD00031AE51E
|
||||
:0300DE0021BC033F
|
||||
:0300DF0003218773
|
||||
:0300E000C0074313
|
||||
:0300E100033AE4FB
|
||||
:0300E200C70C0048
|
||||
:0300E300039AE598
|
||||
:0300E400C502074B
|
||||
:0300E5000390275E
|
||||
:0300E600C40AF455
|
||||
:0300E700039C0671
|
||||
:0300E800369195B9
|
||||
:0300E900C01643FB
|
||||
:0300EA001FAAF456
|
||||
:0300EB0021CC0124
|
||||
:0300EC0009A1C7A0
|
||||
:0300ED0074309CD0
|
||||
:0300EE00A1E70384
|
||||
:0300EF0003AAF46D
|
||||
:0300F000C02CFF22
|
||||
:0300F100FFF022FB
|
||||
:0300F20016B0271E
|
||||
:0300F300C02B5CC3
|
||||
:0300F40023EC00FA
|
||||
:0300F5007436F36B
|
||||
:0300F60012BCFF3A
|
||||
:0300F70020B02115
|
||||
:0300F800038C0175
|
||||
:0300F900C44024DC
|
||||
:0300FA0003990A5D
|
||||
:0300FB00C406B385
|
||||
:0300FC00039B83E0
|
||||
:0300FD00C00C0133
|
||||
:0300FE0002302F9E
|
||||
:0300FF00ABF2154C
|
||||
:03010000B006D373
|
||||
:03010100000D806E
|
||||
:03010200000024D6
|
||||
:03010300000217E0
|
||||
:03010400000022D6
|
||||
:03010500000C06E5
|
||||
:0301060000019560
|
||||
:03010700000743AB
|
||||
:03010800000B4B9E
|
||||
:030109000006D31A
|
||||
:03010A00000B4B9C
|
||||
:03010B00000CE005
|
||||
:03010C0000015798
|
||||
:03010D00000643A6
|
||||
:03010E00000B4B98
|
||||
:03010F00000C00E1
|
||||
:030110000007B72E
|
||||
:03011100000C05DA
|
||||
:030112000007D70C
|
||||
:03011300000C10CD
|
||||
:030114000007F7EA
|
||||
:03011500000C02D9
|
||||
:03011600000027BF
|
||||
:03011700000C10C9
|
||||
:03011800000D02D5
|
||||
:03011900000FFFD5
|
||||
:03011A000001429F
|
||||
:03011B0000069744
|
||||
:03011C00000D02D1
|
||||
:03011D00000637A2
|
||||
:03011E00000D10C1
|
||||
:03011F00000022BB
|
||||
:03012000000C8050
|
||||
:03012100000124B6
|
||||
:03012200000C02CC
|
||||
:0301230000018058
|
||||
:03012400000E07C3
|
||||
:030125000007438D
|
||||
:03012600000B3992
|
||||
:03012700000C05C4
|
||||
:030128000001478C
|
||||
:030129000006438A
|
||||
:03012A00000B398E
|
||||
:03012B00000C01C4
|
||||
:03012C000001814E
|
||||
:03012D0000074385
|
||||
:03012E00000B3291
|
||||
:03012F00000C10B1
|
||||
:03013000000021AB
|
||||
:03013100000B3987
|
||||
:03013200000C10AE
|
||||
:0301330000018147
|
||||
:030134000007437E
|
||||
:03013500000B3983
|
||||
:03013600000C209A
|
||||
:03013700000021A4
|
||||
:03013800000B3980
|
||||
:03013900000201C0
|
||||
:03013A0000003092
|
||||
:03013B00000901B7
|
||||
:03013C00000204BA
|
||||
:03013D000000308F
|
||||
:03013E00000901B4
|
||||
:03013F00000202B9
|
||||
:030140000000308C
|
||||
:03014100000901B1
|
||||
:03014200000204B4
|
||||
:0301430000003089
|
||||
:03014400000901AE
|
||||
:03014500000202B3
|
||||
:0301460000003086
|
||||
:03014700000901AB
|
||||
:03014800000C8028
|
||||
:03014900000FFFA5
|
||||
:03014A000001644D
|
||||
:03014B00000207A8
|
||||
:03014C000001624D
|
||||
:03014D00000FFFA1
|
||||
:03014E000001505D
|
||||
:03014F00000D0898
|
||||
:0301500000012289
|
||||
:03015100000201A8
|
||||
:03014200000C802E
|
||||
:03014300000FFFAB
|
||||
:0301440000016453
|
||||
:03014500000207AE
|
||||
:0301460000016253
|
||||
:03014700000FFFA7
|
||||
:0301480000015063
|
||||
:03014900000D089E
|
||||
:03014A000001228F
|
||||
:03014B00000201AE
|
||||
:03014C0000003080
|
||||
:03014D00000901A5
|
||||
:03014E00000204A8
|
||||
:03014F000000307D
|
||||
:03015000000901A2
|
||||
:03015100000202A7
|
||||
:030152000000307A
|
||||
:030153000009019F
|
||||
:03015400000204A2
|
||||
:0301550000003077
|
||||
:030156000009019C
|
||||
:03015700000202A1
|
||||
:0301580000003074
|
||||
:0301590000090199
|
||||
:03015A00000C0096
|
||||
:03015B0000002F72
|
||||
:03015C000007D3C6
|
||||
:03015D00000B8410
|
||||
:03015E000002108C
|
||||
:03015F000000227B
|
||||
:0301600000020E8C
|
||||
:0301610000002774
|
||||
:03016200000C503E
|
||||
:0301630000003960
|
||||
:03016400000799F8
|
||||
:03016500000B6428
|
||||
:0301660000021282
|
||||
:0301670000003065
|
||||
:030168000002147E
|
||||
:0301690000003162
|
||||
:03016A000002137D
|
||||
:03016B000006B3D8
|
||||
:03016C00000D1073
|
||||
:03016D000000325D
|
||||
:03016E00000C0082
|
||||
:03016F000000335A
|
||||
:03017000000C7010
|
||||
:0301710000003952
|
||||
:03017200000C502E
|
||||
:0301730000003950
|
||||
:0301740000021571
|
||||
:0301750000003057
|
||||
:030176000002166E
|
||||
:0301770000003154
|
||||
:0301780000020280
|
||||
:0301790000003251
|
||||
:03017A00000C0076
|
||||
:03017B000006B3C8
|
||||
:03017C0000020777
|
||||
:03017D000000334C
|
||||
:03017E00000C7002
|
||||
:03015400000C009C
|
||||
:0301550000002F78
|
||||
:030156000007D3CC
|
||||
:03015700000B7E1C
|
||||
:0301580000021092
|
||||
:0301590000002281
|
||||
:03015A0000020E92
|
||||
:03015B000000277A
|
||||
:03015C00000C5044
|
||||
:03015D0000003966
|
||||
:03015E00000799FE
|
||||
:03015F00000B5E34
|
||||
:0301600000021288
|
||||
:030161000000306B
|
||||
:0301620000021484
|
||||
:0301630000003168
|
||||
:0301640000021383
|
||||
:030165000006B3DE
|
||||
:03016600000D1079
|
||||
:0301670000003263
|
||||
:03016800000C0088
|
||||
:0301690000003360
|
||||
:03016A00000C7016
|
||||
:03016B0000003958
|
||||
:03016C00000C5034
|
||||
:03016D0000003956
|
||||
:03016E0000021577
|
||||
:03016F000000305D
|
||||
:0301700000021674
|
||||
:030171000000315A
|
||||
:0301720000020286
|
||||
:0301730000003257
|
||||
:03017400000C007C
|
||||
:030175000006B3CE
|
||||
:030176000002077D
|
||||
:0301770000003352
|
||||
:03017800000C7008
|
||||
:030179000000394A
|
||||
:03017A00000C5026
|
||||
:03017B0000003948
|
||||
:03017C00000C4034
|
||||
:03017D0000003946
|
||||
:03017E00000C0072
|
||||
:03017F0000003944
|
||||
:03018000000C5020
|
||||
:0301810000003942
|
||||
:03018200000C402E
|
||||
:0301830000003940
|
||||
:03018400000C006C
|
||||
:030185000000393E
|
||||
:03018600000C006A
|
||||
:03018000000C0070
|
||||
:03018100000C006F
|
||||
:03018200000ABFB1
|
||||
:03018300000C026B
|
||||
:0301840000002F49
|
||||
:03018500000C0A61
|
||||
:0301860000002A4C
|
||||
:03018700000C0069
|
||||
:03018800000ABEAC
|
||||
:03018900000C0265
|
||||
:03018A0000002F43
|
||||
:03018B00000C0A5B
|
||||
:03018C0000002A46
|
||||
:03018D00000C0063
|
||||
:03018E000000244A
|
||||
:03018F000007D393
|
||||
:03019000000BACB5
|
||||
:0301910000020168
|
||||
:0301880000002450
|
||||
:030189000007D399
|
||||
:03018A00000BA6C1
|
||||
:03018B000002016E
|
||||
:03018C0000003040
|
||||
:03018D0000090165
|
||||
:03018E0000021557
|
||||
:03018F000000303D
|
||||
:0301900000090162
|
||||
:0301910000021653
|
||||
:030192000000303A
|
||||
:030193000009015F
|
||||
:0301940000021551
|
||||
:0301950000003037
|
||||
:030196000009015C
|
||||
:030197000002164D
|
||||
:03019400000C1F3D
|
||||
:03019500000D80DA
|
||||
:0301960000002244
|
||||
:0301970000020162
|
||||
:0301980000003034
|
||||
:0301990000090159
|
||||
:03019A00000C1F37
|
||||
:03019B00000D80D4
|
||||
:03019C000000223E
|
||||
:03019D000002015C
|
||||
:03019A000002025E
|
||||
:03019B0000003031
|
||||
:03019C0000090156
|
||||
:03019D0000020459
|
||||
:03019E000000302E
|
||||
:03019F0000090153
|
||||
:0301A00000020258
|
||||
:0301A1000000302B
|
||||
:0301A20000090150
|
||||
:0301A30000020453
|
||||
:0301A40000003028
|
||||
:0301A5000009014D
|
||||
:0301A6000002EA6A
|
||||
:0301A7000007103E
|
||||
:0301A800000BAA9F
|
||||
:0301A900000B9DAB
|
||||
:0301AA000007D378
|
||||
:0301AB00000BCA7C
|
||||
:0301AC00000C1D27
|
||||
:0301AD000006D376
|
||||
:0301AE00000D80C1
|
||||
:0301AF000000222B
|
||||
:0301B00000020149
|
||||
:0301A0000002EA70
|
||||
:0301A10000071044
|
||||
:0301A200000BA4AB
|
||||
:0301A300000B97B7
|
||||
:0301A4000007D37E
|
||||
:0301A500000BC488
|
||||
:0301A600000C1D2D
|
||||
:0301A7000006D37C
|
||||
:0301A800000D80C7
|
||||
:0301A90000002231
|
||||
:0301AA000002014F
|
||||
:0301AB0000003021
|
||||
:0301AC0000090146
|
||||
:0301AD000002024B
|
||||
:0301AE000000301E
|
||||
:0301AF0000090143
|
||||
:0301B00000021832
|
||||
:0301B1000000301B
|
||||
:0301B20000090140
|
||||
:0301B30000020245
|
||||
:0301B40000003018
|
||||
:0301B5000009013D
|
||||
:0301B6000002182C
|
||||
:0301B70000003015
|
||||
:0301B8000009013A
|
||||
:0301B90000021031
|
||||
:0301BA0000002E14
|
||||
:0301BB00000C1C19
|
||||
:0301BC000006D367
|
||||
:0301BD00000D80B2
|
||||
:0301BE000000221C
|
||||
:0301BF000002013A
|
||||
:0301B30000021037
|
||||
:0301B40000002E1A
|
||||
:0301B500000C1C1F
|
||||
:0301B6000006D36D
|
||||
:0301B700000D80B8
|
||||
:0301B80000002222
|
||||
:0301B90000020140
|
||||
:0301BA0000003012
|
||||
:0301BB0000090137
|
||||
:0301BC000002023C
|
||||
:0301BD000000300F
|
||||
:0301BE0000090134
|
||||
:0301BF0000021724
|
||||
:0301C0000000300C
|
||||
:0301C10000090131
|
||||
:0301C20000020236
|
||||
:0301C30000003009
|
||||
:0301C4000009012E
|
||||
:0301C5000002171E
|
||||
:0301C60000003006
|
||||
:0301C7000009012B
|
||||
:0301C8000007D35A
|
||||
:0301C900000B9197
|
||||
:0301CA00000C0026
|
||||
:0301CB0000002F02
|
||||
:0301CC000007D356
|
||||
:0301CD00000B84A0
|
||||
:0301CE00000B5EC5
|
||||
:0301CF00000C071A
|
||||
:0301D00000002FFD
|
||||
:0301D100000C041B
|
||||
:0301D20000002109
|
||||
:0301D300000C001D
|
||||
:0301D40000091E01
|
||||
:0301C2000007D360
|
||||
:0301C300000B8BA3
|
||||
:0301C400000C002C
|
||||
:0301C50000002F08
|
||||
:0301C6000007D35C
|
||||
:0301C700000B7EAC
|
||||
:0301C800000B58D1
|
||||
:0301C900000C0720
|
||||
:0301CA0000002F03
|
||||
:0301CB00000C0421
|
||||
:0301CC000000210F
|
||||
:0301CD00000C0023
|
||||
:0301CE0000091E07
|
||||
:0301CF00000C1011
|
||||
:0301D0000000210B
|
||||
:0301D100000C0817
|
||||
:0301D20000091E03
|
||||
:0301D300000C40DD
|
||||
:0301D40000002107
|
||||
:0301D500000C100B
|
||||
:0301D60000002105
|
||||
:0301D700000C0811
|
||||
:0301D80000091EFD
|
||||
:0301D900000C40D7
|
||||
:0301DA0000002101
|
||||
:0301DB00000C1005
|
||||
:0301DC0000091EF9
|
||||
:0301DD00000C0013
|
||||
:0301DE00000026F8
|
||||
:0301DF00000C0110
|
||||
:0301E000000029F3
|
||||
:0301E100000C000F
|
||||
:0301E20000002FEB
|
||||
:0301E300000C20ED
|
||||
:0301E400000023F5
|
||||
:0301E500000A000D
|
||||
:0301E600000ABE4E
|
||||
:0301E700000BE723
|
||||
:0301D60000091EFF
|
||||
:0301D700000C0019
|
||||
:0301D80000003AEA
|
||||
:0301D900000C0116
|
||||
:0301DA00000029F9
|
||||
:0301DB00000C0015
|
||||
:0301DC0000002FF1
|
||||
:0301DD00000C20F3
|
||||
:0301DE00000023FB
|
||||
:0301DF00000A0013
|
||||
:0301E000000ABF53
|
||||
:0301E100000BE12F
|
||||
:00000001FF
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -58,9 +58,11 @@ static int proc_xbus_command_write(struct file *file, const char __user *buffer,
|
||||
|
||||
/* Command line parameters */
|
||||
extern int debug;
|
||||
static DEF_PARM(uint, command_queue_length, 1000, 0444, "Maximal command queue length");
|
||||
static DEF_PARM(uint, command_queue_length, 1500, 0444, "Maximal command queue length");
|
||||
static DEF_PARM(uint, poll_timeout, 1000, 0644, "Timeout (in jiffies) waiting for units to reply");
|
||||
static DEF_PARM_BOOL(rx_tasklet, 0, 0644, "Use receive tasklets");
|
||||
static DEF_PARM_BOOL(dahdi_autoreg, 0, 0644,
|
||||
"Register devices automatically (1) or not (0)");
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
static int xbus_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data);
|
||||
@@ -870,12 +872,22 @@ err:
|
||||
goto out;
|
||||
}
|
||||
|
||||
static int xbus_register_dahdi_device(xbus_t *xbus)
|
||||
int xbus_is_registered(xbus_t *xbus)
|
||||
{
|
||||
return xbus->ddev && xbus->ddev->dev.parent;
|
||||
}
|
||||
|
||||
int xbus_register_dahdi_device(xbus_t *xbus)
|
||||
{
|
||||
int i;
|
||||
int offset = 0;
|
||||
|
||||
XBUS_DBG(DEVICES, xbus, "Entering %s\n", __func__);
|
||||
if (xbus_is_registered(xbus)) {
|
||||
XBUS_ERR(xbus, "Already registered to DAHDI\n");
|
||||
WARN_ON(1);
|
||||
return -EINVAL;
|
||||
}
|
||||
xbus->ddev = dahdi_create_device();
|
||||
/*
|
||||
* This actually describe the dahdi_spaninfo version 3
|
||||
@@ -929,7 +941,7 @@ static int xbus_register_dahdi_device(xbus_t *xbus)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void xbus_unregister_dahdi_device(xbus_t *xbus)
|
||||
void xbus_unregister_dahdi_device(xbus_t *xbus)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -1017,7 +1029,8 @@ void xbus_populate(void *data)
|
||||
*/
|
||||
xbus_request_sync(xbus, SYNC_MODE_PLL);
|
||||
elect_syncer("xbus_populate(end)"); /* FIXME: try to do it later */
|
||||
xbus_register_dahdi_device(xbus);
|
||||
if (dahdi_autoreg)
|
||||
xbus_register_dahdi_device(xbus);
|
||||
out:
|
||||
XBUS_DBG(DEVICES, xbus, "Leaving\n");
|
||||
wake_up_interruptible_all(&worker->wait_for_xpd_initialization);
|
||||
@@ -1400,7 +1413,6 @@ xbus_t *xbus_new(struct xbus_ops *ops, ushort max_send_size, struct device *tran
|
||||
xbus = xbus_alloc();
|
||||
if(!xbus) {
|
||||
ERR("%s: Failed allocating new xbus\n", __FUNCTION__);
|
||||
module_put(THIS_MODULE);
|
||||
return NULL;
|
||||
}
|
||||
snprintf(xbus->busname, XBUS_NAMELEN, "XBUS-%02d", xbus->num);
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include "xframe_queue.h"
|
||||
#include "xbus-pcm.h"
|
||||
|
||||
#define MAX_BUSES 32
|
||||
#define MAX_BUSES 128
|
||||
#define XFRAME_DATASIZE 512
|
||||
#define MAX_ENV_STR 40
|
||||
|
||||
@@ -343,6 +343,10 @@ int xpd_device_register(xbus_t *xbus, xpd_t *xpd);
|
||||
void xpd_device_unregister(xpd_t *xpd);
|
||||
int echocancel_xpd(xpd_t *xpd, int on);
|
||||
|
||||
int xbus_is_registered(xbus_t *xbus);
|
||||
int xbus_register_dahdi_device(xbus_t *xbus);
|
||||
void xbus_unregister_dahdi_device(xbus_t *xbus);
|
||||
|
||||
int xpp_driver_init(void);
|
||||
void xpp_driver_exit(void);
|
||||
int xbus_sysfs_transport_create(xbus_t *xbus);
|
||||
|
||||
@@ -613,6 +613,48 @@ static DEVICE_ATTR_READER(span_show, dev, buf)
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_READER(type_show, dev, buf)
|
||||
{
|
||||
xpd_t *xpd;
|
||||
@@ -695,7 +737,7 @@ static int xpd_match(struct device *dev, struct device_driver *driver)
|
||||
static struct device_attribute xpd_dev_attrs[] = {
|
||||
__ATTR(chipregs, S_IRUGO | S_IWUSR, chipregs_show, chipregs_store),
|
||||
__ATTR(blink, S_IRUGO | S_IWUSR, blink_show, blink_store),
|
||||
__ATTR_RO(span),
|
||||
__ATTR(span, S_IRUGO | S_IWUSR, span_show, span_store),
|
||||
__ATTR_RO(type),
|
||||
__ATTR_RO(offhook),
|
||||
__ATTR_RO(timing_priority),
|
||||
|
||||
@@ -1136,11 +1136,6 @@ static int __init xpp_dahdi_init(void)
|
||||
|
||||
INFO("revision %s MAX_XPDS=%d (%d*%d)\n", XPP_VERSION,
|
||||
MAX_XPDS, MAX_UNIT, MAX_SUBUNIT);
|
||||
#ifdef CONFIG_DAHDI_BRI_DCHANS
|
||||
INFO("FEATURE: with BRISTUFF support\n");
|
||||
#else
|
||||
INFO("FEATURE: without BRISTUFF support\n");
|
||||
#endif
|
||||
#ifdef CONFIG_PROC_FS
|
||||
xpp_proc_toplevel = proc_mkdir(PROC_DIR, NULL);
|
||||
if(!xpp_proc_toplevel) {
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#endif
|
||||
#include <linux/fs.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/ioctl.h>
|
||||
|
||||
#ifdef CONFIG_DAHDI_NET
|
||||
@@ -1567,6 +1568,7 @@ struct mutex {
|
||||
* be of the form DAHDI_DBG_*
|
||||
*/
|
||||
#define DAHDI_DBG_GENERAL BIT(0)
|
||||
#define DAHDI_DBG_ASSIGN BIT(1)
|
||||
#define DAHDI_DBG_DEVICES BIT(7) /* instantiation/destruction etc. */
|
||||
#define dahdi_dbg(bits, fmt, ...) \
|
||||
((void)((debug & (DAHDI_DBG_ ## bits)) && DAHDI_PRINTK(DEBUG, \
|
||||
@@ -1579,6 +1581,10 @@ struct mutex {
|
||||
((void)((debug & (DAHDI_DBG_ ## bits)) && \
|
||||
chan_printk(DEBUG, "-" #bits, chan, \
|
||||
"%s: " fmt, __func__, ## __VA_ARGS__)))
|
||||
#define dahdi_dev_dbg(bits, dev, fmt, ...) \
|
||||
((void)((debug & (DAHDI_DBG_ ## bits)) && \
|
||||
dev_printk(KERN_DEBUG, dev, \
|
||||
"DBG-%s(%s): " fmt, #bits, __func__, ## __VA_ARGS__)))
|
||||
#endif /* DAHDI_PRINK_MACROS_USE_debug */
|
||||
|
||||
#endif /* _DAHDI_KERNEL_H */
|
||||
|
||||
Reference in New Issue
Block a user