diff options
author | Dave Kleikamp <shaggy@austin.ibm.com> | 2006-01-24 15:34:47 -0500 |
---|---|---|
committer | Dave Kleikamp <shaggy@austin.ibm.com> | 2006-01-24 15:34:47 -0500 |
commit | 0a0fc0ddbe732779366ab6b1b879f62195e65967 (patch) | |
tree | 7b42490a676cf39ae0691b6859ecf7fd410f229b /net/atm | |
parent | 4d5dbd0945d9e0833dd7964a3d6ee33157f7cc7a (diff) | |
parent | 3ee68c4af3fd7228c1be63254b9f884614f9ebb2 (diff) |
Merge with /home/shaggy/git/linus-clean/
Diffstat (limited to 'net/atm')
-rw-r--r-- | net/atm/atm_misc.c | 11 | ||||
-rw-r--r-- | net/atm/br2684.c | 7 | ||||
-rw-r--r-- | net/atm/clip.c | 1 | ||||
-rw-r--r-- | net/atm/common.c | 66 | ||||
-rw-r--r-- | net/atm/common.h | 2 | ||||
-rw-r--r-- | net/atm/ioctl.c | 1 | ||||
-rw-r--r-- | net/atm/lec.c | 10 | ||||
-rw-r--r-- | net/atm/mpc.c | 3 | ||||
-rw-r--r-- | net/atm/pppoatm.c | 1 | ||||
-rw-r--r-- | net/atm/pvc.c | 2 | ||||
-rw-r--r-- | net/atm/raw.c | 1 | ||||
-rw-r--r-- | net/atm/resources.c | 79 | ||||
-rw-r--r-- | net/atm/resources.h | 3 | ||||
-rw-r--r-- | net/atm/svc.c | 2 |
14 files changed, 99 insertions, 90 deletions
diff --git a/net/atm/atm_misc.c b/net/atm/atm_misc.c index 223c7ad5bd..02cc7e71ef 100644 --- a/net/atm/atm_misc.c +++ b/net/atm/atm_misc.c | |||
@@ -74,11 +74,14 @@ struct sk_buff *atm_alloc_charge(struct atm_vcc *vcc,int pdu_size, | |||
74 | */ | 74 | */ |
75 | 75 | ||
76 | 76 | ||
77 | int atm_pcr_goal(struct atm_trafprm *tp) | 77 | int atm_pcr_goal(const struct atm_trafprm *tp) |
78 | { | 78 | { |
79 | if (tp->pcr && tp->pcr != ATM_MAX_PCR) return -tp->pcr; | 79 | if (tp->pcr && tp->pcr != ATM_MAX_PCR) |
80 | if (tp->min_pcr && !tp->pcr) return tp->min_pcr; | 80 | return -tp->pcr; |
81 | if (tp->max_pcr != ATM_MAX_PCR) return -tp->max_pcr; | 81 | if (tp->min_pcr && !tp->pcr) |
82 | return tp->min_pcr; | ||
83 | if (tp->max_pcr != ATM_MAX_PCR) | ||
84 | return -tp->max_pcr; | ||
82 | return 0; | 85 | return 0; |
83 | } | 86 | } |
84 | 87 | ||
diff --git a/net/atm/br2684.c b/net/atm/br2684.c index 72f3f7b8de..680ccb12aa 100644 --- a/net/atm/br2684.c +++ b/net/atm/br2684.c | |||
@@ -18,6 +18,7 @@ Author: Marcell GAL, 2000, XDSL Ltd, Hungary | |||
18 | #include <net/arp.h> | 18 | #include <net/arp.h> |
19 | #include <linux/atm.h> | 19 | #include <linux/atm.h> |
20 | #include <linux/atmdev.h> | 20 | #include <linux/atmdev.h> |
21 | #include <linux/capability.h> | ||
21 | #include <linux/seq_file.h> | 22 | #include <linux/seq_file.h> |
22 | 23 | ||
23 | #include <linux/atmbr2684.h> | 24 | #include <linux/atmbr2684.h> |
@@ -295,14 +296,14 @@ static inline __be16 br_type_trans(struct sk_buff *skb, struct net_device *dev) | |||
295 | unsigned char *rawp; | 296 | unsigned char *rawp; |
296 | eth = eth_hdr(skb); | 297 | eth = eth_hdr(skb); |
297 | 298 | ||
298 | if (*eth->h_dest & 1) { | 299 | if (is_multicast_ether_addr(eth->h_dest)) { |
299 | if (memcmp(eth->h_dest, dev->broadcast, ETH_ALEN) == 0) | 300 | if (!compare_ether_addr(eth->h_dest, dev->broadcast)) |
300 | skb->pkt_type = PACKET_BROADCAST; | 301 | skb->pkt_type = PACKET_BROADCAST; |
301 | else | 302 | else |
302 | skb->pkt_type = PACKET_MULTICAST; | 303 | skb->pkt_type = PACKET_MULTICAST; |
303 | } | 304 | } |
304 | 305 | ||
305 | else if (memcmp(eth->h_dest, dev->dev_addr, ETH_ALEN)) | 306 | else if (compare_ether_addr(eth->h_dest, dev->dev_addr)) |
306 | skb->pkt_type = PACKET_OTHERHOST; | 307 | skb->pkt_type = PACKET_OTHERHOST; |
307 | 308 | ||
308 | if (ntohs(eth->h_proto) >= 1536) | 309 | if (ntohs(eth->h_proto) >= 1536) |
diff --git a/net/atm/clip.c b/net/atm/clip.c index 4f54c9a5e8..73370de975 100644 --- a/net/atm/clip.c +++ b/net/atm/clip.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/atmdev.h> | 19 | #include <linux/atmdev.h> |
20 | #include <linux/atmclip.h> | 20 | #include <linux/atmclip.h> |
21 | #include <linux/atmarp.h> | 21 | #include <linux/atmarp.h> |
22 | #include <linux/capability.h> | ||
22 | #include <linux/ip.h> /* for net/route.h */ | 23 | #include <linux/ip.h> /* for net/route.h */ |
23 | #include <linux/in.h> /* for struct sockaddr_in */ | 24 | #include <linux/in.h> /* for struct sockaddr_in */ |
24 | #include <linux/if.h> /* for IFF_UP */ | 25 | #include <linux/if.h> /* for IFF_UP */ |
diff --git a/net/atm/common.c b/net/atm/common.c index 63feea49fb..6656b111cc 100644 --- a/net/atm/common.c +++ b/net/atm/common.c | |||
@@ -221,6 +221,29 @@ void vcc_release_async(struct atm_vcc *vcc, int reply) | |||
221 | EXPORT_SYMBOL(vcc_release_async); | 221 | EXPORT_SYMBOL(vcc_release_async); |
222 | 222 | ||
223 | 223 | ||
224 | void atm_dev_release_vccs(struct atm_dev *dev) | ||
225 | { | ||
226 | int i; | ||
227 | |||
228 | write_lock_irq(&vcc_sklist_lock); | ||
229 | for (i = 0; i < VCC_HTABLE_SIZE; i++) { | ||
230 | struct hlist_head *head = &vcc_hash[i]; | ||
231 | struct hlist_node *node, *tmp; | ||
232 | struct sock *s; | ||
233 | struct atm_vcc *vcc; | ||
234 | |||
235 | sk_for_each_safe(s, node, tmp, head) { | ||
236 | vcc = atm_sk(s); | ||
237 | if (vcc->dev == dev) { | ||
238 | vcc_release_async(vcc, -EPIPE); | ||
239 | sk_del_node_init(s); | ||
240 | } | ||
241 | } | ||
242 | } | ||
243 | write_unlock_irq(&vcc_sklist_lock); | ||
244 | } | ||
245 | |||
246 | |||
224 | static int adjust_tp(struct atm_trafprm *tp,unsigned char aal) | 247 | static int adjust_tp(struct atm_trafprm *tp,unsigned char aal) |
225 | { | 248 | { |
226 | int max_sdu; | 249 | int max_sdu; |
@@ -332,12 +355,13 @@ static int __vcc_connect(struct atm_vcc *vcc, struct atm_dev *dev, short vpi, | |||
332 | return -EINVAL; | 355 | return -EINVAL; |
333 | if (vci > 0 && vci < ATM_NOT_RSV_VCI && !capable(CAP_NET_BIND_SERVICE)) | 356 | if (vci > 0 && vci < ATM_NOT_RSV_VCI && !capable(CAP_NET_BIND_SERVICE)) |
334 | return -EPERM; | 357 | return -EPERM; |
335 | error = 0; | 358 | error = -ENODEV; |
336 | if (!try_module_get(dev->ops->owner)) | 359 | if (!try_module_get(dev->ops->owner)) |
337 | return -ENODEV; | 360 | return error; |
338 | vcc->dev = dev; | 361 | vcc->dev = dev; |
339 | write_lock_irq(&vcc_sklist_lock); | 362 | write_lock_irq(&vcc_sklist_lock); |
340 | if ((error = find_ci(vcc, &vpi, &vci))) { | 363 | if (test_bit(ATM_DF_REMOVED, &dev->flags) || |
364 | (error = find_ci(vcc, &vpi, &vci))) { | ||
341 | write_unlock_irq(&vcc_sklist_lock); | 365 | write_unlock_irq(&vcc_sklist_lock); |
342 | goto fail_module_put; | 366 | goto fail_module_put; |
343 | } | 367 | } |
@@ -423,33 +447,23 @@ int vcc_connect(struct socket *sock, int itf, short vpi, int vci) | |||
423 | if (vcc->qos.txtp.traffic_class == ATM_ANYCLASS || | 447 | if (vcc->qos.txtp.traffic_class == ATM_ANYCLASS || |
424 | vcc->qos.rxtp.traffic_class == ATM_ANYCLASS) | 448 | vcc->qos.rxtp.traffic_class == ATM_ANYCLASS) |
425 | return -EINVAL; | 449 | return -EINVAL; |
426 | if (itf != ATM_ITF_ANY) { | 450 | if (likely(itf != ATM_ITF_ANY)) { |
427 | dev = atm_dev_lookup(itf); | 451 | dev = try_then_request_module(atm_dev_lookup(itf), "atm-device-%d", itf); |
428 | if (!dev) | ||
429 | return -ENODEV; | ||
430 | error = __vcc_connect(vcc, dev, vpi, vci); | ||
431 | if (error) { | ||
432 | atm_dev_put(dev); | ||
433 | return error; | ||
434 | } | ||
435 | } else { | 452 | } else { |
436 | struct list_head *p, *next; | ||
437 | |||
438 | dev = NULL; | 453 | dev = NULL; |
439 | spin_lock(&atm_dev_lock); | 454 | down(&atm_dev_mutex); |
440 | list_for_each_safe(p, next, &atm_devs) { | 455 | if (!list_empty(&atm_devs)) { |
441 | dev = list_entry(p, struct atm_dev, dev_list); | 456 | dev = list_entry(atm_devs.next, struct atm_dev, dev_list); |
442 | atm_dev_hold(dev); | 457 | atm_dev_hold(dev); |
443 | spin_unlock(&atm_dev_lock); | ||
444 | if (!__vcc_connect(vcc, dev, vpi, vci)) | ||
445 | break; | ||
446 | atm_dev_put(dev); | ||
447 | dev = NULL; | ||
448 | spin_lock(&atm_dev_lock); | ||
449 | } | 458 | } |
450 | spin_unlock(&atm_dev_lock); | 459 | up(&atm_dev_mutex); |
451 | if (!dev) | 460 | } |
452 | return -ENODEV; | 461 | if (!dev) |
462 | return -ENODEV; | ||
463 | error = __vcc_connect(vcc, dev, vpi, vci); | ||
464 | if (error) { | ||
465 | atm_dev_put(dev); | ||
466 | return error; | ||
453 | } | 467 | } |
454 | if (vpi == ATM_VPI_UNSPEC || vci == ATM_VCI_UNSPEC) | 468 | if (vpi == ATM_VPI_UNSPEC || vci == ATM_VCI_UNSPEC) |
455 | set_bit(ATM_VF_PARTIAL,&vcc->flags); | 469 | set_bit(ATM_VF_PARTIAL,&vcc->flags); |
diff --git a/net/atm/common.h b/net/atm/common.h index e49ed41c0e..4887c317ce 100644 --- a/net/atm/common.h +++ b/net/atm/common.h | |||
@@ -47,4 +47,6 @@ static inline void atm_proc_exit(void) | |||
47 | /* SVC */ | 47 | /* SVC */ |
48 | int svc_change_qos(struct atm_vcc *vcc,struct atm_qos *qos); | 48 | int svc_change_qos(struct atm_vcc *vcc,struct atm_qos *qos); |
49 | 49 | ||
50 | void atm_dev_release_vccs(struct atm_dev *dev); | ||
51 | |||
50 | #endif | 52 | #endif |
diff --git a/net/atm/ioctl.c b/net/atm/ioctl.c index a150198b05..eb109af7eb 100644 --- a/net/atm/ioctl.c +++ b/net/atm/ioctl.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/atmdev.h> | 12 | #include <linux/atmdev.h> |
13 | #include <linux/atmclip.h> /* CLIP_*ENCAP */ | 13 | #include <linux/atmclip.h> /* CLIP_*ENCAP */ |
14 | #include <linux/atmarp.h> /* manifest constants */ | 14 | #include <linux/atmarp.h> /* manifest constants */ |
15 | #include <linux/capability.h> | ||
15 | #include <linux/sonet.h> /* for ioctls */ | 16 | #include <linux/sonet.h> /* for ioctls */ |
16 | #include <linux/atmsvc.h> | 17 | #include <linux/atmsvc.h> |
17 | #include <linux/atmmpc.h> | 18 | #include <linux/atmmpc.h> |
diff --git a/net/atm/lec.c b/net/atm/lec.c index ad840b9afb..c4fc722fef 100644 --- a/net/atm/lec.c +++ b/net/atm/lec.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <linux/config.h> | 7 | #include <linux/config.h> |
8 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> |
9 | #include <linux/bitops.h> | 9 | #include <linux/bitops.h> |
10 | #include <linux/capability.h> | ||
10 | 11 | ||
11 | /* We are ethernet device */ | 12 | /* We are ethernet device */ |
12 | #include <linux/if_ether.h> | 13 | #include <linux/if_ether.h> |
@@ -1321,7 +1322,7 @@ static int lane2_associate_req (struct net_device *dev, u8 *lan_dst, | |||
1321 | struct sk_buff *skb; | 1322 | struct sk_buff *skb; |
1322 | struct lec_priv *priv = (struct lec_priv*)dev->priv; | 1323 | struct lec_priv *priv = (struct lec_priv*)dev->priv; |
1323 | 1324 | ||
1324 | if ( memcmp(lan_dst, dev->dev_addr, ETH_ALEN) != 0 ) | 1325 | if (compare_ether_addr(lan_dst, dev->dev_addr)) |
1325 | return (0); /* not our mac address */ | 1326 | return (0); /* not our mac address */ |
1326 | 1327 | ||
1327 | kfree(priv->tlvs); /* NULL if there was no previous association */ | 1328 | kfree(priv->tlvs); /* NULL if there was no previous association */ |
@@ -1798,7 +1799,7 @@ lec_arp_find(struct lec_priv *priv, | |||
1798 | 1799 | ||
1799 | to_return = priv->lec_arp_tables[place]; | 1800 | to_return = priv->lec_arp_tables[place]; |
1800 | while(to_return) { | 1801 | while(to_return) { |
1801 | if (memcmp(mac_addr, to_return->mac_addr, ETH_ALEN) == 0) { | 1802 | if (!compare_ether_addr(mac_addr, to_return->mac_addr)) { |
1802 | return to_return; | 1803 | return to_return; |
1803 | } | 1804 | } |
1804 | to_return = to_return->next; | 1805 | to_return = to_return->next; |
@@ -1811,8 +1812,7 @@ make_entry(struct lec_priv *priv, unsigned char *mac_addr) | |||
1811 | { | 1812 | { |
1812 | struct lec_arp_table *to_return; | 1813 | struct lec_arp_table *to_return; |
1813 | 1814 | ||
1814 | to_return = (struct lec_arp_table *) kmalloc(sizeof(struct lec_arp_table), | 1815 | to_return = kmalloc(sizeof(struct lec_arp_table), GFP_ATOMIC); |
1815 | GFP_ATOMIC); | ||
1816 | if (!to_return) { | 1816 | if (!to_return) { |
1817 | printk("LEC: Arp entry kmalloc failed\n"); | 1817 | printk("LEC: Arp entry kmalloc failed\n"); |
1818 | return NULL; | 1818 | return NULL; |
@@ -2002,7 +2002,7 @@ lec_arp_resolve(struct lec_priv *priv, unsigned char *mac_to_find, | |||
2002 | return priv->mcast_vcc; | 2002 | return priv->mcast_vcc; |
2003 | break; | 2003 | break; |
2004 | case 2: /* LANE2 wants arp for multicast addresses */ | 2004 | case 2: /* LANE2 wants arp for multicast addresses */ |
2005 | if ( memcmp(mac_to_find, bus_mac, ETH_ALEN) == 0) | 2005 | if (!compare_ether_addr(mac_to_find, bus_mac)) |
2006 | return priv->mcast_vcc; | 2006 | return priv->mcast_vcc; |
2007 | break; | 2007 | break; |
2008 | default: | 2008 | default: |
diff --git a/net/atm/mpc.c b/net/atm/mpc.c index 526d953141..c304ef1513 100644 --- a/net/atm/mpc.c +++ b/net/atm/mpc.c | |||
@@ -3,6 +3,7 @@ | |||
3 | #include <linux/timer.h> | 3 | #include <linux/timer.h> |
4 | #include <linux/init.h> | 4 | #include <linux/init.h> |
5 | #include <linux/bitops.h> | 5 | #include <linux/bitops.h> |
6 | #include <linux/capability.h> | ||
6 | #include <linux/seq_file.h> | 7 | #include <linux/seq_file.h> |
7 | 8 | ||
8 | /* We are an ethernet device */ | 9 | /* We are an ethernet device */ |
@@ -552,7 +553,7 @@ static int mpc_send_packet(struct sk_buff *skb, struct net_device *dev) | |||
552 | goto non_ip; /* Multi-Protocol Over ATM :-) */ | 553 | goto non_ip; /* Multi-Protocol Over ATM :-) */ |
553 | 554 | ||
554 | while (i < mpc->number_of_mps_macs) { | 555 | while (i < mpc->number_of_mps_macs) { |
555 | if (memcmp(eth->h_dest, (mpc->mps_macs + i*ETH_ALEN), ETH_ALEN) == 0) | 556 | if (!compare_ether_addr(eth->h_dest, (mpc->mps_macs + i*ETH_ALEN))) |
556 | if ( send_via_shortcut(skb, mpc) == 0 ) /* try shortcut */ | 557 | if ( send_via_shortcut(skb, mpc) == 0 ) /* try shortcut */ |
557 | return 0; /* success! */ | 558 | return 0; /* success! */ |
558 | i++; | 559 | i++; |
diff --git a/net/atm/pppoatm.c b/net/atm/pppoatm.c index 58f4a2b5ae..1489067c1e 100644 --- a/net/atm/pppoatm.c +++ b/net/atm/pppoatm.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/skbuff.h> | 39 | #include <linux/skbuff.h> |
40 | #include <linux/atm.h> | 40 | #include <linux/atm.h> |
41 | #include <linux/atmdev.h> | 41 | #include <linux/atmdev.h> |
42 | #include <linux/capability.h> | ||
42 | #include <linux/ppp_defs.h> | 43 | #include <linux/ppp_defs.h> |
43 | #include <linux/if_ppp.h> | 44 | #include <linux/if_ppp.h> |
44 | #include <linux/ppp_channel.h> | 45 | #include <linux/ppp_channel.h> |
diff --git a/net/atm/pvc.c b/net/atm/pvc.c index 2684a92da2..f2c541774d 100644 --- a/net/atm/pvc.c +++ b/net/atm/pvc.c | |||
@@ -102,7 +102,7 @@ static int pvc_getname(struct socket *sock,struct sockaddr *sockaddr, | |||
102 | } | 102 | } |
103 | 103 | ||
104 | 104 | ||
105 | static struct proto_ops pvc_proto_ops = { | 105 | static const struct proto_ops pvc_proto_ops = { |
106 | .family = PF_ATMPVC, | 106 | .family = PF_ATMPVC, |
107 | .owner = THIS_MODULE, | 107 | .owner = THIS_MODULE, |
108 | 108 | ||
diff --git a/net/atm/raw.c b/net/atm/raw.c index 4a0466e91a..3e57b17ca5 100644 --- a/net/atm/raw.c +++ b/net/atm/raw.c | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <linux/module.h> | 6 | #include <linux/module.h> |
7 | #include <linux/sched.h> | 7 | #include <linux/sched.h> |
8 | #include <linux/atmdev.h> | 8 | #include <linux/atmdev.h> |
9 | #include <linux/capability.h> | ||
9 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
10 | #include <linux/skbuff.h> | 11 | #include <linux/skbuff.h> |
11 | #include <linux/mm.h> | 12 | #include <linux/mm.h> |
diff --git a/net/atm/resources.c b/net/atm/resources.c index 415d2615d4..224190537c 100644 --- a/net/atm/resources.c +++ b/net/atm/resources.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/kernel.h> /* for barrier */ | 16 | #include <linux/kernel.h> /* for barrier */ |
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/bitops.h> | 18 | #include <linux/bitops.h> |
19 | #include <linux/capability.h> | ||
19 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
20 | #include <net/sock.h> /* for struct sock */ | 21 | #include <net/sock.h> /* for struct sock */ |
21 | 22 | ||
@@ -25,7 +26,7 @@ | |||
25 | 26 | ||
26 | 27 | ||
27 | LIST_HEAD(atm_devs); | 28 | LIST_HEAD(atm_devs); |
28 | DEFINE_SPINLOCK(atm_dev_lock); | 29 | DECLARE_MUTEX(atm_dev_mutex); |
29 | 30 | ||
30 | static struct atm_dev *__alloc_atm_dev(const char *type) | 31 | static struct atm_dev *__alloc_atm_dev(const char *type) |
31 | { | 32 | { |
@@ -52,7 +53,7 @@ static struct atm_dev *__atm_dev_lookup(int number) | |||
52 | 53 | ||
53 | list_for_each(p, &atm_devs) { | 54 | list_for_each(p, &atm_devs) { |
54 | dev = list_entry(p, struct atm_dev, dev_list); | 55 | dev = list_entry(p, struct atm_dev, dev_list); |
55 | if ((dev->ops) && (dev->number == number)) { | 56 | if (dev->number == number) { |
56 | atm_dev_hold(dev); | 57 | atm_dev_hold(dev); |
57 | return dev; | 58 | return dev; |
58 | } | 59 | } |
@@ -64,12 +65,13 @@ struct atm_dev *atm_dev_lookup(int number) | |||
64 | { | 65 | { |
65 | struct atm_dev *dev; | 66 | struct atm_dev *dev; |
66 | 67 | ||
67 | spin_lock(&atm_dev_lock); | 68 | down(&atm_dev_mutex); |
68 | dev = __atm_dev_lookup(number); | 69 | dev = __atm_dev_lookup(number); |
69 | spin_unlock(&atm_dev_lock); | 70 | up(&atm_dev_mutex); |
70 | return dev; | 71 | return dev; |
71 | } | 72 | } |
72 | 73 | ||
74 | |||
73 | struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops, | 75 | struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops, |
74 | int number, unsigned long *flags) | 76 | int number, unsigned long *flags) |
75 | { | 77 | { |
@@ -81,11 +83,11 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops, | |||
81 | type); | 83 | type); |
82 | return NULL; | 84 | return NULL; |
83 | } | 85 | } |
84 | spin_lock(&atm_dev_lock); | 86 | down(&atm_dev_mutex); |
85 | if (number != -1) { | 87 | if (number != -1) { |
86 | if ((inuse = __atm_dev_lookup(number))) { | 88 | if ((inuse = __atm_dev_lookup(number))) { |
87 | atm_dev_put(inuse); | 89 | atm_dev_put(inuse); |
88 | spin_unlock(&atm_dev_lock); | 90 | up(&atm_dev_mutex); |
89 | kfree(dev); | 91 | kfree(dev); |
90 | return NULL; | 92 | return NULL; |
91 | } | 93 | } |
@@ -105,19 +107,17 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops, | |||
105 | memset(&dev->flags, 0, sizeof(dev->flags)); | 107 | memset(&dev->flags, 0, sizeof(dev->flags)); |
106 | memset(&dev->stats, 0, sizeof(dev->stats)); | 108 | memset(&dev->stats, 0, sizeof(dev->stats)); |
107 | atomic_set(&dev->refcnt, 1); | 109 | atomic_set(&dev->refcnt, 1); |
108 | list_add_tail(&dev->dev_list, &atm_devs); | ||
109 | spin_unlock(&atm_dev_lock); | ||
110 | 110 | ||
111 | if (atm_proc_dev_register(dev) < 0) { | 111 | if (atm_proc_dev_register(dev) < 0) { |
112 | printk(KERN_ERR "atm_dev_register: " | 112 | printk(KERN_ERR "atm_dev_register: " |
113 | "atm_proc_dev_register failed for dev %s\n", | 113 | "atm_proc_dev_register failed for dev %s\n", |
114 | type); | 114 | type); |
115 | spin_lock(&atm_dev_lock); | 115 | up(&atm_dev_mutex); |
116 | list_del(&dev->dev_list); | ||
117 | spin_unlock(&atm_dev_lock); | ||
118 | kfree(dev); | 116 | kfree(dev); |
119 | return NULL; | 117 | return NULL; |
120 | } | 118 | } |
119 | list_add_tail(&dev->dev_list, &atm_devs); | ||
120 | up(&atm_dev_mutex); | ||
121 | 121 | ||
122 | return dev; | 122 | return dev; |
123 | } | 123 | } |
@@ -125,37 +125,22 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops, | |||
125 | 125 | ||
126 | void atm_dev_deregister(struct atm_dev *dev) | 126 | void atm_dev_deregister(struct atm_dev *dev) |
127 | { | 127 | { |
128 | unsigned long warning_time; | 128 | BUG_ON(test_bit(ATM_DF_REMOVED, &dev->flags)); |
129 | set_bit(ATM_DF_REMOVED, &dev->flags); | ||
130 | |||
131 | /* | ||
132 | * if we remove current device from atm_devs list, new device | ||
133 | * with same number can appear, such we need deregister proc, | ||
134 | * release async all vccs and remove them from vccs list too | ||
135 | */ | ||
136 | down(&atm_dev_mutex); | ||
137 | list_del(&dev->dev_list); | ||
138 | up(&atm_dev_mutex); | ||
129 | 139 | ||
140 | atm_dev_release_vccs(dev); | ||
130 | atm_proc_dev_deregister(dev); | 141 | atm_proc_dev_deregister(dev); |
131 | 142 | ||
132 | spin_lock(&atm_dev_lock); | 143 | atm_dev_put(dev); |
133 | list_del(&dev->dev_list); | ||
134 | spin_unlock(&atm_dev_lock); | ||
135 | |||
136 | warning_time = jiffies; | ||
137 | while (atomic_read(&dev->refcnt) != 1) { | ||
138 | msleep(250); | ||
139 | if ((jiffies - warning_time) > 10 * HZ) { | ||
140 | printk(KERN_EMERG "atm_dev_deregister: waiting for " | ||
141 | "dev %d to become free. Usage count = %d\n", | ||
142 | dev->number, atomic_read(&dev->refcnt)); | ||
143 | warning_time = jiffies; | ||
144 | } | ||
145 | } | ||
146 | |||
147 | kfree(dev); | ||
148 | } | ||
149 | |||
150 | void shutdown_atm_dev(struct atm_dev *dev) | ||
151 | { | ||
152 | if (atomic_read(&dev->refcnt) > 1) { | ||
153 | set_bit(ATM_DF_CLOSE, &dev->flags); | ||
154 | return; | ||
155 | } | ||
156 | if (dev->ops->dev_close) | ||
157 | dev->ops->dev_close(dev); | ||
158 | atm_dev_deregister(dev); | ||
159 | } | 144 | } |
160 | 145 | ||
161 | 146 | ||
@@ -211,16 +196,16 @@ int atm_dev_ioctl(unsigned int cmd, void __user *arg) | |||
211 | return -EFAULT; | 196 | return -EFAULT; |
212 | if (get_user(len, &iobuf->length)) | 197 | if (get_user(len, &iobuf->length)) |
213 | return -EFAULT; | 198 | return -EFAULT; |
214 | spin_lock(&atm_dev_lock); | 199 | down(&atm_dev_mutex); |
215 | list_for_each(p, &atm_devs) | 200 | list_for_each(p, &atm_devs) |
216 | size += sizeof(int); | 201 | size += sizeof(int); |
217 | if (size > len) { | 202 | if (size > len) { |
218 | spin_unlock(&atm_dev_lock); | 203 | up(&atm_dev_mutex); |
219 | return -E2BIG; | 204 | return -E2BIG; |
220 | } | 205 | } |
221 | tmp_buf = kmalloc(size, GFP_ATOMIC); | 206 | tmp_buf = kmalloc(size, GFP_ATOMIC); |
222 | if (!tmp_buf) { | 207 | if (!tmp_buf) { |
223 | spin_unlock(&atm_dev_lock); | 208 | up(&atm_dev_mutex); |
224 | return -ENOMEM; | 209 | return -ENOMEM; |
225 | } | 210 | } |
226 | tmp_p = tmp_buf; | 211 | tmp_p = tmp_buf; |
@@ -228,7 +213,7 @@ int atm_dev_ioctl(unsigned int cmd, void __user *arg) | |||
228 | dev = list_entry(p, struct atm_dev, dev_list); | 213 | dev = list_entry(p, struct atm_dev, dev_list); |
229 | *tmp_p++ = dev->number; | 214 | *tmp_p++ = dev->number; |
230 | } | 215 | } |
231 | spin_unlock(&atm_dev_lock); | 216 | up(&atm_dev_mutex); |
232 | error = ((copy_to_user(buf, tmp_buf, size)) || | 217 | error = ((copy_to_user(buf, tmp_buf, size)) || |
233 | put_user(size, &iobuf->length)) | 218 | put_user(size, &iobuf->length)) |
234 | ? -EFAULT : 0; | 219 | ? -EFAULT : 0; |
@@ -245,7 +230,8 @@ int atm_dev_ioctl(unsigned int cmd, void __user *arg) | |||
245 | if (get_user(number, &sioc->number)) | 230 | if (get_user(number, &sioc->number)) |
246 | return -EFAULT; | 231 | return -EFAULT; |
247 | 232 | ||
248 | if (!(dev = atm_dev_lookup(number))) | 233 | if (!(dev = try_then_request_module(atm_dev_lookup(number), |
234 | "atm-device-%d", number))) | ||
249 | return -ENODEV; | 235 | return -ENODEV; |
250 | 236 | ||
251 | switch (cmd) { | 237 | switch (cmd) { |
@@ -414,13 +400,13 @@ static __inline__ void *dev_get_idx(loff_t left) | |||
414 | 400 | ||
415 | void *atm_dev_seq_start(struct seq_file *seq, loff_t *pos) | 401 | void *atm_dev_seq_start(struct seq_file *seq, loff_t *pos) |
416 | { | 402 | { |
417 | spin_lock(&atm_dev_lock); | 403 | down(&atm_dev_mutex); |
418 | return *pos ? dev_get_idx(*pos) : (void *) 1; | 404 | return *pos ? dev_get_idx(*pos) : (void *) 1; |
419 | } | 405 | } |
420 | 406 | ||
421 | void atm_dev_seq_stop(struct seq_file *seq, void *v) | 407 | void atm_dev_seq_stop(struct seq_file *seq, void *v) |
422 | { | 408 | { |
423 | spin_unlock(&atm_dev_lock); | 409 | up(&atm_dev_mutex); |
424 | } | 410 | } |
425 | 411 | ||
426 | void *atm_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) | 412 | void *atm_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) |
@@ -434,4 +420,3 @@ void *atm_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) | |||
434 | EXPORT_SYMBOL(atm_dev_register); | 420 | EXPORT_SYMBOL(atm_dev_register); |
435 | EXPORT_SYMBOL(atm_dev_deregister); | 421 | EXPORT_SYMBOL(atm_dev_deregister); |
436 | EXPORT_SYMBOL(atm_dev_lookup); | 422 | EXPORT_SYMBOL(atm_dev_lookup); |
437 | EXPORT_SYMBOL(shutdown_atm_dev); | ||
diff --git a/net/atm/resources.h b/net/atm/resources.h index 12910619db..b7fb82a93b 100644 --- a/net/atm/resources.h +++ b/net/atm/resources.h | |||
@@ -11,8 +11,7 @@ | |||
11 | 11 | ||
12 | 12 | ||
13 | extern struct list_head atm_devs; | 13 | extern struct list_head atm_devs; |
14 | extern spinlock_t atm_dev_lock; | 14 | extern struct semaphore atm_dev_mutex; |
15 | |||
16 | 15 | ||
17 | int atm_dev_ioctl(unsigned int cmd, void __user *arg); | 16 | int atm_dev_ioctl(unsigned int cmd, void __user *arg); |
18 | 17 | ||
diff --git a/net/atm/svc.c b/net/atm/svc.c index d7b266136b..3a180cfd7b 100644 --- a/net/atm/svc.c +++ b/net/atm/svc.c | |||
@@ -613,7 +613,7 @@ static int svc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
613 | return error; | 613 | return error; |
614 | } | 614 | } |
615 | 615 | ||
616 | static struct proto_ops svc_proto_ops = { | 616 | static const struct proto_ops svc_proto_ops = { |
617 | .family = PF_ATMSVC, | 617 | .family = PF_ATMSVC, |
618 | .owner = THIS_MODULE, | 618 | .owner = THIS_MODULE, |
619 | 619 | ||