2006-03-20 21:50:26

by Greg KH

[permalink] [raw]
Subject: [GIT PATCH] Driver Core and sysfs stuff for 2.6.16

Here are some driver core and sysfs patches for 2.6.16. They contain
the following changes:
- EXPORT_SYMBOL_GPL_FUTURE() added to the kernel
- mark a few subsystems with this new export
- fix a few sysfs bugs (fixes a few bugs with USB device
removals).
- kref optimization
- semaphore to mutex conversions
- module sysfs files reference counting fixes
- make sysfs a bit more verbous about errors/stupid usages.
- mark where people are using the driver model wrong more
obvious.
- add kobject_add_dir() function
- add binary blob file type helper to debugfs
- remove a few sysfs functions from being exported as no one
except the kobject code should be using it (it is impossible
to use these, so no one has.)
- firmware error path fixes

All of these patches have been in the -mm tree for a number of weeks, if
not months.

Please pull from:
rsync://rsync.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-2.6.git/
or if master.kernel.org hasn't synced up yet:
master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6.git/

Patches will be sent as a follow-on to this message to lkml for people
to see.

thanks,

greg k-h


Documentation/feature-removal-schedule.txt | 18 ++
arch/arm/common/locomo.c | 2
arch/arm/common/sa1111.c | 2
arch/m68knommu/kernel/vmlinux.lds.S | 10 +
arch/v850/kernel/vmlinux.lds.S | 8 +
block/genhd.c | 31 ++--
drivers/base/cpu.c | 2
drivers/base/firmware_class.c | 6
drivers/base/map.c | 21 +--
drivers/base/platform.c | 4
drivers/char/s3c2410-rtc.c | 4
drivers/char/watchdog/mpcore_wdt.c | 4
drivers/i2c/busses/i2c-iop3xx.c | 9 +
drivers/i2c/busses/i2c-mpc.c | 5
drivers/i2c/busses/i2c-mv64xxx.c | 4
drivers/ide/mips/au1xxx-ide.c | 5
drivers/mmc/pxamci.c | 2
drivers/net/arm/am79c961a.c | 4
drivers/net/fs_enet/mac-fcc.c | 2
drivers/net/fs_enet/mac-fec.c | 2
drivers/net/fs_enet/mac-scc.c | 2
drivers/net/gianfar.c | 4
drivers/net/smc91x.c | 4
drivers/pcmcia/omap_cf.c | 2
drivers/serial/s3c2410.c | 2
drivers/usb/core/driver.c | 6
drivers/usb/host/ohci-omap.c | 9 +
drivers/video/epson1355fb.c | 1
drivers/video/sa1100fb.c | 2
drivers/video/vfb.c | 1
fs/char_dev.c | 17 +-
fs/debugfs/file.c | 46 ++++++
fs/sysfs/dir.c | 37 ++++-
fs/sysfs/file.c | 9 -
fs/sysfs/inode.c | 9 -
fs/sysfs/symlink.c | 6
fs/sysfs/sysfs.h | 1
include/asm-generic/vmlinux.lds.h | 14 ++
include/linux/cpu.h | 2
include/linux/debugfs.h | 15 ++
include/linux/device.h | 2
include/linux/kobj_map.h | 4
include/linux/kobject.h | 4
include/linux/module.h | 10 +
kernel/ksysfs.c | 3
kernel/module.c | 199 +++++++++++++++++------------
kernel/params.c | 10 -
kernel/rcupdate.c | 6
lib/kobject.c | 60 +++++++-
lib/kobject_uevent.c | 2
lib/kref.c | 7 -
scripts/genksyms/keywords.c_shipped | 91 ++++++-------
scripts/genksyms/keywords.gperf | 1
53 files changed, 514 insertions(+), 219 deletions(-)

---------------

Adrian Bunk:
Kobject: kobject.h: fix a typo

Andrew Morton:
get_cpu_sysdev() signedness fix

David Vrabel:
driver core: platform_get_irq*(): return -ENXIO on error
handle errors returned by platform_get_irq*()

Eric Dumazet:
kref: avoid an atomic operation in kref_put()

Eric Sesterhenn:
sysfs: kzalloc conversion

Greg Kroah-Hartman:
sysfs: sysfs_remove_dir() needs to invalidate the dentry
Mark empty release functions as broken
add EXPORT_SYMBOL_GPL_FUTURE()
add EXPORT_SYMBOL_GPL_FUTURE() to RCU subsystem
add EXPORT_SYMBOL_GPL_FUTURE() to USB subsystem
fix module sysfs files reference counting
Kobject: provide better warning messages when people do stupid things
sysfs: don't export dir symbols
sysfs: fix a kobject leak in sysfs_add_link on the error path

Jeff Moyer:
firmware: fix BUG: in fw_realloc_buffer

Jes Sorensen:
kobj_map semaphore to mutex conversion

Jun'ichi Nomura:
kobject: fix build error if CONFIG_SYSFS=n
kobject_add_dir

Maneesh Soni:
sysfs: fix problem with duplicate sysfs directories and files

Michael Ellerman:
debugfs: Add debugfs_create_blob() helper for exporting binary data

Sam Ravnborg:
Clean up module.c symbol searching logic

Tilman Schmidt:
Driver core: add macros notice(), dev_notice()


2006-03-20 22:01:32

by Greg KH

[permalink] [raw]
Subject: [PATCH 20/23] kobject_add_dir

Adding kobject_add_dir() function which creates a subdirectory
for a given kobject.

Signed-off-by: Jun'ichi Nomura <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---

include/linux/kobject.h | 2 ++
lib/kobject.c | 38 ++++++++++++++++++++++++++++++++++++++
2 files changed, 40 insertions(+), 0 deletions(-)

