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-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *  net/dccp/ccid.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *  An implementation of the DCCP protocol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *  Arnaldo Carvalho de Melo <acme@conectiva.com.br>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *  CCID infrastructure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include "ccid.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include "ccids/lib/tfrc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) static struct ccid_operations *ccids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 	&ccid2_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #ifdef CONFIG_IP_DCCP_CCID3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 	&ccid3_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) static struct ccid_operations *ccid_by_number(const u8 id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	for (i = 0; i < ARRAY_SIZE(ccids); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 		if (ccids[i]->ccid_id == id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 			return ccids[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) /* check that up to @array_len members in @ccid_array are supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) bool ccid_support_check(u8 const *ccid_array, u8 array_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	while (array_len > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 		if (ccid_by_number(ccid_array[--array_len]) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	return true;
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  * ccid_get_builtin_ccids  -  Populate a list of built-in CCIDs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)  * @ccid_array: pointer to copy into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45)  * @array_len: value to return length into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)  * This function allocates memory - caller must see that it is freed after use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) int ccid_get_builtin_ccids(u8 **ccid_array, u8 *array_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	*ccid_array = kmalloc(ARRAY_SIZE(ccids), gfp_any());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	if (*ccid_array == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	for (*array_len = 0; *array_len < ARRAY_SIZE(ccids); *array_len += 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		(*ccid_array)[*array_len] = ccids[*array_len]->ccid_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) int ccid_getsockopt_builtin_ccids(struct sock *sk, int len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 				  char __user *optval, int __user *optlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	u8 *ccid_array, array_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	if (ccid_get_builtin_ccids(&ccid_array, &array_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	if (put_user(array_len, optlen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	else if (len > 0 && copy_to_user(optval, ccid_array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 					 len > array_len ? array_len : len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		err = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	kfree(ccid_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) static struct kmem_cache *ccid_kmem_cache_create(int obj_size, char *slab_name_fmt, const char *fmt,...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	struct kmem_cache *slab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	vsnprintf(slab_name_fmt, CCID_SLAB_NAME_LENGTH, fmt, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	slab = kmem_cache_create(slab_name_fmt, sizeof(struct ccid) + obj_size, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 				 SLAB_HWCACHE_ALIGN, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	return slab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) static void ccid_kmem_cache_destroy(struct kmem_cache *slab)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	kmem_cache_destroy(slab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) static int __init ccid_activate(struct ccid_operations *ccid_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	int err = -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	ccid_ops->ccid_hc_rx_slab =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 			ccid_kmem_cache_create(ccid_ops->ccid_hc_rx_obj_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 					       ccid_ops->ccid_hc_rx_slab_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 					       "ccid%u_hc_rx_sock",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 					       ccid_ops->ccid_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	if (ccid_ops->ccid_hc_rx_slab == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	ccid_ops->ccid_hc_tx_slab =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 			ccid_kmem_cache_create(ccid_ops->ccid_hc_tx_obj_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 					       ccid_ops->ccid_hc_tx_slab_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 					       "ccid%u_hc_tx_sock",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 					       ccid_ops->ccid_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	if (ccid_ops->ccid_hc_tx_slab == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		goto out_free_rx_slab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	pr_info("DCCP: Activated CCID %d (%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		ccid_ops->ccid_id, ccid_ops->ccid_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) out_free_rx_slab:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	ccid_kmem_cache_destroy(ccid_ops->ccid_hc_rx_slab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	ccid_ops->ccid_hc_rx_slab = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static void ccid_deactivate(struct ccid_operations *ccid_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	ccid_kmem_cache_destroy(ccid_ops->ccid_hc_tx_slab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	ccid_ops->ccid_hc_tx_slab = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	ccid_kmem_cache_destroy(ccid_ops->ccid_hc_rx_slab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	ccid_ops->ccid_hc_rx_slab = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	pr_info("DCCP: Deactivated CCID %d (%s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		ccid_ops->ccid_id, ccid_ops->ccid_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct ccid *ccid_new(const u8 id, struct sock *sk, bool rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	struct ccid_operations *ccid_ops = ccid_by_number(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	struct ccid *ccid = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	if (ccid_ops == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	ccid = kmem_cache_alloc(rx ? ccid_ops->ccid_hc_rx_slab :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 				     ccid_ops->ccid_hc_tx_slab, gfp_any());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	if (ccid == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	ccid->ccid_ops = ccid_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	if (rx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		memset(ccid + 1, 0, ccid_ops->ccid_hc_rx_obj_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		if (ccid->ccid_ops->ccid_hc_rx_init != NULL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		    ccid->ccid_ops->ccid_hc_rx_init(ccid, sk) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 			goto out_free_ccid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		memset(ccid + 1, 0, ccid_ops->ccid_hc_tx_obj_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		if (ccid->ccid_ops->ccid_hc_tx_init != NULL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		    ccid->ccid_ops->ccid_hc_tx_init(ccid, sk) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 			goto out_free_ccid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	return ccid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) out_free_ccid:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	kmem_cache_free(rx ? ccid_ops->ccid_hc_rx_slab :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 			ccid_ops->ccid_hc_tx_slab, ccid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	ccid = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) void ccid_hc_rx_delete(struct ccid *ccid, struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	if (ccid != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		if (ccid->ccid_ops->ccid_hc_rx_exit != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 			ccid->ccid_ops->ccid_hc_rx_exit(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		kmem_cache_free(ccid->ccid_ops->ccid_hc_rx_slab, ccid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) void ccid_hc_tx_delete(struct ccid *ccid, struct sock *sk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	if (ccid != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		if (ccid->ccid_ops->ccid_hc_tx_exit != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 			ccid->ccid_ops->ccid_hc_tx_exit(sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		kmem_cache_free(ccid->ccid_ops->ccid_hc_tx_slab, ccid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) int __init ccid_initialize_builtins(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	int i, err = tfrc_lib_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	for (i = 0; i < ARRAY_SIZE(ccids); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		err = ccid_activate(ccids[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 			goto unwind_registrations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) unwind_registrations:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	while(--i >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		ccid_deactivate(ccids[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	tfrc_lib_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	return err;
^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) void ccid_cleanup_builtins(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	for (i = 0; i < ARRAY_SIZE(ccids); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		ccid_deactivate(ccids[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	tfrc_lib_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }