aboutsummaryrefslogtreecommitdiff
path: root/drivers/isdn/mISDN
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn/mISDN')
-rw-r--r--drivers/isdn/mISDN/Kconfig2
-rw-r--r--drivers/isdn/mISDN/core.c68
-rw-r--r--drivers/isdn/mISDN/dsp_core.c4
-rw-r--r--drivers/isdn/mISDN/dsp_pipeline.c2
-rw-r--r--drivers/isdn/mISDN/l1oip_core.c16
-rw-r--r--drivers/isdn/mISDN/socket.c20
-rw-r--r--drivers/isdn/mISDN/stack.c10
-rw-r--r--drivers/isdn/mISDN/timerdev.c76
8 files changed, 104 insertions, 94 deletions
diff --git a/drivers/isdn/mISDN/Kconfig b/drivers/isdn/mISDN/Kconfig
index 1747a02a019..c0730d5c734 100644
--- a/drivers/isdn/mISDN/Kconfig
+++ b/drivers/isdn/mISDN/Kconfig
@@ -17,7 +17,7 @@ config MISDN_DSP
This module may be used for special applications that require
cross connecting of bchannels, conferencing, dtmf decoding,
- echo cancelation, tone generation, and Blowfish encryption and
+ echo cancellation, tone generation, and Blowfish encryption and
decryption. It may use hardware features if available.
E.g. it is required for PBX4Linux. Go to http://isdn.eversberg.eu
diff --git a/drivers/isdn/mISDN/core.c b/drivers/isdn/mISDN/core.c
index 3e245712bba..faf505462a4 100644
--- a/drivers/isdn/mISDN/core.c
+++ b/drivers/isdn/mISDN/core.c
@@ -37,8 +37,8 @@ static void mISDN_dev_release(struct device *dev)
/* nothing to do: the device is part of its parent's data structure */
}
-static ssize_t _show_id(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t id_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct mISDNdevice *mdev = dev_to_mISDN(dev);
@@ -46,9 +46,10 @@ static ssize_t _show_id(struct device *dev,
return -ENODEV;
return sprintf(buf, "%d\n", mdev->id);
}
+static DEVICE_ATTR_RO(id);
-static ssize_t _show_nrbchan(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t nrbchan_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct mISDNdevice *mdev = dev_to_mISDN(dev);
@@ -56,9 +57,10 @@ static ssize_t _show_nrbchan(struct device *dev,
return -ENODEV;
return sprintf(buf, "%d\n", mdev->nrbchan);
}
+static DEVICE_ATTR_RO(nrbchan);
-static ssize_t _show_d_protocols(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t d_protocols_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct mISDNdevice *mdev = dev_to_mISDN(dev);
@@ -66,9 +68,10 @@ static ssize_t _show_d_protocols(struct device *dev,
return -ENODEV;
return sprintf(buf, "%d\n", mdev->Dprotocols);
}
+static DEVICE_ATTR_RO(d_protocols);
-static ssize_t _show_b_protocols(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t b_protocols_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct mISDNdevice *mdev = dev_to_mISDN(dev);
@@ -76,9 +79,10 @@ static ssize_t _show_b_protocols(struct device *dev,
return -ENODEV;
return sprintf(buf, "%d\n", mdev->Bprotocols | get_all_Bprotocols());
}
+static DEVICE_ATTR_RO(b_protocols);
-static ssize_t _show_protocol(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t protocol_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct mISDNdevice *mdev = dev_to_mISDN(dev);
@@ -86,17 +90,19 @@ static ssize_t _show_protocol(struct device *dev,
return -ENODEV;
return sprintf(buf, "%d\n", mdev->D.protocol);
}
+static DEVICE_ATTR_RO(protocol);
-static ssize_t _show_name(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t name_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
strcpy(buf, dev_name(dev));
return strlen(buf);
}
+static DEVICE_ATTR_RO(name);
#if 0 /* hangs */
-static ssize_t _set_name(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
+static ssize_t name_set(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
{
int err = 0;
char *out = kmalloc(count + 1, GFP_KERNEL);
@@ -113,10 +119,11 @@ static ssize_t _set_name(struct device *dev, struct device_attribute *attr,
return (err < 0) ? err : count;
}
+static DEVICE_ATTR_RW(name);
#endif
-static ssize_t _show_channelmap(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t channelmap_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct mISDNdevice *mdev = dev_to_mISDN(dev);
char *bp = buf;
@@ -127,18 +134,19 @@ static ssize_t _show_channelmap(struct device *dev,
return bp - buf;
}
-
-static struct device_attribute mISDN_dev_attrs[] = {
- __ATTR(id, S_IRUGO, _show_id, NULL),
- __ATTR(d_protocols, S_IRUGO, _show_d_protocols, NULL),
- __ATTR(b_protocols, S_IRUGO, _show_b_protocols, NULL),
- __ATTR(protocol, S_IRUGO, _show_protocol, NULL),
- __ATTR(channelmap, S_IRUGO, _show_channelmap, NULL),
- __ATTR(nrbchan, S_IRUGO, _show_nrbchan, NULL),
- __ATTR(name, S_IRUGO, _show_name, NULL),
-/* __ATTR(name, S_IRUGO | S_IWUSR, _show_name, _set_name), */
- {}
+static DEVICE_ATTR_RO(channelmap);
+
+static struct attribute *mISDN_attrs[] = {
+ &dev_attr_id.attr,
+ &dev_attr_d_protocols.attr,
+ &dev_attr_b_protocols.attr,
+ &dev_attr_protocol.attr,
+ &dev_attr_channelmap.attr,
+ &dev_attr_nrbchan.attr,
+ &dev_attr_name.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(mISDN);
static int mISDN_uevent(struct device *dev, struct kobj_uevent_env *env)
{
@@ -162,19 +170,19 @@ static struct class mISDN_class = {
.name = "mISDN",
.owner = THIS_MODULE,
.dev_uevent = mISDN_uevent,
- .dev_attrs = mISDN_dev_attrs,
+ .dev_groups = mISDN_groups,
.dev_release = mISDN_dev_release,
.class_release = mISDN_class_release,
};
static int
-_get_mdevice(struct device *dev, void *id)
+_get_mdevice(struct device *dev, const void *id)
{
struct mISDNdevice *mdev = dev_to_mISDN(dev);
if (!mdev)
return 0;
- if (mdev->id != *(u_int *)id)
+ if (mdev->id != *(const u_int *)id)
return 0;
return 1;
}
diff --git a/drivers/isdn/mISDN/dsp_core.c b/drivers/isdn/mISDN/dsp_core.c
index 22b720ec80c..77025f5cb57 100644
--- a/drivers/isdn/mISDN/dsp_core.c
+++ b/drivers/isdn/mISDN/dsp_core.c
@@ -288,8 +288,10 @@ dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb)
u8 *data;
int len;
- if (skb->len < sizeof(int))
+ if (skb->len < sizeof(int)) {
printk(KERN_ERR "%s: PH_CONTROL message too short\n", __func__);
+ return -EINVAL;
+ }
cont = *((int *)skb->data);
len = skb->len - sizeof(int);
data = skb->data + sizeof(int);
diff --git a/drivers/isdn/mISDN/dsp_pipeline.c b/drivers/isdn/mISDN/dsp_pipeline.c
index 88305c9cbff..8b1a66c6ca8 100644
--- a/drivers/isdn/mISDN/dsp_pipeline.c
+++ b/drivers/isdn/mISDN/dsp_pipeline.c
@@ -102,7 +102,7 @@ int mISDN_dsp_element_register(struct mISDN_dsp_element *elem)
entry->dev.class = elements_class;
entry->dev.release = mISDN_dsp_dev_release;
dev_set_drvdata(&entry->dev, elem);
- dev_set_name(&entry->dev, elem->name);
+ dev_set_name(&entry->dev, "%s", elem->name);
ret = device_register(&entry->dev);
if (ret) {
printk(KERN_ERR "%s: failed to register %s\n",
diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c
index f8e405c383a..9f454d76cc0 100644
--- a/drivers/isdn/mISDN/l1oip_core.c
+++ b/drivers/isdn/mISDN/l1oip_core.c
@@ -287,11 +287,9 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask,
p = frame;
/* restart timer */
- if ((int)(hc->keep_tl.expires-jiffies) < 5 * HZ) {
- del_timer(&hc->keep_tl);
- hc->keep_tl.expires = jiffies + L1OIP_KEEPALIVE * HZ;
- add_timer(&hc->keep_tl);
- } else
+ if (time_before(hc->keep_tl.expires, jiffies + 5 * HZ))
+ mod_timer(&hc->keep_tl, jiffies + L1OIP_KEEPALIVE * HZ);
+ else
hc->keep_tl.expires = jiffies + L1OIP_KEEPALIVE * HZ;
if (debug & DEBUG_L1OIP_MSG)
@@ -621,11 +619,9 @@ multiframe:
goto multiframe;
/* restart timer */
- if ((int)(hc->timeout_tl.expires-jiffies) < 5 * HZ || !hc->timeout_on) {
+ if (time_before(hc->timeout_tl.expires, jiffies + 5 * HZ) || !hc->timeout_on) {
hc->timeout_on = 1;
- del_timer(&hc->timeout_tl);
- hc->timeout_tl.expires = jiffies + L1OIP_TIMEOUT * HZ;
- add_timer(&hc->timeout_tl);
+ mod_timer(&hc->timeout_tl, jiffies + L1OIP_TIMEOUT * HZ);
} else /* only adjust timer */
hc->timeout_tl.expires = jiffies + L1OIP_TIMEOUT * HZ;
@@ -689,7 +685,7 @@ l1oip_socket_thread(void *data)
hc->sin_remote.sin_addr.s_addr = htonl(hc->remoteip);
hc->sin_remote.sin_port = htons((unsigned short)hc->remoteport);
- /* bind to incomming port */
+ /* bind to incoming port */
if (socket->ops->bind(socket, (struct sockaddr *)&hc->sin_local,
sizeof(hc->sin_local))) {
printk(KERN_ERR "%s: Failed to bind socket to port %d.\n",
diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c
index abe2d699b6f..1be82284cf9 100644
--- a/drivers/isdn/mISDN/socket.c
+++ b/drivers/isdn/mISDN/socket.c
@@ -117,7 +117,6 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
{
struct sk_buff *skb;
struct sock *sk = sock->sk;
- struct sockaddr_mISDN *maddr;
int copied, err;
@@ -135,9 +134,9 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
if (!skb)
return err;
- if (msg->msg_namelen >= sizeof(struct sockaddr_mISDN)) {
- msg->msg_namelen = sizeof(struct sockaddr_mISDN);
- maddr = (struct sockaddr_mISDN *)msg->msg_name;
+ if (msg->msg_name) {
+ DECLARE_SOCKADDR(struct sockaddr_mISDN *, maddr, msg->msg_name);
+
maddr->family = AF_ISDN;
maddr->dev = _pms(sk)->dev->id;
if ((sk->sk_protocol == ISDN_P_LAPD_TE) ||
@@ -150,11 +149,7 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
maddr->sapi = _pms(sk)->ch.addr & 0xFF;
maddr->tei = (_pms(sk)->ch.addr >> 8) & 0xFF;
}
- } else {
- if (msg->msg_namelen)
- printk(KERN_WARNING "%s: too small namelen %d\n",
- __func__, msg->msg_namelen);
- msg->msg_namelen = 0;
+ msg->msg_namelen = sizeof(*maddr);
}
copied = skb->len + MISDN_HEADER_LEN;
@@ -184,7 +179,6 @@ mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
struct sock *sk = sock->sk;
struct sk_buff *skb;
int err = -ENOMEM;
- struct sockaddr_mISDN *maddr;
if (*debug & DEBUG_SOCKET)
printk(KERN_DEBUG "%s: len %d flags %x ch %d proto %x\n",
@@ -219,7 +213,7 @@ mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
if (msg->msg_namelen >= sizeof(struct sockaddr_mISDN)) {
/* if we have a address, we use it */
- maddr = (struct sockaddr_mISDN *)msg->msg_name;
+ DECLARE_SOCKADDR(struct sockaddr_mISDN *, maddr, msg->msg_name);
mISDN_HEAD_ID(skb) = maddr->channel;
} else { /* use default for L2 messages */
if ((sk->sk_protocol == ISDN_P_LAPD_TE) ||
@@ -483,7 +477,6 @@ data_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
{
struct sockaddr_mISDN *maddr = (struct sockaddr_mISDN *) addr;
struct sock *sk = sock->sk;
- struct hlist_node *node;
struct sock *csk;
int err = 0;
@@ -508,7 +501,7 @@ data_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
if (sk->sk_protocol < ISDN_P_B_START) {
read_lock_bh(&data_sockets.lock);
- sk_for_each(csk, node, &data_sockets.head) {
+ sk_for_each(csk, &data_sockets.head) {
if (sk == csk)
continue;
if (_pms(csk)->dev != _pms(sk)->dev)
@@ -579,6 +572,7 @@ data_sock_getname(struct socket *sock, struct sockaddr *addr,
lock_sock(sk);
*addr_len = sizeof(*maddr);
+ maddr->family = AF_ISDN;
maddr->dev = _pms(sk)->dev->id;
maddr->channel = _pms(sk)->ch.nr;
maddr->sapi = _pms(sk)->ch.addr & 0xff;
diff --git a/drivers/isdn/mISDN/stack.c b/drivers/isdn/mISDN/stack.c
index 5f21f629b7a..9cb4b621fbc 100644
--- a/drivers/isdn/mISDN/stack.c
+++ b/drivers/isdn/mISDN/stack.c
@@ -18,6 +18,7 @@
#include <linux/slab.h>
#include <linux/mISDNif.h>
#include <linux/kthread.h>
+#include <linux/sched.h>
#include "core.h"
static u_int *debug;
@@ -63,12 +64,11 @@ unlock:
static void
send_socklist(struct mISDN_sock_list *sl, struct sk_buff *skb)
{
- struct hlist_node *node;
struct sock *sk;
struct sk_buff *cskb = NULL;
read_lock(&sl->lock);
- sk_for_each(sk, node, &sl->head) {
+ sk_for_each(sk, &sl->head) {
if (sk->sk_state != MISDN_BOUND)
continue;
if (!cskb)
@@ -202,6 +202,9 @@ static int
mISDNStackd(void *data)
{
struct mISDNstack *st = data;
+#ifdef MISDN_MSG_STATS
+ cputime_t utime, stime;
+#endif
int err = 0;
sigfillset(&current->blocked);
@@ -303,9 +306,10 @@ mISDNStackd(void *data)
"msg %d sleep %d stopped\n",
dev_name(&st->dev->dev), st->msg_cnt, st->sleep_cnt,
st->stopped_cnt);
+ task_cputime(st->thread, &utime, &stime);
printk(KERN_DEBUG
"mISDNStackd daemon for %s utime(%ld) stime(%ld)\n",
- dev_name(&st->dev->dev), st->thread->utime, st->thread->stime);
+ dev_name(&st->dev->dev), utime, stime);
printk(KERN_DEBUG
"mISDNStackd daemon for %s nvcsw(%ld) nivcsw(%ld)\n",
dev_name(&st->dev->dev), st->thread->nvcsw, st->thread->nivcsw);
diff --git a/drivers/isdn/mISDN/timerdev.c b/drivers/isdn/mISDN/timerdev.c
index 1094667d8f3..9438d7ec330 100644
--- a/drivers/isdn/mISDN/timerdev.c
+++ b/drivers/isdn/mISDN/timerdev.c
@@ -64,7 +64,6 @@ mISDN_open(struct inode *ino, struct file *filep)
dev->work = 0;
init_waitqueue_head(&dev->wait);
filep->private_data = dev;
- __module_get(THIS_MODULE);
return nonseekable_open(ino, filep);
}
@@ -72,19 +71,28 @@ static int
mISDN_close(struct inode *ino, struct file *filep)
{
struct mISDNtimerdev *dev = filep->private_data;
+ struct list_head *list = &dev->pending;
struct mISDNtimer *timer, *next;
if (*debug & DEBUG_TIMER)
printk(KERN_DEBUG "%s(%p,%p)\n", __func__, ino, filep);
- list_for_each_entry_safe(timer, next, &dev->pending, list) {
- del_timer(&timer->tl);
+
+ spin_lock_irq(&dev->lock);
+ while (!list_empty(list)) {
+ timer = list_first_entry(list, struct mISDNtimer, list);
+ spin_unlock_irq(&dev->lock);
+ del_timer_sync(&timer->tl);
+ spin_lock_irq(&dev->lock);
+ /* it might have been moved to ->expired */
+ list_del(&timer->list);
kfree(timer);
}
+ spin_unlock_irq(&dev->lock);
+
list_for_each_entry_safe(timer, next, &dev->expired, list) {
kfree(timer);
}
kfree(dev);
- module_put(THIS_MODULE);
return 0;
}
@@ -92,36 +100,41 @@ static ssize_t
mISDN_read(struct file *filep, char __user *buf, size_t count, loff_t *off)
{
struct mISDNtimerdev *dev = filep->private_data;
+ struct list_head *list = &dev->expired;
struct mISDNtimer *timer;
- u_long flags;
int ret = 0;
if (*debug & DEBUG_TIMER)
printk(KERN_DEBUG "%s(%p, %p, %d, %p)\n", __func__,
filep, buf, (int)count, off);
- if (list_empty(&dev->expired) && (dev->work == 0)) {
+ if (count < sizeof(int))
+ return -ENOSPC;
+
+ spin_lock_irq(&dev->lock);
+ while (list_empty(list) && (dev->work == 0)) {
+ spin_unlock_irq(&dev->lock);
if (filep->f_flags & O_NONBLOCK)
return -EAGAIN;
wait_event_interruptible(dev->wait, (dev->work ||
- !list_empty(&dev->expired)));
+ !list_empty(list)));
if (signal_pending(current))
return -ERESTARTSYS;
+ spin_lock_irq(&dev->lock);
}
- if (count < sizeof(int))
- return -ENOSPC;
if (dev->work)
dev->work = 0;
- if (!list_empty(&dev->expired)) {
- spin_lock_irqsave(&dev->lock, flags);
- timer = (struct mISDNtimer *)dev->expired.next;
+ if (!list_empty(list)) {
+ timer = list_first_entry(list, struct mISDNtimer, list);
list_del(&timer->list);
- spin_unlock_irqrestore(&dev->lock, flags);
+ spin_unlock_irq(&dev->lock);
if (put_user(timer->id, (int __user *)buf))
ret = -EFAULT;
else
ret = sizeof(int);
kfree(timer);
+ } else {
+ spin_unlock_irq(&dev->lock);
}
return ret;
}
@@ -153,7 +166,8 @@ dev_expire_timer(unsigned long data)
u_long flags;
spin_lock_irqsave(&timer->dev->lock, flags);
- list_move_tail(&timer->list, &timer->dev->expired);
+ if (timer->id >= 0)
+ list_move_tail(&timer->list, &timer->dev->expired);
spin_unlock_irqrestore(&timer->dev->lock, flags);
wake_up_interruptible(&timer->dev->wait);
}
@@ -162,7 +176,6 @@ static int
misdn_add_timer(struct mISDNtimerdev *dev, int timeout)
{
int id;
- u_long flags;
struct mISDNtimer *timer;
if (!timeout) {
@@ -173,19 +186,16 @@ misdn_add_timer(struct mISDNtimerdev *dev, int timeout)
timer = kzalloc(sizeof(struct mISDNtimer), GFP_KERNEL);
if (!timer)
return -ENOMEM;
- spin_lock_irqsave(&dev->lock, flags);
- timer->id = dev->next_id++;
+ timer->dev = dev;
+ setup_timer(&timer->tl, dev_expire_timer, (long)timer);
+ spin_lock_irq(&dev->lock);
+ id = timer->id = dev->next_id++;
if (dev->next_id < 0)
dev->next_id = 1;
list_add_tail(&timer->list, &dev->pending);
- spin_unlock_irqrestore(&dev->lock, flags);
- timer->dev = dev;
- timer->tl.data = (long)timer;
- timer->tl.function = dev_expire_timer;
- init_timer(&timer->tl);
timer->tl.expires = jiffies + ((HZ * (u_long)timeout) / 1000);
add_timer(&timer->tl);
- id = timer->id;
+ spin_unlock_irq(&dev->lock);
}
return id;
}
@@ -193,26 +203,21 @@ misdn_add_timer(struct mISDNtimerdev *dev, int timeout)
static int
misdn_del_timer(struct mISDNtimerdev *dev, int id)
{
- u_long flags;
struct mISDNtimer *timer;
- int ret = 0;
- spin_lock_irqsave(&dev->lock, flags);
+ spin_lock_irq(&dev->lock);
list_for_each_entry(timer, &dev->pending, list) {
if (timer->id == id) {
list_del_init(&timer->list);
- /* RED-PEN AK: race -- timer can be still running on
- * other CPU. Needs reference count I think
- */
- del_timer(&timer->tl);
- ret = timer->id;
+ timer->id = -1;
+ spin_unlock_irq(&dev->lock);
+ del_timer_sync(&timer->tl);
kfree(timer);
- goto unlock;
+ return id;
}
}
-unlock:
- spin_unlock_irqrestore(&dev->lock, flags);
- return ret;
+ spin_unlock_irq(&dev->lock);
+ return 0;
}
static long
@@ -262,6 +267,7 @@ mISDN_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
}
static const struct file_operations mISDN_fops = {
+ .owner = THIS_MODULE,
.read = mISDN_read,
.poll = mISDN_poll,
.unlocked_ioctl = mISDN_ioctl,