aboutsummaryrefslogtreecommitdiffstats
path: root/net/atm
diff options
context:
space:
mode:
authorDave Kleikamp <shaggy@austin.ibm.com>2006-01-24 15:34:47 -0500
committerDave Kleikamp <shaggy@austin.ibm.com>2006-01-24 15:34:47 -0500
commit0a0fc0ddbe732779366ab6b1b879f62195e65967 (patch)
tree7b42490a676cf39ae0691b6859ecf7fd410f229b /net/atm
parent4d5dbd0945d9e0833dd7964a3d6ee33157f7cc7a (diff)
parent3ee68c4af3fd7228c1be63254b9f884614f9ebb2 (diff)
Merge with /home/shaggy/git/linus-clean/
Diffstat (limited to 'net/atm')
-rw-r--r--net/atm/atm_misc.c11
-rw-r--r--net/atm/br2684.c7
-rw-r--r--net/atm/clip.c1
-rw-r--r--net/atm/common.c66
-rw-r--r--net/atm/common.h2
-rw-r--r--net/atm/ioctl.c1
-rw-r--r--net/atm/lec.c10
-rw-r--r--net/atm/mpc.c3
-rw-r--r--net/atm/pppoatm.c1
-rw-r--r--net/atm/pvc.c2
-rw-r--r--net/atm/raw.c1
-rw-r--r--net/atm/resources.c79
-rw-r--r--net/atm/resources.h3
-rw-r--r--net/atm/svc.c2
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
77int atm_pcr_goal(struct atm_trafprm *tp) 77int 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)
221EXPORT_SYMBOL(vcc_release_async); 221EXPORT_SYMBOL(vcc_release_async);
222 222
223 223
224void 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
224static int adjust_tp(struct atm_trafprm *tp,unsigned char aal) 247static 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 */
48int svc_change_qos(struct atm_vcc *vcc,struct atm_qos *qos); 48int svc_change_qos(struct atm_vcc *vcc,struct atm_qos *qos);
49 49
50void 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
105static struct proto_ops pvc_proto_ops = { 105static 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
27LIST_HEAD(atm_devs); 28LIST_HEAD(atm_devs);
28DEFINE_SPINLOCK(atm_dev_lock); 29DECLARE_MUTEX(atm_dev_mutex);
29 30
30static struct atm_dev *__alloc_atm_dev(const char *type) 31static 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
73struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops, 75struct 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
126void atm_dev_deregister(struct atm_dev *dev) 126void 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
150void 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
415void *atm_dev_seq_start(struct seq_file *seq, loff_t *pos) 401void *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
421void atm_dev_seq_stop(struct seq_file *seq, void *v) 407void 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
426void *atm_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) 412void *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)
434EXPORT_SYMBOL(atm_dev_register); 420EXPORT_SYMBOL(atm_dev_register);
435EXPORT_SYMBOL(atm_dev_deregister); 421EXPORT_SYMBOL(atm_dev_deregister);
436EXPORT_SYMBOL(atm_dev_lookup); 422EXPORT_SYMBOL(atm_dev_lookup);
437EXPORT_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
13extern struct list_head atm_devs; 13extern struct list_head atm_devs;
14extern spinlock_t atm_dev_lock; 14extern struct semaphore atm_dev_mutex;
15
16 15
17int atm_dev_ioctl(unsigned int cmd, void __user *arg); 16int 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
616static struct proto_ops svc_proto_ops = { 616static 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