diff options
-rw-r--r-- | include/net/ax25.h | 10 | ||||
-rw-r--r-- | net/ax25/ax25_iface.c | 55 | ||||
-rw-r--r-- | net/netrom/af_netrom.c | 8 | ||||
-rw-r--r-- | net/rose/af_rose.c | 8 |
4 files changed, 29 insertions, 52 deletions
diff --git a/include/net/ax25.h b/include/net/ax25.h index 51060ef74590..5ae10dd2e32e 100644 --- a/include/net/ax25.h +++ b/include/net/ax25.h | |||
@@ -342,8 +342,14 @@ struct ax25_protocol { | |||
342 | 342 | ||
343 | extern void ax25_register_pid(struct ax25_protocol *ap); | 343 | extern void ax25_register_pid(struct ax25_protocol *ap); |
344 | extern void ax25_protocol_release(unsigned int); | 344 | extern void ax25_protocol_release(unsigned int); |
345 | extern int __must_check ax25_linkfail_register(void (*)(ax25_cb *, int)); | 345 | |
346 | extern void ax25_linkfail_release(void (*)(ax25_cb *, int)); | 346 | struct ax25_linkfail { |
347 | struct hlist_node lf_node; | ||
348 | void (*func)(ax25_cb *, int); | ||
349 | }; | ||
350 | |||
351 | extern void ax25_linkfail_register(struct ax25_linkfail *lf); | ||
352 | extern void ax25_linkfail_release(struct ax25_linkfail *lf); | ||
347 | extern int __must_check ax25_listen_register(ax25_address *, | 353 | extern int __must_check ax25_listen_register(ax25_address *, |
348 | struct net_device *); | 354 | struct net_device *); |
349 | extern void ax25_listen_release(ax25_address *, struct net_device *); | 355 | extern void ax25_listen_release(ax25_address *, struct net_device *); |
diff --git a/net/ax25/ax25_iface.c b/net/ax25/ax25_iface.c index 51e293420b7f..aff3e652c2d1 100644 --- a/net/ax25/ax25_iface.c +++ b/net/ax25/ax25_iface.c | |||
@@ -32,10 +32,7 @@ | |||
32 | static struct ax25_protocol *protocol_list; | 32 | static struct ax25_protocol *protocol_list; |
33 | static DEFINE_RWLOCK(protocol_list_lock); | 33 | static DEFINE_RWLOCK(protocol_list_lock); |
34 | 34 | ||
35 | static struct linkfail_struct { | 35 | static HLIST_HEAD(ax25_linkfail_list); |
36 | struct linkfail_struct *next; | ||
37 | void (*func)(ax25_cb *, int); | ||
38 | } *linkfail_list = NULL; | ||
39 | static DEFINE_SPINLOCK(linkfail_lock); | 36 | static DEFINE_SPINLOCK(linkfail_lock); |
40 | 37 | ||
41 | static struct listen_struct { | 38 | static struct listen_struct { |
@@ -93,54 +90,19 @@ void ax25_protocol_release(unsigned int pid) | |||
93 | 90 | ||
94 | EXPORT_SYMBOL(ax25_protocol_release); | 91 | EXPORT_SYMBOL(ax25_protocol_release); |
95 | 92 | ||
96 | int ax25_linkfail_register(void (*func)(ax25_cb *, int)) | 93 | void ax25_linkfail_register(struct ax25_linkfail *lf) |
97 | { | 94 | { |
98 | struct linkfail_struct *linkfail; | ||
99 | |||
100 | if ((linkfail = kmalloc(sizeof(*linkfail), GFP_ATOMIC)) == NULL) | ||
101 | return 0; | ||
102 | |||
103 | linkfail->func = func; | ||
104 | |||
105 | spin_lock_bh(&linkfail_lock); | 95 | spin_lock_bh(&linkfail_lock); |
106 | linkfail->next = linkfail_list; | 96 | hlist_add_head(&lf->lf_node, &ax25_linkfail_list); |
107 | linkfail_list = linkfail; | ||
108 | spin_unlock_bh(&linkfail_lock); | 97 | spin_unlock_bh(&linkfail_lock); |
109 | |||
110 | return 1; | ||
111 | } | 98 | } |
112 | 99 | ||
113 | EXPORT_SYMBOL(ax25_linkfail_register); | 100 | EXPORT_SYMBOL(ax25_linkfail_register); |
114 | 101 | ||
115 | void ax25_linkfail_release(void (*func)(ax25_cb *, int)) | 102 | void ax25_linkfail_release(struct ax25_linkfail *lf) |
116 | { | 103 | { |
117 | struct linkfail_struct *s, *linkfail; | ||
118 | |||
119 | spin_lock_bh(&linkfail_lock); | 104 | spin_lock_bh(&linkfail_lock); |
120 | linkfail = linkfail_list; | 105 | hlist_del_init(&lf->lf_node); |
121 | if (linkfail == NULL) { | ||
122 | spin_unlock_bh(&linkfail_lock); | ||
123 | return; | ||
124 | } | ||
125 | |||
126 | if (linkfail->func == func) { | ||
127 | linkfail_list = linkfail->next; | ||
128 | spin_unlock_bh(&linkfail_lock); | ||
129 | kfree(linkfail); | ||
130 | return; | ||
131 | } | ||
132 | |||
133 | while (linkfail != NULL && linkfail->next != NULL) { | ||
134 | if (linkfail->next->func == func) { | ||
135 | s = linkfail->next; | ||
136 | linkfail->next = linkfail->next->next; | ||
137 | spin_unlock_bh(&linkfail_lock); | ||
138 | kfree(s); | ||
139 | return; | ||
140 | } | ||
141 | |||
142 | linkfail = linkfail->next; | ||
143 | } | ||
144 | spin_unlock_bh(&linkfail_lock); | 106 | spin_unlock_bh(&linkfail_lock); |
145 | } | 107 | } |
146 | 108 | ||
@@ -237,11 +199,12 @@ int ax25_listen_mine(ax25_address *callsign, struct net_device *dev) | |||
237 | 199 | ||
238 | void ax25_link_failed(ax25_cb *ax25, int reason) | 200 | void ax25_link_failed(ax25_cb *ax25, int reason) |
239 | { | 201 | { |
240 | struct linkfail_struct *linkfail; | 202 | struct ax25_linkfail *lf; |
203 | struct hlist_node *node; | ||
241 | 204 | ||
242 | spin_lock_bh(&linkfail_lock); | 205 | spin_lock_bh(&linkfail_lock); |
243 | for (linkfail = linkfail_list; linkfail != NULL; linkfail = linkfail->next) | 206 | hlist_for_each_entry(lf, node, &ax25_linkfail_list, lf_node) |
244 | (linkfail->func)(ax25, reason); | 207 | lf->func(ax25, reason); |
245 | spin_unlock_bh(&linkfail_lock); | 208 | spin_unlock_bh(&linkfail_lock); |
246 | } | 209 | } |
247 | 210 | ||
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index f4675bf3976c..43bbe2c9e49a 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c | |||
@@ -1382,6 +1382,10 @@ static struct ax25_protocol nr_pid = { | |||
1382 | .func = nr_route_frame | 1382 | .func = nr_route_frame |
1383 | }; | 1383 | }; |
1384 | 1384 | ||
1385 | static struct ax25_linkfail nr_linkfail_notifier = { | ||
1386 | .func = nr_link_failed, | ||
1387 | }; | ||
1388 | |||
1385 | static int __init nr_proto_init(void) | 1389 | static int __init nr_proto_init(void) |
1386 | { | 1390 | { |
1387 | int i; | 1391 | int i; |
@@ -1430,7 +1434,7 @@ static int __init nr_proto_init(void) | |||
1430 | register_netdevice_notifier(&nr_dev_notifier); | 1434 | register_netdevice_notifier(&nr_dev_notifier); |
1431 | 1435 | ||
1432 | ax25_register_pid(&nr_pid); | 1436 | ax25_register_pid(&nr_pid); |
1433 | ax25_linkfail_register(nr_link_failed); | 1437 | ax25_linkfail_register(&nr_linkfail_notifier); |
1434 | 1438 | ||
1435 | #ifdef CONFIG_SYSCTL | 1439 | #ifdef CONFIG_SYSCTL |
1436 | nr_register_sysctl(); | 1440 | nr_register_sysctl(); |
@@ -1479,7 +1483,7 @@ static void __exit nr_exit(void) | |||
1479 | nr_unregister_sysctl(); | 1483 | nr_unregister_sysctl(); |
1480 | #endif | 1484 | #endif |
1481 | 1485 | ||
1482 | ax25_linkfail_release(nr_link_failed); | 1486 | ax25_linkfail_release(&nr_linkfail_notifier); |
1483 | ax25_protocol_release(AX25_P_NETROM); | 1487 | ax25_protocol_release(AX25_P_NETROM); |
1484 | 1488 | ||
1485 | unregister_netdevice_notifier(&nr_dev_notifier); | 1489 | unregister_netdevice_notifier(&nr_dev_notifier); |
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 09f8a06bf806..9e279464c9d1 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c | |||
@@ -1487,6 +1487,10 @@ static struct ax25_protocol rose_pid = { | |||
1487 | .func = rose_route_frame | 1487 | .func = rose_route_frame |
1488 | }; | 1488 | }; |
1489 | 1489 | ||
1490 | static struct ax25_linkfail rose_linkfail_notifier = { | ||
1491 | .func = rose_link_failed | ||
1492 | }; | ||
1493 | |||
1490 | static int __init rose_proto_init(void) | 1494 | static int __init rose_proto_init(void) |
1491 | { | 1495 | { |
1492 | int i; | 1496 | int i; |
@@ -1537,7 +1541,7 @@ static int __init rose_proto_init(void) | |||
1537 | register_netdevice_notifier(&rose_dev_notifier); | 1541 | register_netdevice_notifier(&rose_dev_notifier); |
1538 | 1542 | ||
1539 | ax25_register_pid(&rose_pid); | 1543 | ax25_register_pid(&rose_pid); |
1540 | ax25_linkfail_register(rose_link_failed); | 1544 | ax25_linkfail_register(&rose_linkfail_notifier); |
1541 | 1545 | ||
1542 | #ifdef CONFIG_SYSCTL | 1546 | #ifdef CONFIG_SYSCTL |
1543 | rose_register_sysctl(); | 1547 | rose_register_sysctl(); |
@@ -1585,7 +1589,7 @@ static void __exit rose_exit(void) | |||
1585 | rose_rt_free(); | 1589 | rose_rt_free(); |
1586 | 1590 | ||
1587 | ax25_protocol_release(AX25_P_ROSE); | 1591 | ax25_protocol_release(AX25_P_ROSE); |
1588 | ax25_linkfail_release(rose_link_failed); | 1592 | ax25_linkfail_release(&rose_linkfail_notifier); |
1589 | 1593 | ||
1590 | if (ax25cmp(&rose_callsign, &null_ax25_address) != 0) | 1594 | if (ax25cmp(&rose_callsign, &null_ax25_address) != 0) |
1591 | ax25_listen_release(&rose_callsign, NULL); | 1595 | ax25_listen_release(&rose_callsign, NULL); |