diff options
Diffstat (limited to 'drivers/staging/ozwpan/ozproto.c')
-rw-r--r-- | drivers/staging/ozwpan/ozproto.c | 41 |
1 files changed, 27 insertions, 14 deletions
diff --git a/drivers/staging/ozwpan/ozproto.c b/drivers/staging/ozwpan/ozproto.c index 110205599190..3d3a3a890f73 100644 --- a/drivers/staging/ozwpan/ozproto.c +++ b/drivers/staging/ozwpan/ozproto.c @@ -11,6 +11,7 @@ #include <linux/etherdevice.h> #include <linux/errno.h> #include <linux/ieee80211.h> +#include <linux/slab.h> #include "ozdbg.h" #include "ozprotocol.h" #include "ozeltbuf.h" @@ -29,8 +30,6 @@ #define OZ_DO_STOP 1 #define OZ_DO_SLEEP 2 -#define OZ_MAX_TIMER_POOL_SIZE 16 - struct oz_binding { struct packet_type ptype; char name[OZ_MAX_BINDING_LEN]; @@ -53,6 +52,9 @@ static u8 g_session_id; static u16 g_apps = 0x1; static int g_processing_rx; +struct kmem_cache *oz_elt_info_cache; +struct kmem_cache *oz_tx_frame_cache; + /* * Context: softirq-serialized */ @@ -110,7 +112,6 @@ static void oz_send_conn_rsp(struct oz_pd *pd, u8 status) } oz_dbg(ON, "TX: OZ_ELT_CONNECT_RSP %d", status); dev_queue_xmit(skb); - return; } /* @@ -177,13 +178,14 @@ static struct oz_pd *oz_connect_req(struct oz_pd *cur_pd, struct oz_elt *elt, } else { struct oz_pd *pd2 = NULL; struct list_head *e; + pd = oz_pd_alloc(pd_addr); if (pd == NULL) return NULL; getnstimeofday(&pd->last_rx_timestamp); spin_lock_bh(&g_polling_lock); list_for_each(e, &g_pd_list) { - pd2 = container_of(e, struct oz_pd, link); + pd2 = list_entry(e, struct oz_pd, link); if (ether_addr_equal(pd2->mac_addr, pd_addr)) { free_pd = pd; pd = pd2; @@ -260,6 +262,7 @@ done: u16 start_apps = new_apps & ~pd->total_apps & ~0x1; u16 stop_apps = pd->total_apps & ~new_apps & ~0x1; u16 resume_apps = new_apps & pd->paused_apps & ~0x1; + spin_unlock_bh(&g_polling_lock); oz_pd_set_state(pd, OZ_PD_S_CONNECTED); oz_dbg(ON, "new_apps=0x%x total_apps=0x%x paused_apps=0x%x\n", @@ -381,6 +384,7 @@ static void oz_rx_frame(struct sk_buff *skb) if ((oz_hdr->control & OZ_F_ACK_REQUESTED) && (pd->state == OZ_PD_S_CONNECTED)) { int backlog = pd->nb_queued_frames; + pd->trigger_pkt_num = pkt_num; /* Send queued frames */ oz_send_queued_frames(pd, backlog); @@ -481,6 +485,9 @@ void oz_protocol_term(void) } spin_unlock_bh(&g_polling_lock); oz_dbg(ON, "Protocol stopped\n"); + + kmem_cache_destroy(oz_tx_frame_cache); + kmem_cache_destroy(oz_elt_info_cache); } /* @@ -596,13 +603,11 @@ void oz_pd_request_heartbeat(struct oz_pd *pd) struct oz_pd *oz_pd_find(const u8 *mac_addr) { struct oz_pd *pd; - struct list_head *e; spin_lock_bh(&g_polling_lock); - list_for_each(e, &g_pd_list) { - pd = container_of(e, struct oz_pd, link); + list_for_each_entry(pd, &g_pd_list, link) { if (ether_addr_equal(pd->mac_addr, mac_addr)) { - atomic_inc(&pd->ref_count); + oz_pd_get(pd); spin_unlock_bh(&g_polling_lock); return pd; } @@ -616,7 +621,7 @@ struct oz_pd *oz_pd_find(const u8 *mac_addr) */ void oz_app_enable(int app_id, int enable) { - if (app_id <= OZ_APPID_MAX) { + if (app_id < OZ_NB_APPS) { spin_lock_bh(&g_polling_lock); if (enable) g_apps |= (1<<app_id); @@ -695,11 +700,10 @@ void oz_binding_add(const char *net_dev) */ static void pd_stop_all_for_device(struct net_device *net_dev) { - struct list_head h; + LIST_HEAD(h); struct oz_pd *pd; struct oz_pd *n; - INIT_LIST_HEAD(&h); spin_lock_bh(&g_polling_lock); list_for_each_entry_safe(pd, n, &g_pd_list, link) { if (pd->net_dev == net_dev) { @@ -764,11 +768,22 @@ static char *oz_get_next_device_name(char *s, char *dname, int max_size) */ int oz_protocol_init(char *devs) { + oz_elt_info_cache = KMEM_CACHE(oz_elt_info, 0); + if (!oz_elt_info_cache) + return -ENOMEM; + + oz_tx_frame_cache = KMEM_CACHE(oz_tx_frame, 0); + if (!oz_tx_frame_cache) { + kmem_cache_destroy(oz_elt_info_cache); + return -ENOMEM; + } + skb_queue_head_init(&g_rx_queue); if (devs[0] == '*') { oz_binding_add(NULL); } else { char d[32]; + while (*devs) { devs = oz_get_next_device_name(devs, d, sizeof(d)); if (d[0]) @@ -784,14 +799,12 @@ int oz_protocol_init(char *devs) int oz_get_pd_list(struct oz_mac_addr *addr, int max_count) { struct oz_pd *pd; - struct list_head *e; int count = 0; spin_lock_bh(&g_polling_lock); - list_for_each(e, &g_pd_list) { + list_for_each_entry(pd, &g_pd_list, link) { if (count >= max_count) break; - pd = container_of(e, struct oz_pd, link); ether_addr_copy((u8 *)&addr[count++], pd->mac_addr); } spin_unlock_bh(&g_polling_lock); |