4 * An implementation of the DCCP protocol
5 * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
16 static struct ccid
*ccids
[CCID_MAX
];
17 #if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
18 static atomic_t ccids_lockct
= ATOMIC_INIT(0);
19 static DEFINE_SPINLOCK(ccids_lock
);
22 * The strategy is: modifications ccids vector are short, do not sleep and
23 * veeery rare, but read access should be free of any exclusive locks.
25 static void ccids_write_lock(void)
27 spin_lock(&ccids_lock
);
28 while (atomic_read(&ccids_lockct
) != 0) {
29 spin_unlock(&ccids_lock
);
31 spin_lock(&ccids_lock
);
35 static inline void ccids_write_unlock(void)
37 spin_unlock(&ccids_lock
);
40 static inline void ccids_read_lock(void)
42 atomic_inc(&ccids_lockct
);
43 spin_unlock_wait(&ccids_lock
);
46 static inline void ccids_read_unlock(void)
48 atomic_dec(&ccids_lockct
);
52 #define ccids_write_lock() do { } while(0)
53 #define ccids_write_unlock() do { } while(0)
54 #define ccids_read_lock() do { } while(0)
55 #define ccids_read_unlock() do { } while(0)
58 int ccid_register(struct ccid
*ccid
)
62 if (ccid
->ccid_init
== NULL
)
67 if (ccids
[ccid
->ccid_id
] == NULL
) {
68 ccids
[ccid
->ccid_id
] = ccid
;
73 pr_info("CCID: Registered CCID %d (%s)\n",
74 ccid
->ccid_id
, ccid
->ccid_name
);
78 EXPORT_SYMBOL_GPL(ccid_register
);
80 int ccid_unregister(struct ccid
*ccid
)
83 ccids
[ccid
->ccid_id
] = NULL
;
85 pr_info("CCID: Unregistered CCID %d (%s)\n",
86 ccid
->ccid_id
, ccid
->ccid_name
);
90 EXPORT_SYMBOL_GPL(ccid_unregister
);
92 struct ccid
*ccid_init(unsigned char id
, struct sock
*sk
)
97 if (ccids
[id
] == NULL
)
98 request_module("net-dccp-ccid-%d", id
);
106 if (!try_module_get(ccid
->ccid_owner
))
109 if (ccid
->ccid_init(sk
) != 0)
115 module_put(ccid
->ccid_owner
);
121 EXPORT_SYMBOL_GPL(ccid_init
);
123 void ccid_exit(struct ccid
*ccid
, struct sock
*sk
)
130 if (ccids
[ccid
->ccid_id
] != NULL
) {
131 if (ccid
->ccid_exit
!= NULL
)
133 module_put(ccid
->ccid_owner
);
139 EXPORT_SYMBOL_GPL(ccid_exit
);