Commit 8eff18f1 authored by Stephen Hemminger's avatar Stephen Hemminger

[IRDA]: Remove hashbin from irlan.

parent 62cde326
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <net/irda/irqueue.h>
#include <net/irda/irttp.h> #include <net/irda/irttp.h>
#define IRLAN_MTU 1518 #define IRLAN_MTU 1518
...@@ -161,9 +160,8 @@ struct irlan_provider_cb { ...@@ -161,9 +160,8 @@ struct irlan_provider_cb {
* IrLAN control block * IrLAN control block
*/ */
struct irlan_cb { struct irlan_cb {
irda_queue_t q; /* Must be first */
int magic; int magic;
struct list_head dev_list;
struct net_device dev; /* Ethernet device structure*/ struct net_device dev; /* Ethernet device structure*/
struct net_device_stats stats; struct net_device_stats stats;
...@@ -204,6 +202,7 @@ void irlan_open_data_tsap(struct irlan_cb *self); ...@@ -204,6 +202,7 @@ void irlan_open_data_tsap(struct irlan_cb *self);
int irlan_run_ctrl_tx_queue(struct irlan_cb *self); int irlan_run_ctrl_tx_queue(struct irlan_cb *self);
struct irlan_cb *irlan_get_any(void);
void irlan_get_provider_info(struct irlan_cb *self); void irlan_get_provider_info(struct irlan_cb *self);
void irlan_get_unicast_addr(struct irlan_cb *self); void irlan_get_unicast_addr(struct irlan_cb *self);
void irlan_get_media_char(struct irlan_cb *self); void irlan_get_media_char(struct irlan_cb *self);
...@@ -222,8 +221,6 @@ int irlan_insert_array_param(struct sk_buff *skb, char *name, __u8 *value, ...@@ -222,8 +221,6 @@ int irlan_insert_array_param(struct sk_buff *skb, char *name, __u8 *value,
int irlan_extract_param(__u8 *buf, char *name, char *value, __u16 *len); int irlan_extract_param(__u8 *buf, char *name, char *value, __u16 *len);
void print_ret_code(__u8 code); void print_ret_code(__u8 code);
extern hashbin_t *irlan;
#endif #endif
...@@ -154,7 +154,6 @@ void irlan_client_discovery_indication(discinfo_t *discovery, ...@@ -154,7 +154,6 @@ void irlan_client_discovery_indication(discinfo_t *discovery,
IRDA_DEBUG(1, "%s()\n", __FUNCTION__ ); IRDA_DEBUG(1, "%s()\n", __FUNCTION__ );
ASSERT(irlan != NULL, return;);
ASSERT(discovery != NULL, return;); ASSERT(discovery != NULL, return;);
/* /*
...@@ -170,7 +169,8 @@ void irlan_client_discovery_indication(discinfo_t *discovery, ...@@ -170,7 +169,8 @@ void irlan_client_discovery_indication(discinfo_t *discovery,
daddr = discovery->daddr; daddr = discovery->daddr;
/* Find instance */ /* Find instance */
self = (struct irlan_cb *) hashbin_get_first(irlan); rcu_read_lock();
self = irlan_get_any();
if (self) { if (self) {
ASSERT(self->magic == IRLAN_MAGIC, return;); ASSERT(self->magic == IRLAN_MAGIC, return;);
...@@ -179,6 +179,7 @@ void irlan_client_discovery_indication(discinfo_t *discovery, ...@@ -179,6 +179,7 @@ void irlan_client_discovery_indication(discinfo_t *discovery,
irlan_client_wakeup(self, saddr, daddr); irlan_client_wakeup(self, saddr, daddr);
} }
rcu_read_unlock();
} }
/* /*
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/rtnetlink.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/bitops.h> #include <asm/bitops.h>
...@@ -63,7 +64,8 @@ ...@@ -63,7 +64,8 @@
/* /*
* Master structure * Master structure
*/ */
hashbin_t *irlan = NULL; static LIST_HEAD(irlans);
static void *ckey; static void *ckey;
static void *skey; static void *skey;
...@@ -124,12 +126,6 @@ int __init irlan_init(void) ...@@ -124,12 +126,6 @@ int __init irlan_init(void)
__u16 hints; __u16 hints;
IRDA_DEBUG(0, "%s()\n", __FUNCTION__ ); IRDA_DEBUG(0, "%s()\n", __FUNCTION__ );
/* Allocate master structure */
irlan = hashbin_new(HB_LOCK); /* protect from /proc */
if (irlan == NULL) {
printk(KERN_WARNING "IrLAN: Can't allocate hashbin!\n");
return -ENOMEM;
}
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
create_proc_info_entry("irlan", 0, proc_irda, irlan_proc_read); create_proc_info_entry("irlan", 0, proc_irda, irlan_proc_read);
#endif /* CONFIG_PROC_FS */ #endif /* CONFIG_PROC_FS */
...@@ -158,6 +154,8 @@ int __init irlan_init(void) ...@@ -158,6 +154,8 @@ int __init irlan_init(void)
void __exit irlan_cleanup(void) void __exit irlan_cleanup(void)
{ {
struct irlan_cb *self, *next;
IRDA_DEBUG(4, "%s()\n", __FUNCTION__ ); IRDA_DEBUG(4, "%s()\n", __FUNCTION__ );
irlmp_unregister_client(ckey); irlmp_unregister_client(ckey);
...@@ -166,10 +164,13 @@ void __exit irlan_cleanup(void) ...@@ -166,10 +164,13 @@ void __exit irlan_cleanup(void)
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
remove_proc_entry("irlan", proc_irda); remove_proc_entry("irlan", proc_irda);
#endif /* CONFIG_PROC_FS */ #endif /* CONFIG_PROC_FS */
/*
* Delete hashbin and close all irlan client instances in it /* Cleanup any leftover network devices */
*/ rtnl_lock();
hashbin_delete(irlan, (FREE_FUNC) __irlan_close); list_for_each_entry_safe(self, next, &irlans, dev_list) {
__irlan_close(self);
}
rtnl_unlock();
} }
/* /*
...@@ -210,7 +211,6 @@ struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr) ...@@ -210,7 +211,6 @@ struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr)
struct irlan_cb *self; struct irlan_cb *self;
IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
ASSERT(irlan != NULL, return NULL;);
/* /*
* Initialize the irlan structure. * Initialize the irlan structure.
...@@ -243,7 +243,7 @@ struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr) ...@@ -243,7 +243,7 @@ struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr)
init_timer(&self->client.kick_timer); init_timer(&self->client.kick_timer);
init_waitqueue_head(&self->open_wait); init_waitqueue_head(&self->open_wait);
hashbin_insert(irlan, (irda_queue_t *) self, daddr, NULL); list_add_rcu(&self->dev_list, &irlans);
skb_queue_head_init(&self->client.txq); skb_queue_head_init(&self->client.txq);
...@@ -258,8 +258,7 @@ struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr) ...@@ -258,8 +258,7 @@ struct irlan_cb *irlan_open(__u32 saddr, __u32 daddr)
* Function __irlan_close (self) * Function __irlan_close (self)
* *
* This function closes and deallocates the IrLAN client instances. Be * This function closes and deallocates the IrLAN client instances. Be
* aware that other functions which calles client_close() must call * aware that other functions which calles client_close()
* hashbin_remove() first!!!
*/ */
static void __irlan_close(struct irlan_cb *self) static void __irlan_close(struct irlan_cb *self)
{ {
...@@ -267,6 +266,7 @@ static void __irlan_close(struct irlan_cb *self) ...@@ -267,6 +266,7 @@ static void __irlan_close(struct irlan_cb *self)
IRDA_DEBUG(2, "%s()\n", __FUNCTION__ ); IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
ASSERT_RTNL();
ASSERT(self != NULL, return;); ASSERT(self != NULL, return;);
ASSERT(self->magic == IRLAN_MAGIC, return;); ASSERT(self->magic == IRLAN_MAGIC, return;);
...@@ -283,12 +283,23 @@ static void __irlan_close(struct irlan_cb *self) ...@@ -283,12 +283,23 @@ static void __irlan_close(struct irlan_cb *self)
while ((skb = skb_dequeue(&self->client.txq))) while ((skb = skb_dequeue(&self->client.txq)))
dev_kfree_skb(skb); dev_kfree_skb(skb);
unregister_netdev(&self->dev); unregister_netdevice(&self->dev);
self->magic = 0; self->magic = 0;
kfree(self); kfree(self);
} }
/* Find any instance of irlan, used for client discovery wakeup */
struct irlan_cb *irlan_get_any(void)
{
struct irlan_cb *self;
list_for_each_entry_rcu(self, &irlans, dev_list) {
return self;
}
return NULL;
}
/* /*
* Function irlan_connect_indication (instance, sap, qos, max_sdu_size, skb) * Function irlan_connect_indication (instance, sap, qos, max_sdu_size, skb)
* *
...@@ -1087,17 +1098,15 @@ int irlan_extract_param(__u8 *buf, char *name, char *value, __u16 *len) ...@@ -1087,17 +1098,15 @@ int irlan_extract_param(__u8 *buf, char *name, char *value, __u16 *len)
static int irlan_proc_read(char *buf, char **start, off_t offset, int len) static int irlan_proc_read(char *buf, char **start, off_t offset, int len)
{ {
struct irlan_cb *self; struct irlan_cb *self;
unsigned long flags;
ASSERT(irlan != NULL, return 0;);
len = 0; len = 0;
spin_lock_irqsave(&irlan->hb_spinlock, flags); rcu_read_lock();
len += sprintf(buf+len, "IrLAN instances:\n"); len += sprintf(buf+len, "IrLAN instances:\n");
self = (struct irlan_cb *) hashbin_get_first(irlan); list_for_each_entry_rcu(self, &irlans, dev_list) {
while (self != NULL) {
ASSERT(self->magic == IRLAN_MAGIC, break;); ASSERT(self->magic == IRLAN_MAGIC, break;);
len += sprintf(buf+len, "ifname: %s,\n", len += sprintf(buf+len, "ifname: %s,\n",
...@@ -1126,10 +1135,8 @@ static int irlan_proc_read(char *buf, char **start, off_t offset, int len) ...@@ -1126,10 +1135,8 @@ static int irlan_proc_read(char *buf, char **start, off_t offset, int len)
netif_queue_stopped(&self->dev) ? "TRUE" : "FALSE"); netif_queue_stopped(&self->dev) ? "TRUE" : "FALSE");
len += sprintf(buf+len, "\n"); len += sprintf(buf+len, "\n");
self = (struct irlan_cb *) hashbin_get_next(irlan);
} }
spin_unlock_irqrestore(&irlan->hb_spinlock, flags); rcu_read_unlock();
return len; return len;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment