^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Author Karsten Keil <kkeil@novell.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright 2008 by Karsten Keil <kkeil@novell.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/mISDNif.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/kthread.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/sched/cputime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) static u_int *debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) _queue_message(struct mISDNstack *st, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct mISDNhead *hh = mISDN_HEAD_P(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) if (*debug & DEBUG_QUEUE_FUNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) printk(KERN_DEBUG "%s prim(%x) id(%x) %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) __func__, hh->prim, hh->id, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) skb_queue_tail(&st->msgq, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) if (likely(!test_bit(mISDN_STACK_STOPPED, &st->status))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) test_and_set_bit(mISDN_STACK_WORK, &st->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) wake_up_interruptible(&st->workq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) mISDN_queue_message(struct mISDNchannel *ch, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) _queue_message(ch->st, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static struct mISDNchannel *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) get_channel4id(struct mISDNstack *st, u_int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct mISDNchannel *ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) mutex_lock(&st->lmutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) list_for_each_entry(ch, &st->layer2, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (id == ch->nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) goto unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) ch = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) mutex_unlock(&st->lmutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) return ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) send_socklist(struct mISDN_sock_list *sl, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct sock *sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct sk_buff *cskb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) read_lock(&sl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) sk_for_each(sk, &sl->head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (sk->sk_state != MISDN_BOUND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (!cskb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) cskb = skb_copy(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) if (!cskb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) printk(KERN_WARNING "%s no skb\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (!sock_queue_rcv_skb(sk, cskb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) cskb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) read_unlock(&sl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) dev_kfree_skb(cskb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) send_layer2(struct mISDNstack *st, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct sk_buff *cskb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct mISDNhead *hh = mISDN_HEAD_P(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct mISDNchannel *ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (!st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) mutex_lock(&st->lmutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if ((hh->id & MISDN_ID_ADDR_MASK) == MISDN_ID_ANY) { /* L2 for all */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) list_for_each_entry(ch, &st->layer2, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (list_is_last(&ch->list, &st->layer2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) cskb = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) cskb = skb_copy(skb, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (cskb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) ret = ch->send(ch, cskb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (*debug & DEBUG_SEND_ERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) "%s ch%d prim(%x) addr(%x)"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) " err %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) __func__, ch->nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) hh->prim, ch->addr, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) dev_kfree_skb(cskb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) printk(KERN_WARNING "%s ch%d addr %x no mem\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) __func__, ch->nr, ch->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) list_for_each_entry(ch, &st->layer2, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if ((hh->id & MISDN_ID_ADDR_MASK) == ch->addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) ret = ch->send(ch, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) ret = st->dev->teimgr->ctrl(st->dev->teimgr, CHECK_DATA, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) else if (*debug & DEBUG_SEND_ERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) "%s mgr prim(%x) err %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) __func__, hh->prim, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) mutex_unlock(&st->lmutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) send_msg_to_layer(struct mISDNstack *st, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct mISDNhead *hh = mISDN_HEAD_P(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) struct mISDNchannel *ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) int lm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) lm = hh->prim & MISDN_LAYERMASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) if (*debug & DEBUG_QUEUE_FUNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) printk(KERN_DEBUG "%s prim(%x) id(%x) %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) __func__, hh->prim, hh->id, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (lm == 0x1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (!hlist_empty(&st->l1sock.head)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) __net_timestamp(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) send_socklist(&st->l1sock, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return st->layer1->send(st->layer1, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) } else if (lm == 0x2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (!hlist_empty(&st->l1sock.head))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) send_socklist(&st->l1sock, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) send_layer2(st, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) } else if (lm == 0x4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) ch = get_channel4id(st, hh->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return ch->send(ch, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) "%s: dev(%s) prim(%x) id(%x) no channel\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) __func__, dev_name(&st->dev->dev), hh->prim,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) hh->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) } else if (lm == 0x8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) WARN_ON(lm == 0x8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) ch = get_channel4id(st, hh->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) return ch->send(ch, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) "%s: dev(%s) prim(%x) id(%x) no channel\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) __func__, dev_name(&st->dev->dev), hh->prim,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) hh->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) /* broadcast not handled yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) printk(KERN_WARNING "%s: dev(%s) prim %x not delivered\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) __func__, dev_name(&st->dev->dev), hh->prim);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) do_clear_stack(struct mISDNstack *st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) mISDNStackd(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) struct mISDNstack *st = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) #ifdef MISDN_MSG_STATS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) u64 utime, stime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) sigfillset(¤t->blocked);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (*debug & DEBUG_MSG_THREAD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) printk(KERN_DEBUG "mISDNStackd %s started\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) dev_name(&st->dev->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (st->notify != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) complete(st->notify);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) st->notify = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (unlikely(test_bit(mISDN_STACK_STOPPED, &st->status))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) test_and_clear_bit(mISDN_STACK_WORK, &st->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) test_and_clear_bit(mISDN_STACK_RUNNING, &st->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) test_and_set_bit(mISDN_STACK_RUNNING, &st->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) while (test_bit(mISDN_STACK_WORK, &st->status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) skb = skb_dequeue(&st->msgq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) test_and_clear_bit(mISDN_STACK_WORK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) &st->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /* test if a race happens */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) skb = skb_dequeue(&st->msgq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) test_and_set_bit(mISDN_STACK_WORK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) &st->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) #ifdef MISDN_MSG_STATS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) st->msg_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) err = send_msg_to_layer(st, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (unlikely(err)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (*debug & DEBUG_SEND_ERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) "%s: %s prim(%x) id(%x) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) "send call(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) __func__, dev_name(&st->dev->dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) mISDN_HEAD_PRIM(skb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) mISDN_HEAD_ID(skb), err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (unlikely(test_bit(mISDN_STACK_STOPPED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) &st->status))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) test_and_clear_bit(mISDN_STACK_WORK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) &st->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) test_and_clear_bit(mISDN_STACK_RUNNING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) &st->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (test_bit(mISDN_STACK_CLEARING, &st->status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) test_and_set_bit(mISDN_STACK_STOPPED, &st->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) test_and_clear_bit(mISDN_STACK_RUNNING, &st->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) do_clear_stack(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) test_and_clear_bit(mISDN_STACK_CLEARING, &st->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) test_and_set_bit(mISDN_STACK_RESTART, &st->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (test_and_clear_bit(mISDN_STACK_RESTART, &st->status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) test_and_clear_bit(mISDN_STACK_STOPPED, &st->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) test_and_set_bit(mISDN_STACK_RUNNING, &st->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (!skb_queue_empty(&st->msgq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) test_and_set_bit(mISDN_STACK_WORK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) &st->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (test_bit(mISDN_STACK_ABORT, &st->status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (st->notify != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) complete(st->notify);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) st->notify = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) #ifdef MISDN_MSG_STATS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) st->sleep_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) test_and_clear_bit(mISDN_STACK_ACTIVE, &st->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) wait_event_interruptible(st->workq, (st->status &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) mISDN_STACK_ACTION_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (*debug & DEBUG_MSG_THREAD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) printk(KERN_DEBUG "%s: %s wake status %08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) __func__, dev_name(&st->dev->dev), st->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) test_and_set_bit(mISDN_STACK_ACTIVE, &st->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) test_and_clear_bit(mISDN_STACK_WAKEUP, &st->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (test_bit(mISDN_STACK_STOPPED, &st->status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) test_and_clear_bit(mISDN_STACK_RUNNING, &st->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) #ifdef MISDN_MSG_STATS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) st->stopped_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) #ifdef MISDN_MSG_STATS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) printk(KERN_DEBUG "mISDNStackd daemon for %s proceed %d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) "msg %d sleep %d stopped\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) dev_name(&st->dev->dev), st->msg_cnt, st->sleep_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) st->stopped_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) task_cputime(st->thread, &utime, &stime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) "mISDNStackd daemon for %s utime(%llu) stime(%llu)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) dev_name(&st->dev->dev), utime, stime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) printk(KERN_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) "mISDNStackd daemon for %s nvcsw(%ld) nivcsw(%ld)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) dev_name(&st->dev->dev), st->thread->nvcsw, st->thread->nivcsw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) printk(KERN_DEBUG "mISDNStackd daemon for %s killed now\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) dev_name(&st->dev->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) test_and_set_bit(mISDN_STACK_KILLED, &st->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) test_and_clear_bit(mISDN_STACK_RUNNING, &st->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) test_and_clear_bit(mISDN_STACK_ACTIVE, &st->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) test_and_clear_bit(mISDN_STACK_ABORT, &st->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) skb_queue_purge(&st->msgq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) st->thread = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if (st->notify != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) complete(st->notify);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) st->notify = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) l1_receive(struct mISDNchannel *ch, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (!ch->st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) __net_timestamp(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) _queue_message(ch->st, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) set_channel_address(struct mISDNchannel *ch, u_int sapi, u_int tei)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) ch->addr = sapi | (tei << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) __add_layer2(struct mISDNchannel *ch, struct mISDNstack *st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) list_add_tail(&ch->list, &st->layer2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) add_layer2(struct mISDNchannel *ch, struct mISDNstack *st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) mutex_lock(&st->lmutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) __add_layer2(ch, st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) mutex_unlock(&st->lmutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) st_own_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (!ch->st || !ch->st->layer1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) return ch->st->layer1->ctrl(ch->st->layer1, cmd, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) create_stack(struct mISDNdevice *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) struct mISDNstack *newst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) DECLARE_COMPLETION_ONSTACK(done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) newst = kzalloc(sizeof(struct mISDNstack), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (!newst) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) printk(KERN_ERR "kmalloc mISDN_stack failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) newst->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) INIT_LIST_HEAD(&newst->layer2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) INIT_HLIST_HEAD(&newst->l1sock.head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) rwlock_init(&newst->l1sock.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) init_waitqueue_head(&newst->workq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) skb_queue_head_init(&newst->msgq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) mutex_init(&newst->lmutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) dev->D.st = newst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) err = create_teimanager(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) printk(KERN_ERR "kmalloc teimanager failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) kfree(newst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) dev->teimgr->peer = &newst->own;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) dev->teimgr->recv = mISDN_queue_message;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) dev->teimgr->st = newst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) newst->layer1 = &dev->D;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) dev->D.recv = l1_receive;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) dev->D.peer = &newst->own;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) newst->own.st = newst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) newst->own.ctrl = st_own_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) newst->own.send = mISDN_queue_message;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) newst->own.recv = mISDN_queue_message;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (*debug & DEBUG_CORE_FUNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) printk(KERN_DEBUG "%s: st(%s)\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) dev_name(&newst->dev->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) newst->notify = &done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) newst->thread = kthread_run(mISDNStackd, (void *)newst, "mISDN_%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) dev_name(&newst->dev->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (IS_ERR(newst->thread)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) err = PTR_ERR(newst->thread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) "mISDN:cannot create kernel thread for %s (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) dev_name(&newst->dev->dev), err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) delete_teimanager(dev->teimgr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) kfree(newst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) wait_for_completion(&done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) connect_layer1(struct mISDNdevice *dev, struct mISDNchannel *ch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) u_int protocol, struct sockaddr_mISDN *adr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) struct mISDN_sock *msk = container_of(ch, struct mISDN_sock, ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) struct channel_req rq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (*debug & DEBUG_CORE_FUNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) printk(KERN_DEBUG "%s: %s proto(%x) adr(%d %d %d %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) __func__, dev_name(&dev->dev), protocol, adr->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) adr->channel, adr->sapi, adr->tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) switch (protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) case ISDN_P_NT_S0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) case ISDN_P_NT_E1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) case ISDN_P_TE_S0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) case ISDN_P_TE_E1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) ch->recv = mISDN_queue_message;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) ch->peer = &dev->D.st->own;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) ch->st = dev->D.st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) rq.protocol = protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) rq.adr.channel = adr->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) err = dev->D.ctrl(&dev->D, OPEN_CHANNEL, &rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) printk(KERN_DEBUG "%s: ret %d (dev %d)\n", __func__, err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) dev->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) write_lock_bh(&dev->D.st->l1sock.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) sk_add_node(&msk->sk, &dev->D.st->l1sock.head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) write_unlock_bh(&dev->D.st->l1sock.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return -ENOPROTOOPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) connect_Bstack(struct mISDNdevice *dev, struct mISDNchannel *ch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) u_int protocol, struct sockaddr_mISDN *adr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) struct channel_req rq, rq2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) int pmask, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) struct Bprotocol *bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (*debug & DEBUG_CORE_FUNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) printk(KERN_DEBUG "%s: %s proto(%x) adr(%d %d %d %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) __func__, dev_name(&dev->dev), protocol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) adr->dev, adr->channel, adr->sapi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) adr->tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) ch->st = dev->D.st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) pmask = 1 << (protocol & ISDN_P_B_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (pmask & dev->Bprotocols) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) rq.protocol = protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) rq.adr = *adr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) err = dev->D.ctrl(&dev->D, OPEN_CHANNEL, &rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) ch->recv = rq.ch->send;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) ch->peer = rq.ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) rq.ch->recv = ch->send;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) rq.ch->peer = ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) rq.ch->st = dev->D.st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) bp = get_Bprotocol4mask(pmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (!bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) return -ENOPROTOOPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) rq2.protocol = protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) rq2.adr = *adr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) rq2.ch = ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) err = bp->create(&rq2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) ch->recv = rq2.ch->send;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) ch->peer = rq2.ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) rq2.ch->st = dev->D.st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) rq.protocol = rq2.protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) rq.adr = *adr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) err = dev->D.ctrl(&dev->D, OPEN_CHANNEL, &rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) rq2.ch->ctrl(rq2.ch, CLOSE_CHANNEL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) rq2.ch->recv = rq.ch->send;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) rq2.ch->peer = rq.ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) rq.ch->recv = rq2.ch->send;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) rq.ch->peer = rq2.ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) rq.ch->st = dev->D.st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) ch->protocol = protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) ch->nr = rq.ch->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) create_l2entity(struct mISDNdevice *dev, struct mISDNchannel *ch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) u_int protocol, struct sockaddr_mISDN *adr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) struct channel_req rq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if (*debug & DEBUG_CORE_FUNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) printk(KERN_DEBUG "%s: %s proto(%x) adr(%d %d %d %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) __func__, dev_name(&dev->dev), protocol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) adr->dev, adr->channel, adr->sapi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) adr->tei);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) rq.protocol = ISDN_P_TE_S0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (dev->Dprotocols & (1 << ISDN_P_TE_E1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) rq.protocol = ISDN_P_TE_E1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) switch (protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) case ISDN_P_LAPD_NT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) rq.protocol = ISDN_P_NT_S0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) if (dev->Dprotocols & (1 << ISDN_P_NT_E1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) rq.protocol = ISDN_P_NT_E1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) case ISDN_P_LAPD_TE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) ch->recv = mISDN_queue_message;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) ch->peer = &dev->D.st->own;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) ch->st = dev->D.st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) rq.adr.channel = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) err = dev->D.ctrl(&dev->D, OPEN_CHANNEL, &rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) printk(KERN_DEBUG "%s: ret 1 %d\n", __func__, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) rq.protocol = protocol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) rq.adr = *adr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) rq.ch = ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) err = dev->teimgr->ctrl(dev->teimgr, OPEN_CHANNEL, &rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) printk(KERN_DEBUG "%s: ret 2 %d\n", __func__, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if ((protocol == ISDN_P_LAPD_NT) && !rq.ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) add_layer2(rq.ch, dev->D.st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) rq.ch->recv = mISDN_queue_message;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) rq.ch->peer = &dev->D.st->own;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) rq.ch->ctrl(rq.ch, OPEN_CHANNEL, NULL); /* can't fail */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) err = -EPROTONOSUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) delete_channel(struct mISDNchannel *ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) struct mISDN_sock *msk = container_of(ch, struct mISDN_sock, ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) struct mISDNchannel *pch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) if (!ch->st) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) printk(KERN_WARNING "%s: no stack\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) if (*debug & DEBUG_CORE_FUNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) printk(KERN_DEBUG "%s: st(%s) protocol(%x)\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) dev_name(&ch->st->dev->dev), ch->protocol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) if (ch->protocol >= ISDN_P_B_START) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) if (ch->peer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) ch->peer->ctrl(ch->peer, CLOSE_CHANNEL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) ch->peer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) switch (ch->protocol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) case ISDN_P_NT_S0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) case ISDN_P_TE_S0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) case ISDN_P_NT_E1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) case ISDN_P_TE_E1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) write_lock_bh(&ch->st->l1sock.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) sk_del_node_init(&msk->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) write_unlock_bh(&ch->st->l1sock.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) ch->st->dev->D.ctrl(&ch->st->dev->D, CLOSE_CHANNEL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) case ISDN_P_LAPD_TE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) pch = get_channel4id(ch->st, ch->nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) if (pch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) mutex_lock(&ch->st->lmutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) list_del(&pch->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) mutex_unlock(&ch->st->lmutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) pch->ctrl(pch, CLOSE_CHANNEL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) pch = ch->st->dev->teimgr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) pch->ctrl(pch, CLOSE_CHANNEL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) printk(KERN_WARNING "%s: no l2 channel\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) case ISDN_P_LAPD_NT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) pch = ch->st->dev->teimgr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (pch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) pch->ctrl(pch, CLOSE_CHANNEL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) printk(KERN_WARNING "%s: no l2 channel\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) delete_stack(struct mISDNdevice *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) struct mISDNstack *st = dev->D.st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) DECLARE_COMPLETION_ONSTACK(done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if (*debug & DEBUG_CORE_FUNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) printk(KERN_DEBUG "%s: st(%s)\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) dev_name(&st->dev->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) if (dev->teimgr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) delete_teimanager(dev->teimgr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if (st->thread) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) if (st->notify) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) printk(KERN_WARNING "%s: notifier in use\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) complete(st->notify);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) st->notify = &done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) test_and_set_bit(mISDN_STACK_ABORT, &st->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) test_and_set_bit(mISDN_STACK_WAKEUP, &st->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) wake_up_interruptible(&st->workq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) wait_for_completion(&done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) if (!list_empty(&st->layer2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) printk(KERN_WARNING "%s: layer2 list not empty\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if (!hlist_empty(&st->l1sock.head))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) printk(KERN_WARNING "%s: layer1 list not empty\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) kfree(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) mISDN_initstack(u_int *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) debug = dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) }