Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /* net/atm/signaling.c - ATM signaling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/errno.h>	/* error codes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/kernel.h>	/* printk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/sched.h>	/* jiffies and HZ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/atm.h>		/* ATM stuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/atmsap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/atmsvc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/atmdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include "resources.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include "signaling.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) struct atm_vcc *sigd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) static void sigd_put_skb(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	if (!sigd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 		pr_debug("atmsvc: no signaling daemon\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 		kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	atm_force_charge(sigd, skb->truesize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	skb_queue_tail(&sk_atm(sigd)->sk_receive_queue, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	sk_atm(sigd)->sk_data_ready(sk_atm(sigd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) static void modify_qos(struct atm_vcc *vcc, struct atmsvc_msg *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	if (test_bit(ATM_VF_RELEASED, &vcc->flags) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	    !test_bit(ATM_VF_READY, &vcc->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	msg->type = as_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	if (!vcc->dev->ops->change_qos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		msg->reply = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		/* should lock VCC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		msg->reply = vcc->dev->ops->change_qos(vcc, &msg->qos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 						       msg->reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		if (!msg->reply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 			msg->type = as_okay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	 * Should probably just turn around the old skb. But then, the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	 * space accounting needs to follow the change too. Maybe later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	while (!(skb = alloc_skb(sizeof(struct atmsvc_msg), GFP_KERNEL)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	*(struct atmsvc_msg *)skb_put(skb, sizeof(struct atmsvc_msg)) = *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	sigd_put_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) static int sigd_send(struct atm_vcc *vcc, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	struct atmsvc_msg *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	struct atm_vcc *session_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	struct sock *sk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	msg = (struct atmsvc_msg *) skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	WARN_ON(refcount_sub_and_test(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	vcc = *(struct atm_vcc **) &msg->vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	pr_debug("%d (0x%lx)\n", (int)msg->type, (unsigned long)vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	sk = sk_atm(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	switch (msg->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	case as_okay:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		sk->sk_err = -msg->reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		clear_bit(ATM_VF_WAITING, &vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		if (!*vcc->local.sas_addr.prv && !*vcc->local.sas_addr.pub) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 			vcc->local.sas_family = AF_ATMSVC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 			memcpy(vcc->local.sas_addr.prv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 			       msg->local.sas_addr.prv, ATM_ESA_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 			memcpy(vcc->local.sas_addr.pub,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 			       msg->local.sas_addr.pub, ATM_E164_LEN + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		session_vcc = vcc->session ? vcc->session : vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		if (session_vcc->vpi || session_vcc->vci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		session_vcc->itf = msg->pvc.sap_addr.itf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		session_vcc->vpi = msg->pvc.sap_addr.vpi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		session_vcc->vci = msg->pvc.sap_addr.vci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		if (session_vcc->vpi || session_vcc->vci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 			session_vcc->qos = msg->qos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	case as_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		clear_bit(ATM_VF_REGIS, &vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		clear_bit(ATM_VF_READY, &vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		sk->sk_err = -msg->reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		clear_bit(ATM_VF_WAITING, &vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	case as_indicate:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		vcc = *(struct atm_vcc **)&msg->listen_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		sk = sk_atm(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		pr_debug("as_indicate!!!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		lock_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		if (sk_acceptq_is_full(sk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 			sigd_enq(NULL, as_reject, vcc, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 			dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 			goto as_indicate_complete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		sk_acceptq_added(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		skb_queue_tail(&sk->sk_receive_queue, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		pr_debug("waking sk_sleep(sk) 0x%p\n", sk_sleep(sk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		sk->sk_state_change(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) as_indicate_complete:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		release_sock(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	case as_close:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		set_bit(ATM_VF_RELEASED, &vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		vcc_release_async(vcc, msg->reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	case as_modify:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		modify_qos(vcc, msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	case as_addparty:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	case as_dropparty:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		sk->sk_err_soft = -msg->reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 					/* < 0 failure, otherwise ep_ref */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		clear_bit(ATM_VF_WAITING, &vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		pr_alert("bad message type %d\n", (int)msg->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	sk->sk_state_change(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) void sigd_enq2(struct atm_vcc *vcc, enum atmsvc_msg_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	       struct atm_vcc *listen_vcc, const struct sockaddr_atmpvc *pvc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	       const struct sockaddr_atmsvc *svc, const struct atm_qos *qos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	       int reply)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	struct atmsvc_msg *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	static unsigned int session = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	pr_debug("%d (0x%p)\n", (int)type, vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	while (!(skb = alloc_skb(sizeof(struct atmsvc_msg), GFP_KERNEL)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	msg = skb_put_zero(skb, sizeof(struct atmsvc_msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	msg->type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	*(struct atm_vcc **) &msg->vcc = vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	*(struct atm_vcc **) &msg->listen_vcc = listen_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	msg->reply = reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	if (qos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		msg->qos = *qos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	if (vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		msg->sap = vcc->sap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	if (svc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		msg->svc = *svc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	if (vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		msg->local = vcc->local;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	if (pvc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		msg->pvc = *pvc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	if (vcc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		if (type == as_connect && test_bit(ATM_VF_SESSION, &vcc->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 			msg->session = ++session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 			/* every new pmp connect gets the next session number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	sigd_put_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	if (vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		set_bit(ATM_VF_REGIS, &vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) void sigd_enq(struct atm_vcc *vcc, enum atmsvc_msg_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	      struct atm_vcc *listen_vcc, const struct sockaddr_atmpvc *pvc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	      const struct sockaddr_atmsvc *svc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	sigd_enq2(vcc, type, listen_vcc, pvc, svc, vcc ? &vcc->qos : NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	/* other ISP applications may use "reply" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) static void purge_vcc(struct atm_vcc *vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	if (sk_atm(vcc)->sk_family == PF_ATMSVC &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	    !test_bit(ATM_VF_META, &vcc->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		set_bit(ATM_VF_RELEASED, &vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		clear_bit(ATM_VF_REGIS, &vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		vcc_release_async(vcc, -EUNATCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) static void sigd_close(struct atm_vcc *vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	struct sock *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	pr_debug("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	sigd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	if (skb_peek(&sk_atm(vcc)->sk_receive_queue))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		pr_err("closing with requests pending\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	skb_queue_purge(&sk_atm(vcc)->sk_receive_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	read_lock(&vcc_sklist_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	for (i = 0; i < VCC_HTABLE_SIZE; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		struct hlist_head *head = &vcc_hash[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		sk_for_each(s, head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 			vcc = atm_sk(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 			purge_vcc(vcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	read_unlock(&vcc_sklist_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static const struct atmdev_ops sigd_dev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	.close = sigd_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	.send =	sigd_send
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) static struct atm_dev sigd_dev = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	.ops =		&sigd_dev_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	.type =		"sig",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	.number =	999,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	.lock =		__SPIN_LOCK_UNLOCKED(sigd_dev.lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) int sigd_attach(struct atm_vcc *vcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	if (sigd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		return -EADDRINUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	pr_debug("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	sigd = vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	vcc->dev = &sigd_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	vcc_insert_socket(sk_atm(vcc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	set_bit(ATM_VF_META, &vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	set_bit(ATM_VF_READY, &vcc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }