diff options
author | Stanislaw Gruszka <stf_xl@wp.pl> | 2005-11-29 19:16:41 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2005-11-29 19:16:41 -0500 |
commit | 64bf69ddff7637b7ed7acf9b2a823cc0ee519439 (patch) | |
tree | fb3a746e36bcfa307979bef2a20ce5f1d32ec537 /drivers/atm | |
parent | aaaaaadbe7a663d110814db50fcbe7d320eb4c32 (diff) |
[ATM]: deregistration removes device from atm_devs list immediately
atm_dev_deregister() removes device from atm_dev list immediately to
prevent operations on a phantom device. Decision to free device based
only on ->refcnt now. Remove shutdown_atm_dev() use atm_dev_deregister()
instead. atm_dev_deregister() also asynchronously releases all vccs
related to device.
Signed-off-by: Stanislaw Gruszka <stf_xl@wp.pl>
Signed-off-by: Chas Williams <chas@cmf.nrl.navy.mil>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/atm')
-rw-r--r-- | drivers/atm/atmtcp.c | 20 |
1 files changed, 2 insertions, 18 deletions
diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c index 57f1810fdccd..fc518d85543d 100644 --- a/drivers/atm/atmtcp.c +++ b/drivers/atm/atmtcp.c | |||
@@ -246,10 +246,6 @@ static void atmtcp_c_close(struct atm_vcc *vcc) | |||
246 | { | 246 | { |
247 | struct atm_dev *atmtcp_dev; | 247 | struct atm_dev *atmtcp_dev; |
248 | struct atmtcp_dev_data *dev_data; | 248 | struct atmtcp_dev_data *dev_data; |
249 | struct sock *s; | ||
250 | struct hlist_node *node; | ||
251 | struct atm_vcc *walk; | ||
252 | int i; | ||
253 | 249 | ||
254 | atmtcp_dev = (struct atm_dev *) vcc->dev_data; | 250 | atmtcp_dev = (struct atm_dev *) vcc->dev_data; |
255 | dev_data = PRIV(atmtcp_dev); | 251 | dev_data = PRIV(atmtcp_dev); |
@@ -257,20 +253,8 @@ static void atmtcp_c_close(struct atm_vcc *vcc) | |||
257 | if (dev_data->persist) return; | 253 | if (dev_data->persist) return; |
258 | atmtcp_dev->dev_data = NULL; | 254 | atmtcp_dev->dev_data = NULL; |
259 | kfree(dev_data); | 255 | kfree(dev_data); |
260 | shutdown_atm_dev(atmtcp_dev); | 256 | atm_dev_deregister(atmtcp_dev); |
261 | vcc->dev_data = NULL; | 257 | vcc->dev_data = NULL; |
262 | read_lock(&vcc_sklist_lock); | ||
263 | for(i = 0; i < VCC_HTABLE_SIZE; ++i) { | ||
264 | struct hlist_head *head = &vcc_hash[i]; | ||
265 | |||
266 | sk_for_each(s, node, head) { | ||
267 | walk = atm_sk(s); | ||
268 | if (walk->dev != atmtcp_dev) | ||
269 | continue; | ||
270 | wake_up(s->sk_sleep); | ||
271 | } | ||
272 | } | ||
273 | read_unlock(&vcc_sklist_lock); | ||
274 | module_put(THIS_MODULE); | 258 | module_put(THIS_MODULE); |
275 | } | 259 | } |
276 | 260 | ||
@@ -450,7 +434,7 @@ static int atmtcp_remove_persistent(int itf) | |||
450 | if (PRIV(dev)->vcc) return 0; | 434 | if (PRIV(dev)->vcc) return 0; |
451 | kfree(dev_data); | 435 | kfree(dev_data); |
452 | atm_dev_put(dev); | 436 | atm_dev_put(dev); |
453 | shutdown_atm_dev(dev); | 437 | atm_dev_deregister(dev); |
454 | return 0; | 438 | return 0; |
455 | } | 439 | } |
456 | 440 | ||