7423172a50968de1905a61413c52bb070a62f5ce
diff --git a/include/linux/kobject.h b/include/linux/kobject.h
index 7ece63f..4cb1214 100644
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -80,6 +80,8 @@ extern void kobject_unregister(struct ko
extern struct kobject * kobject_get(struct kobject *);
extern void kobject_put(struct kobject *);

+extern struct kobject *kobject_add_dir(struct kobject *, const char *);
+
extern char * kobject_get_path(struct kobject *, gfp_t);

struct kobj_type {
diff --git a/lib/kobject.c b/lib/kobject.c
index 36668c8..25204a4 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -385,6 +385,44 @@ void kobject_put(struct kobject * kobj)
}


+static void dir_release(struct kobject *kobj)
+{
+ kfree(kobj);
+}
+
+static struct kobj_type dir_ktype = {
+ .release = dir_release,
+ .sysfs_ops = NULL,
+ .default_attrs = NULL,
+};
+
+/**
+ * kobject_add_dir - add sub directory of object.
+ * @parent: object in which a directory is created.
+ * @name: directory name.
+ *
+ * Add a plain directory object as child of given object.
+ */
+struct kobject *kobject_add_dir(struct kobject *parent, const char *name)
+{
+ struct kobject *k;
+
+ if (!parent)
+ return NULL;
+
+ k = kzalloc(sizeof(*k), GFP_KERNEL);
+ if (!k)
+ return NULL;
+
+ k->parent = parent;
+ k->ktype = &dir_ktype;
+ kobject_set_name(k, name);
+ kobject_register(k);
+
+ return k;
+}
+EXPORT_SYMBOL_GPL(kobject_add_dir);
+
/**
* kset_init - initialize a kset for use
* @k: kset
--
1.2.4


2006-03-20 22:01:04

by Greg KH

[permalink] [raw]
Subject: [PATCH 21/23] get_cpu_sysdev() signedness fix

Doing (int < NR_CPUS) doesn't dtrt if it's negative..

Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---

drivers/base/cpu.c | 2 +-
include/linux/cpu.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

a29d642a4aa99c5234314ab2523281139226c231
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 07a7f97..29f3d75 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -141,7 +141,7 @@ int __devinit register_cpu(struct cpu *c
return error;
}

-struct sys_device *get_cpu_sysdev(int cpu)
+struct sys_device *get_cpu_sysdev(unsigned cpu)
{
if (cpu < NR_CPUS)
return cpu_sys_devices[cpu];
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 0ed1d48..d612b89 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -32,7 +32,7 @@ struct cpu {
};

extern int register_cpu(struct cpu *, int, struct node *);
-extern struct sys_device *get_cpu_sysdev(int cpu);
+extern struct sys_device *get_cpu_sysdev(unsigned cpu);
#ifdef CONFIG_HOTPLUG_CPU
extern void unregister_cpu(struct cpu *, struct node *);
#endif
--
1.2.4


2006-03-20 22:01:05

by Greg KH

[permalink] [raw]
Subject: [PATCH 22/23] sysfs: don't export dir symbols

These functions should only be used by the kobject core, and if any
driver tries to use them, bad things happen. Unexport them to try to
prevent this from happening.

Signed-off-by: Greg Kroah-Hartman <[email protected]>

---

fs/sysfs/dir.c | 4 ----
1 files changed, 0 insertions(+), 4 deletions(-)

832c57e9afa7a263bb2f8ee6d04d527ef6709aae
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index bea1f4c..9ee9568 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -510,7 +510,3 @@ struct file_operations sysfs_dir_operati
.read = generic_read_dir,
.readdir = sysfs_readdir,
};
-
-EXPORT_SYMBOL_GPL(sysfs_create_dir);
-EXPORT_SYMBOL_GPL(sysfs_remove_dir);
-EXPORT_SYMBOL_GPL(sysfs_rename_dir);
--
1.2.4


2006-03-20 22:01:32

by Greg KH

[permalink] [raw]
Subject: [PATCH 18/23] sysfs: fix problem with duplicate sysfs directories and files

The following patch checks for existing sysfs_dirent before
preparing new one while creating sysfs directories and files.

Signed-off-by: Maneesh Soni <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---

fs/sysfs/dir.c | 32 +++++++++++++++++++++++++++++++-
fs/sysfs/file.c | 6 ++++--
fs/sysfs/symlink.c | 5 +++--
fs/sysfs/sysfs.h | 1 +
4 files changed, 39 insertions(+), 5 deletions(-)

c516865cfbac0d862d4888df91793ad1e74ffd58
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index cfd290d..bea1f4c 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -50,6 +50,32 @@ static struct sysfs_dirent * sysfs_new_d
return sd;
}

+/**
+ *
+ * Return -EEXIST if there is already a sysfs element with the same name for
+ * the same parent.
+ *
+ * called with parent inode's i_mutex held
+ */
+int sysfs_dirent_exist(struct sysfs_dirent *parent_sd,
+ const unsigned char *new)
+{
+ struct sysfs_dirent * sd;
+
+ list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
+ if (sd->s_element) {
+ const unsigned char *existing = sysfs_get_name(sd);
+ if (strcmp(existing, new))
+ continue;
+ else
+ return -EEXIST;
+ }
+ }
+
+ return 0;
+}
+
+
int sysfs_make_dirent(struct sysfs_dirent * parent_sd, struct dentry * dentry,
void * element, umode_t mode, int type)
{
@@ -102,7 +128,11 @@ static int create_dir(struct kobject * k
mutex_lock(&p->d_inode->i_mutex);
*d = lookup_one_len(n, p, strlen(n));
if (!IS_ERR(*d)) {
- error = sysfs_make_dirent(p->d_fsdata, *d, k, mode, SYSFS_DIR);
+ if (sysfs_dirent_exist(p->d_fsdata, n))
+ error = -EEXIST;
+ else
+ error = sysfs_make_dirent(p->d_fsdata, *d, k, mode,
+ SYSFS_DIR);
if (!error) {
error = sysfs_create(*d, mode, init_dir);
if (!error) {
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index e21f402..5e83e72 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -361,10 +361,12 @@ int sysfs_add_file(struct dentry * dir,
{
struct sysfs_dirent * parent_sd = dir->d_fsdata;
umode_t mode = (attr->mode & S_IALLUGO) | S_IFREG;
- int error = 0;
+ int error = -EEXIST;

mutex_lock(&dir->d_inode->i_mutex);
- error = sysfs_make_dirent(parent_sd, NULL, (void *) attr, mode, type);
+ if (!sysfs_dirent_exist(parent_sd, attr->name))
+ error = sysfs_make_dirent(parent_sd, NULL, (void *)attr,
+ mode, type);
mutex_unlock(&dir->d_inode->i_mutex);

return error;
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index e38d633..fe23f47 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -82,12 +82,13 @@ exit1:
int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char * name)
{
struct dentry * dentry = kobj->dentry;
- int error = 0;
+ int error = -EEXIST;

BUG_ON(!kobj || !kobj->dentry || !name);

mutex_lock(&dentry->d_inode->i_mutex);
- error = sysfs_add_link(dentry, name, target);
+ if (!sysfs_dirent_exist(dentry->d_fsdata, name))
+ error = sysfs_add_link(dentry, name, target);
mutex_unlock(&dentry->d_inode->i_mutex);
return error;
}
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index 3f8953e..cf11d5b 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -5,6 +5,7 @@ extern kmem_cache_t *sysfs_dir_cachep;
extern struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent *);
extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *));

+extern int sysfs_dirent_exist(struct sysfs_dirent *, const unsigned char *);
extern int sysfs_make_dirent(struct sysfs_dirent *, struct dentry *, void *,
umode_t, int);

--
1.2.4


2006-03-20 22:02:10

by Greg KH

[permalink] [raw]
Subject: [PATCH 06/23] kref: avoid an atomic operation in kref_put()

Avoid an atomic operation in kref_put() when the last reference is
dropped. On most platforms, atomic_read() is a plan read of the counter
and involves no atomic at all.

Signed-off-by: Eric Dumazet <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---

lib/kref.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)

8b5536bbee53620f8d5f367987e5727ba36d886d
diff --git a/lib/kref.c b/lib/kref.c
index 0d07cc3..4a467fa 100644
--- a/lib/kref.c
+++ b/lib/kref.c
@@ -52,7 +52,12 @@ int kref_put(struct kref *kref, void (*r
WARN_ON(release == NULL);
WARN_ON(release == (void (*)(struct kref *))kfree);

- if (atomic_dec_and_test(&kref->refcount)) {
+ /*
+ * if current count is one, we are the last user and can release object
+ * right now, avoiding an atomic operation on 'refcount'
+ */
+ if ((atomic_read(&kref->refcount) == 1) ||
+ (atomic_dec_and_test(&kref->refcount))) {
release(kref);
return 1;
}
--
1.2.4


2006-03-20 22:02:11

by Greg KH

[permalink] [raw]
Subject: [PATCH 16/23] Kobject: provide better warning messages when people do stupid things

Now that kobject_add() is used more than kobject_register() the kernel
wasn't always letting people know that they were doing something wrong.
This change fixes this.

Signed-off-by: Greg Kroah-Hartman <[email protected]>

---

lib/kobject.c | 22 ++++++++++++++--------
1 files changed, 14 insertions(+), 8 deletions(-)

dcd0da002122a70fe1c625c0ca9f58c95aa33ebe
diff --git a/lib/kobject.c b/lib/kobject.c
index efe67fa..36668c8 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -194,6 +194,17 @@ int kobject_add(struct kobject * kobj)
unlink(kobj);
if (parent)
kobject_put(parent);
+
+ /* be noisy on error issues */
+ if (error == -EEXIST)
+ printk("kobject_add failed for %s with -EEXIST, "
+ "don't try to register things with the "
+ "same name in the same directory.\n",
+ kobject_name(kobj));
+ else
+ printk("kobject_add failed for %s (%d)\n",
+ kobject_name(kobj), error);
+ dump_stack();
}

return error;
@@ -207,18 +218,13 @@ int kobject_add(struct kobject * kobj)

int kobject_register(struct kobject * kobj)
{
- int error = 0;
+ int error = -EINVAL;
if (kobj) {
kobject_init(kobj);
error = kobject_add(kobj);
- if (error) {
- printk("kobject_register failed for %s (%d)\n",
- kobject_name(kobj),error);
- dump_stack();
- } else
+ if (!error)
kobject_uevent(kobj, KOBJ_ADD);
- } else
- error = -EINVAL;
+ }
return error;
}

--
1.2.4


2006-03-20 22:02:15

by Greg KH

[permalink] [raw]
Subject: [PATCH 07/23] kobj_map semaphore to mutex conversion

Convert the kobj_map code to use a mutex instead of a semaphore. It
converts the single two users as well, genhd.c and char_dev.c.

Signed-off-by: Jes Sorensen <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---

block/genhd.c | 31 ++++++++++++++++---------------
drivers/base/map.c | 21 +++++++++++----------
fs/char_dev.c | 17 +++++++++--------
include/linux/kobj_map.h | 4 ++--
4 files changed, 38 insertions(+), 35 deletions(-)

58383af629efb07e5a0694e445eda0c65b16e1de
diff --git a/block/genhd.c b/block/genhd.c
index db57546..64510fd 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -15,12 +15,13 @@
#include <linux/kmod.h>
#include <linux/kobj_map.h>
#include <linux/buffer_head.h>
+#include <linux/mutex.h>

#define MAX_PROBE_HASH 255 /* random */

static struct subsystem block_subsys;

-static DECLARE_MUTEX(block_subsys_sem);
+static DEFINE_MUTEX(block_subsys_lock);

/*
* Can be deleted altogether. Later.
@@ -46,7 +47,7 @@ struct blkdev_info {
/*
* iterate over a list of blkdev_info structures. allows
* the major_names array to be iterated over from outside this file
- * must be called with the block_subsys_sem held
+ * must be called with the block_subsys_lock held
*/
void *get_next_blkdev(void *dev)
{
@@ -85,20 +86,20 @@ out:

void *acquire_blkdev_list(void)
{
- down(&block_subsys_sem);
+ mutex_lock(&block_subsys_lock);
return get_next_blkdev(NULL);
}

void release_blkdev_list(void *dev)
{
- up(&block_subsys_sem);
+ mutex_unlock(&block_subsys_lock);
kfree(dev);
}


/*
* Count the number of records in the blkdev_list.
- * must be called with the block_subsys_sem held
+ * must be called with the block_subsys_lock held
*/
int count_blkdev_list(void)
{
@@ -118,7 +119,7 @@ int count_blkdev_list(void)
/*
* extract the major and name values from a blkdev_info struct
* passed in as a void to *dev. Must be called with
- * block_subsys_sem held
+ * block_subsys_lock held
*/
int get_blkdev_info(void *dev, int *major, char **name)
{
@@ -138,7 +139,7 @@ int register_blkdev(unsigned int major,
struct blk_major_name **n, *p;
int index, ret = 0;

- down(&block_subsys_sem);
+ mutex_lock(&block_subsys_lock);

/* temporary */
if (major == 0) {
@@ -183,7 +184,7 @@ int register_blkdev(unsigned int major,
kfree(p);
}
out:
- up(&block_subsys_sem);
+ mutex_unlock(&block_subsys_lock);
return ret;
}

@@ -197,7 +198,7 @@ int unregister_blkdev(unsigned int major
int index = major_to_index(major);
int ret = 0;

- down(&block_subsys_sem);
+ mutex_lock(&block_subsys_lock);
for (n = &major_names[index]; *n; n = &(*n)->next)
if ((*n)->major == major)
break;
@@ -207,7 +208,7 @@ int unregister_blkdev(unsigned int major
p = *n;
*n = p->next;
}
- up(&block_subsys_sem);
+ mutex_unlock(&block_subsys_lock);
kfree(p);

return ret;
@@ -301,7 +302,7 @@ static void *part_start(struct seq_file
struct list_head *p;
loff_t l = *pos;

- down(&block_subsys_sem);
+ mutex_lock(&block_subsys_lock);
list_for_each(p, &block_subsys.kset.list)
if (!l--)
return list_entry(p, struct gendisk, kobj.entry);
@@ -318,7 +319,7 @@ static void *part_next(struct seq_file *

static void part_stop(struct seq_file *part, void *v)
{
- up(&block_subsys_sem);
+ mutex_unlock(&block_subsys_lock);
}

static int show_partition(struct seq_file *part, void *v)
@@ -377,7 +378,7 @@ static struct kobject *base_probe(dev_t

static int __init genhd_device_init(void)
{
- bdev_map = kobj_map_init(base_probe, &block_subsys_sem);
+ bdev_map = kobj_map_init(base_probe, &block_subsys_lock);
blk_dev_init();
subsystem_register(&block_subsys);
return 0;
@@ -611,7 +612,7 @@ static void *diskstats_start(struct seq_
loff_t k = *pos;
struct list_head *p;

- down(&block_subsys_sem);
+ mutex_lock(&block_subsys_lock);
list_for_each(p, &block_subsys.kset.list)
if (!k--)
return list_entry(p, struct gendisk, kobj.entry);
@@ -628,7 +629,7 @@ static void *diskstats_next(struct seq_f

static void diskstats_stop(struct seq_file *part, void *v)
{
- up(&block_subsys_sem);
+ mutex_unlock(&block_subsys_lock);
}

static int diskstats_show(struct seq_file *s, void *v)
diff --git a/drivers/base/map.c b/drivers/base/map.c
index b449dae..e87017f 100644
--- a/drivers/base/map.c
+++ b/drivers/base/map.c
@@ -11,6 +11,7 @@

#include <linux/module.h>
#include <linux/slab.h>
+#include <linux/mutex.h>
#include <linux/kdev_t.h>
#include <linux/kobject.h>
#include <linux/kobj_map.h>
@@ -25,7 +26,7 @@ struct kobj_map {
int (*lock)(dev_t, void *);
void *data;
} *probes[255];
- struct semaphore *sem;
+ struct mutex *lock;
};

int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range,
@@ -53,7 +54,7 @@ int kobj_map(struct kobj_map *domain, de
p->range = range;
p->data = data;
}
- down(domain->sem);
+ mutex_lock(domain->lock);
for (i = 0, p -= n; i < n; i++, p++, index++) {
struct probe **s = &domain->probes[index % 255];
while (*s && (*s)->range < range)
@@ -61,7 +62,7 @@ int kobj_map(struct kobj_map *domain, de
p->next = *s;
*s = p;
}
- up(domain->sem);
+ mutex_unlock(domain->lock);
return 0;
}

@@ -75,7 +76,7 @@ void kobj_unmap(struct kobj_map *domain,
if (n > 255)
n = 255;

- down(domain->sem);
+ mutex_lock(domain->lock);
for (i = 0; i < n; i++, index++) {
struct probe **s;
for (s = &domain->probes[index % 255]; *s; s = &(*s)->next) {
@@ -88,7 +89,7 @@ void kobj_unmap(struct kobj_map *domain,
}
}
}
- up(domain->sem);
+ mutex_unlock(domain->lock);
kfree(found);
}

@@ -99,7 +100,7 @@ struct kobject *kobj_lookup(struct kobj_
unsigned long best = ~0UL;

retry:
- down(domain->sem);
+ mutex_lock(domain->lock);
for (p = domain->probes[MAJOR(dev) % 255]; p; p = p->next) {
struct kobject *(*probe)(dev_t, int *, void *);
struct module *owner;
@@ -120,7 +121,7 @@ retry:
module_put(owner);
continue;
}
- up(domain->sem);
+ mutex_unlock(domain->lock);
kobj = probe(dev, index, data);
/* Currently ->owner protects _only_ ->probe() itself. */
module_put(owner);
@@ -128,11 +129,11 @@ retry:
return kobj;
goto retry;
}
- up(domain->sem);
+ mutex_unlock(domain->lock);
return NULL;
}

-struct kobj_map *kobj_map_init(kobj_probe_t *base_probe, struct semaphore *sem)
+struct kobj_map *kobj_map_init(kobj_probe_t *base_probe, struct mutex *lock)
{
struct kobj_map *p = kmalloc(sizeof(struct kobj_map), GFP_KERNEL);
struct probe *base = kzalloc(sizeof(*base), GFP_KERNEL);
@@ -149,6 +150,6 @@ struct kobj_map *kobj_map_init(kobj_prob
base->get = base_probe;
for (i = 0; i < 255; i++)
p->probes[i] = base;
- p->sem = sem;
+ p->lock = lock;
return p;
}
diff --git a/fs/char_dev.c b/fs/char_dev.c
index 21195c4..5c36345 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -19,6 +19,7 @@
#include <linux/kobject.h>
#include <linux/kobj_map.h>
#include <linux/cdev.h>
+#include <linux/mutex.h>

#ifdef CONFIG_KMOD
#include <linux/kmod.h>
@@ -28,7 +29,7 @@ static struct kobj_map *cdev_map;

#define MAX_PROBE_HASH 255 /* random */

-static DECLARE_MUTEX(chrdevs_lock);
+static DEFINE_MUTEX(chrdevs_lock);

static struct char_device_struct {
struct char_device_struct *next;
@@ -88,13 +89,13 @@ out:

void *acquire_chrdev_list(void)
{
- down(&chrdevs_lock);
+ mutex_lock(&chrdevs_lock);
return get_next_chrdev(NULL);
}

void release_chrdev_list(void *dev)
{
- up(&chrdevs_lock);
+ mutex_unlock(&chrdevs_lock);
kfree(dev);
}

@@ -151,7 +152,7 @@ __register_chrdev_region(unsigned int ma

memset(cd, 0, sizeof(struct char_device_struct));

- down(&chrdevs_lock);
+ mutex_lock(&chrdevs_lock);

/* temporary */
if (major == 0) {
@@ -186,10 +187,10 @@ __register_chrdev_region(unsigned int ma
}
cd->next = *cp;
*cp = cd;
- up(&chrdevs_lock);
+ mutex_unlock(&chrdevs_lock);
return cd;
out:
- up(&chrdevs_lock);
+ mutex_unlock(&chrdevs_lock);
kfree(cd);
return ERR_PTR(ret);
}
@@ -200,7 +201,7 @@ __unregister_chrdev_region(unsigned majo
struct char_device_struct *cd = NULL, **cp;
int i = major_to_index(major);

- down(&chrdevs_lock);
+ mutex_lock(&chrdevs_lock);
for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next)
if ((*cp)->major == major &&
(*cp)->baseminor == baseminor &&
@@ -210,7 +211,7 @@ __unregister_chrdev_region(unsigned majo
cd = *cp;
*cp = cd->next;
}
- up(&chrdevs_lock);
+ mutex_unlock(&chrdevs_lock);
return cd;
}

diff --git a/include/linux/kobj_map.h b/include/linux/kobj_map.h
index cbe7d80..bafe178 100644
--- a/include/linux/kobj_map.h
+++ b/include/linux/kobj_map.h
@@ -1,6 +1,6 @@
#ifdef __KERNEL__

-#include <asm/semaphore.h>
+#include <linux/mutex.h>

typedef struct kobject *kobj_probe_t(dev_t, int *, void *);
struct kobj_map;
@@ -9,6 +9,6 @@ int kobj_map(struct kobj_map *, dev_t, u
kobj_probe_t *, int (*)(dev_t, void *), void *);
void kobj_unmap(struct kobj_map *, dev_t, unsigned long);
struct kobject *kobj_lookup(struct kobj_map *, dev_t, int *);
-struct kobj_map *kobj_map_init(kobj_probe_t *, struct semaphore *);
+struct kobj_map *kobj_map_init(kobj_probe_t *, struct mutex *);

#endif
--
1.2.4


2006-03-20 22:02:16

by Greg KH

[permalink] [raw]
Subject: [PATCH 09/23] add EXPORT_SYMBOL_GPL_FUTURE()

This patch adds the ability to mark symbols that will be changed in the
future, so that kernel modules that don't include MODULE_LICENSE("GPL")
and use the symbols, will be flagged and printed out to the system log.

Signed-off-by: Greg Kroah-Hartman <[email protected]>

---

arch/m68knommu/kernel/vmlinux.lds.S | 10 ++++
arch/v850/kernel/vmlinux.lds.S | 8 +++
include/asm-generic/vmlinux.lds.h | 14 +++++
include/linux/module.h | 9 +++
kernel/module.c | 49 ++++++++++++++++++-
scripts/genksyms/keywords.c_shipped | 91 ++++++++++++++++++-----------------
scripts/genksyms/keywords.gperf | 1
7 files changed, 135 insertions(+), 47 deletions(-)

9f28bb7e1d0188a993403ab39b774785892805e1
diff --git a/arch/m68knommu/kernel/vmlinux.lds.S b/arch/m68knommu/kernel/vmlinux.lds.S
index ac9de26..a331cc9 100644
--- a/arch/m68knommu/kernel/vmlinux.lds.S
+++ b/arch/m68knommu/kernel/vmlinux.lds.S
@@ -269,6 +269,11 @@ SECTIONS {
*(__ksymtab_gpl)
__stop___ksymtab_gpl = .;

+ /* Kernel symbol table: GPL-future symbols */
+ __start___ksymtab_gpl_future = .;
+ *(__ksymtab_gpl_future)
+ __stop___ksymtab_gpl_future = .;
+
/* Kernel symbol table: Normal symbols */
__start___kcrctab = .;
*(__kcrctab)
@@ -279,6 +284,11 @@ SECTIONS {
*(__kcrctab_gpl)
__stop___kcrctab_gpl = .;

+ /* Kernel symbol table: GPL-future symbols */
+ __start___kcrctab_gpl_future = .;
+ *(__kcrctab_gpl_future)
+ __stop___kcrctab_gpl_future = .;
+
/* Kernel symbol table: strings */
*(__ksymtab_strings)

diff --git a/arch/v850/kernel/vmlinux.lds.S b/arch/v850/kernel/vmlinux.lds.S
index 5be05f4..5b2ffcc 100644
--- a/arch/v850/kernel/vmlinux.lds.S
+++ b/arch/v850/kernel/vmlinux.lds.S
@@ -64,6 +64,10 @@
___start___ksymtab_gpl = .; \
*(__ksymtab_gpl) \
___stop___ksymtab_gpl = .; \
+ /* Kernel symbol table: GPL-future symbols */ \
+ ___start___ksymtab_gpl_future = .; \
+ *(__ksymtab_gpl_future) \
+ ___stop___ksymtab_gpl_future = .; \
/* Kernel symbol table: strings */ \
*(__ksymtab_strings) \
/* Kernel symbol table: Normal symbols */ \
@@ -74,6 +78,10 @@
___start___kcrctab_gpl = .; \
*(__kcrctab_gpl) \
___stop___kcrctab_gpl = .; \
+ /* Kernel symbol table: GPL-future symbols */ \
+ ___start___kcrctab_gpl_future = .; \
+ *(__kcrctab_gpl_future) \
+ ___stop___kcrctab_gpl_future = .; \
/* Built-in module parameters */ \
. = ALIGN (4) ; \
___start___param = .; \
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 35de20c..9d11550 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -58,6 +58,13 @@
VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .; \
} \
\
+ /* Kernel symbol table: GPL-future-only symbols */ \
+ __ksymtab_gpl_future : AT(ADDR(__ksymtab_gpl_future) - LOAD_OFFSET) { \
+ VMLINUX_SYMBOL(__start___ksymtab_gpl_future) = .; \
+ *(__ksymtab_gpl_future) \
+ VMLINUX_SYMBOL(__stop___ksymtab_gpl_future) = .; \
+ } \
+ \
/* Kernel symbol table: Normal symbols */ \
__kcrctab : AT(ADDR(__kcrctab) - LOAD_OFFSET) { \
VMLINUX_SYMBOL(__start___kcrctab) = .; \
@@ -72,6 +79,13 @@
VMLINUX_SYMBOL(__stop___kcrctab_gpl) = .; \
} \
\
+ /* Kernel symbol table: GPL-future-only symbols */ \
+ __kcrctab_gpl_future : AT(ADDR(__kcrctab_gpl_future) - LOAD_OFFSET) { \
+ VMLINUX_SYMBOL(__start___kcrctab_gpl_future) = .; \
+ *(__kcrctab_gpl_future) \
+ VMLINUX_SYMBOL(__stop___kcrctab_gpl_future) = .; \
+ } \
+ \
/* Kernel symbol table: strings */ \
__ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \
*(__ksymtab_strings) \
diff --git a/include/linux/module.h b/include/linux/module.h
index 84d75f3..a25d5f6 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -198,6 +198,9 @@ void *__symbol_get_gpl(const char *symbo
#define EXPORT_SYMBOL_GPL(sym) \
__EXPORT_SYMBOL(sym, "_gpl")

+#define EXPORT_SYMBOL_GPL_FUTURE(sym) \
+ __EXPORT_SYMBOL(sym, "_gpl_future")
+
#endif

struct module_ref
@@ -255,6 +258,11 @@ struct module
unsigned int num_gpl_syms;
const unsigned long *gpl_crcs;

+ /* symbols that will be GPL-only in the near future. */
+ const struct kernel_symbol *gpl_future_syms;
+ unsigned int num_gpl_future_syms;
+ const unsigned long *gpl_future_crcs;
+
/* Exception table */
unsigned int num_exentries;
const struct exception_table_entry *extable;
@@ -441,6 +449,7 @@ void module_remove_driver(struct device_
#else /* !CONFIG_MODULES... */
#define EXPORT_SYMBOL(sym)
#define EXPORT_SYMBOL_GPL(sym)
+#define EXPORT_SYMBOL_GPL_FUTURE(sym)

/* Given an address, look for it in the exception tables. */
static inline const struct exception_table_entry *
diff --git a/kernel/module.c b/kernel/module.c
index 2a892b2..5ca99fb 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -126,8 +126,11 @@ extern const struct kernel_symbol __star
extern const struct kernel_symbol __stop___ksymtab[];
extern const struct kernel_symbol __start___ksymtab_gpl[];
extern const struct kernel_symbol __stop___ksymtab_gpl[];
+extern const struct kernel_symbol __start___ksymtab_gpl_future[];
+extern const struct kernel_symbol __stop___ksymtab_gpl_future[];
extern const unsigned long __start___kcrctab[];
extern const unsigned long __start___kcrctab_gpl[];
+extern const unsigned long __start___kcrctab_gpl_future[];

#ifndef CONFIG_MODVERSIONS
#define symversion(base, idx) NULL
@@ -172,6 +175,22 @@ static unsigned long __find_symbol(const
return ks->value;
}
}
+ ks = lookup_symbol(name, __start___ksymtab_gpl_future,
+ __stop___ksymtab_gpl_future);
+ if (ks) {
+ if (!gplok) {
+ printk(KERN_WARNING "Symbol %s is being used "
+ "by a non-GPL module, which will not "
+ "be allowed in the future\n", name);
+ printk(KERN_WARNING "Please see the file "
+ "Documentation/feature-removal-schedule.txt "
+ "in the kernel source tree for more "
+ "details.\n");
+ }
+ *crc = symversion(__start___kcrctab_gpl_future,
+ (ks - __start___ksymtab_gpl_future));
+ return ks->value;
+ }

/* Now try modules. */
list_for_each_entry(mod, &modules, list) {
@@ -191,6 +210,23 @@ static unsigned long __find_symbol(const
return ks->value;
}
}
+ ks = lookup_symbol(name, mod->gpl_future_syms,
+ (mod->gpl_future_syms +
+ mod->num_gpl_future_syms));
+ if (ks) {
+ if (!gplok) {
+ printk(KERN_WARNING "Symbol %s is being used "
+ "by a non-GPL module, which will not "
+ "be allowed in the future\n", name);
+ printk(KERN_WARNING "Please see the file "
+ "Documentation/feature-removal-schedule.txt "
+ "in the kernel source tree for more "
+ "details.\n");
+ }
+ *crc = symversion(mod->gpl_future_crcs,
+ (ks - mod->gpl_future_syms));
+ return ks->value;
+ }
}
DEBUGP("Failed to find symbol %s\n", name);
return 0;
@@ -1546,7 +1582,8 @@ static struct module *load_module(void _
char *secstrings, *args, *modmagic, *strtab = NULL;
unsigned int i, symindex = 0, strindex = 0, setupindex, exindex,
exportindex, modindex, obsparmindex, infoindex, gplindex,
- crcindex, gplcrcindex, versindex, pcpuindex;
+ crcindex, gplcrcindex, versindex, pcpuindex, gplfutureindex,
+ gplfuturecrcindex;
long arglen;
struct module *mod;
long err = 0;
@@ -1627,8 +1664,10 @@ static struct module *load_module(void _
/* Optional sections */
exportindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab");
gplindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl");
+ gplfutureindex = find_sec(hdr, sechdrs, secstrings, "__ksymtab_gpl_future");
crcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab");
gplcrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl");
+ gplfuturecrcindex = find_sec(hdr, sechdrs, secstrings, "__kcrctab_gpl_future");
setupindex = find_sec(hdr, sechdrs, secstrings, "__param");
exindex = find_sec(hdr, sechdrs, secstrings, "__ex_table");
obsparmindex = find_sec(hdr, sechdrs, secstrings, "__obsparm");
@@ -1784,10 +1823,16 @@ static struct module *load_module(void _
mod->gpl_syms = (void *)sechdrs[gplindex].sh_addr;
if (gplcrcindex)
mod->gpl_crcs = (void *)sechdrs[gplcrcindex].sh_addr;
+ mod->num_gpl_future_syms = sechdrs[gplfutureindex].sh_size /
+ sizeof(*mod->gpl_future_syms);
+ mod->gpl_future_syms = (void *)sechdrs[gplfutureindex].sh_addr;
+ if (gplfuturecrcindex)
+ mod->gpl_future_crcs = (void *)sechdrs[gplfuturecrcindex].sh_addr;

#ifdef CONFIG_MODVERSIONS
if ((mod->num_syms && !crcindex) ||
- (mod->num_gpl_syms && !gplcrcindex)) {
+ (mod->num_gpl_syms && !gplcrcindex) ||
+ (mod->num_gpl_future_syms && !gplfuturecrcindex)) {
printk(KERN_WARNING "%s: No versions for exported symbols."
" Tainting kernel.\n", mod->name);
add_taint(TAINT_FORCED_MODULE);
diff --git a/scripts/genksyms/keywords.c_shipped b/scripts/genksyms/keywords.c_shipped
index ee46478..d8153f5 100644
--- a/scripts/genksyms/keywords.c_shipped
+++ b/scripts/genksyms/keywords.c_shipped
@@ -52,9 +52,9 @@ is_reserved_hash (register const char *s
71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
71, 71, 71, 71, 71, 71, 71, 71, 71, 71,
- 71, 71, 71, 71, 71, 71, 71, 71, 71, 15,
- 71, 71, 71, 71, 71, 71, 15, 71, 71, 71,
- 10, 71, 71, 71, 71, 71, 71, 71, 71, 71,
+ 71, 71, 71, 71, 71, 71, 71, 71, 71, 0,
+ 71, 71, 71, 71, 71, 71, 35, 71, 71, 71,
+ 5, 71, 71, 71, 71, 71, 71, 71, 71, 71,
71, 71, 71, 71, 71, 0, 71, 0, 71, 5,
5, 0, 10, 20, 71, 25, 71, 71, 20, 0,
20, 30, 25, 71, 10, 5, 0, 20, 15, 71,
@@ -84,9 +84,9 @@ is_reserved_word (register const char *s
{
enum
{
- TOTAL_KEYWORDS = 41,
+ TOTAL_KEYWORDS = 42,
MIN_WORD_LENGTH = 3,
- MAX_WORD_LENGTH = 17,
+ MAX_WORD_LENGTH = 24,
MIN_HASH_VALUE = 3,
MAX_HASH_VALUE = 70
};
@@ -94,104 +94,105 @@ is_reserved_word (register const char *s
static const struct resword wordlist[] =
{
{""}, {""}, {""},
-#line 24 "scripts/genksyms/keywords.gperf"
+#line 25 "scripts/genksyms/keywords.gperf"
{"asm", ASM_KEYW},
{""},
-#line 7 "scripts/genksyms/keywords.gperf"
+#line 8 "scripts/genksyms/keywords.gperf"
{"__asm", ASM_KEYW},
{""},
-#line 8 "scripts/genksyms/keywords.gperf"
+#line 9 "scripts/genksyms/keywords.gperf"
{"__asm__", ASM_KEYW},
{""},
-#line 21 "scripts/genksyms/keywords.gperf"
+#line 22 "scripts/genksyms/keywords.gperf"
{"_restrict", RESTRICT_KEYW},
-#line 50 "scripts/genksyms/keywords.gperf"
+#line 51 "scripts/genksyms/keywords.gperf"
{"__typeof__", TYPEOF_KEYW},
-#line 9 "scripts/genksyms/keywords.gperf"
+#line 10 "scripts/genksyms/keywords.gperf"
{"__attribute", ATTRIBUTE_KEYW},
-#line 11 "scripts/genksyms/keywords.gperf"
+#line 12 "scripts/genksyms/keywords.gperf"
{"__const", CONST_KEYW},
-#line 10 "scripts/genksyms/keywords.gperf"
+#line 11 "scripts/genksyms/keywords.gperf"
{"__attribute__", ATTRIBUTE_KEYW},
-#line 12 "scripts/genksyms/keywords.gperf"
+#line 13 "scripts/genksyms/keywords.gperf"
{"__const__", CONST_KEYW},
-#line 16 "scripts/genksyms/keywords.gperf"
+#line 17 "scripts/genksyms/keywords.gperf"
{"__signed__", SIGNED_KEYW},
-#line 42 "scripts/genksyms/keywords.gperf"
+#line 43 "scripts/genksyms/keywords.gperf"
{"static", STATIC_KEYW},
{""},
-#line 15 "scripts/genksyms/keywords.gperf"
+#line 16 "scripts/genksyms/keywords.gperf"
{"__signed", SIGNED_KEYW},
-#line 30 "scripts/genksyms/keywords.gperf"
+#line 31 "scripts/genksyms/keywords.gperf"
{"char", CHAR_KEYW},
{""},
-#line 43 "scripts/genksyms/keywords.gperf"
+#line 44 "scripts/genksyms/keywords.gperf"
{"struct", STRUCT_KEYW},
-#line 22 "scripts/genksyms/keywords.gperf"
- {"__restrict__", RESTRICT_KEYW},
#line 23 "scripts/genksyms/keywords.gperf"
+ {"__restrict__", RESTRICT_KEYW},
+#line 24 "scripts/genksyms/keywords.gperf"
{"restrict", RESTRICT_KEYW},
-#line 33 "scripts/genksyms/keywords.gperf"
+#line 34 "scripts/genksyms/keywords.gperf"
{"enum", ENUM_KEYW},
-#line 17 "scripts/genksyms/keywords.gperf"
+#line 18 "scripts/genksyms/keywords.gperf"
{"__volatile", VOLATILE_KEYW},
-#line 34 "scripts/genksyms/keywords.gperf"
+#line 35 "scripts/genksyms/keywords.gperf"
{"extern", EXTERN_KEYW},
-#line 18 "scripts/genksyms/keywords.gperf"
+#line 19 "scripts/genksyms/keywords.gperf"
{"__volatile__", VOLATILE_KEYW},
-#line 37 "scripts/genksyms/keywords.gperf"
+#line 38 "scripts/genksyms/keywords.gperf"
{"int", INT_KEYW},
- {""},
-#line 31 "scripts/genksyms/keywords.gperf"
- {"const", CONST_KEYW},
+#line 7 "scripts/genksyms/keywords.gperf"
+ {"EXPORT_SYMBOL_GPL_FUTURE", EXPORT_SYMBOL_KEYW},
#line 32 "scripts/genksyms/keywords.gperf"
+ {"const", CONST_KEYW},
+#line 33 "scripts/genksyms/keywords.gperf"
{"double", DOUBLE_KEYW},
{""},
-#line 13 "scripts/genksyms/keywords.gperf"
+#line 14 "scripts/genksyms/keywords.gperf"
{"__inline", INLINE_KEYW},
-#line 29 "scripts/genksyms/keywords.gperf"
+#line 30 "scripts/genksyms/keywords.gperf"
{"auto", AUTO_KEYW},
-#line 14 "scripts/genksyms/keywords.gperf"
+#line 15 "scripts/genksyms/keywords.gperf"
{"__inline__", INLINE_KEYW},
-#line 41 "scripts/genksyms/keywords.gperf"
+#line 42 "scripts/genksyms/keywords.gperf"
{"signed", SIGNED_KEYW},
{""},
-#line 46 "scripts/genksyms/keywords.gperf"
+#line 47 "scripts/genksyms/keywords.gperf"
{"unsigned", UNSIGNED_KEYW},
{""},
-#line 40 "scripts/genksyms/keywords.gperf"
+#line 41 "scripts/genksyms/keywords.gperf"
{"short", SHORT_KEYW},
-#line 49 "scripts/genksyms/keywords.gperf"
+#line 50 "scripts/genksyms/keywords.gperf"
{"typeof", TYPEOF_KEYW},
-#line 44 "scripts/genksyms/keywords.gperf"
+#line 45 "scripts/genksyms/keywords.gperf"
{"typedef", TYPEDEF_KEYW},
-#line 48 "scripts/genksyms/keywords.gperf"
+#line 49 "scripts/genksyms/keywords.gperf"
{"volatile", VOLATILE_KEYW},
{""},
-#line 35 "scripts/genksyms/keywords.gperf"
+#line 36 "scripts/genksyms/keywords.gperf"
{"float", FLOAT_KEYW},
{""}, {""},
-#line 39 "scripts/genksyms/keywords.gperf"
+#line 40 "scripts/genksyms/keywords.gperf"
{"register", REGISTER_KEYW},
-#line 47 "scripts/genksyms/keywords.gperf"
+#line 48 "scripts/genksyms/keywords.gperf"
{"void", VOID_KEYW},
{""},
-#line 36 "scripts/genksyms/keywords.gperf"
+#line 37 "scripts/genksyms/keywords.gperf"
{"inline", INLINE_KEYW},
{""},
#line 5 "scripts/genksyms/keywords.gperf"
{"EXPORT_SYMBOL", EXPORT_SYMBOL_KEYW},
{""},
-#line 20 "scripts/genksyms/keywords.gperf"
+#line 21 "scripts/genksyms/keywords.gperf"
{"_Bool", BOOL_KEYW},
{""},
#line 6 "scripts/genksyms/keywords.gperf"
{"EXPORT_SYMBOL_GPL", EXPORT_SYMBOL_KEYW},
{""}, {""}, {""}, {""}, {""}, {""},
-#line 38 "scripts/genksyms/keywords.gperf"
+#line 39 "scripts/genksyms/keywords.gperf"
{"long", LONG_KEYW},
{""}, {""}, {""}, {""}, {""},
-#line 45 "scripts/genksyms/keywords.gperf"
+#line 46 "scripts/genksyms/keywords.gperf"
{"union", UNION_KEYW}
};

diff --git a/scripts/genksyms/keywords.gperf b/scripts/genksyms/keywords.gperf
index b6bec76..c75e0c8 100644
--- a/scripts/genksyms/keywords.gperf
+++ b/scripts/genksyms/keywords.gperf
@@ -4,6 +4,7 @@ struct resword { const char *name; int t
%%
EXPORT_SYMBOL, EXPORT_SYMBOL_KEYW
EXPORT_SYMBOL_GPL, EXPORT_SYMBOL_KEYW
+EXPORT_SYMBOL_GPL_FUTURE, EXPORT_SYMBOL_KEYW
__asm, ASM_KEYW
__asm__, ASM_KEYW
__attribute, ATTRIBUTE_KEYW
--
1.2.4


2006-03-20 22:02:13

by Greg KH

[permalink] [raw]
Subject: [PATCH 19/23] debugfs: Add debugfs_create_blob() helper for exporting binary data

I wanted to export a binary blob via debugfs, and although it was pretty easy
it seems like it'd be easier if there was a helper for it. It's a pity we need
the wrapper struct but I can't see a cleaner way to do it.

Signed-off-by: Michael Ellerman <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---

fs/debugfs/file.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
include/linux/debugfs.h | 15 +++++++++++++++
2 files changed, 61 insertions(+), 0 deletions(-)

dd308bc355a1aa4f202fe9a3133b6c676cb9606c
diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
index d575452..40c4fc9 100644
--- a/fs/debugfs/file.c
+++ b/fs/debugfs/file.c
@@ -251,3 +251,49 @@ struct dentry *debugfs_create_bool(const
}
EXPORT_SYMBOL_GPL(debugfs_create_bool);

+static ssize_t read_file_blob(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct debugfs_blob_wrapper *blob = file->private_data;
+ return simple_read_from_buffer(user_buf, count, ppos, blob->data,
+ blob->size);
+}
+
+static struct file_operations fops_blob = {
+ .read = read_file_blob,
+ .open = default_open,
+};
+
+/**
+ * debugfs_create_blob - create a file in the debugfs filesystem that is
+ * used to read and write a binary blob.
+ *
+ * @name: a pointer to a string containing the name of the file to create.
+ * @mode: the permission that the file should have
+ * @parent: a pointer to the parent dentry for this file. This should be a
+ * directory dentry if set. If this paramater is NULL, then the
+ * file will be created in the root of the debugfs filesystem.
+ * @blob: a pointer to a struct debugfs_blob_wrapper which contains a pointer
+ * to the blob data and the size of the data.
+ *
+ * This function creates a file in debugfs with the given name that exports
+ * @blob->data as a binary blob. If the @mode variable is so set it can be
+ * read from. Writing is not supported.
+ *
+ * This function will return a pointer to a dentry if it succeeds. This
+ * pointer must be passed to the debugfs_remove() function when the file is
+ * to be removed (no automatic cleanup happens if your module is unloaded,
+ * you are responsible here.) If an error occurs, NULL will be returned.
+ *
+ * If debugfs is not enabled in the kernel, the value -ENODEV will be
+ * returned. It is not wise to check for this value, but rather, check for
+ * NULL or !NULL instead as to eliminate the need for #ifdef in the calling
+ * code.
+ */
+struct dentry *debugfs_create_blob(const char *name, mode_t mode,
+ struct dentry *parent,
+ struct debugfs_blob_wrapper *blob)
+{
+ return debugfs_create_file(name, mode, parent, blob, &fops_blob);
+}
+EXPORT_SYMBOL_GPL(debugfs_create_blob);
diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h
index a5fa6a6..4b0428e 100644
--- a/include/linux/debugfs.h
+++ b/include/linux/debugfs.h
@@ -21,6 +21,11 @@

struct file_operations;

+struct debugfs_blob_wrapper {
+ void *data;
+ unsigned long size;
+};
+
#if defined(CONFIG_DEBUG_FS)
struct dentry *debugfs_create_file(const char *name, mode_t mode,
struct dentry *parent, void *data,
@@ -39,6 +44,9 @@ struct dentry *debugfs_create_u32(const
struct dentry *debugfs_create_bool(const char *name, mode_t mode,
struct dentry *parent, u32 *value);

+struct dentry *debugfs_create_blob(const char *name, mode_t mode,
+ struct dentry *parent,
+ struct debugfs_blob_wrapper *blob);
#else

#include <linux/err.h>
@@ -94,6 +102,13 @@ static inline struct dentry *debugfs_cre
return ERR_PTR(-ENODEV);
}

+static inline struct dentry *debugfs_create_blob(const char *name, mode_t mode,
+ struct dentry *parent,
+ struct debugfs_blob_wrapper *blob)
+{
+ return ERR_PTR(-ENODEV);
+}
+
#endif

#endif
--
1.2.4


2006-03-20 22:02:15

by Greg KH

[permalink] [raw]
Subject: [PATCH 01/23] sysfs: sysfs_remove_dir() needs to invalidate the dentry

When calling sysfs_remove_dir() don't allow any further sysfs functions
to work for this kobject anymore. This fixes a nasty USB cdc-acm oops
on disconnect.

Many thanks to Bob Copeland and Paul Fulghum for taking the time to
track this down.

Cc: Bob Copeland <[email protected]>
Cc: Paul Fulghum <[email protected]>
Cc: Maneesh Soni <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---

fs/sysfs/dir.c | 1 +
fs/sysfs/inode.c | 6 +++++-
2 files changed, 6 insertions(+), 1 deletions(-)

641e6f30a095f3752ed84fd9d279382f5d3ef4c1
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 49bd219..cfd290d 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -302,6 +302,7 @@ void sysfs_remove_dir(struct kobject * k
* Drop reference from dget() on entrance.
*/
dput(dentry);
+ kobj->dentry = NULL;
}

int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index 689f7bc..6beee6f 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -227,12 +227,16 @@ void sysfs_drop_dentry(struct sysfs_dire
void sysfs_hash_and_remove(struct dentry * dir, const char * name)
{
struct sysfs_dirent * sd;
- struct sysfs_dirent * parent_sd = dir->d_fsdata;
+ struct sysfs_dirent * parent_sd;
+
+ if (!dir)
+ return;

if (dir->d_inode == NULL)
/* no inode means this hasn't been made visible yet */
return;

+ parent_sd = dir->d_fsdata;
mutex_lock(&dir->d_inode->i_mutex);
list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
if (!sd->s_element)
--
1.2.4


2006-03-20 22:02:16

by Greg KH

[permalink] [raw]
Subject: [PATCH 14/23] firmware: fix BUG: in fw_realloc_buffer

The fw_realloc_buffer routine does not handle an increase in buffer size of
more than 4k. It's not clear to me why it expects that it will only get an
extra 4k of data. The attached patch modifies fw_realloc_buffer to vmalloc
as much memory as is requested, instead of what we previously had + 4k.

I've tested this on my laptop, which would crash occaisionally on boot
without the patch. With the patch, it hasn't crashed, but I can't be
certain that this code path is exercised.

Signed-off-by: Jeff Moyer <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---

drivers/base/firmware_class.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)

30560ba6eda308c13a361d08eb5d4eaab94ab37e
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index e97e911..4723182 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -211,18 +211,20 @@ static int
fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
{
u8 *new_data;
+ int new_size = fw_priv->alloc_size;

if (min_size <= fw_priv->alloc_size)
return 0;

- new_data = vmalloc(fw_priv->alloc_size + PAGE_SIZE);
+ new_size = ALIGN(min_size, PAGE_SIZE);
+ new_data = vmalloc(new_size);
if (!new_data) {
printk(KERN_ERR "%s: unable to alloc buffer\n", __FUNCTION__);
/* Make sure that we don't keep incomplete data */
fw_load_abort(fw_priv);
return -ENOMEM;
}
- fw_priv->alloc_size += PAGE_SIZE;
+ fw_priv->alloc_size = new_size;
if (fw_priv->fw->data) {
memcpy(new_data, fw_priv->fw->data, fw_priv->fw->size);
vfree(fw_priv->fw->data);
--
1.2.4


2006-03-20 22:02:13

by Greg KH

[permalink] [raw]
Subject: [PATCH 10/23] add EXPORT_SYMBOL_GPL_FUTURE() to RCU subsystem

As the RCU symbols are going to be changed to GPL in the near future,
lets warn users that this is going to happen.

Cc: Paul McKenney <[email protected]>
Acked-by: Dipankar Sarma <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---

kernel/rcupdate.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)

01ca70dca5c64cb774a8ac2f50bddff21d60169f
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c
index 8cf15a5..fedf5e3 100644
--- a/kernel/rcupdate.c
+++ b/kernel/rcupdate.c
@@ -609,7 +609,7 @@ module_param(qlowmark, int, 0);
module_param(rsinterval, int, 0);
#endif
EXPORT_SYMBOL_GPL(rcu_batches_completed);
-EXPORT_SYMBOL(call_rcu); /* WARNING: GPL-only in April 2006. */
-EXPORT_SYMBOL(call_rcu_bh); /* WARNING: GPL-only in April 2006. */
+EXPORT_SYMBOL_GPL_FUTURE(call_rcu); /* WARNING: GPL-only in April 2006. */
+EXPORT_SYMBOL_GPL_FUTURE(call_rcu_bh); /* WARNING: GPL-only in April 2006. */
EXPORT_SYMBOL_GPL(synchronize_rcu);
-EXPORT_SYMBOL(synchronize_kernel); /* WARNING: GPL-only in April 2006. */
+EXPORT_SYMBOL_GPL_FUTURE(synchronize_kernel); /* WARNING: GPL-only in April 2006. */
--
1.2.4


2006-03-20 22:02:12

by Greg KH

[permalink] [raw]
Subject: [PATCH 13/23] sysfs: kzalloc conversion

this converts fs/sysfs to kzalloc() usage.
compile tested with make allyesconfig

Signed-off-by: Eric Sesterhenn <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---

fs/sysfs/file.c | 3 +--
fs/sysfs/inode.c | 3 +--
2 files changed, 2 insertions(+), 4 deletions(-)

58d49283b87751f7af75e021a629dcddb027e8eb
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index d0e3d84..e21f402 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -301,9 +301,8 @@ static int check_perm(struct inode * ino
/* No error? Great, allocate a buffer for the file, and store it
* it in file->private_data for easy access.
*/
- buffer = kmalloc(sizeof(struct sysfs_buffer),GFP_KERNEL);
+ buffer = kzalloc(sizeof(struct sysfs_buffer), GFP_KERNEL);
if (buffer) {
- memset(buffer,0,sizeof(struct sysfs_buffer));
init_MUTEX(&buffer->sem);
buffer->needs_read_fill = 1;
buffer->ops = ops;
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index 6beee6f..4c29ac4 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -54,11 +54,10 @@ int sysfs_setattr(struct dentry * dentry

if (!sd_iattr) {
/* setting attributes for the first time, allocate now */
- sd_iattr = kmalloc(sizeof(struct iattr), GFP_KERNEL);
+ sd_iattr = kzalloc(sizeof(struct iattr), GFP_KERNEL);
if (!sd_iattr)
return -ENOMEM;
/* assign default attributes */
- memset(sd_iattr, 0, sizeof(struct iattr));
sd_iattr->ia_mode = sd->s_mode;
sd_iattr->ia_uid = 0;
sd_iattr->ia_gid = 0;
--
1.2.4


2006-03-20 22:02:12

by Greg KH

[permalink] [raw]
Subject: [PATCH 17/23] Kobject: kobject.h: fix a typo

It shouldn't cause real harm, but it hurts my eyes.

Signed-off-by: Adrian Bunk <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---

include/linux/kobject.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

22f98c0cd7e003b896ee52ded945081307118745
diff --git a/include/linux/kobject.h b/include/linux/kobject.h
index c374b5f..7ece63f 100644
--- a/include/linux/kobject.h
+++ b/include/linux/kobject.h
@@ -255,7 +255,7 @@ struct subsys_attribute {
extern int subsys_create_file(struct subsystem * , struct subsys_attribute *);
extern void subsys_remove_file(struct subsystem * , struct subsys_attribute *);

-#if defined(CONFIG_HOTPLUG) & defined(CONFIG_NET)
+#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
void kobject_uevent(struct kobject *kobj, enum kobject_action action);

int add_uevent_var(char **envp, int num_envp, int *cur_index,
--
1.2.4


2006-03-20 22:08:14

by Greg KH

[permalink] [raw]
Subject: [PATCH 12/23] fix module sysfs files reference counting

The module files, refcnt, version, and srcversion did not properly
increment the owner's module reference count, allowing the modules to
be removed while the files were open, causing oopses.

This patch fixes this, and also fixes the problem that the version and
srcversion files were not showing up, unless CONFIG_MODULE_UNLOAD was
enabled, which is not correct.

Cc: Nathan Lynch <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---

include/linux/module.h | 1 +
kernel/module.c | 77 +++++++++++++++++++-----------------------------
kernel/params.c | 10 ------
3 files changed, 32 insertions(+), 56 deletions(-)

03e88ae1b13dfdc8bbaa59b8198e1ca53aad12ac
diff --git a/include/linux/module.h b/include/linux/module.h
index a25d5f6..70bd843 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -245,6 +245,7 @@ struct module
/* Sysfs stuff. */
struct module_kobject mkobj;
struct module_param_attrs *param_attrs;
+ struct module_attribute *modinfo_attrs;
const char *version;
const char *srcversion;

diff --git a/kernel/module.c b/kernel/module.c
index 5ca99fb..77764f2 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -429,7 +429,6 @@ static inline void percpu_modcopy(void *
}
#endif /* CONFIG_SMP */

-#ifdef CONFIG_MODULE_UNLOAD
#define MODINFO_ATTR(field) \
static void setup_modinfo_##field(struct module *mod, const char *s) \
{ \
@@ -461,12 +460,7 @@ static struct module_attribute modinfo_#
MODINFO_ATTR(version);
MODINFO_ATTR(srcversion);

-static struct module_attribute *modinfo_attrs[] = {
- &modinfo_version,
- &modinfo_srcversion,
- NULL,
-};
-
+#ifdef CONFIG_MODULE_UNLOAD
/* Init the unload section of the module. */
static void module_unload_init(struct module *mod)
{
@@ -781,6 +775,15 @@ static inline void module_unload_init(st
}
#endif /* CONFIG_MODULE_UNLOAD */

+static struct module_attribute *modinfo_attrs[] = {
+ &modinfo_version,
+ &modinfo_srcversion,
+#ifdef CONFIG_MODULE_UNLOAD
+ &refcnt,
+#endif
+ NULL,
+};
+
#ifdef CONFIG_OBSOLETE_MODPARM
/* Bounds checking done below */
static int obsparm_copy_string(const char *val, struct kernel_param *kp)
@@ -1106,37 +1109,28 @@ static inline void remove_sect_attrs(str
}
#endif /* CONFIG_KALLSYMS */

-
-#ifdef CONFIG_MODULE_UNLOAD
-static inline int module_add_refcnt_attr(struct module *mod)
-{
- return sysfs_create_file(&mod->mkobj.kobj, &refcnt.attr);
-}
-static void module_remove_refcnt_attr(struct module *mod)
-{
- return sysfs_remove_file(&mod->mkobj.kobj, &refcnt.attr);
-}
-#else
-static inline int module_add_refcnt_attr(struct module *mod)
-{
- return 0;
-}
-static void module_remove_refcnt_attr(struct module *mod)
-{
-}
-#endif
-
-#ifdef CONFIG_MODULE_UNLOAD
static int module_add_modinfo_attrs(struct module *mod)
{
struct module_attribute *attr;
+ struct module_attribute *temp_attr;
int error = 0;
int i;

+ mod->modinfo_attrs = kzalloc((sizeof(struct module_attribute) *
+ (ARRAY_SIZE(modinfo_attrs) + 1)),
+ GFP_KERNEL);
+ if (!mod->modinfo_attrs)
+ return -ENOMEM;
+
+ temp_attr = mod->modinfo_attrs;
for (i = 0; (attr = modinfo_attrs[i]) && !error; i++) {
if (!attr->test ||
- (attr->test && attr->test(mod)))
- error = sysfs_create_file(&mod->mkobj.kobj,&attr->attr);
+ (attr->test && attr->test(mod))) {
+ memcpy(temp_attr, attr, sizeof(*temp_attr));
+ temp_attr->attr.owner = mod;
+ error = sysfs_create_file(&mod->mkobj.kobj,&temp_attr->attr);
+ ++temp_attr;
+ }
}
return error;
}
@@ -1146,12 +1140,16 @@ static void module_remove_modinfo_attrs(
struct module_attribute *attr;
int i;

- for (i = 0; (attr = modinfo_attrs[i]); i++) {
+ for (i = 0; (attr = &mod->modinfo_attrs[i]); i++) {
+ /* pick a field to test for end of list */
+ if (!attr->attr.name)
+ break;
sysfs_remove_file(&mod->mkobj.kobj,&attr->attr);
- attr->free(mod);
+ if (attr->free)
+ attr->free(mod);
}
+ kfree(mod->modinfo_attrs);
}
-#endif

static int mod_sysfs_setup(struct module *mod,
struct kernel_param *kparam,
@@ -1169,19 +1167,13 @@ static int mod_sysfs_setup(struct module
if (err)
goto out;

- err = module_add_refcnt_attr(mod);
- if (err)
- goto out_unreg;
-
err = module_param_sysfs_setup(mod, kparam, num_params);
if (err)
goto out_unreg;

-#ifdef CONFIG_MODULE_UNLOAD
err = module_add_modinfo_attrs(mod);
if (err)
goto out_unreg;
-#endif

return 0;

@@ -1193,10 +1185,7 @@ out:

static void mod_kobject_remove(struct module *mod)
{
-#ifdef CONFIG_MODULE_UNLOAD
module_remove_modinfo_attrs(mod);
-#endif
- module_remove_refcnt_attr(mod);
module_param_sysfs_remove(mod);

kobject_unregister(&mod->mkobj.kobj);
@@ -1474,7 +1463,6 @@ static char *get_modinfo(Elf_Shdr *sechd
return NULL;
}

-#ifdef CONFIG_MODULE_UNLOAD
static void setup_modinfo(struct module *mod, Elf_Shdr *sechdrs,
unsigned int infoindex)
{
@@ -1489,7 +1477,6 @@ static void setup_modinfo(struct module
attr->attr.name));
}
}
-#endif

#ifdef CONFIG_KALLSYMS
int is_exported(const char *name, const struct module *mod)
@@ -1803,10 +1790,8 @@ static struct module *load_module(void _
if (strcmp(mod->name, "driverloader") == 0)
add_taint(TAINT_PROPRIETARY_MODULE);

-#ifdef CONFIG_MODULE_UNLOAD
/* Set up MODINFO_ATTR fields */
setup_modinfo(mod, sechdrs, infoindex);
-#endif

/* Fix up syms, so that st_value is a pointer to location. */
err = simplify_symbols(sechdrs, symindex, strtab, versindex, pcpuindex,
diff --git a/kernel/params.c b/kernel/params.c
index c76ad25..a291505 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -638,13 +638,8 @@ static ssize_t module_attr_show(struct k
if (!attribute->show)
return -EIO;

- if (!try_module_get(mk->mod))
- return -ENODEV;
-
ret = attribute->show(attribute, mk->mod, buf);

- module_put(mk->mod);
-
return ret;
}

@@ -662,13 +657,8 @@ static ssize_t module_attr_store(struct
if (!attribute->store)
return -EIO;

- if (!try_module_get(mk->mod))
- return -ENODEV;
-
ret = attribute->store(attribute, mk->mod, buf, len);

- module_put(mk->mod);
-
return ret;
}

--
1.2.4


2006-03-20 22:08:16

by Greg KH

[permalink] [raw]
Subject: [PATCH 04/23] driver core: platform_get_irq*(): return -ENXIO on error

platform_get_irq*() cannot return 0 on error as 0 is a valid IRQ on some
platforms, return -ENXIO instead.

Signed-off-by: David Vrabel <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---

drivers/base/platform.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)

305b3228f9ff4d59f49e6d34a7034d44ee8ce2f0
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 461554a..89b2683 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -61,7 +61,7 @@ int platform_get_irq(struct platform_dev
{
struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num);

- return r ? r->start : 0;
+ return r ? r->start : -ENXIO;
}
EXPORT_SYMBOL_GPL(platform_get_irq);

@@ -98,7 +98,7 @@ int platform_get_irq_byname(struct platf
{
struct resource *r = platform_get_resource_byname(dev, IORESOURCE_IRQ, name);

- return r ? r->start : 0;
+ return r ? r->start : -ENXIO;
}
EXPORT_SYMBOL_GPL(platform_get_irq_byname);

--
1.2.4


2006-03-20 22:08:15

by Greg KH

[permalink] [raw]
Subject: [PATCH 08/23] Clean up module.c symbol searching logic

Signed-off-by: Sam Ravnborg <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---

kernel/module.c | 73 +++++++++++++++++++++++++++++++------------------------
1 files changed, 41 insertions(+), 32 deletions(-)

3fd6805f4dfb02bcfb5634972eabad0e790f119a
diff --git a/kernel/module.c b/kernel/module.c
index 5aad477..2a892b2 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -135,6 +135,18 @@ extern const unsigned long __start___kcr
#define symversion(base, idx) ((base) ? ((base) + (idx)) : NULL)
#endif

+/* lookup symbol in given range of kernel_symbols */
+static const struct kernel_symbol *lookup_symbol(const char *name,
+ const struct kernel_symbol *start,
+ const struct kernel_symbol *stop)
+{
+ const struct kernel_symbol *ks = start;
+ for (; ks < stop; ks++)
+ if (strcmp(ks->name, name) == 0)
+ return ks;
+ return NULL;
+}
+
/* Find a symbol, return value, crc and module which owns it */
static unsigned long __find_symbol(const char *name,
struct module **owner,
@@ -142,39 +154,41 @@ static unsigned long __find_symbol(const
int gplok)
{
struct module *mod;
- unsigned int i;
+ const struct kernel_symbol *ks;

/* Core kernel first. */
*owner = NULL;
- for (i = 0; __start___ksymtab+i < __stop___ksymtab; i++) {
- if (strcmp(__start___ksymtab[i].name, name) == 0) {
- *crc = symversion(__start___kcrctab, i);
- return __start___ksymtab[i].value;
- }
+ ks = lookup_symbol(name, __start___ksymtab, __stop___ksymtab);
+ if (ks) {
+ *crc = symversion(__start___kcrctab, (ks - __start___ksymtab));
+ return ks->value;
}
if (gplok) {
- for (i = 0; __start___ksymtab_gpl+i<__stop___ksymtab_gpl; i++)
- if (strcmp(__start___ksymtab_gpl[i].name, name) == 0) {
- *crc = symversion(__start___kcrctab_gpl, i);
- return __start___ksymtab_gpl[i].value;
- }
+ ks = lookup_symbol(name, __start___ksymtab_gpl,
+ __stop___ksymtab_gpl);
+ if (ks) {
+ *crc = symversion(__start___kcrctab_gpl,
+ (ks - __start___ksymtab_gpl));
+ return ks->value;
+ }
}

/* Now try modules. */
list_for_each_entry(mod, &modules, list) {
*owner = mod;
- for (i = 0; i < mod->num_syms; i++)
- if (strcmp(mod->syms[i].name, name) == 0) {
- *crc = symversion(mod->crcs, i);
- return mod->syms[i].value;
- }
+ ks = lookup_symbol(name, mod->syms, mod->syms + mod->num_syms);
+ if (ks) {
+ *crc = symversion(mod->crcs, (ks - mod->syms));
+ return ks->value;
+ }

if (gplok) {
- for (i = 0; i < mod->num_gpl_syms; i++) {
- if (strcmp(mod->gpl_syms[i].name, name) == 0) {
- *crc = symversion(mod->gpl_crcs, i);
- return mod->gpl_syms[i].value;
- }
+ ks = lookup_symbol(name, mod->gpl_syms,
+ mod->gpl_syms + mod->num_gpl_syms);
+ if (ks) {
+ *crc = symversion(mod->gpl_crcs,
+ (ks - mod->gpl_syms));
+ return ks->value;
}
}
}
@@ -1444,18 +1458,13 @@ static void setup_modinfo(struct module
#ifdef CONFIG_KALLSYMS
int is_exported(const char *name, const struct module *mod)
{
- unsigned int i;
-
- if (!mod) {
- for (i = 0; __start___ksymtab+i < __stop___ksymtab; i++)
- if (strcmp(__start___ksymtab[i].name, name) == 0)
- return 1;
- return 0;
- }
- for (i = 0; i < mod->num_syms; i++)
- if (strcmp(mod->syms[i].name, name) == 0)
+ if (!mod && lookup_symbol(name, __start___ksymtab, __stop___ksymtab))
+ return 1;
+ else
+ if (lookup_symbol(name, mod->syms, mod->syms + mod->num_syms))
return 1;
- return 0;
+ else
+ return 0;
}

/* As per nm */
--
1.2.4


2006-03-20 22:09:37

by Greg KH

[permalink] [raw]
Subject: [PATCH 02/23] kobject: fix build error if CONFIG_SYSFS=n

Moving uevent_seqnum and uevent_helper to kobject_uevent.c
because they are used even if CONFIG_SYSFS=n
while kernel/ksysfs.c is built only if CONFIG_SYSFS=y,

Signed-off-by: Jun'ichi Nomura <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---

kernel/ksysfs.c | 3 ---
lib/kobject_uevent.c | 2 ++
2 files changed, 2 insertions(+), 3 deletions(-)

51107301b629640f9ab76fe23bf385e187b9ac29
diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c
index d5eeae0..f2690ed 100644
--- a/kernel/ksysfs.c
+++ b/kernel/ksysfs.c
@@ -15,9 +15,6 @@
#include <linux/module.h>
#include <linux/init.h>

-u64 uevent_seqnum;
-char uevent_helper[UEVENT_HELPER_PATH_LEN] = "/sbin/hotplug";
-
#define KERNEL_ATTR_RO(_name) \
static struct subsys_attribute _name##_attr = __ATTR_RO(_name)

diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
index 086a0c6..982226d 100644
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
@@ -26,6 +26,8 @@
#define NUM_ENVP 32 /* number of env pointers */

#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
+u64 uevent_seqnum;
+char uevent_helper[UEVENT_HELPER_PATH_LEN] = "/sbin/hotplug";
static DEFINE_SPINLOCK(sequence_lock);
static struct sock *uevent_sock;

--
1.2.4


2006-03-20 22:09:38

by Greg KH

[permalink] [raw]
Subject: [PATCH 05/23] handle errors returned by platform_get_irq*()

platform_get_irq*() now returns on -ENXIO when the resource cannot be
found. Ensure all users of platform_get_irq*() handle this error
appropriately.

Signed-off-by: David Vrabel <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---

arch/arm/common/locomo.c | 2 ++
arch/arm/common/sa1111.c | 2 ++
drivers/char/s3c2410-rtc.c | 4 ++--
drivers/char/watchdog/mpcore_wdt.c | 4 ++++
drivers/i2c/busses/i2c-iop3xx.c | 9 +++++++--
drivers/i2c/busses/i2c-mpc.c | 5 +++++
drivers/i2c/busses/i2c-mv64xxx.c | 4 ++++
drivers/ide/mips/au1xxx-ide.c | 5 +++++
drivers/mmc/pxamci.c | 2 +-
drivers/net/arm/am79c961a.c | 4 +++-
drivers/net/fs_enet/mac-fcc.c | 2 ++
drivers/net/fs_enet/mac-fec.c | 2 ++
drivers/net/fs_enet/mac-scc.c | 2 ++
drivers/net/gianfar.c | 4 ++++
drivers/net/smc91x.c | 4 ++++
drivers/pcmcia/omap_cf.c | 2 +-
drivers/serial/s3c2410.c | 2 ++
drivers/usb/host/ohci-omap.c | 9 +++++++--
drivers/video/sa1100fb.c | 2 +-
19 files changed, 60 insertions(+), 10 deletions(-)

489447380a2921ec0e9154f773c44ab3167ede4b
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
index d31b1cb..2360940 100644
--- a/arch/arm/common/locomo.c
+++ b/arch/arm/common/locomo.c
@@ -788,6 +788,8 @@ static int locomo_probe(struct platform_
if (!mem)
return -EINVAL;
irq = platform_get_irq(dev, 0);
+ if (irq < 0)
+ return -ENXIO;

return __locomo_probe(&dev->dev, mem, irq);
}
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index 1475089..93352f6 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -943,6 +943,8 @@ static int sa1111_probe(struct platform_
if (!mem)
return -EINVAL;
irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return -ENXIO;

return __sa1111_probe(&pdev->dev, mem, irq);
}
diff --git a/drivers/char/s3c2410-rtc.c b/drivers/char/s3c2410-rtc.c
index 2e30865..b0038b1 100644
--- a/drivers/char/s3c2410-rtc.c
+++ b/drivers/char/s3c2410-rtc.c
@@ -448,13 +448,13 @@ static int s3c2410_rtc_probe(struct plat
/* find the IRQs */

s3c2410_rtc_tickno = platform_get_irq(pdev, 1);
- if (s3c2410_rtc_tickno <= 0) {
+ if (s3c2410_rtc_tickno < 0) {
dev_err(&pdev->dev, "no irq for rtc tick\n");
return -ENOENT;
}

s3c2410_rtc_alarmno = platform_get_irq(pdev, 0);
- if (s3c2410_rtc_alarmno <= 0) {
+ if (s3c2410_rtc_alarmno < 0) {
dev_err(&pdev->dev, "no irq for alarm\n");
return -ENOENT;
}
diff --git a/drivers/char/watchdog/mpcore_wdt.c b/drivers/char/watchdog/mpcore_wdt.c
index b4d8434..2c2c517 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(st

wdt->dev = &dev->dev;
wdt->irq = platform_get_irq(dev, 0);
+ if (wdt->irq < 0) {
+ ret = -ENXIO;
+ goto err_free;
+ }
wdt->base = ioremap(res->start, res->end - res->start + 1);
if (!wdt->base) {
ret = -ENOMEM;
diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c
index 1414851..d00a02f 100644
--- a/drivers/i2c/busses/i2c-iop3xx.c
+++ b/drivers/i2c/busses/i2c-iop3xx.c
@@ -434,7 +434,7 @@ static int
iop3xx_i2c_probe(struct platform_device *pdev)
{
struct resource *res;
- int ret;
+ int ret, irq;
struct i2c_adapter *new_adapter;
struct i2c_algo_iop3xx_data *adapter_data;

@@ -470,7 +470,12 @@ iop3xx_i2c_probe(struct platform_device
goto release_region;
}

- ret = request_irq(platform_get_irq(pdev, 0), iop3xx_i2c_irq_handler, 0,
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ ret = -ENXIO;
+ goto unmap;
+ }
+ ret = request_irq(irq, iop3xx_i2c_irq_handler, 0,
pdev->name, adapter_data);

if (ret) {
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index 5ccd338..2721e4c 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
}

i2c->irq = platform_get_irq(pdev, 0);
+ if (i2c->irq < 0) {
+ result = -ENXIO;
+ goto fail_get_irq;
+ }
i2c->flags = pdata->device_flags;
init_waitqueue_head(&i2c->queue);

@@ -340,6 +344,7 @@ static int fsl_i2c_probe(struct platform
fail_irq:
iounmap(i2c->base);
fail_map:
+ fail_get_irq:
kfree(i2c);
return result;
};
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index 22781d8..ac5cde1 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
drv_data->freq_m = pdata->freq_m;
drv_data->freq_n = pdata->freq_n;
drv_data->irq = platform_get_irq(pd, 0);
+ if (drv_data->irq < 0) {
+ rc = -ENXIO;
+ goto exit_unmap_regs;
+ }
drv_data->adapter.id = I2C_HW_MV64XXX;
drv_data->adapter.algo = &mv64xxx_i2c_algo;
drv_data->adapter.owner = THIS_MODULE;
diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c
index 32431dc..71f27e9 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 *d
ret = -ENODEV;
goto out;
}
+ if (ahwif->irq < 0) {
+ pr_debug("%s %d: no IRQ\n", DRV_NAME, pdev->id);
+ ret = -ENODEV;
+ goto out;
+ }

if (!request_mem_region (res->start, res->end-res->start, pdev->name)) {
pr_debug("%s: request_mem_region failed\n", DRV_NAME);
diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c
index 285d7d0..c32fad1 100644
--- a/drivers/mmc/pxamci.c
+++ b/drivers/mmc/pxamci.c
@@ -438,7 +438,7 @@ static int pxamci_probe(struct platform_

r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq = platform_get_irq(pdev, 0);
- if (!r || irq == NO_IRQ)
+ if (!r || irq < 0)
return -ENXIO;

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 53e3afc..09d5c3f 100644
--- a/drivers/net/arm/am79c961a.c
+++ b/drivers/net/arm/am79c961a.c
@@ -696,7 +696,9 @@ static int __init am79c961_probe(struct
dev->base_addr = res->start;
dev->irq = platform_get_irq(pdev, 0);

- ret = -ENODEV;
+ ret = -ENODEV;
+ if (dev->irq < 0)
+ goto nodev;
if (!request_region(dev->base_addr, 0x18, dev->name))
goto nodev;

diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c
index e67b1d0..95e2bb8 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_pr

/* Fill out IRQ field */
fep->interrupt = platform_get_irq(pdev, 0);
+ if (fep->interrupt < 0)
+ return -EINVAL;

/* Attach the memory for the FCC Parameter RAM */
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 2e8f444..3dad69d 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_pr

/* Fill out IRQ field */
fep->interrupt = platform_get_irq_byname(pdev,"interrupt");
+ if (fep->interrupt < 0)
+ return -EINVAL;

r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
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 a3897fd..a772b28 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_pr

/* Fill out IRQ field */
fep->interrupt = platform_get_irq_byname(pdev, "interrupt");
+ if (fep->interrupt < 0)
+ return -EINVAL;

r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
fep->scc.sccp = (void *)r->start;
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 0e8e3fc..771e25d 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -193,8 +193,12 @@ static int gfar_probe(struct platform_de
priv->interruptTransmit = platform_get_irq_byname(pdev, "tx");
priv->interruptReceive = platform_get_irq_byname(pdev, "rx");
priv->interruptError = platform_get_irq_byname(pdev, "error");
+ if (priv->interruptTransmit < 0 || priv->interruptReceive < 0 || priv->interruptError < 0)
+ goto regs_fail;
} else {
priv->interruptTransmit = platform_get_irq(pdev, 0);
+ if (priv->interruptTransmit < 0)
+ goto regs_fail;
}

/* get a pointer to the register memory */
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index 7ec0812..75e9b3b 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -2221,6 +2221,10 @@ static int smc_drv_probe(struct platform

ndev->dma = (unsigned char)-1;
ndev->irq = platform_get_irq(pdev, 0);
+ if (ndev->irq < 0) {
+ ret = -ENODEV;
+ goto out_free_netdev;
+ }

ret = smc_request_attrib(pdev);
if (ret)
diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c
index 47b5ade..2c23d75 100644
--- a/drivers/pcmcia/omap_cf.c
+++ b/drivers/pcmcia/omap_cf.c
@@ -218,7 +218,7 @@ static int __init omap_cf_probe(struct d

/* either CFLASH.IREQ (INT_1610_CF) or some GPIO */
irq = platform_get_irq(pdev, 0);
- if (!irq)
+ if (irq < 0)
return -EINVAL;

cf = kcalloc(1, sizeof *cf, GFP_KERNEL);
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 7410e09..00d7c0a 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -1066,6 +1066,8 @@ static int s3c24xx_serial_init_port(stru
port->mapbase = res->start;
port->membase = S3C24XX_VA_UART + (res->start - S3C24XX_PA_UART);
port->irq = platform_get_irq(platdev, 0);
+ if (port->irq < 0)
+ port->irq = 0;

ourport->clk = clk_get(&platdev->dev, "uart");

diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index 3785b3f..ca19abe 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
int usb_hcd_omap_probe (const struct hc_driver *driver,
struct platform_device *pdev)
{
- int retval;
+ int retval, irq;
struct usb_hcd *hcd = 0;
struct ohci_hcd *ohci;

@@ -329,7 +329,12 @@ int usb_hcd_omap_probe (const struct hc_
if (retval < 0)
goto err2;

- retval = usb_add_hcd(hcd, platform_get_irq(pdev, 0), SA_INTERRUPT);
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ retval = -ENXIO;
+ goto err2;
+ }
+ retval = usb_add_hcd(hcd, irq, SA_INTERRUPT);
if (retval == 0)
return retval;

diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index 8a893ce..d9831fd 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -1457,7 +1457,7 @@ static int __init sa1100fb_probe(struct
int ret, irq;

irq = platform_get_irq(pdev, 0);
- if (irq <= 0)
+ if (irq < 0)
return -EINVAL;

if (!request_mem_region(0xb0100000, 0x10000, "LCD"))
--
1.2.4


2006-03-20 22:09:39

by Greg KH

[permalink] [raw]
Subject: [PATCH 23/23] sysfs: fix a kobject leak in sysfs_add_link on the error path

As pointed out by Oliver Neukum.

Cc: Maneesh Soni <[email protected]>
Cc: Oliver Neukum <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---

fs/sysfs/symlink.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)

b3229087c5e08589cea4f5040dab56f7dc11332a
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index fe23f47..d2eac3c 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -66,6 +66,7 @@ static int sysfs_add_link(struct dentry
if (!error)
return 0;

+ kobject_put(target);
kfree(sl->link_name);
exit2:
kfree(sl);
--
1.2.4


2006-03-20 22:12:30

by Greg KH

[permalink] [raw]
Subject: [PATCH 03/23] Mark empty release functions as broken

Come on people, this is just wrong...

Signed-off-by: Greg Kroah-Hartman <[email protected]>

---

drivers/video/epson1355fb.c | 1 +
drivers/video/vfb.c | 1 +
2 files changed, 2 insertions(+), 0 deletions(-)

972de6c8bfd8b36618563be454df1e95a36dc379
diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c
index 3b0e713..0827594 100644
--- a/drivers/video/epson1355fb.c
+++ b/drivers/video/epson1355fb.c
@@ -607,6 +607,7 @@ static void clearfb16(struct fb_info *in

static void epson1355fb_platform_release(struct device *device)
{
+ dev_err(device, "This driver is broken, please bug the authors so they will fix it.\n");
}

static int epson1355fb_remove(struct platform_device *dev)
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index 53208cb..77eed1f 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -401,6 +401,7 @@ static int __init vfb_setup(char *option
static void vfb_platform_release(struct device *device)
{
// This is called when the reference count goes to zero.
+ dev_err(device, "This driver is broken, please bug the authors so they will fix it.\n");
}

static int __init vfb_probe(struct platform_device *dev)
--
1.2.4


2006-03-20 22:12:31

by Greg KH

[permalink] [raw]
Subject: [PATCH 15/23] Driver core: add macros notice(), dev_notice()

Both usb.h and device.h have collections of convenience macros for
printk() with the KERN_ERR, KERN_WARNING, and KERN_NOTICE severity
levels. This patch adds macros for the KERN_NOTICE level which was
so far uncatered for.

These macros already exist privately in drivers/isdn/gigaset/gigaset.h
(currently in the process of being submitted for the kernel tree)
but they really belong with their brothers and sisters in
include/linux/{device,usb}.h.

Signed-off-by: Tilman Schmidt <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---

include/linux/device.h | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)

4f2928d0a439553f0288d9483faf417430629635
diff --git a/include/linux/device.h b/include/linux/device.h
index 58df18d..5b595fd 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -424,6 +424,8 @@ extern void firmware_unregister(struct s
dev_printk(KERN_INFO , dev , format , ## arg)
#define dev_warn(dev, format, arg...) \
dev_printk(KERN_WARNING , dev , format , ## arg)
+#define dev_notice(dev, format, arg...) \
+ dev_printk(KERN_NOTICE , dev , format , ## arg)

/* Create alias, so I can be autoloaded. */
#define MODULE_ALIAS_CHARDEV(major,minor) \
--
1.2.4


2006-03-20 23:33:37

by Junichi Nomura

[permalink] [raw]
Subject: Re: [PATCH 02/23] kobject: fix build error if CONFIG_SYSFS=n

Hi Greg,

Moving them inside CONFIG_HOTPLUG && CONFIG_NET will break
CONFIG_NET=n build, because kernel/ksysfs.c will use them
#ifdef CONFIG_HOTPLUG.

Greg Kroah-Hartman wrote:
> Moving uevent_seqnum and uevent_helper to kobject_uevent.c
> because they are used even if CONFIG_SYSFS=n
> while kernel/ksysfs.c is built only if CONFIG_SYSFS=y,
...
> diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
> index 086a0c6..982226d 100644
> --- a/lib/kobject_uevent.c
> +++ b/lib/kobject_uevent.c
> @@ -26,6 +26,8 @@
> #define NUM_ENVP 32 /* number of env pointers */
>
> #if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
> +u64 uevent_seqnum;
> +char uevent_helper[UEVENT_HELPER_PATH_LEN] = "/sbin/hotplug";
> static DEFINE_SPINLOCK(sequence_lock);
> static struct sock *uevent_sock;

Thanks,
--
Jun'ichi Nomura, NEC Solutions (America), Inc.

2006-03-21 00:13:43

by Olivier Galibert

[permalink] [raw]
Subject: Re: [PATCH 04/23] driver core: platform_get_irq*(): return -ENXIO on error

On Mon, Mar 20, 2006 at 02:00:38PM -0800, Greg Kroah-Hartman wrote:
> platform_get_irq*() cannot return 0 on error as 0 is a valid IRQ on some
> platforms, return -ENXIO instead.

0 is NO_IRQ, and can not be a valid IRQ number, ever. A
platform_get_irq*() returning 0 as a valid irq is buggy.

Check http://lkml.org/lkml/2005/11/21/211

OG.

2006-03-21 09:33:22

by David Vrabel

[permalink] [raw]
Subject: Re: [PATCH 04/23] driver core: platform_get_irq*(): return -ENXIO on error

Olivier Galibert wrote:
> On Mon, Mar 20, 2006 at 02:00:38PM -0800, Greg Kroah-Hartman wrote:
>
>>platform_get_irq*() cannot return 0 on error as 0 is a valid IRQ on some
>>platforms, return -ENXIO instead.
>
>
> 0 is NO_IRQ, and can not be a valid IRQ number, ever. A
> platform_get_irq*() returning 0 as a valid irq is buggy.
>
> Check http://lkml.org/lkml/2005/11/21/211

Regardless, it does make sense to make these functions to return a -ve
error code as is standard.

David Vrabel
--
David Vrabel, Design Engineer

Arcom, Clifton Road Tel: +44 (0)1223 411200 ext. 3233
Cambridge CB1 7EA, UK Web: http://www.arcom.com/

2006-03-21 10:26:55

by Russell King

[permalink] [raw]
Subject: Re: [PATCH 04/23] driver core: platform_get_irq*(): return -ENXIO on error

On Tue, Mar 21, 2006 at 01:13:36AM +0100, Olivier Galibert wrote:
> On Mon, Mar 20, 2006 at 02:00:38PM -0800, Greg Kroah-Hartman wrote:
> > platform_get_irq*() cannot return 0 on error as 0 is a valid IRQ on some
> > platforms, return -ENXIO instead.
>
> 0 is NO_IRQ, and can not be a valid IRQ number, ever. A
> platform_get_irq*() returning 0 as a valid irq is buggy.
>
> Check http://lkml.org/lkml/2005/11/21/211

No. That's Linus' _opinion_, which is not applicable to systems without
the obviously broken PCI or ISA busses. On such systems, IRQ0 has no
special meaning what so ever.

Greg - please continue sending this patch.

--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 Serial core

2006-03-21 12:50:51

by Olivier Galibert

[permalink] [raw]
Subject: Re: [PATCH 04/23] driver core: platform_get_irq*(): return -ENXIO on error

On Tue, Mar 21, 2006 at 08:07:09AM +0000, Russell King wrote:
> On Tue, Mar 21, 2006 at 01:13:36AM +0100, Olivier Galibert wrote:
> > On Mon, Mar 20, 2006 at 02:00:38PM -0800, Greg Kroah-Hartman wrote:
> > > platform_get_irq*() cannot return 0 on error as 0 is a valid IRQ on some
> > > platforms, return -ENXIO instead.
> >
> > 0 is NO_IRQ, and can not be a valid IRQ number, ever. A
> > platform_get_irq*() returning 0 as a valid irq is buggy.
> >
> > Check http://lkml.org/lkml/2005/11/21/211
>
> No. That's Linus' _opinion_, which is not applicable to systems without
> the obviously broken PCI or ISA busses. On such systems, IRQ0 has no
> special meaning what so ever.

Do the drivers know?

OG.

2006-03-21 17:16:49

by Artem B. Bityutskiy

[permalink] [raw]
Subject: Re: [PATCH 16/23] Kobject: provide better warning messages when people do stupid things

Greg Kroah-Hartman wrote:
> +
> + /* be noisy on error issues */
> + if (error == -EEXIST)
> + printk("kobject_add failed for %s with -EEXIST, "
> + "don't try to register things with the "
> + "same name in the same directory.\n",
> + kobject_name(kobj));

This looks like an attempt to put documentation into kernel code. Isn't
it better to add good documentation to the header file just above the
prototype?

When I started using sysfs, I noticed a lack of good comments above
prototypes of exported functions.

--
Best regards, Artem B. Bityutskiy
Oktet Labs (St. Petersburg), Software Engineer.
+7 812 4286709 (office) +7 911 2449030 (mobile)
E-mail: [email protected], Web: http://www.oktetlabs.ru

2006-03-21 20:31:40

by Russell King

[permalink] [raw]
Subject: Re: [PATCH 04/23] driver core: platform_get_irq*(): return -ENXIO on error

On Tue, Mar 21, 2006 at 01:50:49PM +0100, Olivier Galibert wrote:
> On Tue, Mar 21, 2006 at 08:07:09AM +0000, Russell King wrote:
> > On Tue, Mar 21, 2006 at 01:13:36AM +0100, Olivier Galibert wrote:
> > > On Mon, Mar 20, 2006 at 02:00:38PM -0800, Greg Kroah-Hartman wrote:
> > > > platform_get_irq*() cannot return 0 on error as 0 is a valid IRQ on some
> > > > platforms, return -ENXIO instead.
> > >
> > > 0 is NO_IRQ, and can not be a valid IRQ number, ever. A
> > > platform_get_irq*() returning 0 as a valid irq is buggy.
> > >
> > > Check http://lkml.org/lkml/2005/11/21/211
> >
> > No. That's Linus' _opinion_, which is not applicable to systems without
> > the obviously broken PCI or ISA busses. On such systems, IRQ0 has no
> > special meaning what so ever.
>
> Do the drivers know?

If you look at the following patch in the series, the users of this function
have been updated. So the answer is "yes".

--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 Serial core

2006-03-21 22:50:28

by Olivier Galibert

[permalink] [raw]
Subject: Re: [PATCH 04/23] driver core: platform_get_irq*(): return -ENXIO on error

On Tue, Mar 21, 2006 at 08:31:25PM +0000, Russell King wrote:
> On Tue, Mar 21, 2006 at 01:50:49PM +0100, Olivier Galibert wrote:
> > On Tue, Mar 21, 2006 at 08:07:09AM +0000, Russell King wrote:
> > > On Tue, Mar 21, 2006 at 01:13:36AM +0100, Olivier Galibert wrote:
> > > > On Mon, Mar 20, 2006 at 02:00:38PM -0800, Greg Kroah-Hartman wrote:
> > > > > platform_get_irq*() cannot return 0 on error as 0 is a valid IRQ on some
> > > > > platforms, return -ENXIO instead.
> > > >
> > > > 0 is NO_IRQ, and can not be a valid IRQ number, ever. A
> > > > platform_get_irq*() returning 0 as a valid irq is buggy.
> > > >
> > > > Check http://lkml.org/lkml/2005/11/21/211
> > >
> > > No. That's Linus' _opinion_, which is not applicable to systems without
> > > the obviously broken PCI or ISA busses. On such systems, IRQ0 has no
> > > special meaning what so ever.
> >
> > Do the drivers know?
>
> If you look at the following patch in the series, the users of this function
> have been updated. So the answer is "yes".

They've just been updated not to barf with -ENOENT, nothing more.
That's nowhere near an audit of use of the return value.

But whatever, I'm not the one who will have to debug it.

OG.

2006-03-22 22:18:06

by Greg KH

[permalink] [raw]
Subject: Re: [PATCH 16/23] Kobject: provide better warning messages when people do stupid things

On Tue, Mar 21, 2006 at 08:16:46PM +0300, Artem B. Bityutskiy wrote:
> Greg Kroah-Hartman wrote:
> >+
> >+ /* be noisy on error issues */
> >+ if (error == -EEXIST)
> >+ printk("kobject_add failed for %s with -EEXIST, "
> >+ "don't try to register things with the "
> >+ "same name in the same directory.\n",
> >+ kobject_name(kobj));
>
> This looks like an attempt to put documentation into kernel code. Isn't
> it better to add good documentation to the header file just above the
> prototype?

Normally I would agree with you, but it's users that hit this error,
when they load a combination of drivers that no developer has in the
past. And due to the noise in my inbox, people are still quite confused
when this happens. That error message is to help people determine what
the real problem is.

> When I started using sysfs, I noticed a lack of good comments above
> prototypes of exported functions.

I agree, care to provide a patch that fixes this?

thanks,

greg k-h

2006-03-25 08:52:24

by Artem B. Bityutskiy

[permalink] [raw]
Subject: Re: [PATCH 16/23] Kobject: provide better warning messages when people do stupid things

Greg KH wrote:
>>When I started using sysfs, I noticed a lack of good comments above
>>prototypes of exported functions.
>
> I agree, care to provide a patch that fixes this?
>
I fear I have no enough knowledge for that.

--
Best regards, Artem B. Bityutskiy
Oktet Labs (St. Petersburg), Software Engineer.
+7 812 4286709 (office) +7 911 2449030 (mobile)
E-mail: [email protected], Web: http://www.oktetlabs.ru