diff options
author | Jiri Slaby <jslaby@suse.cz> | 2012-11-15 03:49:50 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-11-15 20:20:57 -0500 |
commit | 55bef83cc68bda76a14a23b1076a9a9a9e43af68 (patch) | |
tree | 65614337f5cd23e1aebb5f97ae23fe53dbfd9fd5 /drivers/isdn | |
parent | 81c79838ca24f48e0e4bb96502d131d6af758ae0 (diff) |
ISDN: capi, use kref from tty_port
After commit "TTY: move tty buffers to tty_port", the tty buffers are
not freed in some drivers. This is because tty_port_destructor is not
called whenever a tty_port is freed. This was an assumption I counted
with but was unfortunately untrue. So fix the drivers to fulfil this
assumption.
Here it is enough to switch to refcounting in tty_port.
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/isdn')
-rw-r--r-- | drivers/isdn/capi/capi.c | 36 |
1 files changed, 17 insertions, 19 deletions
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index c679867c2ccd..89562a845f6a 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c | |||
@@ -77,8 +77,6 @@ struct ackqueue_entry { | |||
77 | }; | 77 | }; |
78 | 78 | ||
79 | struct capiminor { | 79 | struct capiminor { |
80 | struct kref kref; | ||
81 | |||
82 | unsigned int minor; | 80 | unsigned int minor; |
83 | 81 | ||
84 | struct capi20_appl *ap; | 82 | struct capi20_appl *ap; |
@@ -190,7 +188,20 @@ static void capiminor_del_all_ack(struct capiminor *mp) | |||
190 | 188 | ||
191 | /* -------- struct capiminor ---------------------------------------- */ | 189 | /* -------- struct capiminor ---------------------------------------- */ |
192 | 190 | ||
193 | static const struct tty_port_operations capiminor_port_ops; /* we have none */ | 191 | static void capiminor_destroy(struct tty_port *port) |
192 | { | ||
193 | struct capiminor *mp = container_of(port, struct capiminor, port); | ||
194 | |||
195 | kfree_skb(mp->outskb); | ||
196 | skb_queue_purge(&mp->inqueue); | ||
197 | skb_queue_purge(&mp->outqueue); | ||
198 | capiminor_del_all_ack(mp); | ||
199 | kfree(mp); | ||
200 | } | ||
201 | |||
202 | static const struct tty_port_operations capiminor_port_ops = { | ||
203 | .destruct = capiminor_destroy, | ||
204 | }; | ||
194 | 205 | ||
195 | static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci) | 206 | static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci) |
196 | { | 207 | { |
@@ -204,8 +215,6 @@ static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci) | |||
204 | return NULL; | 215 | return NULL; |
205 | } | 216 | } |
206 | 217 | ||
207 | kref_init(&mp->kref); | ||
208 | |||
209 | mp->ap = ap; | 218 | mp->ap = ap; |
210 | mp->ncci = ncci; | 219 | mp->ncci = ncci; |
211 | INIT_LIST_HEAD(&mp->ackqueue); | 220 | INIT_LIST_HEAD(&mp->ackqueue); |
@@ -247,21 +256,10 @@ err_out2: | |||
247 | spin_unlock(&capiminors_lock); | 256 | spin_unlock(&capiminors_lock); |
248 | 257 | ||
249 | err_out1: | 258 | err_out1: |
250 | kfree(mp); | 259 | tty_port_put(&mp->port); |
251 | return NULL; | 260 | return NULL; |
252 | } | 261 | } |
253 | 262 | ||
254 | static void capiminor_destroy(struct kref *kref) | ||
255 | { | ||
256 | struct capiminor *mp = container_of(kref, struct capiminor, kref); | ||
257 | |||
258 | kfree_skb(mp->outskb); | ||
259 | skb_queue_purge(&mp->inqueue); | ||
260 | skb_queue_purge(&mp->outqueue); | ||
261 | capiminor_del_all_ack(mp); | ||
262 | kfree(mp); | ||
263 | } | ||
264 | |||
265 | static struct capiminor *capiminor_get(unsigned int minor) | 263 | static struct capiminor *capiminor_get(unsigned int minor) |
266 | { | 264 | { |
267 | struct capiminor *mp; | 265 | struct capiminor *mp; |
@@ -269,7 +267,7 @@ static struct capiminor *capiminor_get(unsigned int minor) | |||
269 | spin_lock(&capiminors_lock); | 267 | spin_lock(&capiminors_lock); |
270 | mp = capiminors[minor]; | 268 | mp = capiminors[minor]; |
271 | if (mp) | 269 | if (mp) |
272 | kref_get(&mp->kref); | 270 | tty_port_get(&mp->port); |
273 | spin_unlock(&capiminors_lock); | 271 | spin_unlock(&capiminors_lock); |
274 | 272 | ||
275 | return mp; | 273 | return mp; |
@@ -277,7 +275,7 @@ static struct capiminor *capiminor_get(unsigned int minor) | |||
277 | 275 | ||
278 | static inline void capiminor_put(struct capiminor *mp) | 276 | static inline void capiminor_put(struct capiminor *mp) |
279 | { | 277 | { |
280 | kref_put(&mp->kref, capiminor_destroy); | 278 | tty_port_put(&mp->port); |
281 | } | 279 | } |
282 | 280 | ||
283 | static void capiminor_free(struct capiminor *mp) | 281 | static void capiminor_free(struct capiminor *mp) |