~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux-2.6.17/kernel/intermodule.c

Version: ~ [ 2.6.16 ] ~ [ 2.6.17 ] ~
Architecture: ~ [ ia64 ] ~ [ i386 ] ~ [ arm ] ~ [ ppc ] ~ [ sparc64 ] ~

  1 /* Deprecated, do not use.  Moved from module.c to here. --RR */
  2 
  3 /* Written by Keith Owens <kaos@ocs.com.au> Oct 2000 */
  4 #include <linux/module.h>
  5 #include <linux/kmod.h>
  6 #include <linux/spinlock.h>
  7 #include <linux/list.h>
  8 #include <linux/slab.h>
  9 
 10 /* inter_module functions are always available, even when the kernel is
 11  * compiled without modules.  Consumers of inter_module_xxx routines
 12  * will always work, even when both are built into the kernel, this
 13  * approach removes lots of #ifdefs in mainline code.
 14  */
 15 
 16 static struct list_head ime_list = LIST_HEAD_INIT(ime_list);
 17 static DEFINE_SPINLOCK(ime_lock);
 18 static int kmalloc_failed;
 19 
 20 struct inter_module_entry {
 21         struct list_head list;
 22         const char *im_name;
 23         struct module *owner;
 24         const void *userdata;
 25 };
 26 
 27 /**
 28  * inter_module_register - register a new set of inter module data.
 29  * @im_name: an arbitrary string to identify the data, must be unique
 30  * @owner: module that is registering the data, always use THIS_MODULE
 31  * @userdata: pointer to arbitrary userdata to be registered
 32  *
 33  * Description: Check that the im_name has not already been registered,
 34  * complain if it has.  For new data, add it to the inter_module_entry
 35  * list.
 36  */
 37 void inter_module_register(const char *im_name, struct module *owner, const void *userdata)
 38 {
 39         struct list_head *tmp;
 40         struct inter_module_entry *ime, *ime_new;
 41 
 42         if (!(ime_new = kzalloc(sizeof(*ime), GFP_KERNEL))) {
 43                 /* Overloaded kernel, not fatal */
 44                 printk(KERN_ERR
 45                         "Aiee, inter_module_register: cannot kmalloc entry for '%s'\n",
 46                         im_name);
 47                 kmalloc_failed = 1;
 48                 return;
 49         }
 50         ime_new->im_name = im_name;
 51         ime_new->owner = owner;
 52         ime_new->userdata = userdata;
 53 
 54         spin_lock(&ime_lock);
 55         list_for_each(tmp, &ime_list) {
 56                 ime = list_entry(tmp, struct inter_module_entry, list);
 57                 if (strcmp(ime->im_name, im_name) == 0) {
 58                         spin_unlock(&ime_lock);
 59                         kfree(ime_new);
 60                         /* Program logic error, fatal */
 61                         printk(KERN_ERR "inter_module_register: duplicate im_name '%s'", im_name);
 62                         BUG();
 63                 }
 64         }
 65         list_add(&(ime_new->list), &ime_list);
 66         spin_unlock(&ime_lock);
 67 }
 68 
 69 /**
 70  * inter_module_unregister - unregister a set of inter module data.
 71  * @im_name: an arbitrary string to identify the data, must be unique
 72  *
 73  * Description: Check that the im_name has been registered, complain if
 74  * it has not.  For existing data, remove it from the
 75  * inter_module_entry list.
 76  */
 77 void inter_module_unregister(const char *im_name)
 78 {
 79         struct list_head *tmp;
 80         struct inter_module_entry *ime;
 81 
 82         spin_lock(&ime_lock);
 83         list_for_each(tmp, &ime_list) {
 84                 ime = list_entry(tmp, struct inter_module_entry, list);
 85                 if (strcmp(ime->im_name, im_name) == 0) {
 86                         list_del(&(ime->list));
 87                         spin_unlock(&ime_lock);
 88                         kfree(ime);
 89                         return;
 90                 }
 91         }
 92         spin_unlock(&ime_lock);
 93         if (kmalloc_failed) {
 94                 printk(KERN_ERR
 95                         "inter_module_unregister: no entry for '%s', "
 96                         "probably caused by previous kmalloc failure\n",
 97                         im_name);
 98                 return;
 99         }
100         else {
101                 /* Program logic error, fatal */
102                 printk(KERN_ERR "inter_module_unregister: no entry for '%s'", im_name);
103                 BUG();
104         }
105 }
106 
107 /**
108  * inter_module_get - return arbitrary userdata from another module.
109  * @im_name: an arbitrary string to identify the data, must be unique
110  *
111  * Description: If the im_name has not been registered, return NULL.
112  * Try to increment the use count on the owning module, if that fails
113  * then return NULL.  Otherwise return the userdata.
114  */
115 static const void *inter_module_get(const char *im_name)
116 {
117         struct list_head *tmp;
118         struct inter_module_entry *ime;
119         const void *result = NULL;
120 
121         spin_lock(&ime_lock);
122         list_for_each(tmp, &ime_list) {
123                 ime = list_entry(tmp, struct inter_module_entry, list);
124                 if (strcmp(ime->im_name, im_name) == 0) {
125                         if (try_module_get(ime->owner))
126                                 result = ime->userdata;
127                         break;
128                 }
129         }
130         spin_unlock(&ime_lock);
131         return(result);
132 }
133 
134 /**
135  * inter_module_get_request - im get with automatic request_module.
136  * @im_name: an arbitrary string to identify the data, must be unique
137  * @modname: module that is expected to register im_name
138  *
139  * Description: If inter_module_get fails, do request_module then retry.
140  */
141 const void *inter_module_get_request(const char *im_name, const char *modname)
142 {
143         const void *result = inter_module_get(im_name);
144         if (!result) {
145                 request_module("%s", modname);
146                 result = inter_module_get(im_name);
147         }
148         return(result);
149 }
150 
151 /**
152  * inter_module_put - release use of data from another module.
153  * @im_name: an arbitrary string to identify the data, must be unique
154  *
155  * Description: If the im_name has not been registered, complain,
156  * otherwise decrement the use count on the owning module.
157  */
158 void inter_module_put(const char *im_name)
159 {
160         struct list_head *tmp;
161         struct inter_module_entry *ime;
162 
163         spin_lock(&ime_lock);
164         list_for_each(tmp, &ime_list) {
165                 ime = list_entry(tmp, struct inter_module_entry, list);
166                 if (strcmp(ime->im_name, im_name) == 0) {
167                         if (ime->owner)
168                                 module_put(ime->owner);
169                         spin_unlock(&ime_lock);
170                         return;
171                 }
172         }
173         spin_unlock(&ime_lock);
174         printk(KERN_ERR "inter_module_put: no entry for '%s'", im_name);
175         BUG();
176 }
177 
178 EXPORT_SYMBOL(inter_module_register);
179 EXPORT_SYMBOL(inter_module_unregister);
180 EXPORT_SYMBOL(inter_module_get_request);
181 EXPORT_SYMBOL(inter_module_put);
182 
183 MODULE_LICENSE("GPL");
184 
185 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.