aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-03-21 12:25:15 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-21 12:25:15 -0500
commit08a4ecee986dd98e86090ff5faac4782b6765aed (patch)
tree74df5de49f38c432a6a18303b0c6d834fd09028f
parentba93c6297b9cfad5a70b5e5ed13c9dbead6601d3 (diff)
parentb3229087c5e08589cea4f5040dab56f7dc11332a (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6: (23 commits) [PATCH] sysfs: fix a kobject leak in sysfs_add_link on the error path [PATCH] sysfs: don't export dir symbols [PATCH] get_cpu_sysdev() signedness fix [PATCH] kobject_add_dir [PATCH] debugfs: Add debugfs_create_blob() helper for exporting binary data [PATCH] sysfs: fix problem with duplicate sysfs directories and files [PATCH] Kobject: kobject.h: fix a typo [PATCH] Kobject: provide better warning messages when people do stupid things [PATCH] Driver core: add macros notice(), dev_notice() [PATCH] firmware: fix BUG: in fw_realloc_buffer [PATCH] sysfs: kzalloc conversion [PATCH] fix module sysfs files reference counting [PATCH] add EXPORT_SYMBOL_GPL_FUTURE() to USB subsystem [PATCH] add EXPORT_SYMBOL_GPL_FUTURE() to RCU subsystem [PATCH] add EXPORT_SYMBOL_GPL_FUTURE() [PATCH] Clean up module.c symbol searching logic [PATCH] kobj_map semaphore to mutex conversion [PATCH] kref: avoid an atomic operation in kref_put() [PATCH] handle errors returned by platform_get_irq*() [PATCH] driver core: platform_get_irq*(): return -ENXIO on error ...
-rw-r--r--Documentation/feature-removal-schedule.txt18
-rw-r--r--arch/arm/common/locomo.c2
-rw-r--r--arch/arm/common/sa1111.c2
-rw-r--r--arch/m68knommu/kernel/vmlinux.lds.S10
-rw-r--r--arch/v850/kernel/vmlinux.lds.S8
-rw-r--r--block/genhd.c31
-rw-r--r--drivers/base/cpu.c2
-rw-r--r--drivers/base/firmware_class.c6
-rw-r--r--drivers/base/map.c21
-rw-r--r--drivers/base/platform.c4
-rw-r--r--drivers/char/s3c2410-rtc.c4
-rw-r--r--drivers/char/watchdog/mpcore_wdt.c4
-rw-r--r--drivers/i2c/busses/i2c-iop3xx.c9
-rw-r--r--drivers/i2c/busses/i2c-mpc.c5
-rw-r--r--drivers/i2c/busses/i2c-mv64xxx.c4
-rw-r--r--drivers/ide/mips/au1xxx-ide.c5
-rw-r--r--drivers/mmc/pxamci.c2
-rw-r--r--drivers/net/arm/am79c961a.c4
-rw-r--r--drivers/net/fs_enet/mac-fcc.c2
-rw-r--r--drivers/net/fs_enet/mac-fec.c2
-rw-r--r--drivers/net/fs_enet/mac-scc.c2
-rw-r--r--drivers/net/gianfar.c4
-rw-r--r--drivers/net/smc91x.c4
-rw-r--r--drivers/pcmcia/omap_cf.c2
-rw-r--r--drivers/serial/s3c2410.c2
-rw-r--r--drivers/usb/core/driver.c6
-rw-r--r--drivers/usb/host/ohci-omap.c9
-rw-r--r--drivers/video/epson1355fb.c1
-rw-r--r--drivers/video/sa1100fb.c2
-rw-r--r--drivers/video/vfb.c1
-rw-r--r--fs/char_dev.c17
-rw-r--r--fs/debugfs/file.c46
-rw-r--r--fs/sysfs/dir.c37
-rw-r--r--fs/sysfs/file.c9
-rw-r--r--fs/sysfs/inode.c9
-rw-r--r--fs/sysfs/symlink.c6
-rw-r--r--fs/sysfs/sysfs.h1
-rw-r--r--include/asm-generic/vmlinux.lds.h14
-rw-r--r--include/linux/cpu.h2
-rw-r--r--include/linux/debugfs.h15
-rw-r--r--include/linux/device.h2
-rw-r--r--include/linux/kobj_map.h4
-rw-r--r--include/linux/kobject.h4
-rw-r--r--include/linux/module.h10
-rw-r--r--kernel/ksysfs.c3
-rw-r--r--kernel/module.c199
-rw-r--r--kernel/params.c10
-rw-r--r--kernel/rcupdate.c6
-rw-r--r--lib/kobject.c60
-rw-r--r--lib/kobject_uevent.c2
-rw-r--r--lib/kref.c7
-rw-r--r--scripts/genksyms/keywords.c_shipped91
-rw-r--r--scripts/genksyms/keywords.gperf1
53 files changed, 514 insertions, 219 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 28a31c5e2289..afeaf6218ea2 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -196,3 +196,21 @@ Why: Board specific code doesn't build anymore since ~2.6.0 and no
196 users have complained indicating there is no more need for these 196 users have complained indicating there is no more need for these
197 boards. This should really be considered a last call. 197 boards. This should really be considered a last call.
198Who: Ralf Baechle <ralf@linux-mips.org> 198Who: Ralf Baechle <ralf@linux-mips.org>
199
200---------------------------
201
202What: USB driver API moves to EXPORT_SYMBOL_GPL
203When: Febuary 2008
204Files: include/linux/usb.h, drivers/usb/core/driver.c
205Why: The USB subsystem has changed a lot over time, and it has been
206 possible to create userspace USB drivers using usbfs/libusb/gadgetfs
207 that operate as fast as the USB bus allows. Because of this, the USB
208 subsystem will not be allowing closed source kernel drivers to
209 register with it, after this grace period is over. If anyone needs
210 any help in converting their closed source drivers over to use the
211 userspace filesystems, please contact the
212 linux-usb-devel@lists.sourceforge.net mailing list, and the developers
213 there will be glad to help you out.
214Who: Greg Kroah-Hartman <gregkh@suse.de>
215
216---------------------------
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
index d31b1cb7eea0..23609400a8e2 100644
--- a/arch/arm/common/locomo.c
+++ b/arch/arm/common/locomo.c
@@ -788,6 +788,8 @@ static int locomo_probe(struct platform_device *dev)
788 if (!mem) 788 if (!mem)
789 return -EINVAL; 789 return -EINVAL;
790 irq = platform_get_irq(dev, 0); 790 irq = platform_get_irq(dev, 0);
791 if (irq < 0)
792 return -ENXIO;
791 793
792 return __locomo_probe(&dev->dev, mem, irq); 794 return __locomo_probe(&dev->dev, mem, irq);
793} 795}
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index 1475089f9b42..93352f6097c1 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -943,6 +943,8 @@ static int sa1111_probe(struct platform_device *pdev)
943 if (!mem) 943 if (!mem)
944 return -EINVAL; 944 return -EINVAL;
945 irq = platform_get_irq(pdev, 0); 945 irq = platform_get_irq(pdev, 0);
946 if (irq < 0)
947 return -ENXIO;
946 948
947 return __sa1111_probe(&pdev->dev, mem, irq); 949 return __sa1111_probe(&pdev->dev, mem, irq);
948} 950}
diff --git a/arch/m68knommu/kernel/vmlinux.lds.S b/arch/m68knommu/kernel/vmlinux.lds.S
index ac9de2661c0b..a331cc90797c 100644
--- a/arch/m68knommu/kernel/vmlinux.lds.S
+++ b/arch/m68knommu/kernel/vmlinux.lds.S
@@ -269,6 +269,11 @@ SECTIONS {
269 *(__ksymtab_gpl) 269 *(__ksymtab_gpl)
270 __stop___ksymtab_gpl = .; 270 __stop___ksymtab_gpl = .;
271 271
272 /* Kernel symbol table: GPL-future symbols */
273 __start___ksymtab_gpl_future = .;
274 *(__ksymtab_gpl_future)
275 __stop___ksymtab_gpl_future = .;
276
272 /* Kernel symbol table: Normal symbols */ 277 /* Kernel symbol table: Normal symbols */
273 __start___kcrctab = .; 278 __start___kcrctab = .;
274 *(__kcrctab) 279 *(__kcrctab)
@@ -279,6 +284,11 @@ SECTIONS {
279 *(__kcrctab_gpl) 284 *(__kcrctab_gpl)
280 __stop___kcrctab_gpl = .; 285 __stop___kcrctab_gpl = .;
281 286
287 /* Kernel symbol table: GPL-future symbols */
288 __start___kcrctab_gpl_future = .;
289 *(__kcrctab_gpl_future)
290 __stop___kcrctab_gpl_future = .;
291
282 /* Kernel symbol table: strings */ 292 /* Kernel symbol table: strings */
283 *(__ksymtab_strings) 293 *(__ksymtab_strings)
284 294
diff --git a/arch/v850/kernel/vmlinux.lds.S b/arch/v850/kernel/vmlinux.lds.S
index 5be05f47109e..5b2ffcc6e2b2 100644
--- a/arch/v850/kernel/vmlinux.lds.S
+++ b/arch/v850/kernel/vmlinux.lds.S
@@ -64,6 +64,10 @@
64 ___start___ksymtab_gpl = .; \ 64 ___start___ksymtab_gpl = .; \
65 *(__ksymtab_gpl) \ 65 *(__ksymtab_gpl) \
66 ___stop___ksymtab_gpl = .; \ 66 ___stop___ksymtab_gpl = .; \
67 /* Kernel symbol table: GPL-future symbols */ \
68 ___start___ksymtab_gpl_future = .; \
69 *(__ksymtab_gpl_future) \
70 ___stop___ksymtab_gpl_future = .; \
67 /* Kernel symbol table: strings */ \ 71 /* Kernel symbol table: strings */ \
68 *(__ksymtab_strings) \ 72 *(__ksymtab_strings) \
69 /* Kernel symbol table: Normal symbols */ \ 73 /* Kernel symbol table: Normal symbols */ \
@@ -74,6 +78,10 @@
74 ___start___kcrctab_gpl = .; \ 78 ___start___kcrctab_gpl = .; \
75 *(__kcrctab_gpl) \ 79 *(__kcrctab_gpl) \
76 ___stop___kcrctab_gpl = .; \ 80 ___stop___kcrctab_gpl = .; \
81 /* Kernel symbol table: GPL-future symbols */ \
82 ___start___kcrctab_gpl_future = .; \
83 *(__kcrctab_gpl_future) \
84 ___stop___kcrctab_gpl_future = .; \
77 /* Built-in module parameters */ \ 85 /* Built-in module parameters */ \
78 . = ALIGN (4) ; \ 86 . = ALIGN (4) ; \
79 ___start___param = .; \ 87 ___start___param = .; \
diff --git a/block/genhd.c b/block/genhd.c
index db57546a709d..64510fd88621 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -15,12 +15,13 @@
15#include <linux/kmod.h> 15#include <linux/kmod.h>
16#include <linux/kobj_map.h> 16#include <linux/kobj_map.h>
17#include <linux/buffer_head.h> 17#include <linux/buffer_head.h>
18#include <linux/mutex.h>
18 19
19#define MAX_PROBE_HASH 255 /* random */ 20#define MAX_PROBE_HASH 255 /* random */
20 21
21static struct subsystem block_subsys; 22static struct subsystem block_subsys;
22 23
23static DECLARE_MUTEX(block_subsys_sem); 24static DEFINE_MUTEX(block_subsys_lock);
24 25
25/* 26/*
26 * Can be deleted altogether. Later. 27 * Can be deleted altogether. Later.
@@ -46,7 +47,7 @@ struct blkdev_info {
46/* 47/*
47 * iterate over a list of blkdev_info structures. allows 48 * iterate over a list of blkdev_info structures. allows
48 * the major_names array to be iterated over from outside this file 49 * the major_names array to be iterated over from outside this file
49 * must be called with the block_subsys_sem held 50 * must be called with the block_subsys_lock held
50 */ 51 */
51void *get_next_blkdev(void *dev) 52void *get_next_blkdev(void *dev)
52{ 53{
@@ -85,20 +86,20 @@ out:
85 86
86void *acquire_blkdev_list(void) 87void *acquire_blkdev_list(void)
87{ 88{
88 down(&block_subsys_sem); 89 mutex_lock(&block_subsys_lock);
89 return get_next_blkdev(NULL); 90 return get_next_blkdev(NULL);
90} 91}
91 92
92void release_blkdev_list(void *dev) 93void release_blkdev_list(void *dev)
93{ 94{
94 up(&block_subsys_sem); 95 mutex_unlock(&block_subsys_lock);
95 kfree(dev); 96 kfree(dev);
96} 97}
97 98
98 99
99/* 100/*
100 * Count the number of records in the blkdev_list. 101 * Count the number of records in the blkdev_list.
101 * must be called with the block_subsys_sem held 102 * must be called with the block_subsys_lock held
102 */ 103 */
103int count_blkdev_list(void) 104int count_blkdev_list(void)
104{ 105{
@@ -118,7 +119,7 @@ int count_blkdev_list(void)
118/* 119/*
119 * extract the major and name values from a blkdev_info struct 120 * extract the major and name values from a blkdev_info struct
120 * passed in as a void to *dev. Must be called with 121 * passed in as a void to *dev. Must be called with
121 * block_subsys_sem held 122 * block_subsys_lock held
122 */ 123 */
123int get_blkdev_info(void *dev, int *major, char **name) 124int get_blkdev_info(void *dev, int *major, char **name)
124{ 125{
@@ -138,7 +139,7 @@ int register_blkdev(unsigned int major, const char *name)
138 struct blk_major_name **n, *p; 139 struct blk_major_name **n, *p;
139 int index, ret = 0; 140 int index, ret = 0;
140 141
141 down(&block_subsys_sem); 142 mutex_lock(&block_subsys_lock);
142 143
143 /* temporary */ 144 /* temporary */
144 if (major == 0) { 145 if (major == 0) {
@@ -183,7 +184,7 @@ int register_blkdev(unsigned int major, const char *name)
183 kfree(p); 184 kfree(p);
184 } 185 }
185out: 186out:
186 up(&block_subsys_sem); 187 mutex_unlock(&block_subsys_lock);
187 return ret; 188 return ret;
188} 189}
189 190
@@ -197,7 +198,7 @@ int unregister_blkdev(unsigned int major, const char *name)
197 int index = major_to_index(major); 198 int index = major_to_index(major);
198 int ret = 0; 199 int ret = 0;
199 200
200 down(&block_subsys_sem); 201 mutex_lock(&block_subsys_lock);
201 for (n = &major_names[index]; *n; n = &(*n)->next) 202 for (n = &major_names[index]; *n; n = &(*n)->next)
202 if ((*n)->major == major) 203 if ((*n)->major == major)
203 break; 204 break;
@@ -207,7 +208,7 @@ int unregister_blkdev(unsigned int major, const char *name)
207 p = *n; 208 p = *n;
208 *n = p->next; 209 *n = p->next;
209 } 210 }
210 up(&block_subsys_sem); 211 mutex_unlock(&block_subsys_lock);
211 kfree(p); 212 kfree(p);
212 213
213 return ret; 214 return ret;
@@ -301,7 +302,7 @@ static void *part_start(struct seq_file *part, loff_t *pos)
301 struct list_head *p; 302 struct list_head *p;
302 loff_t l = *pos; 303 loff_t l = *pos;
303 304
304 down(&block_subsys_sem); 305 mutex_lock(&block_subsys_lock);
305 list_for_each(p, &block_subsys.kset.list) 306 list_for_each(p, &block_subsys.kset.list)
306 if (!l--) 307 if (!l--)
307 return list_entry(p, struct gendisk, kobj.entry); 308 return list_entry(p, struct gendisk, kobj.entry);
@@ -318,7 +319,7 @@ static void *part_next(struct seq_file *part, void *v, loff_t *pos)
318 319
319static void part_stop(struct seq_file *part, void *v) 320static void part_stop(struct seq_file *part, void *v)
320{ 321{
321 up(&block_subsys_sem); 322 mutex_unlock(&block_subsys_lock);
322} 323}
323 324
324static int show_partition(struct seq_file *part, void *v) 325static int show_partition(struct seq_file *part, void *v)
@@ -377,7 +378,7 @@ static struct kobject *base_probe(dev_t dev, int *part, void *data)
377 378
378static int __init genhd_device_init(void) 379static int __init genhd_device_init(void)
379{ 380{
380 bdev_map = kobj_map_init(base_probe, &block_subsys_sem); 381 bdev_map = kobj_map_init(base_probe, &block_subsys_lock);
381 blk_dev_init(); 382 blk_dev_init();
382 subsystem_register(&block_subsys); 383 subsystem_register(&block_subsys);
383 return 0; 384 return 0;
@@ -611,7 +612,7 @@ static void *diskstats_start(struct seq_file *part, loff_t *pos)
611 loff_t k = *pos; 612 loff_t k = *pos;
612 struct list_head *p; 613 struct list_head *p;
613 614
614 down(&block_subsys_sem); 615 mutex_lock(&block_subsys_lock);
615 list_for_each(p, &block_subsys.kset.list) 616 list_for_each(p, &block_subsys.kset.list)
616 if (!k--) 617 if (!k--)
617 return list_entry(p, struct gendisk, kobj.entry); 618 return list_entry(p, struct gendisk, kobj.entry);
@@ -628,7 +629,7 @@ static void *diskstats_next(struct seq_file *part, void *v, loff_t *pos)
628 629
629static void diskstats_stop(struct seq_file *part, void *v) 630static void diskstats_stop(struct seq_file *part, void *v)
630{ 631{
631 up(&block_subsys_sem); 632 mutex_unlock(&block_subsys_lock);
632} 633}
633 634
634static int diskstats_show(struct seq_file *s, void *v) 635static int diskstats_show(struct seq_file *s, void *v)
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 07a7f97e1de9..29f3d7504da1 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -141,7 +141,7 @@ int __devinit register_cpu(struct cpu *cpu, int num, struct node *root)
141 return error; 141 return error;
142} 142}
143 143
144struct sys_device *get_cpu_sysdev(int cpu) 144struct sys_device *get_cpu_sysdev(unsigned cpu)
145{ 145{
146 if (cpu < NR_CPUS) 146 if (cpu < NR_CPUS)
147 return cpu_sys_devices[cpu]; 147 return cpu_sys_devices[cpu];
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index e97e911ebf7a..472318205236 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -211,18 +211,20 @@ static int
211fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size) 211fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
212{ 212{
213 u8 *new_data; 213 u8 *new_data;
214 int new_size = fw_priv->alloc_size;
214 215
215 if (min_size <= fw_priv->alloc_size) 216 if (min_size <= fw_priv->alloc_size)
216 return 0; 217 return 0;
217 218
218 new_data = vmalloc(fw_priv->alloc_size + PAGE_SIZE); 219 new_size = ALIGN(min_size, PAGE_SIZE);
220 new_data = vmalloc(new_size);
219 if (!new_data) { 221 if (!new_data) {
220 printk(KERN_ERR "%s: unable to alloc buffer\n", __FUNCTION__); 222 printk(KERN_ERR "%s: unable to alloc buffer\n", __FUNCTION__);
221 /* Make sure that we don't keep incomplete data */ 223 /* Make sure that we don't keep incomplete data */
222 fw_load_abort(fw_priv); 224 fw_load_abort(fw_priv);
223 return -ENOMEM; 225 return -ENOMEM;
224 } 226 }
225 fw_priv->alloc_size += PAGE_SIZE; 227 fw_priv->alloc_size = new_size;
226 if (fw_priv->fw->data) { 228 if (fw_priv->fw->data) {
227 memcpy(new_data, fw_priv->fw->data, fw_priv->fw->size); 229 memcpy(new_data, fw_priv->fw->data, fw_priv->fw->size);
228 vfree(fw_priv->fw->data); 230 vfree(fw_priv->fw->data);
diff --git a/drivers/base/map.c b/drivers/base/map.c
index b449dae6f0d3..e87017f36853 100644
--- a/drivers/base/map.c
+++ b/drivers/base/map.c
@@ -11,6 +11,7 @@
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include <linux/mutex.h>
14#include <linux/kdev_t.h> 15#include <linux/kdev_t.h>
15#include <linux/kobject.h> 16#include <linux/kobject.h>
16#include <linux/kobj_map.h> 17#include <linux/kobj_map.h>
@@ -25,7 +26,7 @@ struct kobj_map {
25 int (*lock)(dev_t, void *); 26 int (*lock)(dev_t, void *);
26 void *data; 27 void *data;
27 } *probes[255]; 28 } *probes[255];
28 struct semaphore *sem; 29 struct mutex *lock;
29}; 30};
30 31
31int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range, 32int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range,
@@ -53,7 +54,7 @@ int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range,
53 p->range = range; 54 p->range = range;
54 p->data = data; 55 p->data = data;
55 } 56 }
56 down(domain->sem); 57 mutex_lock(domain->lock);
57 for (i = 0, p -= n; i < n; i++, p++, index++) { 58 for (i = 0, p -= n; i < n; i++, p++, index++) {
58 struct probe **s = &domain->probes[index % 255]; 59 struct probe **s = &domain->probes[index % 255];
59 while (*s && (*s)->range < range) 60 while (*s && (*s)->range < range)
@@ -61,7 +62,7 @@ int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range,
61 p->next = *s; 62 p->next = *s;
62 *s = p; 63 *s = p;
63 } 64 }
64 up(domain->sem); 65 mutex_unlock(domain->lock);
65 return 0; 66 return 0;
66} 67}
67 68
@@ -75,7 +76,7 @@ void kobj_unmap(struct kobj_map *domain, dev_t dev, unsigned long range)
75 if (n > 255) 76 if (n > 255)
76 n = 255; 77 n = 255;
77 78
78 down(domain->sem); 79 mutex_lock(domain->lock);
79 for (i = 0; i < n; i++, index++) { 80 for (i = 0; i < n; i++, index++) {
80 struct probe **s; 81 struct probe **s;
81 for (s = &domain->probes[index % 255]; *s; s = &(*s)->next) { 82 for (s = &domain->probes[index % 255]; *s; s = &(*s)->next) {
@@ -88,7 +89,7 @@ void kobj_unmap(struct kobj_map *domain, dev_t dev, unsigned long range)
88 } 89 }
89 } 90 }
90 } 91 }
91 up(domain->sem); 92 mutex_unlock(domain->lock);
92 kfree(found); 93 kfree(found);
93} 94}
94 95
@@ -99,7 +100,7 @@ struct kobject *kobj_lookup(struct kobj_map *domain, dev_t dev, int *index)
99 unsigned long best = ~0UL; 100 unsigned long best = ~0UL;
100 101
101retry: 102retry:
102 down(domain->sem); 103 mutex_lock(domain->lock);
103 for (p = domain->probes[MAJOR(dev) % 255]; p; p = p->next) { 104 for (p = domain->probes[MAJOR(dev) % 255]; p; p = p->next) {
104 struct kobject *(*probe)(dev_t, int *, void *); 105 struct kobject *(*probe)(dev_t, int *, void *);
105 struct module *owner; 106 struct module *owner;
@@ -120,7 +121,7 @@ retry:
120 module_put(owner); 121 module_put(owner);
121 continue; 122 continue;
122 } 123 }
123 up(domain->sem); 124 mutex_unlock(domain->lock);
124 kobj = probe(dev, index, data); 125 kobj = probe(dev, index, data);
125 /* Currently ->owner protects _only_ ->probe() itself. */ 126 /* Currently ->owner protects _only_ ->probe() itself. */
126 module_put(owner); 127 module_put(owner);
@@ -128,11 +129,11 @@ retry:
128 return kobj; 129 return kobj;
129 goto retry; 130 goto retry;
130 } 131 }
131 up(domain->sem); 132 mutex_unlock(domain->lock);
132 return NULL; 133 return NULL;
133} 134}
134 135
135struct kobj_map *kobj_map_init(kobj_probe_t *base_probe, struct semaphore *sem) 136struct kobj_map *kobj_map_init(kobj_probe_t *base_probe, struct mutex *lock)
136{ 137{
137 struct kobj_map *p = kmalloc(sizeof(struct kobj_map), GFP_KERNEL); 138 struct kobj_map *p = kmalloc(sizeof(struct kobj_map), GFP_KERNEL);
138 struct probe *base = kzalloc(sizeof(*base), GFP_KERNEL); 139 struct probe *base = kzalloc(sizeof(*base), GFP_KERNEL);
@@ -149,6 +150,6 @@ struct kobj_map *kobj_map_init(kobj_probe_t *base_probe, struct semaphore *sem)
149 base->get = base_probe; 150 base->get = base_probe;
150 for (i = 0; i < 255; i++) 151 for (i = 0; i < 255; i++)
151 p->probes[i] = base; 152 p->probes[i] = base;
152 p->sem = sem; 153 p->lock = lock;
153 return p; 154 return p;
154} 155}
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 461554a02517..89b268321321 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -61,7 +61,7 @@ int platform_get_irq(struct platform_device *dev, unsigned int num)
61{ 61{
62 struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num); 62 struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num);
63 63
64 return r ? r->start : 0; 64 return r ? r->start : -ENXIO;
65} 65}
66EXPORT_SYMBOL_GPL(platform_get_irq); 66EXPORT_SYMBOL_GPL(platform_get_irq);
67 67
@@ -98,7 +98,7 @@ int platform_get_irq_byname(struct platform_device *dev, char *name)
98{ 98{
99 struct resource *r = platform_get_resource_byname(dev, IORESOURCE_IRQ, name); 99 struct resource *r = platform_get_resource_byname(dev, IORESOURCE_IRQ, name);
100 100
101 return r ? r->start : 0; 101 return r ? r->start : -ENXIO;
102} 102}
103EXPORT_SYMBOL_GPL(platform_get_irq_byname); 103EXPORT_SYMBOL_GPL(platform_get_irq_byname);
104 104
diff --git a/drivers/char/s3c2410-rtc.c b/drivers/char/s3c2410-rtc.c
index 2e308657f6f6..b0038b19b505 100644
--- a/drivers/char/s3c2410-rtc.c
+++ b/drivers/char/s3c2410-rtc.c
@@ -448,13 +448,13 @@ static int s3c2410_rtc_probe(struct platform_device *pdev)
448 /* find the IRQs */ 448 /* find the IRQs */
449 449
450 s3c2410_rtc_tickno = platform_get_irq(pdev, 1); 450 s3c2410_rtc_tickno = platform_get_irq(pdev, 1);
451 if (s3c2410_rtc_tickno <= 0) { 451 if (s3c2410_rtc_tickno < 0) {
452 dev_err(&pdev->dev, "no irq for rtc tick\n"); 452 dev_err(&pdev->dev, "no irq for rtc tick\n");
453 return -ENOENT; 453 return -ENOENT;
454 } 454 }
455 455
456 s3c2410_rtc_alarmno = platform_get_irq(pdev, 0); 456 s3c2410_rtc_alarmno = platform_get_irq(pdev, 0);
457 if (s3c2410_rtc_alarmno <= 0) { 457 if (s3c2410_rtc_alarmno < 0) {
458 dev_err(&pdev->dev, "no irq for alarm\n"); 458 dev_err(&pdev->dev, "no irq for alarm\n");
459 return -ENOENT; 459 return -ENOENT;
460 } 460 }
diff --git a/drivers/char/watchdog/mpcore_wdt.c b/drivers/char/watchdog/mpcore_wdt.c
index b4d843489881..2c2c51773200 100644
--- a/drivers/char/watchdog/mpcore_wdt.c
+++ b/drivers/char/watchdog/mpcore_wdt.c
@@ -338,6 +338,10 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev)
338 338
339 wdt->dev = &dev->dev; 339 wdt->dev = &dev->dev;
340 wdt->irq = platform_get_irq(dev, 0); 340 wdt->irq = platform_get_irq(dev, 0);
341 if (wdt->irq < 0) {
342 ret = -ENXIO;
343 goto err_free;
344 }
341 wdt->base = ioremap(res->start, res->end - res->start + 1); 345 wdt->base = ioremap(res->start, res->end - res->start + 1);
342 if (!wdt->base) { 346 if (!wdt->base) {
343 ret = -ENOMEM; 347 ret = -ENOMEM;
diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c
index 1414851a17b8..d00a02fc23e4 100644
--- a/drivers/i2c/busses/i2c-iop3xx.c
+++ b/drivers/i2c/busses/i2c-iop3xx.c
@@ -434,7 +434,7 @@ static int
434iop3xx_i2c_probe(struct platform_device *pdev) 434iop3xx_i2c_probe(struct platform_device *pdev)
435{ 435{
436 struct resource *res; 436 struct resource *res;
437 int ret; 437 int ret, irq;
438 struct i2c_adapter *new_adapter; 438 struct i2c_adapter *new_adapter;
439 struct i2c_algo_iop3xx_data *adapter_data; 439 struct i2c_algo_iop3xx_data *adapter_data;
440 440
@@ -470,7 +470,12 @@ iop3xx_i2c_probe(struct platform_device *pdev)
470 goto release_region; 470 goto release_region;
471 } 471 }
472 472
473 ret = request_irq(platform_get_irq(pdev, 0), iop3xx_i2c_irq_handler, 0, 473 irq = platform_get_irq(pdev, 0);
474 if (irq < 0) {
475 ret = -ENXIO;
476 goto unmap;
477 }
478 ret = request_irq(irq, iop3xx_i2c_irq_handler, 0,
474 pdev->name, adapter_data); 479 pdev->name, adapter_data);
475 480
476 if (ret) { 481 if (ret) {
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index 5ccd338a9dc9..2721e4c8184a 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -302,6 +302,10 @@ static int fsl_i2c_probe(struct platform_device *pdev)
302 } 302 }
303 303
304 i2c->irq = platform_get_irq(pdev, 0); 304 i2c->irq = platform_get_irq(pdev, 0);
305 if (i2c->irq < 0) {
306 result = -ENXIO;
307 goto fail_get_irq;
308 }
305 i2c->flags = pdata->device_flags; 309 i2c->flags = pdata->device_flags;
306 init_waitqueue_head(&i2c->queue); 310 init_waitqueue_head(&i2c->queue);
307 311
@@ -340,6 +344,7 @@ static int fsl_i2c_probe(struct platform_device *pdev)
340 fail_irq: 344 fail_irq:
341 iounmap(i2c->base); 345 iounmap(i2c->base);
342 fail_map: 346 fail_map:
347 fail_get_irq:
343 kfree(i2c); 348 kfree(i2c);
344 return result; 349 return result;
345}; 350};
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index 22781d84f79f..ac5cde1bbd2b 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -516,6 +516,10 @@ mv64xxx_i2c_probe(struct platform_device *pd)
516 drv_data->freq_m = pdata->freq_m; 516 drv_data->freq_m = pdata->freq_m;
517 drv_data->freq_n = pdata->freq_n; 517 drv_data->freq_n = pdata->freq_n;
518 drv_data->irq = platform_get_irq(pd, 0); 518 drv_data->irq = platform_get_irq(pd, 0);
519 if (drv_data->irq < 0) {
520 rc = -ENXIO;
521 goto exit_unmap_regs;
522 }
519 drv_data->adapter.id = I2C_HW_MV64XXX; 523 drv_data->adapter.id = I2C_HW_MV64XXX;
520 drv_data->adapter.algo = &mv64xxx_i2c_algo; 524 drv_data->adapter.algo = &mv64xxx_i2c_algo;
521 drv_data->adapter.owner = THIS_MODULE; 525 drv_data->adapter.owner = THIS_MODULE;
diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c
index 32431dcf5d8e..71f27e955d87 100644
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -674,6 +674,11 @@ static int au_ide_probe(struct device *dev)
674 ret = -ENODEV; 674 ret = -ENODEV;
675 goto out; 675 goto out;
676 } 676 }
677 if (ahwif->irq < 0) {
678 pr_debug("%s %d: no IRQ\n", DRV_NAME, pdev->id);
679 ret = -ENODEV;
680 goto out;
681 }
677 682
678 if (!request_mem_region (res->start, res->end-res->start, pdev->name)) { 683 if (!request_mem_region (res->start, res->end-res->start, pdev->name)) {
679 pr_debug("%s: request_mem_region failed\n", DRV_NAME); 684 pr_debug("%s: request_mem_region failed\n", DRV_NAME);
diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c
index 285d7d068097..c32fad1ce51c 100644
--- a/drivers/mmc/pxamci.c
+++ b/drivers/mmc/pxamci.c
@@ -438,7 +438,7 @@ static int pxamci_probe(struct platform_device *pdev)
438 438
439 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 439 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
440 irq = platform_get_irq(pdev, 0); 440 irq = platform_get_irq(pdev, 0);
441 if (!r || irq == NO_IRQ) 441 if (!r || irq < 0)
442 return -ENXIO; 442 return -ENXIO;
443 443
444 r = request_mem_region(r->start, SZ_4K, DRIVER_NAME); 444 r = request_mem_region(r->start, SZ_4K, DRIVER_NAME);
diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c
index 53e3afc1b7b7..09d5c3f26985 100644
--- a/drivers/net/arm/am79c961a.c
+++ b/drivers/net/arm/am79c961a.c
@@ -696,7 +696,9 @@ static int __init am79c961_probe(struct platform_device *pdev)
696 dev->base_addr = res->start; 696 dev->base_addr = res->start;
697 dev->irq = platform_get_irq(pdev, 0); 697 dev->irq = platform_get_irq(pdev, 0);
698 698
699 ret = -ENODEV; 699 ret = -ENODEV;
700 if (dev->irq < 0)
701 goto nodev;
700 if (!request_region(dev->base_addr, 0x18, dev->name)) 702 if (!request_region(dev->base_addr, 0x18, dev->name))
701 goto nodev; 703 goto nodev;
702 704
diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c
index e67b1d06611c..95e2bb8dd7b4 100644
--- a/drivers/net/fs_enet/mac-fcc.c
+++ b/drivers/net/fs_enet/mac-fcc.c
@@ -118,6 +118,8 @@ static int do_pd_setup(struct fs_enet_private *fep)
118 118
119 /* Fill out IRQ field */ 119 /* Fill out IRQ field */
120 fep->interrupt = platform_get_irq(pdev, 0); 120 fep->interrupt = platform_get_irq(pdev, 0);
121 if (fep->interrupt < 0)
122 return -EINVAL;
121 123
122 /* Attach the memory for the FCC Parameter RAM */ 124 /* Attach the memory for the FCC Parameter RAM */
123 r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fcc_pram"); 125 r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fcc_pram");
diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c
index 2e8f44469699..3dad69dfdb2c 100644
--- a/drivers/net/fs_enet/mac-fec.c
+++ b/drivers/net/fs_enet/mac-fec.c
@@ -144,6 +144,8 @@ static int do_pd_setup(struct fs_enet_private *fep)
144 144
145 /* Fill out IRQ field */ 145 /* Fill out IRQ field */
146 fep->interrupt = platform_get_irq_byname(pdev,"interrupt"); 146 fep->interrupt = platform_get_irq_byname(pdev,"interrupt");
147 if (fep->interrupt < 0)
148 return -EINVAL;
147 149
148 r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); 150 r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
149 fep->fec.fecp =(void*)r->start; 151 fep->fec.fecp =(void*)r->start;
diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c
index a3897fda71fa..a772b286f96d 100644
--- a/drivers/net/fs_enet/mac-scc.c
+++ b/drivers/net/fs_enet/mac-scc.c
@@ -118,6 +118,8 @@ static int do_pd_setup(struct fs_enet_private *fep)
118 118
119 /* Fill out IRQ field */ 119 /* Fill out IRQ field */
120 fep->interrupt = platform_get_irq_byname(pdev, "interrupt"); 120 fep->interrupt = platform_get_irq_byname(pdev, "interrupt");
121 if (fep->interrupt < 0)
122 return -EINVAL;
121 123
122 r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); 124 r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
123 fep->scc.sccp = (void *)r->start; 125 fep->scc.sccp = (void *)r->start;
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 0e8e3fcde9ff..771e25d8c417 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -193,8 +193,12 @@ static int gfar_probe(struct platform_device *pdev)
193 priv->interruptTransmit = platform_get_irq_byname(pdev, "tx"); 193 priv->interruptTransmit = platform_get_irq_byname(pdev, "tx");
194 priv->interruptReceive = platform_get_irq_byname(pdev, "rx"); 194 priv->interruptReceive = platform_get_irq_byname(pdev, "rx");
195 priv->interruptError = platform_get_irq_byname(pdev, "error"); 195 priv->interruptError = platform_get_irq_byname(pdev, "error");
196 if (priv->interruptTransmit < 0 || priv->interruptReceive < 0 || priv->interruptError < 0)
197 goto regs_fail;
196 } else { 198 } else {
197 priv->interruptTransmit = platform_get_irq(pdev, 0); 199 priv->interruptTransmit = platform_get_irq(pdev, 0);
200 if (priv->interruptTransmit < 0)
201 goto regs_fail;
198 } 202 }
199 203
200 /* get a pointer to the register memory */ 204 /* get a pointer to the register memory */
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index 7ec08127c9d6..75e9b3b910cc 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -2221,6 +2221,10 @@ static int smc_drv_probe(struct platform_device *pdev)
2221 2221
2222 ndev->dma = (unsigned char)-1; 2222 ndev->dma = (unsigned char)-1;
2223 ndev->irq = platform_get_irq(pdev, 0); 2223 ndev->irq = platform_get_irq(pdev, 0);
2224 if (ndev->irq < 0) {
2225 ret = -ENODEV;
2226 goto out_free_netdev;
2227 }
2224 2228
2225 ret = smc_request_attrib(pdev); 2229 ret = smc_request_attrib(pdev);
2226 if (ret) 2230 if (ret)
diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c
index 47b5ade95bde..2c23d7584399 100644
--- a/drivers/pcmcia/omap_cf.c
+++ b/drivers/pcmcia/omap_cf.c
@@ -218,7 +218,7 @@ static int __init omap_cf_probe(struct device *dev)
218 218
219 /* either CFLASH.IREQ (INT_1610_CF) or some GPIO */ 219 /* either CFLASH.IREQ (INT_1610_CF) or some GPIO */
220 irq = platform_get_irq(pdev, 0); 220 irq = platform_get_irq(pdev, 0);
221 if (!irq) 221 if (irq < 0)
222 return -EINVAL; 222 return -EINVAL;
223 223
224 cf = kcalloc(1, sizeof *cf, GFP_KERNEL); 224 cf = kcalloc(1, sizeof *cf, GFP_KERNEL);
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 7410e093a6b9..00d7c0ad8cbf 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -1066,6 +1066,8 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
1066 port->mapbase = res->start; 1066 port->mapbase = res->start;
1067 port->membase = S3C24XX_VA_UART + (res->start - S3C24XX_PA_UART); 1067 port->membase = S3C24XX_VA_UART + (res->start - S3C24XX_PA_UART);
1068 port->irq = platform_get_irq(platdev, 0); 1068 port->irq = platform_get_irq(platdev, 0);
1069 if (port->irq < 0)
1070 port->irq = 0;
1069 1071
1070 ourport->clk = clk_get(&platdev->dev, "uart"); 1072 ourport->clk = clk_get(&platdev->dev, "uart");
1071 1073
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index dce9d987f0fc..c196f3845305 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -378,7 +378,7 @@ const struct usb_device_id *usb_match_id(struct usb_interface *interface,
378 378
379 return NULL; 379 return NULL;
380} 380}
381EXPORT_SYMBOL(usb_match_id); 381EXPORT_SYMBOL_GPL_FUTURE(usb_match_id);
382 382
383int usb_device_match(struct device *dev, struct device_driver *drv) 383int usb_device_match(struct device *dev, struct device_driver *drv)
384{ 384{
@@ -446,7 +446,7 @@ int usb_register_driver(struct usb_driver *new_driver, struct module *owner)
446 446
447 return retval; 447 return retval;
448} 448}
449EXPORT_SYMBOL(usb_register_driver); 449EXPORT_SYMBOL_GPL_FUTURE(usb_register_driver);
450 450
451/** 451/**
452 * usb_deregister - unregister a USB driver 452 * usb_deregister - unregister a USB driver
@@ -469,4 +469,4 @@ void usb_deregister(struct usb_driver *driver)
469 469
470 usbfs_update_special(); 470 usbfs_update_special();
471} 471}
472EXPORT_SYMBOL(usb_deregister); 472EXPORT_SYMBOL_GPL_FUTURE(usb_deregister);
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index 3785b3f7df1b..ca19abe01c53 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -286,7 +286,7 @@ void usb_hcd_omap_remove (struct usb_hcd *, struct platform_device *);
286int usb_hcd_omap_probe (const struct hc_driver *driver, 286int usb_hcd_omap_probe (const struct hc_driver *driver,
287 struct platform_device *pdev) 287 struct platform_device *pdev)
288{ 288{
289 int retval; 289 int retval, irq;
290 struct usb_hcd *hcd = 0; 290 struct usb_hcd *hcd = 0;
291 struct ohci_hcd *ohci; 291 struct ohci_hcd *ohci;
292 292
@@ -329,7 +329,12 @@ int usb_hcd_omap_probe (const struct hc_driver *driver,
329 if (retval < 0) 329 if (retval < 0)
330 goto err2; 330 goto err2;
331 331
332 retval = usb_add_hcd(hcd, platform_get_irq(pdev, 0), SA_INTERRUPT); 332 irq = platform_get_irq(pdev, 0);
333 if (irq < 0) {
334 retval = -ENXIO;
335 goto err2;
336 }
337 retval = usb_add_hcd(hcd, irq, SA_INTERRUPT);
333 if (retval == 0) 338 if (retval == 0)
334 return retval; 339 return retval;
335 340
diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c
index 3b0e71383448..082759447bf6 100644
--- a/drivers/video/epson1355fb.c
+++ b/drivers/video/epson1355fb.c
@@ -607,6 +607,7 @@ static void clearfb16(struct fb_info *info)
607 607
608static void epson1355fb_platform_release(struct device *device) 608static void epson1355fb_platform_release(struct device *device)
609{ 609{
610 dev_err(device, "This driver is broken, please bug the authors so they will fix it.\n");
610} 611}
611 612
612static int epson1355fb_remove(struct platform_device *dev) 613static int epson1355fb_remove(struct platform_device *dev)
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index 8a893ce7040d..d9831fd42341 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -1457,7 +1457,7 @@ static int __init sa1100fb_probe(struct platform_device *pdev)
1457 int ret, irq; 1457 int ret, irq;
1458 1458
1459 irq = platform_get_irq(pdev, 0); 1459 irq = platform_get_irq(pdev, 0);
1460 if (irq <= 0) 1460 if (irq < 0)
1461 return -EINVAL; 1461 return -EINVAL;
1462 1462
1463 if (!request_mem_region(0xb0100000, 0x10000, "LCD")) 1463 if (!request_mem_region(0xb0100000, 0x10000, "LCD"))
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index 53208cb58396..77eed1fd9943 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -401,6 +401,7 @@ static int __init vfb_setup(char *options)
401static void vfb_platform_release(struct device *device) 401static void vfb_platform_release(struct device *device)
402{ 402{
403 // This is called when the reference count goes to zero. 403 // This is called when the reference count goes to zero.
404 dev_err(device, "This driver is broken, please bug the authors so they will fix it.\n");
404} 405}
405 406
406static int __init vfb_probe(struct platform_device *dev) 407static int __init vfb_probe(struct platform_device *dev)
diff --git a/fs/char_dev.c b/fs/char_dev.c
index 21195c481637..5c36345c9bf7 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -19,6 +19,7 @@
19#include <linux/kobject.h> 19#include <linux/kobject.h>
20#include <linux/kobj_map.h> 20#include <linux/kobj_map.h>
21#include <linux/cdev.h> 21#include <linux/cdev.h>
22#include <linux/mutex.h>
22 23
23#ifdef CONFIG_KMOD 24#ifdef CONFIG_KMOD
24#include <linux/kmod.h> 25#include <linux/kmod.h>
@@ -28,7 +29,7 @@ static struct kobj_map *cdev_map;
28 29
29#define MAX_PROBE_HASH 255 /* random */ 30#define MAX_PROBE_HASH 255 /* random */
30 31
31static DECLARE_MUTEX(chrdevs_lock); 32static DEFINE_MUTEX(chrdevs_lock);
32 33
33static struct char_device_struct { 34static struct char_device_struct {
34 struct char_device_struct *next; 35 struct char_device_struct *next;
@@ -88,13 +89,13 @@ out:
88 89
89void *acquire_chrdev_list(void) 90void *acquire_chrdev_list(void)
90{ 91{
91 down(&chrdevs_lock); 92 mutex_lock(&chrdevs_lock);
92 return get_next_chrdev(NULL); 93 return get_next_chrdev(NULL);
93} 94}
94 95
95void release_chrdev_list(void *dev) 96void release_chrdev_list(void *dev)
96{ 97{
97 up(&chrdevs_lock); 98 mutex_unlock(&chrdevs_lock);
98 kfree(dev); 99 kfree(dev);
99} 100}
100 101
@@ -151,7 +152,7 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor,
151 152
152 memset(cd, 0, sizeof(struct char_device_struct)); 153 memset(cd, 0, sizeof(struct char_device_struct));
153 154
154 down(&chrdevs_lock); 155 mutex_lock(&chrdevs_lock);
155 156
156 /* temporary */ 157 /* temporary */
157 if (major == 0) { 158 if (major == 0) {
@@ -186,10 +187,10 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor,
186 } 187 }
187 cd->next = *cp; 188 cd->next = *cp;
188 *cp = cd; 189 *cp = cd;
189 up(&chrdevs_lock); 190 mutex_unlock(&chrdevs_lock);
190 return cd; 191 return cd;
191out: 192out:
192 up(&chrdevs_lock); 193 mutex_unlock(&chrdevs_lock);
193 kfree(cd); 194 kfree(cd);
194 return ERR_PTR(ret); 195 return ERR_PTR(ret);
195} 196}
@@ -200,7 +201,7 @@ __unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct)
200 struct char_device_struct *cd = NULL, **cp; 201 struct char_device_struct *cd = NULL, **cp;
201 int i = major_to_index(major); 202 int i = major_to_index(major);
202 203
203 down(&chrdevs_lock); 204 mutex_lock(&chrdevs_lock);
204 for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next) 205 for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next)
205 if ((*cp)->major == major && 206 if ((*cp)->major == major &&
206 (*cp)->baseminor == baseminor && 207 (*cp)->baseminor == baseminor &&
@@ -210,7 +211,7 @@ __unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct)
210 cd = *cp; 211 cd = *cp;
211 *cp = cd->next; 212 *cp = cd->next;
212 } 213 }
213 up(&chrdevs_lock); 214 mutex_unlock(&chrdevs_lock);
214 return cd; 215 return cd;
215} 216}
216 217
diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
index d575452cd9f7..40c4fc973fad 100644
--- a/fs/debugfs/file.c
+++ b/fs/debugfs/file.c
@@ -251,3 +251,49 @@ struct dentry *debugfs_create_bool(const char *name, mode_t mode,
251} 251}
252EXPORT_SYMBOL_GPL(debugfs_create_bool); 252EXPORT_SYMBOL_GPL(debugfs_create_bool);
253 253
254static ssize_t read_file_blob(struct file *file, char __user *user_buf,
255 size_t count, loff_t *ppos)
256{
257 struct debugfs_blob_wrapper *blob = file->private_data;
258 return simple_read_from_buffer(user_buf, count, ppos, blob->data,
259 blob->size);
260}
261
262static struct file_operations fops_blob = {
263 .read = read_file_blob,
264 .open = default_open,
265};
266
267/**
268 * debugfs_create_blob - create a file in the debugfs filesystem that is
269 * used to read and write a binary blob.
270 *
271 * @name: a pointer to a string containing the name of the file to create.
272 * @mode: the permission that the file should have
273 * @parent: a pointer to the parent dentry for this file. This should be a
274 * directory dentry if set. If this paramater is NULL, then the
275 * file will be created in the root of the debugfs filesystem.
276 * @blob: a pointer to a struct debugfs_blob_wrapper which contains a pointer
277 * to the blob data and the size of the data.
278 *
279 * This function creates a file in debugfs with the given name that exports
280 * @blob->data as a binary blob. If the @mode variable is so set it can be
281 * read from. Writing is not supported.
282 *
283 * This function will return a pointer to a dentry if it succeeds. This
284 * pointer must be passed to the debugfs_remove() function when the file is
285 * to be removed (no automatic cleanup happens if your module is unloaded,
286 * you are responsible here.) If an error occurs, NULL will be returned.
287 *
288 * If debugfs is not enabled in the kernel, the value -ENODEV will be
289 * returned. It is not wise to check for this value, but rather, check for
290 * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
291 * code.
292 */
293struct dentry *debugfs_create_blob(const char *name, mode_t mode,
294 struct dentry *parent,
295 struct debugfs_blob_wrapper *blob)
296{
297 return debugfs_create_file(name, mode, parent, blob, &fops_blob);
298}
299EXPORT_SYMBOL_GPL(debugfs_create_blob);
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 49bd219275db..9ee956864445 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -50,6 +50,32 @@ static struct sysfs_dirent * sysfs_new_dirent(struct sysfs_dirent * parent_sd,
50 return sd; 50 return sd;
51} 51}
52 52
53/**
54 *
55 * Return -EEXIST if there is already a sysfs element with the same name for
56 * the same parent.
57 *
58 * called with parent inode's i_mutex held
59 */
60int sysfs_dirent_exist(struct sysfs_dirent *parent_sd,
61 const unsigned char *new)
62{
63 struct sysfs_dirent * sd;
64
65 list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
66 if (sd->s_element) {
67 const unsigned char *existing = sysfs_get_name(sd);
68 if (strcmp(existing, new))
69 continue;
70 else
71 return -EEXIST;
72 }
73 }
74
75 return 0;
76}
77
78
53int sysfs_make_dirent(struct sysfs_dirent * parent_sd, struct dentry * dentry, 79int sysfs_make_dirent(struct sysfs_dirent * parent_sd, struct dentry * dentry,
54 void * element, umode_t mode, int type) 80 void * element, umode_t mode, int type)
55{ 81{
@@ -102,7 +128,11 @@ static int create_dir(struct kobject * k, struct dentry * p,
102 mutex_lock(&p->d_inode->i_mutex); 128 mutex_lock(&p->d_inode->i_mutex);
103 *d = lookup_one_len(n, p, strlen(n)); 129 *d = lookup_one_len(n, p, strlen(n));
104 if (!IS_ERR(*d)) { 130 if (!IS_ERR(*d)) {
105 error = sysfs_make_dirent(p->d_fsdata, *d, k, mode, SYSFS_DIR); 131 if (sysfs_dirent_exist(p->d_fsdata, n))
132 error = -EEXIST;
133 else
134 error = sysfs_make_dirent(p->d_fsdata, *d, k, mode,
135 SYSFS_DIR);
106 if (!error) { 136 if (!error) {
107 error = sysfs_create(*d, mode, init_dir); 137 error = sysfs_create(*d, mode, init_dir);
108 if (!error) { 138 if (!error) {
@@ -302,6 +332,7 @@ void sysfs_remove_dir(struct kobject * kobj)
302 * Drop reference from dget() on entrance. 332 * Drop reference from dget() on entrance.
303 */ 333 */
304 dput(dentry); 334 dput(dentry);
335 kobj->dentry = NULL;
305} 336}
306 337
307int sysfs_rename_dir(struct kobject * kobj, const char *new_name) 338int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
@@ -479,7 +510,3 @@ struct file_operations sysfs_dir_operations = {
479 .read = generic_read_dir, 510 .read = generic_read_dir,
480 .readdir = sysfs_readdir, 511 .readdir = sysfs_readdir,
481}; 512};
482
483EXPORT_SYMBOL_GPL(sysfs_create_dir);
484EXPORT_SYMBOL_GPL(sysfs_remove_dir);
485EXPORT_SYMBOL_GPL(sysfs_rename_dir);
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index d0e3d8495165..5e83e7246788 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -301,9 +301,8 @@ static int check_perm(struct inode * inode, struct file * file)
301 /* No error? Great, allocate a buffer for the file, and store it 301 /* No error? Great, allocate a buffer for the file, and store it
302 * it in file->private_data for easy access. 302 * it in file->private_data for easy access.
303 */ 303 */
304 buffer = kmalloc(sizeof(struct sysfs_buffer),GFP_KERNEL); 304 buffer = kzalloc(sizeof(struct sysfs_buffer), GFP_KERNEL);
305 if (buffer) { 305 if (buffer) {
306 memset(buffer,0,sizeof(struct sysfs_buffer));
307 init_MUTEX(&buffer->sem); 306 init_MUTEX(&buffer->sem);
308 buffer->needs_read_fill = 1; 307 buffer->needs_read_fill = 1;
309 buffer->ops = ops; 308 buffer->ops = ops;
@@ -362,10 +361,12 @@ int sysfs_add_file(struct dentry * dir, const struct attribute * attr, int type)
362{ 361{
363 struct sysfs_dirent * parent_sd = dir->d_fsdata; 362 struct sysfs_dirent * parent_sd = dir->d_fsdata;
364 umode_t mode = (attr->mode & S_IALLUGO) | S_IFREG; 363 umode_t mode = (attr->mode & S_IALLUGO) | S_IFREG;
365 int error = 0; 364 int error = -EEXIST;
366 365
367 mutex_lock(&dir->d_inode->i_mutex); 366 mutex_lock(&dir->d_inode->i_mutex);
368 error = sysfs_make_dirent(parent_sd, NULL, (void *) attr, mode, type); 367 if (!sysfs_dirent_exist(parent_sd, attr->name))
368 error = sysfs_make_dirent(parent_sd, NULL, (void *)attr,
369 mode, type);
369 mutex_unlock(&dir->d_inode->i_mutex); 370 mutex_unlock(&dir->d_inode->i_mutex);
370 371
371 return error; 372 return error;
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index 689f7bcfaf30..4c29ac41ac3e 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -54,11 +54,10 @@ int sysfs_setattr(struct dentry * dentry, struct iattr * iattr)
54 54
55 if (!sd_iattr) { 55 if (!sd_iattr) {
56 /* setting attributes for the first time, allocate now */ 56 /* setting attributes for the first time, allocate now */
57 sd_iattr = kmalloc(sizeof(struct iattr), GFP_KERNEL); 57 sd_iattr = kzalloc(sizeof(struct iattr), GFP_KERNEL);
58 if (!sd_iattr) 58 if (!sd_iattr)
59 return -ENOMEM; 59 return -ENOMEM;
60 /* assign default attributes */ 60 /* assign default attributes */
61 memset(sd_iattr, 0, sizeof(struct iattr));
62 sd_iattr->ia_mode = sd->s_mode; 61 sd_iattr->ia_mode = sd->s_mode;
63 sd_iattr->ia_uid = 0; 62 sd_iattr->ia_uid = 0;
64 sd_iattr->ia_gid = 0; 63 sd_iattr->ia_gid = 0;
@@ -227,12 +226,16 @@ void sysfs_drop_dentry(struct sysfs_dirent * sd, struct dentry * parent)
227void sysfs_hash_and_remove(struct dentry * dir, const char * name) 226void sysfs_hash_and_remove(struct dentry * dir, const char * name)
228{ 227{
229 struct sysfs_dirent * sd; 228 struct sysfs_dirent * sd;
230 struct sysfs_dirent * parent_sd = dir->d_fsdata; 229 struct sysfs_dirent * parent_sd;
230
231 if (!dir)
232 return;
231 233
232 if (dir->d_inode == NULL) 234 if (dir->d_inode == NULL)
233 /* no inode means this hasn't been made visible yet */ 235 /* no inode means this hasn't been made visible yet */
234 return; 236 return;
235 237
238 parent_sd = dir->d_fsdata;
236 mutex_lock(&dir->d_inode->i_mutex); 239 mutex_lock(&dir->d_inode->i_mutex);
237 list_for_each_entry(sd, &parent_sd->s_children, s_sibling) { 240 list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
238 if (!sd->s_element) 241 if (!sd->s_element)
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index e38d6338a20d..d2eac3ceed5f 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -66,6 +66,7 @@ static int sysfs_add_link(struct dentry * parent, const char * name, struct kobj
66 if (!error) 66 if (!error)
67 return 0; 67 return 0;
68 68
69 kobject_put(target);
69 kfree(sl->link_name); 70 kfree(sl->link_name);
70exit2: 71exit2:
71 kfree(sl); 72 kfree(sl);
@@ -82,12 +83,13 @@ exit1:
82int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char * name) 83int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char * name)
83{ 84{
84 struct dentry * dentry = kobj->dentry; 85 struct dentry * dentry = kobj->dentry;
85 int error = 0; 86 int error = -EEXIST;
86 87
87 BUG_ON(!kobj || !kobj->dentry || !name); 88 BUG_ON(!kobj || !kobj->dentry || !name);
88 89
89 mutex_lock(&dentry->d_inode->i_mutex); 90 mutex_lock(&dentry->d_inode->i_mutex);
90 error = sysfs_add_link(dentry, name, target); 91 if (!sysfs_dirent_exist(dentry->d_fsdata, name))
92 error = sysfs_add_link(dentry, name, target);
91 mutex_unlock(&dentry->d_inode->i_mutex); 93 mutex_unlock(&dentry->d_inode->i_mutex);
92 return error; 94 return error;
93} 95}
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index 3f8953e0e5d0..cf11d5b789d9 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -5,6 +5,7 @@ extern kmem_cache_t *sysfs_dir_cachep;
5extern struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent *); 5extern struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent *);
6extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *)); 6extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *));
7 7
8extern int sysfs_dirent_exist(struct sysfs_dirent *, const unsigned char *);
8extern int sysfs_make_dirent(struct sysfs_dirent *, struct dentry *, void *, 9extern int sysfs_make_dirent(struct sysfs_dirent *, struct dentry *, void *,
9 umode_t, int); 10 umode_t, int);
10 11
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 35de20cf8fac..9d11550b4818 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -58,6 +58,13 @@
58 VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .; \ 58 VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .; \
59 } \ 59 } \
60 \ 60 \
61 /* Kernel symbol table: GPL-future-only symbols */ \
62 __ksymtab_gpl_future : AT(ADDR(__ksymtab_gpl_future) - LOAD_OFFSET) { \
63 VMLINUX_SYMBOL(__start___ksymtab_gpl_future) = .; \
64 *(__ksymtab_gpl_future) \
65 VMLINUX_SYMBOL(__stop___ksymtab_gpl_future) = .; \
66 } \
67 \
61 /* Kernel symbol table: Normal symbols */ \ 68 /* Kernel symbol table: Normal symbols */ \
62 __kcrctab : AT(ADDR(__kcrctab) - LOAD_OFFSET) { \ 69 __kcrctab : AT(ADDR(__kcrctab) - LOAD_OFFSET) { \
63 VMLINUX_SYMBOL(__start___kcrctab) = .; \ 70 VMLINUX_SYMBOL(__start___kcrctab) = .; \
@@ -72,6 +79,13 @@
72 VMLINUX_SYMBOL(__stop___kcrctab_gpl) = .; \ 79 VMLINUX_SYMBOL(__stop___kcrctab_gpl) = .; \
73 } \ 80 } \
74 \ 81 \
82 /* Kernel symbol table: GPL-future-only symbols */ \
83 __kcrctab_gpl_future : AT(ADDR(__kcrctab_gpl_future) - LOAD_OFFSET) { \
84 VMLINUX_SYMBOL(__start___kcrctab_gpl_future) = .; \
85 *(__kcrctab_gpl_future) \
86 VMLINUX_SYMBOL(__stop___kcrctab_gpl_future) = .; \
87 } \
88 \
75 /* Kernel symbol table: strings */ \ 89 /* Kernel symbol table: strings */ \
76 __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \ 90 __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \
77 *(__ksymtab_strings) \ 91 *(__ksymtab_strings) \
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 0ed1d4853c69..d612b89dce33 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -32,7 +32,7 @@ struct cpu {
32}; 32};
33 33
34extern int register_cpu(struct cpu *, int, struct node *); 34extern int register_cpu(struct cpu *, int, struct node *);
35extern struct sys_device *get_cpu_sysdev(int cpu); 35extern struct sys_device *get_cpu_sysdev(unsigned cpu);
36#ifdef CONFIG_HOTPLUG_CPU 36#ifdef CONFIG_HOTPLUG_CPU
37extern void unregister_cpu(struct cpu *, struct node *); 37extern void unregister_cpu(struct cpu *, struct node *);
38#endif 38#endif
diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h
index a5fa6a6eede8..4b0428e335be 100644
--- a/include/linux/debugfs.h
+++ b/include/linux/debugfs.h
@@ -21,6 +21,11 @@
21 21
22struct file_operations; 22struct file_operations;
23 23
24struct debugfs_blob_wrapper {
25 void *data;
26 unsigned long size;
27};
28
24#if defined(CONFIG_DEBUG_FS) 29#if defined(CONFIG_DEBUG_FS)
25struct dentry *debugfs_create_file(const char *name, mode_t mode, 30struct dentry *debugfs_create_file(const char *name, mode_t mode,
26 struct dentry *parent, void *data, 31 struct dentry *parent, void *data,
@@ -39,6 +44,9 @@ struct dentry *debugfs_create_u32(const char *name, mode_t mode,
39struct dentry *debugfs_create_bool(const char *name, mode_t mode, 44struct dentry *debugfs_create_bool(const char *name, mode_t mode,
40 struct dentry *parent, u32 *value); 45 struct dentry *parent, u32 *value);
41 46
47struct dentry *debugfs_create_blob(const char *name, mode_t mode,
48 struct dentry *parent,
49 struct debugfs_blob_wrapper *blob);
42#else 50#else
43 51
44#include <linux/err.h> 52#include <linux/err.h>
@@ -94,6 +102,13 @@ static inline struct dentry *debugfs_create_bool(const char *name, mode_t mode,
94 return ERR_PTR(-ENODEV); 102 return ERR_PTR(-ENODEV);
95} 103}
96 104
105static inline struct dentry *debugfs_create_blob(const char *name, mode_t mode,
106 struct dentry *parent,
107 struct debugfs_blob_wrapper *blob)
108{
109 return ERR_PTR(-ENODEV);
110}
111
97#endif 112#endif
98 113
99#endif 114#endif
diff --git a/include/linux/device.h b/include/linux/device.h
index 58df18d9cd3e..5b595fdfb672 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -424,6 +424,8 @@ extern void firmware_unregister(struct subsystem *);
424 dev_printk(KERN_INFO , dev , format , ## arg) 424 dev_printk(KERN_INFO , dev , format , ## arg)
425#define dev_warn(dev, format, arg...) \ 425#define dev_warn(dev, format, arg...) \
426 dev_printk(KERN_WARNING , dev , format , ## arg) 426 dev_printk(KERN_WARNING , dev , format , ## arg)
427#define dev_notice(dev, format, arg...) \
428 dev_printk(KERN_NOTICE , dev , format , ## arg)
427 429
428/* Create alias, so I can be autoloaded. */ 430/* Create alias, so I can be autoloaded. */
429#define MODULE_ALIAS_CHARDEV(major,minor) \ 431#define MODULE_ALIAS_CHARDEV(major,minor) \
diff --git a/include/linux/kobj_map.h b/include/linux/kobj_map.h
index cbe7d8008042..bafe178a381f 100644
--- a/include/linux/kobj_map.h
+++ b/include/linux/kobj_map.h
@@ -1,6 +1,6 @@
1#ifdef __KERNEL__ 1#ifdef __KERNEL__
2 2
3#include <asm/semaphore.h> 3#include <linux/mutex.h>
4 4
5typedef struct kobject *kobj_probe_t(dev_t, int *, void *); 5typedef struct kobject *kobj_probe_t(dev_t, int *, void *);
6struct kobj_map; 6struct kobj_map;
@@ -9,6 +9,6 @@ int kobj_map(struct kobj_map *, dev_t, unsigned long, struct module *,
9 kobj_probe_t *, int (*)(dev_t, void *), void *); 9 kobj_probe_t *, int (*)(dev_t, void *), void *);
10void kobj_unmap(struct kobj_map *, dev_t, unsigned long); 10void kobj_unmap(struct kobj_map *, dev_t, unsigned long);
11struct kobject *kobj_lookup(struct kobj_map *, dev_t, int *); 11struct kobject *kobj_lookup(struct kobj_map *, dev_t, int *);
12struct kobj_map *kobj_map_init(kobj_probe_t *, struct semaphore *); 12struct kobj_map *kobj_map_init(kobj_probe_t *, struct mutex *);
13 13
14#endif 14#endif
diff --git a/include/linux/kobject.h b/include/linux/kobject.h
index c374b5fa8d3b..4cb1214ec290 100644
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -80,6 +80,8 @@ extern void kobject_unregister(struct kobject *);
80extern struct kobject * kobject_get(struct kobject *); 80extern struct kobject * kobject_get(struct kobject *);
81extern void kobject_put(struct kobject *); 81extern void kobject_put(struct kobject *);
82 82
83extern struct kobject *kobject_add_dir(struct kobject *, const char *);
84
83extern char * kobject_get_path(struct kobject *, gfp_t); 85extern char * kobject_get_path(struct kobject *, gfp_t);
84 86
85struct kobj_type { 87struct kobj_type {
@@ -255,7 +257,7 @@ struct subsys_attribute {
255extern int subsys_create_file(struct subsystem * , struct subsys_attribute *); 257extern int subsys_create_file(struct subsystem * , struct subsys_attribute *);
256extern void subsys_remove_file(struct subsystem * , struct subsys_attribute *); 258extern void subsys_remove_file(struct subsystem * , struct subsys_attribute *);
257 259
258#if defined(CONFIG_HOTPLUG) & defined(CONFIG_NET) 260#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
259void kobject_uevent(struct kobject *kobj, enum kobject_action action); 261void kobject_uevent(struct kobject *kobj, enum kobject_action action);
260 262
261int add_uevent_var(char **envp, int num_envp, int *cur_index, 263int add_uevent_var(char **envp, int num_envp, int *cur_index,
diff --git a/include/linux/module.h b/include/linux/module.h
index 84d75f3a8aca..70bd843c71cb 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -198,6 +198,9 @@ void *__symbol_get_gpl(const char *symbol);
198#define EXPORT_SYMBOL_GPL(sym) \ 198#define EXPORT_SYMBOL_GPL(sym) \
199 __EXPORT_SYMBOL(sym, "_gpl") 199 __EXPORT_SYMBOL(sym, "_gpl")
200 200
201#define EXPORT_SYMBOL_GPL_FUTURE(sym) \
202 __EXPORT_SYMBOL(sym, "_gpl_future")
203
201#endif 204#endif
202 205
203struct module_ref 206struct module_ref
@@ -242,6 +245,7 @@ struct module
242 /* Sysfs stuff. */ 245 /* Sysfs stuff. */
243 struct module_kobject mkobj; 246 struct module_kobject mkobj;
244 struct module_param_attrs *param_attrs; 247 struct module_param_attrs *param_attrs;
248 struct module_attribute *modinfo_attrs;
245 const char *version; 249 const char *version;
246 const char *srcversion; 250 const char *srcversion;
247 251
@@ -255,6 +259,11 @@ struct module
255 unsigned int num_gpl_syms; 259 unsigned int num_gpl_syms;
256 const unsigned long *gpl_crcs; 260 const unsigned long *gpl_crcs;
257 261
262 /* symbols that will be GPL-only in the near future. */
263 const struct kernel_symbol *gpl_future_syms;
264 unsigned int num_gpl_future_syms;
265 const unsigned long *gpl_future_crcs;
266
258 /* Exception table */ 267 /* Exception table */
259 unsigned int num_exentries; 268 unsigned int num_exentries;
260 const struct exception_table_entry *extable; 269 const struct exception_table_entry *extable;
@@ -441,6 +450,7 @@ void module_remove_driver(struct device_driver *);
441#else /* !CONFIG_MODULES... */ 450#else /* !CONFIG_MODULES... */
442#define EXPORT_SYMBOL(sym) 451#define EXPORT_SYMBOL(sym)
443#define EXPORT_SYMBOL_GPL(sym) 452#define EXPORT_SYMBOL_GPL(sym)
453#define EXPORT_SYMBOL_GPL_FUTURE(sym)
444 454
445/* Given an address, look for it in the exception tables. */ 455/* Given an address, look for it in the exception tables. */
446static inline const struct exception_table_entry * 456static inline const struct exception_table_entry *
diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c
index d5eeae0fa5bc..f2690ed74530 100644
--- a/kernel/ksysfs.c
+++ b/kernel/ksysfs.c
@@ -15,9 +15,6 @@
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/init.h> 16#include <linux/init.h>
17 17
18u64 uevent_seqnum;
19char uevent_helper[UEVENT_HELPER_PATH_LEN] = "/sbin/hotplug";
20
21#define KERNEL_ATTR_RO(_name) \ 18#define KERNEL_ATTR_RO(_name) \
22static struct subsys_attribute _name##_attr = __ATTR_RO(_name) 19static struct subsys_attribute _name##_attr = __ATTR_RO(_name)
23 20
diff --git a/kernel/module.c b/kernel/module.c
index 5aad477ddc79..77764f22f021 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -126,8 +126,11 @@ extern const struct kernel_symbol __start___ksymtab[];
126extern const struct kernel_symbol __stop___ksymtab[]; 126extern const struct kernel_symbol __stop___ksymtab[];
127extern const struct kernel_symbol __start___ksymtab_gpl[]; 127extern const struct kernel_symbol __start___ksymtab_gpl[];
128extern const struct kernel_symbol __stop___ksymtab_gpl[]; 128extern const struct kernel_symbol __stop___ksymtab_gpl[];
129extern const struct kernel_symbol __start___ksymtab_gpl_future[];
130extern const struct kernel_symbol __stop___ksymtab_gpl_future[];
129extern const unsigned long __start___kcrctab[]; 131extern const unsigned long __start___kcrctab[];
130extern const unsigned long __start___kcrctab_gpl[]; 132extern const unsigned long __start___kcrctab_gpl[];
133extern const unsigned long __start___kcrctab_gpl_future[];
131 134
132#ifndef CONFIG_MODVERSIONS 135#ifndef CONFIG_MODVERSIONS
133#define symversion(base, idx) NULL 136#define symversion(base, idx) NULL
@@ -135,6 +138,18 @@ extern const unsigned long __start___kcrctab_gpl[];
135#define symversion(base, idx) ((base) ? ((base) + (idx)) : NULL) 138#define symversion(base, idx) ((base) ? ((base) + (idx)) : NULL)
136#endif 139#endif
137 140
141/* lookup symbol in given range of kernel_symbols */
142static const struct kernel_symbol *lookup_symbol(const char *name,
143 const struct kernel_symbol *start,
144 const struct kernel_symbol *stop)
145{
146 const struct kernel_symbol *ks = start;
147 for (; ks < stop; ks++)
148 if (strcmp(ks->name, name) == 0)
149 return ks;
150 return NULL;
151}
152
138/* Find a symbol, return value, crc and module which owns it */ 153/* Find a symbol, return value, crc and module which owns it */
139static unsigned long __find_symbol(const char *name, 154static unsigned long __find_symbol(const char *name,
140 struct module **owner, 155 struct module **owner,
@@ -142,40 +157,75 @@ static unsigned long __find_symbol(const char *name,
142 int gplok) 157 int gplok)
143{ 158{
144 struct module *mod; 159 struct module *mod;
145 unsigned int i; 160 const struct kernel_symbol *ks;
146 161
147 /* Core kernel first. */ 162 /* Core kernel first. */
148 *owner = NULL; 163 *owner = NULL;
149 for (i = 0; __start___ksymtab+i < __stop___ksymtab; i++) { 164 ks = lookup_symbol(name, __start___ksymtab, __stop___ksymtab);
150 if (strcmp(__start___ksymtab[i].name, name) == 0) { 165 if (ks) {
151 *crc = symversion(__start___kcrctab, i); 166 *crc = symversion(__start___kcrctab, (ks - __start___ksymtab));
152 return __start___ksymtab[i].value; 167 return ks->value;
153 }
154 } 168 }
155 if (gplok) { 169 if (gplok) {
156 for (i = 0; __start___ksymtab_gpl+i<__stop___ksymtab_gpl; i++) 170 ks = lookup_symbol(name, __start___ksymtab_gpl,
157 if (strcmp(__start___ksymtab_gpl[i].name, name) == 0) { 171 __stop___ksymtab_gpl);
158 *crc = symversion(__start___kcrctab_gpl, i); 172 if (ks) {
159 return __start___ksymtab_gpl[i].value; 173 *crc = symversion(__start___kcrctab_gpl,
160 } 174 (ks - __start___ksymtab_gpl));
175 return ks->value;
176 }
177 }
178 ks = lookup_symbol(name, __start___ksymtab_gpl_future,
179 __stop___ksymtab_gpl_future);
180 if (ks) {
181 if (!gplok) {
182 printk(KERN_WARNING "Symbol %s is being used "
183 "by a non-GPL module, which will not "
184 "be allowed in the future\n", name);
185 printk(KERN_WARNING "Please see the file "
186 "Documentation/feature-removal-schedule.txt "
187 "in the kernel source tree for more "
188 "details.\n");
189 }
190 *crc = symversion(__start___kcrctab_gpl_future,
191 (ks - __start___ksymtab_gpl_future));
192 return ks->value;
161 } 193 }
162 194
163 /* Now try modules. */ 195 /* Now try modules. */
164 list_for_each_entry(mod, &modules, list) { 196 list_for_each_entry(mod, &modules, list) {
165 *owner = mod; 197 *owner = mod;
166 for (i = 0; i < mod->num_syms; i++) 198 ks = lookup_symbol(name, mod->syms, mod->syms + mod->num_syms);
167 if (strcmp(mod->syms[i].name, name) == 0) { 199 if (ks) {
168 *crc = symversion(mod->crcs, i); 200 *crc = symversion(mod->crcs, (ks - mod->syms));
169 return mod->syms[i].value; 201 return ks->value;
170 } 202 }
171 203
172 if (gplok) { 204 if (gplok) {
173 for (i = 0; i < mod->num_gpl_syms; i++) { 205 ks = lookup_symbol(name, mod->gpl_syms,
174 if (strcmp(mod->gpl_syms[i].name, name) == 0) { 206 mod->gpl_syms + mod->num_gpl_syms);
175 *crc = symversion(mod->gpl_crcs, i); 207 if (ks) {
176 return mod->gpl_syms[i].value; 208 *crc = symversion(mod->gpl_crcs,
177 } 209 (ks - mod->gpl_syms));
210 return ks->value;
211 }
212 }
213 ks = lookup_symbol(name, mod->gpl_future_syms,
214 (mod->gpl_future_syms +
215 mod->num_gpl_future_syms));
216 if (ks) {
217 if (!gplok) {
218 printk(KERN_WARNING "Symbol %s is being used "
219 "by a non-GPL module, which will not "
220 "be allowed in the future\n", name);
221 printk(KERN_WARNING "Please see the file "
222 "Documentation/feature-removal-schedule.txt "
223 "in the kernel source tree for more "
224 "details.\n");
178 } 225 }
226 *crc = symversion(mod->gpl_future_crcs,
227 (ks - mod->gpl_future_syms));
228 return ks->value;
179 } 229 }
180 } 230 }
181 DEBUGP("Failed to find symbol %s\n", name); 231 DEBUGP("Failed to find symbol %s\n", name);
@@ -379,7 +429,6 @@ static inline void percpu_modcopy(void *pcpudst, const void *src,
379} 429}
380#endif /* CONFIG_SMP */ 430#endif /* CONFIG_SMP */
381 431
382#ifdef CONFIG_MODULE_UNLOAD
383#define MODINFO_ATTR(field) \ 432#define MODINFO_ATTR(field) \
384static void setup_modinfo_##field(struct module *mod, const char *s) \ 433static void setup_modinfo_##field(struct module *mod, const char *s) \
385{ \ 434{ \
@@ -411,12 +460,7 @@ static struct module_attribute modinfo_##field = { \
411MODINFO_ATTR(version); 460MODINFO_ATTR(version);
412MODINFO_ATTR(srcversion); 461MODINFO_ATTR(srcversion);
413 462
414static struct module_attribute *modinfo_attrs[] = { 463#ifdef CONFIG_MODULE_UNLOAD
415 &modinfo_version,
416 &modinfo_srcversion,
417 NULL,
418};
419
420/* Init the unload section of the module. */ 464/* Init the unload section of the module. */
421static void module_unload_init(struct module *mod) 465static void module_unload_init(struct module *mod)
422{ 466{
@@ -731,6 +775,15 @@ static inline void module_unload_init(struct module *mod)
731} 775}
732#endif /* CONFIG_MODULE_UNLOAD */ 776#endif /* CONFIG_MODULE_UNLOAD */
733 777
778static struct module_attribute *modinfo_attrs[] = {
779 &modinfo_version,
780 &modinfo_srcversion,
781#ifdef CONFIG_MODULE_UNLOAD
782 &refcnt,
783#endif
784 NULL,
785};
786
734#ifdef CONFIG_OBSOLETE_MODPARM 787#ifdef CONFIG_OBSOLETE_MODPARM
735/* Bounds checking done below */ 788/* Bounds checking done below */
736static int obsparm_copy_string(const char *val, struct kernel_param *kp) 789static int obsparm_copy_string(const char *val, struct kernel_param *kp)
@@ -1056,37 +1109,28 @@ static inline void remove_sect_attrs(struct module *mod)
1056} 1109}
1057#endif /* CONFIG_KALLSYMS */ 1110#endif /* CONFIG_KALLSYMS */
1058 1111
1059
1060#ifdef CONFIG_MODULE_UNLOAD
1061static inline int module_add_refcnt_attr(struct module *mod)
1062{
1063 return sysfs_create_file(&mod->mkobj.kobj, &refcnt.attr);
1064}
1065static void module_remove_refcnt_attr(struct module *mod)
1066{
1067 return sysfs_remove_file(&mod->mkobj.kobj, &refcnt.attr);
1068}
1069#else
1070static inline int module_add_refcnt_attr(struct module *mod)
1071{
1072 return 0;
1073}
1074static void module_remove_refcnt_attr(struct module *mod)
1075{
1076}
1077#endif
1078
1079#ifdef CONFIG_MODULE_UNLOAD
1080static int module_add_modinfo_attrs(struct module *mod) 1112static int module_add_modinfo_attrs(struct module *mod)
1081{ 1113{
1082 struct module_attribute *attr; 1114 struct module_attribute *attr;
1115 struct module_attribute *temp_attr;
1083 int error = 0; 1116 int error = 0;
1084 int i; 1117 int i;
1085 1118
1119 mod->modinfo_attrs = kzalloc((sizeof(struct module_attribute) *
1120 (ARRAY_SIZE(modinfo_attrs) + 1)),
1121 GFP_KERNEL);
1122 if (!mod->modinfo_attrs)
1123 return -ENOMEM;
1124
1125 temp_attr = mod->modinfo_attrs;
1086 for (i = 0; (attr = modinfo_attrs[i]) && !error; i++) { 1126 for (i = 0; (attr = modinfo_attrs[i]) && !error; i++) {
1087 if (!attr->test || 1127 if (!attr->test ||
1088 (attr->test && attr->test(mod))) 1128 (attr->test && attr->test(mod))) {
1089 error = sysfs_create_file(&mod->mkobj.kobj,&attr->attr); 1129 memcpy(temp_attr, attr, sizeof(*temp_attr));
1130 temp_attr->attr.owner = mod;
1131 error = sysfs_create_file(&mod->mkobj.kobj,&temp_attr->attr);
1132 ++temp_attr;
1133 }
1090 } 1134 }
1091 return error; 1135 return error;
1092} 1136}
@@ -1096,12 +1140,16 @@ static void module_remove_modinfo_attrs(struct module *mod)
1096 struct module_attribute *attr; 1140 struct module_attribute *attr;
1097 int i; 1141 int i;
1098 1142
1099 for (i = 0; (attr = modinfo_attrs[i]); i++) { 1143 for (i = 0; (attr = &mod->modinfo_attrs[i]); i++) {
1144 /* pick a field to test for end of list */
1145 if (!attr->attr.name)
1146 break;
1100 sysfs_remove_file(&mod->mkobj.kobj,&attr->attr); 1147 sysfs_remove_file(&mod->mkobj.kobj,&attr->attr);
1101 attr->free(mod); 1148 if (attr->free)
1149 attr->free(mod);
1102 } 1150 }
1151 kfree(mod->modinfo_attrs);
1103} 1152}
1104#endif
1105 1153
1106static int mod_sysfs_setup(struct module *mod, 1154static int mod_sysfs_setup(struct module *mod,
1107 struct kernel_param *kparam, 1155 struct kernel_param *kparam,
@@ -1119,19 +1167,13 @@ static int mod_sysfs_setup(struct module *mod,
1119 if (err) 1167 if (err)
1120 goto out; 1168 goto out;
1121 1169
1122 err = module_add_refcnt_attr(mod);
1123 if (err)
1124 goto out_unreg;
1125
1126 err = module_param_sysfs_setup(mod, kparam, num_params); 1170 err = module_param_sysfs_setup(mod, kparam, num_params);
1127 if (err) 1171 if (err)
1128 goto out_unreg; 1172 goto out_unreg;
1129 1173
1130#ifdef CONFIG_MODULE_UNLOAD
1131 err = module_add_modinfo_attrs(mod); 1174 err = module_add_modinfo_attrs(mod);
1132 if (err) 1175 if (err)
1133 goto out_unreg; 1176 goto out_unreg;
1134#endif
1135 1177
1136 return 0; 1178 return 0;
1137 1179
@@ -1143,10 +1185,7 @@ out:
1143 1185
1144static void mod_kobject_remove(struct module *mod) 1186static void mod_kobject_remove(struct module *mod)
1145{ 1187{
1146#ifdef CONFIG_MODULE_UNLOAD
1147 module_remove_modinfo_attrs(mod); 1188 module_remove_modinfo_attrs(mod);
1148#endif
1149 module_remove_refcnt_attr(mod);
1150 module_param_sysfs_remove(mod); 1189 module_param_sysfs_remove(mod);
1151 1190
1152 kobject_unregister(&mod->mkobj.kobj); 1191 kobject_unregister(&mod->mkobj.kobj);
@@ -1424,7 +1463,6 @@ static char *get_modinfo(Elf_Shdr *sechdrs,
1424 return NULL; 1463 return NULL;
1425} 1464}
1426 1465
1427#ifdef CONFIG_MODULE_UNLOAD
1428static void setup_modinfo(struct module *mod, Elf_Shdr *sechdrs, 1466static void setup_modinfo(struct module *mod, Elf_Shdr *sechdrs,
1429 unsigned int infoindex) 1467 unsigned int infoindex)
1430{ 1468{
@@ -1439,23 +1477,17 @@ static void setup_modinfo(struct module *mod, Elf_Shdr *sechdrs,
1439 attr->attr.name)); 1477 attr->attr.name));
1440 } 1478 }
1441} 1479}
1442#endif
1443 1480
1444#ifdef CONFIG_KALLSYMS 1481#ifdef CONFIG_KALLSYMS
1445int is_exported(const char *name, const struct module *mod) 1482int is_exported(const char *name, const struct module *mod)
1446{ 1483{
1447 unsigned int i; 1484 if (!mod && lookup_symbol(name, __start___ksymtab, __stop___ksymtab))
1448 1485 return 1;
1449 if (!mod) { 1486 else
1450 for (i = 0; __start___ksymtab+i < __stop___ksymtab; i++) 1487 if (lookup_symbol(name, mod->syms, mod->syms + mod->num_syms))
1451 if (strcmp(__start___ksymtab[i].name, name) == 0)
1452 return 1;
1453 return 0;
1454 }
1455 for (i = 0; i < mod->num_syms; i++)
1456 if (strcmp(mod->syms[i].name, name) == 0)
1457 return 1; 1488 return 1;
1458 return 0; 1489 else
1490 return 0;
1459} 1491}
1460 1492
1461/* As per nm */ 1493/* As per nm */
@@ -1537,7 +1569,8 @@ static struct module *load_module(void __user *umod,
1537 char *secstrings, *args, *modmagic, *strtab = NULL; 1569 char *secstrings, *args, *modmagic, *strtab = NULL;
1538 unsigned int i, symindex = 0, strindex = 0, setupindex, exindex, 1570 unsigned int i, symindex = 0, strindex = 0, setupindex, exindex,
1539 exportindex, modindex, obsparmindex, infoindex, gplindex, 1571 exportindex, modindex, obsparmindex, infoindex, gplindex,
1540 crcindex, gplcrcindex, versindex, pcpuindex; 1572 crcindex, gplcrcindex, versindex, pcpuindex, gplfutureindex,
1573 gplfuturecrcindex;
1541 long arglen; 1574 long arglen;
1542 struct module *mod; 1575 struct module *mod;
1543 long err = 0; 1576 long err = 0;
@@ -1618,8 +1651,10 @@ static struct module *load_module(void __user *umod,
1618 /* Optional sections */ 1651 /* Optional sections */
1619 exportindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab"); 1652 exportindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab");
1620 gplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl"); 1653 gplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl");
1654 gplfutureindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl_future");
1621 crcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab"); 1655 crcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab");
1622 gplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl"); 1656 gplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl");
1657 gplfuturecrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl_future");
1623 setupindex = find_sec(hdr, sechdrs, secstrings, "__param"); 1658 setupindex = find_sec(hdr, sechdrs, secstrings, "__param");
1624 exindex = find_sec(hdr, sechdrs, secstrings, "__ex_table"); 1659 exindex = find_sec(hdr, sechdrs, secstrings, "__ex_table");
1625 obsparmindex = find_sec(hdr, sechdrs, secstrings, "__obsparm"); 1660 obsparmindex = find_sec(hdr, sechdrs, secstrings, "__obsparm");
@@ -1755,10 +1790,8 @@ static struct module *load_module(void __user *umod,
1755 if (strcmp(mod->name, "driverloader") == 0) 1790 if (strcmp(mod->name, "driverloader") == 0)
1756 add_taint(TAINT_PROPRIETARY_MODULE); 1791 add_taint(TAINT_PROPRIETARY_MODULE);
1757 1792
1758#ifdef CONFIG_MODULE_UNLOAD
1759 /* Set up MODINFO_ATTR fields */ 1793 /* Set up MODINFO_ATTR fields */
1760 setup_modinfo(mod, sechdrs, infoindex); 1794 setup_modinfo(mod, sechdrs, infoindex);
1761#endif
1762 1795
1763 /* Fix up syms, so that st_value is a pointer to location. */ 1796 /* Fix up syms, so that st_value is a pointer to location. */
1764 err = simplify_symbols(sechdrs, symindex, strtab, versindex, pcpuindex, 1797 err = simplify_symbols(sechdrs, symindex, strtab, versindex, pcpuindex,
@@ -1775,10 +1808,16 @@ static struct module *load_module(void __user *umod,
1775 mod->gpl_syms = (void *)sechdrs[gplindex].sh_addr; 1808 mod->gpl_syms = (void *)sechdrs[gplindex].sh_addr;
1776 if (gplcrcindex) 1809 if (gplcrcindex)
1777 mod->gpl_crcs = (void *)sechdrs[gplcrcindex].sh_addr; 1810 mod->gpl_crcs = (void *)sechdrs[gplcrcindex].sh_addr;
1811 mod->num_gpl_future_syms = sechdrs[gplfutureindex].sh_size /
1812 sizeof(*mod->gpl_future_syms);
1813 mod->gpl_future_syms = (void *)sechdrs[gplfutureindex].sh_addr;
1814 if (gplfuturecrcindex)
1815 mod->gpl_future_crcs = (void *)sechdrs[gplfuturecrcindex].sh_addr;
1778 1816
1779#ifdef CONFIG_MODVERSIONS 1817#ifdef CONFIG_MODVERSIONS
1780 if ((mod->num_syms && !crcindex) || 1818 if ((mod->num_syms && !crcindex) ||
1781 (mod->num_gpl_syms && !gplcrcindex)) { 1819 (mod->num_gpl_syms && !gplcrcindex) ||
1820 (mod->num_gpl_future_syms && !gplfuturecrcindex)) {
1782 printk(KERN_WARNING "%s: No versions for exported symbols." 1821 printk(KERN_WARNING "%s: No versions for exported symbols."
1783 " Tainting kernel.\n", mod->name); 1822 " Tainting kernel.\n", mod->name);
1784 add_taint(TAINT_FORCED_MODULE); 1823 add_taint(TAINT_FORCED_MODULE);
diff --git a/kernel/params.c b/kernel/params.c
index c76ad25e6a21..a29150582310 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -638,13 +638,8 @@ static ssize_t module_attr_show(struct kobject *kobj,
638 if (!attribute->show) 638 if (!attribute->show)
639 return -EIO; 639 return -EIO;
640 640
641 if (!try_module_get(mk->mod))
642 return -ENODEV;
643
644 ret = attribute->show(attribute, mk->mod, buf); 641 ret = attribute->show(attribute, mk->mod, buf);
645 642
646 module_put(mk->mod);
647
648 return ret; 643 return ret;
649} 644}
650 645
@@ -662,13 +657,8 @@ static ssize_t module_attr_store(struct kobject *kobj,
662 if (!attribute->store) 657 if (!attribute->store)
663 return -EIO; 658 return -EIO;
664 659
665 if (!try_module_get(mk->mod))
666 return -ENODEV;
667
668 ret = attribute->store(attribute, mk->mod, buf, len); 660 ret = attribute->store(attribute, mk->mod, buf, len);
669 661
670 module_put(mk->mod);
671
672 return ret; 662 return ret;
673} 663}
674 664
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c
index 8cf15a569fcd..fedf5e369755 100644
--- a/kernel/rcupdate.c
+++ b/kernel/rcupdate.c
@@ -609,7 +609,7 @@ module_param(qlowmark, int, 0);
609module_param(rsinterval, int, 0); 609module_param(rsinterval, int, 0);
610#endif 610#endif
611EXPORT_SYMBOL_GPL(rcu_batches_completed); 611EXPORT_SYMBOL_GPL(rcu_batches_completed);
612EXPORT_SYMBOL(call_rcu); /* WARNING: GPL-only in April 2006. */ 612EXPORT_SYMBOL_GPL_FUTURE(call_rcu); /* WARNING: GPL-only in April 2006. */
613EXPORT_SYMBOL(call_rcu_bh); /* WARNING: GPL-only in April 2006. */ 613EXPORT_SYMBOL_GPL_FUTURE(call_rcu_bh); /* WARNING: GPL-only in April 2006. */
614EXPORT_SYMBOL_GPL(synchronize_rcu); 614EXPORT_SYMBOL_GPL(synchronize_rcu);
615EXPORT_SYMBOL(synchronize_kernel); /* WARNING: GPL-only in April 2006. */ 615EXPORT_SYMBOL_GPL_FUTURE(synchronize_kernel); /* WARNING: GPL-only in April 2006. */
diff --git a/lib/kobject.c b/lib/kobject.c
index efe67fa96a71..25204a41a9b0 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -194,6 +194,17 @@ int kobject_add(struct kobject * kobj)
194 unlink(kobj); 194 unlink(kobj);
195 if (parent) 195 if (parent)
196 kobject_put(parent); 196 kobject_put(parent);
197
198 /* be noisy on error issues */
199 if (error == -EEXIST)
200 printk("kobject_add failed for %s with -EEXIST, "
201 "don't try to register things with the "
202 "same name in the same directory.\n",
203 kobject_name(kobj));
204 else
205 printk("kobject_add failed for %s (%d)\n",
206 kobject_name(kobj), error);
207 dump_stack();
197 } 208 }
198 209
199 return error; 210 return error;
@@ -207,18 +218,13 @@ int kobject_add(struct kobject * kobj)
207 218
208int kobject_register(struct kobject * kobj) 219int kobject_register(struct kobject * kobj)
209{ 220{
210 int error = 0; 221 int error = -EINVAL;
211 if (kobj) { 222 if (kobj) {
212 kobject_init(kobj); 223 kobject_init(kobj);
213 error = kobject_add(kobj); 224 error = kobject_add(kobj);
214 if (error) { 225 if (!error)
215 printk("kobject_register failed for %s (%d)\n",
216 kobject_name(kobj),error);
217 dump_stack();
218 } else
219 kobject_uevent(kobj, KOBJ_ADD); 226 kobject_uevent(kobj, KOBJ_ADD);
220 } else 227 }
221 error = -EINVAL;
222 return error; 228 return error;
223} 229}
224 230
@@ -379,6 +385,44 @@ void kobject_put(struct kobject * kobj)
379} 385}
380 386
381 387
388static void dir_release(struct kobject *kobj)
389{
390 kfree(kobj);
391}
392
393static struct kobj_type dir_ktype = {
394 .release = dir_release,
395 .sysfs_ops = NULL,
396 .default_attrs = NULL,
397};
398
399/**
400 * kobject_add_dir - add sub directory of object.
401 * @parent: object in which a directory is created.
402 * @name: directory name.
403 *
404 * Add a plain directory object as child of given object.
405 */
406struct kobject *kobject_add_dir(struct kobject *parent, const char *name)
407{
408 struct kobject *k;
409
410 if (!parent)
411 return NULL;
412
413 k = kzalloc(sizeof(*k), GFP_KERNEL);
414 if (!k)
415 return NULL;
416
417 k->parent = parent;
418 k->ktype = &dir_ktype;
419 kobject_set_name(k, name);
420 kobject_register(k);
421
422 return k;
423}
424EXPORT_SYMBOL_GPL(kobject_add_dir);
425
382/** 426/**
383 * kset_init - initialize a kset for use 427 * kset_init - initialize a kset for use
384 * @k: kset 428 * @k: kset
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
index 086a0c6e888e..982226daf939 100644
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
@@ -26,6 +26,8 @@
26#define NUM_ENVP 32 /* number of env pointers */ 26#define NUM_ENVP 32 /* number of env pointers */
27 27
28#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET) 28#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
29u64 uevent_seqnum;
30char uevent_helper[UEVENT_HELPER_PATH_LEN] = "/sbin/hotplug";
29static DEFINE_SPINLOCK(sequence_lock); 31static DEFINE_SPINLOCK(sequence_lock);
30static struct sock *uevent_sock; 32static struct sock *uevent_sock;
31 33
diff --git a/lib/kref.c b/lib/kref.c
index 0d07cc31c818..4a467faf1367 100644
--- a/lib/kref.c
+++ b/lib/kref.c
@@ -52,7 +52,12 @@ int kref_put(struct kref *kref, void (*release)(struct kref *kref))
52 WARN_ON(release == NULL); 52 WARN_ON(release == NULL);
53 WARN_ON(release == (void (*)(struct kref *))kfree); 53 WARN_ON(release == (void (*)(struct kref *))kfree);
54 54
55 if (atomic_dec_and_test(&kref->refcount)) { 55 /*
56 * if current count is one, we are the last user and can release object
57 * right now, avoiding an atomic operation on 'refcount'
58 */
59 if ((atomic_read(&kref->refcount) == 1) ||
60 (atomic_dec_and_test(&kref->refcount))) {
56 release(kref); 61 release(kref);
57 return 1; 62 return 1;
58 } 63 }
diff --git a/scripts/genksyms/keywords.c_shipped b/scripts/genksyms/keywords.c_shipped
index ee4647805c58..d8153f572e40 100644
--- a/scripts/genksyms/keywords.c_shipped
+++ b/scripts/genksyms/keywords.c_shipped
@@ -52,9 +52,9 @@ is_reserved_hash (register const char *str, register unsigned int len)
52 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 52 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
53 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 53 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
54 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 54 71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
55 71, 71, 71, 71, 71, 71, 71, 71, 71, 15, 55 71, 71, 71, 71, 71, 71, 71, 71, 71, 0,
56 71, 71, 71, 71, 71, 71, 15, 71, 71, 71, 56 71, 71, 71, 71, 71, 71, 35, 71, 71, 71,
57 10, 71, 71, 71, 71, 71, 71, 71, 71, 71, 57 5, 71, 71, 71, 71, 71, 71, 71, 71, 71,
58 71, 71, 71, 71, 71, 0, 71, 0, 71, 5, 58 71, 71, 71, 71, 71, 0, 71, 0, 71, 5,
59 5, 0, 10, 20, 71, 25, 71, 71, 20, 0, 59 5, 0, 10, 20, 71, 25, 71, 71, 20, 0,
60 20, 30, 25, 71, 10, 5, 0, 20, 15, 71, 60 20, 30, 25, 71, 10, 5, 0, 20, 15, 71,
@@ -84,9 +84,9 @@ is_reserved_word (register const char *str, register unsigned int len)
84{ 84{
85 enum 85 enum
86 { 86 {
87 TOTAL_KEYWORDS = 41, 87 TOTAL_KEYWORDS = 42,
88 MIN_WORD_LENGTH = 3, 88 MIN_WORD_LENGTH = 3,
89 MAX_WORD_LENGTH = 17, 89 MAX_WORD_LENGTH = 24,
90 MIN_HASH_VALUE = 3, 90 MIN_HASH_VALUE = 3,
91 MAX_HASH_VALUE = 70 91 MAX_HASH_VALUE = 70
92 }; 92 };
@@ -94,104 +94,105 @@ is_reserved_word (register const char *str, register unsigned int len)
94 static const struct resword wordlist[] = 94 static const struct resword wordlist[] =
95 { 95 {
96 {""}, {""}, {""}, 96 {""}, {""}, {""},
97#line 24 "scripts/genksyms/keywords.gperf" 97#line 25 "scripts/genksyms/keywords.gperf"
98 {"asm", ASM_KEYW}, 98 {"asm", ASM_KEYW},
99 {""}, 99 {""},
100#line 7 "scripts/genksyms/keywords.gperf" 100#line 8 "scripts/genksyms/keywords.gperf"
101 {"__asm", ASM_KEYW}, 101 {"__asm", ASM_KEYW},
102 {""}, 102 {""},
103#line 8 "scripts/genksyms/keywords.gperf" 103#line 9 "scripts/genksyms/keywords.gperf"
104 {"__asm__", ASM_KEYW}, 104 {"__asm__", ASM_KEYW},
105 {""}, 105 {""},
106#line 21 "scripts/genksyms/keywords.gperf" 106#line 22 "scripts/genksyms/keywords.gperf"
107 {"_restrict", RESTRICT_KEYW}, 107 {"_restrict", RESTRICT_KEYW},
108#line 50 "scripts/genksyms/keywords.gperf" 108#line 51 "scripts/genksyms/keywords.gperf"
109 {"__typeof__", TYPEOF_KEYW}, 109 {"__typeof__", TYPEOF_KEYW},
110#line 9 "scripts/genksyms/keywords.gperf" 110#line 10 "scripts/genksyms/keywords.gperf"
111 {"__attribute", ATTRIBUTE_KEYW}, 111 {"__attribute", ATTRIBUTE_KEYW},
112#line 11 "scripts/genksyms/keywords.gperf" 112#line 12 "scripts/genksyms/keywords.gperf"
113 {"__const", CONST_KEYW}, 113 {"__const", CONST_KEYW},
114#line 10 "scripts/genksyms/keywords.gperf" 114#line 11 "scripts/genksyms/keywords.gperf"
115 {"__attribute__", ATTRIBUTE_KEYW}, 115 {"__attribute__", ATTRIBUTE_KEYW},
116#line 12 "scripts/genksyms/keywords.gperf" 116#line 13 "scripts/genksyms/keywords.gperf"
117 {"__const__", CONST_KEYW}, 117 {"__const__", CONST_KEYW},
118#line 16 "scripts/genksyms/keywords.gperf" 118#line 17 "scripts/genksyms/keywords.gperf"
119 {"__signed__", SIGNED_KEYW}, 119 {"__signed__", SIGNED_KEYW},
120#line 42 "scripts/genksyms/keywords.gperf" 120#line 43 "scripts/genksyms/keywords.gperf"
121 {"static", STATIC_KEYW}, 121 {"static", STATIC_KEYW},
122 {""}, 122 {""},
123#line 15 "scripts/genksyms/keywords.gperf" 123#line 16 "scripts/genksyms/keywords.gperf"
124 {"__signed", SIGNED_KEYW}, 124 {"__signed", SIGNED_KEYW},
125#line 30 "scripts/genksyms/keywords.gperf" 125#line 31 "scripts/genksyms/keywords.gperf"
126 {"char", CHAR_KEYW}, 126 {"char", CHAR_KEYW},
127 {""}, 127 {""},
128#line 43 "scripts/genksyms/keywords.gperf" 128#line 44 "scripts/genksyms/keywords.gperf"
129 {"struct", STRUCT_KEYW}, 129 {"struct", STRUCT_KEYW},
130#line 22 "scripts/genksyms/keywords.gperf"
131 {"__restrict__", RESTRICT_KEYW},
132#line 23 "scripts/genksyms/keywords.gperf" 130#line 23 "scripts/genksyms/keywords.gperf"
131 {"__restrict__", RESTRICT_KEYW},
132#line 24 "scripts/genksyms/keywords.gperf"
133 {"restrict", RESTRICT_KEYW}, 133 {"restrict", RESTRICT_KEYW},
134#line 33 "scripts/genksyms/keywords.gperf" 134#line 34 "scripts/genksyms/keywords.gperf"
135 {"enum", ENUM_KEYW}, 135 {"enum", ENUM_KEYW},
136#line 17 "scripts/genksyms/keywords.gperf" 136#line 18 "scripts/genksyms/keywords.gperf"
137 {"__volatile", VOLATILE_KEYW}, 137 {"__volatile", VOLATILE_KEYW},
138#line 34 "scripts/genksyms/keywords.gperf" 138#line 35 "scripts/genksyms/keywords.gperf"
139 {"extern", EXTERN_KEYW}, 139 {"extern", EXTERN_KEYW},
140#line 18 "scripts/genksyms/keywords.gperf" 140#line 19 "scripts/genksyms/keywords.gperf"
141 {"__volatile__", VOLATILE_KEYW}, 141 {"__volatile__", VOLATILE_KEYW},
142#line 37 "scripts/genksyms/keywords.gperf" 142#line 38 "scripts/genksyms/keywords.gperf"
143 {"int", INT_KEYW}, 143 {"int", INT_KEYW},
144 {""}, 144#line 7 "scripts/genksyms/keywords.gperf"
145#line 31 "scripts/genksyms/keywords.gperf" 145 {"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW},
146 {"const", CONST_KEYW},
147#line 32 "scripts/genksyms/keywords.gperf" 146#line 32 "scripts/genksyms/keywords.gperf"
147 {"const", CONST_KEYW},
148#line 33 "scripts/genksyms/keywords.gperf"
148 {"double", DOUBLE_KEYW}, 149 {"double", DOUBLE_KEYW},
149 {""}, 150 {""},
150#line 13 "scripts/genksyms/keywords.gperf" 151#line 14 "scripts/genksyms/keywords.gperf"
151 {"__inline", INLINE_KEYW}, 152 {"__inline", INLINE_KEYW},
152#line 29 "scripts/genksyms/keywords.gperf" 153#line 30 "scripts/genksyms/keywords.gperf"
153 {"auto", AUTO_KEYW}, 154 {"auto", AUTO_KEYW},
154#line 14 "scripts/genksyms/keywords.gperf" 155#line 15 "scripts/genksyms/keywords.gperf"
155 {"__inline__", INLINE_KEYW}, 156 {"__inline__", INLINE_KEYW},
156#line 41 "scripts/genksyms/keywords.gperf" 157#line 42 "scripts/genksyms/keywords.gperf"
157 {"signed", SIGNED_KEYW}, 158 {"signed", SIGNED_KEYW},
158 {""}, 159 {""},
159#line 46 "scripts/genksyms/keywords.gperf" 160#line 47 "scripts/genksyms/keywords.gperf"
160 {"unsigned", UNSIGNED_KEYW}, 161 {"unsigned", UNSIGNED_KEYW},
161 {""}, 162 {""},
162#line 40 "scripts/genksyms/keywords.gperf" 163#line 41 "scripts/genksyms/keywords.gperf"
163 {"short", SHORT_KEYW}, 164 {"short", SHORT_KEYW},
164#line 49 "scripts/genksyms/keywords.gperf" 165#line 50 "scripts/genksyms/keywords.gperf"
165 {"typeof", TYPEOF_KEYW}, 166 {"typeof", TYPEOF_KEYW},
166#line 44 "scripts/genksyms/keywords.gperf" 167#line 45 "scripts/genksyms/keywords.gperf"
167 {"typedef", TYPEDEF_KEYW}, 168 {"typedef", TYPEDEF_KEYW},
168#line 48 "scripts/genksyms/keywords.gperf" 169#line 49 "scripts/genksyms/keywords.gperf"
169 {"volatile", VOLATILE_KEYW}, 170 {"volatile", VOLATILE_KEYW},
170 {""}, 171 {""},
171#line 35 "scripts/genksyms/keywords.gperf" 172#line 36 "scripts/genksyms/keywords.gperf"
172 {"float", FLOAT_KEYW}, 173 {"float", FLOAT_KEYW},
173 {""}, {""}, 174 {""}, {""},
174#line 39 "scripts/genksyms/keywords.gperf" 175#line 40 "scripts/genksyms/keywords.gperf"
175 {"register", REGISTER_KEYW}, 176 {"register", REGISTER_KEYW},
176#line 47 "scripts/genksyms/keywords.gperf" 177#line 48 "scripts/genksyms/keywords.gperf"
177 {"void", VOID_KEYW}, 178 {"void", VOID_KEYW},
178 {""}, 179 {""},
179#line 36 "scripts/genksyms/keywords.gperf" 180#line 37 "scripts/genksyms/keywords.gperf"
180 {"inline", INLINE_KEYW}, 181 {"inline", INLINE_KEYW},
181 {""}, 182 {""},
182#line 5 "scripts/genksyms/keywords.gperf" 183#line 5 "scripts/genksyms/keywords.gperf"
183 {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW}, 184 {"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW},
184 {""}, 185 {""},
185#line 20 "scripts/genksyms/keywords.gperf" 186#line 21 "scripts/genksyms/keywords.gperf"
186 {"_Bool", BOOL_KEYW}, 187 {"_Bool", BOOL_KEYW},
187 {""}, 188 {""},
188#line 6 "scripts/genksyms/keywords.gperf" 189#line 6 "scripts/genksyms/keywords.gperf"
189 {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW}, 190 {"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW},
190 {""}, {""}, {""}, {""}, {""}, {""}, 191 {""}, {""}, {""}, {""}, {""}, {""},
191#line 38 "scripts/genksyms/keywords.gperf" 192#line 39 "scripts/genksyms/keywords.gperf"
192 {"long", LONG_KEYW}, 193 {"long", LONG_KEYW},
193 {""}, {""}, {""}, {""}, {""}, 194 {""}, {""}, {""}, {""}, {""},
194#line 45 "scripts/genksyms/keywords.gperf" 195#line 46 "scripts/genksyms/keywords.gperf"
195 {"union", UNION_KEYW} 196 {"union", UNION_KEYW}
196 }; 197 };
197 198
diff --git a/scripts/genksyms/keywords.gperf b/scripts/genksyms/keywords.gperf
index b6bec765996e..c75e0c8d8f0c 100644
--- a/scripts/genksyms/keywords.gperf
+++ b/scripts/genksyms/keywords.gperf
@@ -4,6 +4,7 @@ struct resword { const char *name; int token; }
4%% 4%%
5EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW 5EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW
6EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW 6EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW
7EXPORT_SYMBOL_GPL_FUTURE, EXPORT_SYMBOL_KEYW
7__asm, ASM_KEYW 8__asm, ASM_KEYW
8__asm__, ASM_KEYW 9__asm__, ASM_KEYW
9__attribute, ATTRIBUTE_KEYW 10__attribute, ATTRIBUTE_KEYW