2007-05-05 22:45:53 +04:00
/*
* Copyright 2002 - 2005 , Instant802 Networks , Inc .
* Copyright 2005 - 2006 , Devicescape Software , Inc .
* Copyright ( c ) 2006 Jiri Benc < jbenc @ suse . cz >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*/
# include <linux/kernel.h>
# include "ieee80211_rate.h"
# include "ieee80211_i.h"
struct rate_control_alg {
struct list_head list ;
struct rate_control_ops * ops ;
} ;
static LIST_HEAD ( rate_ctrl_algs ) ;
static DEFINE_MUTEX ( rate_ctrl_mutex ) ;
int ieee80211_rate_control_register ( struct rate_control_ops * ops )
{
struct rate_control_alg * alg ;
some kmalloc/memset ->kzalloc (tree wide)
Transform some calls to kmalloc/memset to a single kzalloc (or kcalloc).
Here is a short excerpt of the semantic patch performing
this transformation:
@@
type T2;
expression x;
identifier f,fld;
expression E;
expression E1,E2;
expression e1,e2,e3,y;
statement S;
@@
x =
- kmalloc
+ kzalloc
(E1,E2)
... when != \(x->fld=E;\|y=f(...,x,...);\|f(...,x,...);\|x=E;\|while(...) S\|for(e1;e2;e3) S\)
- memset((T2)x,0,E1);
@@
expression E1,E2,E3;
@@
- kzalloc(E1 * E2,E3)
+ kcalloc(E1,E2,E3)
[akpm@linux-foundation.org: get kcalloc args the right way around]
Signed-off-by: Yoann Padioleau <padator@wanadoo.fr>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Acked-by: Russell King <rmk@arm.linux.org.uk>
Cc: Bryan Wu <bryan.wu@analog.com>
Acked-by: Jiri Slaby <jirislaby@gmail.com>
Cc: Dave Airlie <airlied@linux.ie>
Acked-by: Roland Dreier <rolandd@cisco.com>
Cc: Jiri Kosina <jkosina@suse.cz>
Acked-by: Dmitry Torokhov <dtor@mail.ru>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Acked-by: Pierre Ossman <drzeus-list@drzeus.cx>
Cc: Jeff Garzik <jeff@garzik.org>
Cc: "David S. Miller" <davem@davemloft.net>
Acked-by: Greg KH <greg@kroah.com>
Cc: James Bottomley <James.Bottomley@steeleye.com>
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2007-07-19 12:49:03 +04:00
alg = kzalloc ( sizeof ( * alg ) , GFP_KERNEL ) ;
2007-05-05 22:45:53 +04:00
if ( alg = = NULL ) {
return - ENOMEM ;
}
alg - > ops = ops ;
mutex_lock ( & rate_ctrl_mutex ) ;
list_add_tail ( & alg - > list , & rate_ctrl_algs ) ;
mutex_unlock ( & rate_ctrl_mutex ) ;
return 0 ;
}
EXPORT_SYMBOL ( ieee80211_rate_control_register ) ;
void ieee80211_rate_control_unregister ( struct rate_control_ops * ops )
{
struct rate_control_alg * alg ;
mutex_lock ( & rate_ctrl_mutex ) ;
list_for_each_entry ( alg , & rate_ctrl_algs , list ) {
if ( alg - > ops = = ops ) {
list_del ( & alg - > list ) ;
break ;
}
}
mutex_unlock ( & rate_ctrl_mutex ) ;
kfree ( alg ) ;
}
EXPORT_SYMBOL ( ieee80211_rate_control_unregister ) ;
static struct rate_control_ops *
ieee80211_try_rate_control_ops_get ( const char * name )
{
struct rate_control_alg * alg ;
struct rate_control_ops * ops = NULL ;
mutex_lock ( & rate_ctrl_mutex ) ;
list_for_each_entry ( alg , & rate_ctrl_algs , list ) {
if ( ! name | | ! strcmp ( alg - > ops - > name , name ) )
if ( try_module_get ( alg - > ops - > module ) ) {
ops = alg - > ops ;
break ;
}
}
mutex_unlock ( & rate_ctrl_mutex ) ;
return ops ;
}
/* Get the rate control algorithm. If `name' is NULL, get the first
* available algorithm . */
static struct rate_control_ops *
ieee80211_rate_control_ops_get ( const char * name )
{
struct rate_control_ops * ops ;
ops = ieee80211_try_rate_control_ops_get ( name ) ;
if ( ! ops ) {
request_module ( " rc80211_%s " , name ? name : " default " ) ;
ops = ieee80211_try_rate_control_ops_get ( name ) ;
}
return ops ;
}
static void ieee80211_rate_control_ops_put ( struct rate_control_ops * ops )
{
module_put ( ops - > module ) ;
}
struct rate_control_ref * rate_control_alloc ( const char * name ,
struct ieee80211_local * local )
{
struct rate_control_ref * ref ;
ref = kmalloc ( sizeof ( struct rate_control_ref ) , GFP_KERNEL ) ;
if ( ! ref )
goto fail_ref ;
kref_init ( & ref - > kref ) ;
ref - > ops = ieee80211_rate_control_ops_get ( name ) ;
if ( ! ref - > ops )
goto fail_ops ;
ref - > priv = ref - > ops - > alloc ( local ) ;
if ( ! ref - > priv )
goto fail_priv ;
return ref ;
fail_priv :
ieee80211_rate_control_ops_put ( ref - > ops ) ;
fail_ops :
kfree ( ref ) ;
fail_ref :
return NULL ;
}
static void rate_control_release ( struct kref * kref )
{
struct rate_control_ref * ctrl_ref ;
ctrl_ref = container_of ( kref , struct rate_control_ref , kref ) ;
ctrl_ref - > ops - > free ( ctrl_ref - > priv ) ;
ieee80211_rate_control_ops_put ( ctrl_ref - > ops ) ;
kfree ( ctrl_ref ) ;
}
struct rate_control_ref * rate_control_get ( struct rate_control_ref * ref )
{
kref_get ( & ref - > kref ) ;
return ref ;
}
void rate_control_put ( struct rate_control_ref * ref )
{
kref_put ( & ref - > kref , rate_control_release ) ;
}