aboutsummaryrefslogtreecommitdiff
path: root/drivers/isdn/mISDN/stack.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn/mISDN/stack.c')
-rw-r--r--drivers/isdn/mISDN/stack.c163
1 files changed, 75 insertions, 88 deletions
diff --git a/drivers/isdn/mISDN/stack.c b/drivers/isdn/mISDN/stack.c
index 54cfddcc478..9cb4b621fbc 100644
--- a/drivers/isdn/mISDN/stack.c
+++ b/drivers/isdn/mISDN/stack.c
@@ -15,8 +15,10 @@
*
*/
+#include <linux/slab.h>
#include <linux/mISDNif.h>
#include <linux/kthread.h>
+#include <linux/sched.h>
#include "core.h"
static u_int *debug;
@@ -28,7 +30,7 @@ _queue_message(struct mISDNstack *st, struct sk_buff *skb)
if (*debug & DEBUG_QUEUE_FUNC)
printk(KERN_DEBUG "%s prim(%x) id(%x) %p\n",
- __func__, hh->prim, hh->id, skb);
+ __func__, hh->prim, hh->id, skb);
skb_queue_tail(&st->msgq, skb);
if (likely(!test_bit(mISDN_STACK_STOPPED, &st->status))) {
test_and_set_bit(mISDN_STACK_WORK, &st->status);
@@ -36,7 +38,7 @@ _queue_message(struct mISDNstack *st, struct sk_buff *skb)
}
}
-int
+static int
mISDN_queue_message(struct mISDNchannel *ch, struct sk_buff *skb)
{
_queue_message(ch->st, skb);
@@ -62,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)
@@ -108,15 +109,15 @@ send_layer2(struct mISDNstack *st, struct sk_buff *skb)
if (ret) {
if (*debug & DEBUG_SEND_ERR)
printk(KERN_DEBUG
- "%s ch%d prim(%x) addr(%x)"
- " err %d\n",
- __func__, ch->nr,
- hh->prim, ch->addr, ret);
+ "%s ch%d prim(%x) addr(%x)"
+ " err %d\n",
+ __func__, ch->nr,
+ hh->prim, ch->addr, ret);
dev_kfree_skb(cskb);
}
} else {
printk(KERN_WARNING "%s ch%d addr %x no mem\n",
- __func__, ch->nr, ch->addr);
+ __func__, ch->nr, ch->addr);
goto out;
}
}
@@ -134,8 +135,8 @@ send_layer2(struct mISDNstack *st, struct sk_buff *skb)
skb = NULL;
else if (*debug & DEBUG_SEND_ERR)
printk(KERN_DEBUG
- "%s ch%d mgr prim(%x) addr(%x) err %d\n",
- __func__, ch->nr, hh->prim, ch->addr, ret);
+ "%s mgr prim(%x) err %d\n",
+ __func__, hh->prim, ret);
}
out:
mutex_unlock(&st->lmutex);
@@ -153,7 +154,7 @@ send_msg_to_layer(struct mISDNstack *st, struct sk_buff *skb)
lm = hh->prim & MISDN_LAYERMASK;
if (*debug & DEBUG_QUEUE_FUNC)
printk(KERN_DEBUG "%s prim(%x) id(%x) %p\n",
- __func__, hh->prim, hh->id, skb);
+ __func__, hh->prim, hh->id, skb);
if (lm == 0x1) {
if (!hlist_empty(&st->l1sock.head)) {
__net_timestamp(skb);
@@ -171,8 +172,9 @@ send_msg_to_layer(struct mISDNstack *st, struct sk_buff *skb)
return ch->send(ch, skb);
else
printk(KERN_WARNING
- "%s: dev(%s) prim(%x) id(%x) no channel\n",
- __func__, st->dev->name, hh->prim, hh->id);
+ "%s: dev(%s) prim(%x) id(%x) no channel\n",
+ __func__, dev_name(&st->dev->dev), hh->prim,
+ hh->id);
} else if (lm == 0x8) {
WARN_ON(lm == 0x8);
ch = get_channel4id(st, hh->id);
@@ -180,12 +182,13 @@ send_msg_to_layer(struct mISDNstack *st, struct sk_buff *skb)
return ch->send(ch, skb);
else
printk(KERN_WARNING
- "%s: dev(%s) prim(%x) id(%x) no channel\n",
- __func__, st->dev->name, hh->prim, hh->id);
+ "%s: dev(%s) prim(%x) id(%x) no channel\n",
+ __func__, dev_name(&st->dev->dev), hh->prim,
+ hh->id);
} else {
/* broadcast not handled yet */
printk(KERN_WARNING "%s: dev(%s) prim %x not delivered\n",
- __func__, st->dev->name, hh->prim);
+ __func__, dev_name(&st->dev->dev), hh->prim);
}
return -ESRCH;
}
@@ -199,17 +202,15 @@ static int
mISDNStackd(void *data)
{
struct mISDNstack *st = data;
+#ifdef MISDN_MSG_STATS
+ cputime_t utime, stime;
+#endif
int err = 0;
-#ifdef CONFIG_SMP
- lock_kernel();
-#endif
sigfillset(&current->blocked);
-#ifdef CONFIG_SMP
- unlock_kernel();
-#endif
if (*debug & DEBUG_MSG_THREAD)
- printk(KERN_DEBUG "mISDNStackd %s started\n", st->dev->name);
+ printk(KERN_DEBUG "mISDNStackd %s started\n",
+ dev_name(&st->dev->dev));
if (st->notify != NULL) {
complete(st->notify);
@@ -228,13 +229,13 @@ mISDNStackd(void *data)
skb = skb_dequeue(&st->msgq);
if (!skb) {
test_and_clear_bit(mISDN_STACK_WORK,
- &st->status);
+ &st->status);
/* test if a race happens */
skb = skb_dequeue(&st->msgq);
if (!skb)
continue;
test_and_set_bit(mISDN_STACK_WORK,
- &st->status);
+ &st->status);
}
#ifdef MISDN_MSG_STATS
st->msg_cnt++;
@@ -243,20 +244,20 @@ mISDNStackd(void *data)
if (unlikely(err)) {
if (*debug & DEBUG_SEND_ERR)
printk(KERN_DEBUG
- "%s: %s prim(%x) id(%x) "
- "send call(%d)\n",
- __func__, st->dev->name,
- mISDN_HEAD_PRIM(skb),
- mISDN_HEAD_ID(skb), err);
+ "%s: %s prim(%x) id(%x) "
+ "send call(%d)\n",
+ __func__, dev_name(&st->dev->dev),
+ mISDN_HEAD_PRIM(skb),
+ mISDN_HEAD_ID(skb), err);
dev_kfree_skb(skb);
continue;
}
if (unlikely(test_bit(mISDN_STACK_STOPPED,
- &st->status))) {
+ &st->status))) {
test_and_clear_bit(mISDN_STACK_WORK,
- &st->status);
+ &st->status);
test_and_clear_bit(mISDN_STACK_RUNNING,
- &st->status);
+ &st->status);
break;
}
}
@@ -272,7 +273,7 @@ mISDNStackd(void *data)
test_and_set_bit(mISDN_STACK_RUNNING, &st->status);
if (!skb_queue_empty(&st->msgq))
test_and_set_bit(mISDN_STACK_WORK,
- &st->status);
+ &st->status);
}
if (test_bit(mISDN_STACK_ABORT, &st->status))
break;
@@ -285,10 +286,10 @@ mISDNStackd(void *data)
#endif
test_and_clear_bit(mISDN_STACK_ACTIVE, &st->status);
wait_event_interruptible(st->workq, (st->status &
- mISDN_STACK_ACTION_MASK));
+ mISDN_STACK_ACTION_MASK));
if (*debug & DEBUG_MSG_THREAD)
printk(KERN_DEBUG "%s: %s wake status %08lx\n",
- __func__, st->dev->name, st->status);
+ __func__, dev_name(&st->dev->dev), st->status);
test_and_set_bit(mISDN_STACK_ACTIVE, &st->status);
test_and_clear_bit(mISDN_STACK_WAKEUP, &st->status);
@@ -302,16 +303,18 @@ mISDNStackd(void *data)
}
#ifdef MISDN_MSG_STATS
printk(KERN_DEBUG "mISDNStackd daemon for %s proceed %d "
- "msg %d sleep %d stopped\n",
- st->dev->name, st->msg_cnt, st->sleep_cnt, st->stopped_cnt);
+ "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",
- st->dev->name, st->thread->utime, st->thread->stime);
+ "mISDNStackd daemon for %s utime(%ld) stime(%ld)\n",
+ dev_name(&st->dev->dev), utime, stime);
printk(KERN_DEBUG
- "mISDNStackd daemon for %s nvcsw(%ld) nivcsw(%ld)\n",
- st->dev->name, st->thread->nvcsw, st->thread->nivcsw);
+ "mISDNStackd daemon for %s nvcsw(%ld) nivcsw(%ld)\n",
+ dev_name(&st->dev->dev), st->thread->nvcsw, st->thread->nivcsw);
printk(KERN_DEBUG "mISDNStackd daemon for %s killed now\n",
- st->dev->name);
+ dev_name(&st->dev->dev));
#endif
test_and_set_bit(mISDN_STACK_KILLED, &st->status);
test_and_clear_bit(mISDN_STACK_RUNNING, &st->status);
@@ -359,7 +362,7 @@ add_layer2(struct mISDNchannel *ch, struct mISDNstack *st)
static int
st_own_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
{
- if (!ch->st || ch->st->layer1)
+ if (!ch->st || !ch->st->layer1)
return -EINVAL;
return ch->st->layer1->ctrl(ch->st->layer1, cmd, arg);
}
@@ -401,15 +404,16 @@ create_stack(struct mISDNdevice *dev)
newst->own.send = mISDN_queue_message;
newst->own.recv = mISDN_queue_message;
if (*debug & DEBUG_CORE_FUNC)
- printk(KERN_DEBUG "%s: st(%s)\n", __func__, newst->dev->name);
+ printk(KERN_DEBUG "%s: st(%s)\n", __func__,
+ dev_name(&newst->dev->dev));
newst->notify = &done;
newst->thread = kthread_run(mISDNStackd, (void *)newst, "mISDN_%s",
- newst->dev->name);
+ dev_name(&newst->dev->dev));
if (IS_ERR(newst->thread)) {
err = PTR_ERR(newst->thread);
printk(KERN_ERR
- "mISDN:cannot create kernel thread for %s (%d)\n",
- newst->dev->name, err);
+ "mISDN:cannot create kernel thread for %s (%d)\n",
+ dev_name(&newst->dev->dev), err);
delete_teimanager(dev->teimgr);
kfree(newst);
} else
@@ -419,7 +423,7 @@ create_stack(struct mISDNdevice *dev)
int
connect_layer1(struct mISDNdevice *dev, struct mISDNchannel *ch,
- u_int protocol, struct sockaddr_mISDN *adr)
+ u_int protocol, struct sockaddr_mISDN *adr)
{
struct mISDN_sock *msk = container_of(ch, struct mISDN_sock, ch);
struct channel_req rq;
@@ -428,29 +432,21 @@ connect_layer1(struct mISDNdevice *dev, struct mISDNchannel *ch,
if (*debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "%s: %s proto(%x) adr(%d %d %d %d)\n",
- __func__, dev->name, protocol, adr->dev, adr->channel,
- adr->sapi, adr->tei);
+ __func__, dev_name(&dev->dev), protocol, adr->dev,
+ adr->channel, adr->sapi, adr->tei);
switch (protocol) {
case ISDN_P_NT_S0:
case ISDN_P_NT_E1:
case ISDN_P_TE_S0:
case ISDN_P_TE_E1:
-#ifdef PROTOCOL_CHECK
- /* this should be enhanced */
- if (!list_empty(&dev->D.st->layer2)
- && dev->D.protocol != protocol)
- return -EBUSY;
- if (!hlist_empty(&dev->D.st->l1sock.head)
- && dev->D.protocol != protocol)
- return -EBUSY;
-#endif
ch->recv = mISDN_queue_message;
ch->peer = &dev->D.st->own;
ch->st = dev->D.st;
rq.protocol = protocol;
- rq.adr.channel = 0;
+ rq.adr.channel = adr->channel;
err = dev->D.ctrl(&dev->D, OPEN_CHANNEL, &rq);
- printk(KERN_DEBUG "%s: ret 1 %d\n", __func__, err);
+ printk(KERN_DEBUG "%s: ret %d (dev %d)\n", __func__, err,
+ dev->id);
if (err)
return err;
write_lock_bh(&dev->D.st->l1sock.lock);
@@ -465,7 +461,7 @@ connect_layer1(struct mISDNdevice *dev, struct mISDNchannel *ch,
int
connect_Bstack(struct mISDNdevice *dev, struct mISDNchannel *ch,
- u_int protocol, struct sockaddr_mISDN *adr)
+ u_int protocol, struct sockaddr_mISDN *adr)
{
struct channel_req rq, rq2;
int pmask, err;
@@ -473,9 +469,9 @@ connect_Bstack(struct mISDNdevice *dev, struct mISDNchannel *ch,
if (*debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "%s: %s proto(%x) adr(%d %d %d %d)\n",
- __func__, dev->name, protocol,
- adr->dev, adr->channel, adr->sapi,
- adr->tei);
+ __func__, dev_name(&dev->dev), protocol,
+ adr->dev, adr->channel, adr->sapi,
+ adr->tei);
ch->st = dev->D.st;
pmask = 1 << (protocol & ISDN_P_B_MASK);
if (pmask & dev->Bprotocols) {
@@ -522,16 +518,16 @@ connect_Bstack(struct mISDNdevice *dev, struct mISDNchannel *ch,
int
create_l2entity(struct mISDNdevice *dev, struct mISDNchannel *ch,
- u_int protocol, struct sockaddr_mISDN *adr)
+ u_int protocol, struct sockaddr_mISDN *adr)
{
struct channel_req rq;
int err;
if (*debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "%s: %s proto(%x) adr(%d %d %d %d)\n",
- __func__, dev->name, protocol,
- adr->dev, adr->channel, adr->sapi,
- adr->tei);
+ __func__, dev_name(&dev->dev), protocol,
+ adr->dev, adr->channel, adr->sapi,
+ adr->tei);
rq.protocol = ISDN_P_TE_S0;
if (dev->Dprotocols & (1 << ISDN_P_TE_E1))
rq.protocol = ISDN_P_TE_E1;
@@ -541,15 +537,6 @@ create_l2entity(struct mISDNdevice *dev, struct mISDNchannel *ch,
if (dev->Dprotocols & (1 << ISDN_P_NT_E1))
rq.protocol = ISDN_P_NT_E1;
case ISDN_P_LAPD_TE:
-#ifdef PROTOCOL_CHECK
- /* this should be enhanced */
- if (!list_empty(&dev->D.st->layer2)
- && dev->D.protocol != protocol)
- return -EBUSY;
- if (!hlist_empty(&dev->D.st->l1sock.head)
- && dev->D.protocol != protocol)
- return -EBUSY;
-#endif
ch->recv = mISDN_queue_message;
ch->peer = &dev->D.st->own;
ch->st = dev->D.st;
@@ -590,7 +577,7 @@ delete_channel(struct mISDNchannel *ch)
}
if (*debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "%s: st(%s) protocol(%x)\n", __func__,
- ch->st->dev->name, ch->protocol);
+ dev_name(&ch->st->dev->dev), ch->protocol);
if (ch->protocol >= ISDN_P_B_START) {
if (ch->peer) {
ch->peer->ctrl(ch->peer, CLOSE_CHANNEL, NULL);
@@ -619,7 +606,7 @@ delete_channel(struct mISDNchannel *ch)
pch->ctrl(pch, CLOSE_CHANNEL, NULL);
} else
printk(KERN_WARNING "%s: no l2 channel\n",
- __func__);
+ __func__);
break;
case ISDN_P_LAPD_NT:
pch = ch->st->dev->teimgr;
@@ -627,7 +614,7 @@ delete_channel(struct mISDNchannel *ch)
pch->ctrl(pch, CLOSE_CHANNEL, NULL);
} else
printk(KERN_WARNING "%s: no l2 channel\n",
- __func__);
+ __func__);
break;
default:
break;
@@ -643,14 +630,14 @@ delete_stack(struct mISDNdevice *dev)
if (*debug & DEBUG_CORE_FUNC)
printk(KERN_DEBUG "%s: st(%s)\n", __func__,
- st->dev->name);
+ dev_name(&st->dev->dev));
if (dev->teimgr)
delete_teimanager(dev->teimgr);
if (st->thread) {
if (st->notify) {
printk(KERN_WARNING "%s: notifier in use\n",
- __func__);
- complete(st->notify);
+ __func__);
+ complete(st->notify);
}
st->notify = &done;
test_and_set_bit(mISDN_STACK_ABORT, &st->status);
@@ -660,10 +647,10 @@ delete_stack(struct mISDNdevice *dev)
}
if (!list_empty(&st->layer2))
printk(KERN_WARNING "%s: layer2 list not empty\n",
- __func__);
+ __func__);
if (!hlist_empty(&st->l1sock.head))
printk(KERN_WARNING "%s: layer1 list not empty\n",
- __func__);
+ __func__);
kfree(st);
}