mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
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 ...
This commit is contained in:
commit
08a4ecee98
@ -196,3 +196,21 @@ Why: Board specific code doesn't build anymore since ~2.6.0 and no
|
||||
users have complained indicating there is no more need for these
|
||||
boards. This should really be considered a last call.
|
||||
Who: Ralf Baechle <ralf@linux-mips.org>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: USB driver API moves to EXPORT_SYMBOL_GPL
|
||||
When: Febuary 2008
|
||||
Files: include/linux/usb.h, drivers/usb/core/driver.c
|
||||
Why: The USB subsystem has changed a lot over time, and it has been
|
||||
possible to create userspace USB drivers using usbfs/libusb/gadgetfs
|
||||
that operate as fast as the USB bus allows. Because of this, the USB
|
||||
subsystem will not be allowing closed source kernel drivers to
|
||||
register with it, after this grace period is over. If anyone needs
|
||||
any help in converting their closed source drivers over to use the
|
||||
userspace filesystems, please contact the
|
||||
linux-usb-devel@lists.sourceforge.net mailing list, and the developers
|
||||
there will be glad to help you out.
|
||||
Who: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
|
||||
---------------------------
|
||||
|
@ -788,6 +788,8 @@ static int locomo_probe(struct platform_device *dev)
|
||||
if (!mem)
|
||||
return -EINVAL;
|
||||
irq = platform_get_irq(dev, 0);
|
||||
if (irq < 0)
|
||||
return -ENXIO;
|
||||
|
||||
return __locomo_probe(&dev->dev, mem, irq);
|
||||
}
|
||||
|
@ -943,6 +943,8 @@ static int sa1111_probe(struct platform_device *pdev)
|
||||
if (!mem)
|
||||
return -EINVAL;
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0)
|
||||
return -ENXIO;
|
||||
|
||||
return __sa1111_probe(&pdev->dev, mem, irq);
|
||||
}
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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 = .; \
|
||||
|
@ -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, const char *name)
|
||||
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, const char *name)
|
||||
kfree(p);
|
||||
}
|
||||
out:
|
||||
up(&block_subsys_sem);
|
||||
mutex_unlock(&block_subsys_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -197,7 +198,7 @@ int unregister_blkdev(unsigned int major, const char *name)
|
||||
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, const char *name)
|
||||
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 *part, loff_t *pos)
|
||||
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 *part, void *v, loff_t *pos)
|
||||
|
||||
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 dev, int *part, void *data)
|
||||
|
||||
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_file *part, loff_t *pos)
|
||||
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_file *part, void *v, loff_t *pos)
|
||||
|
||||
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)
|
||||
|
@ -141,7 +141,7 @@ int __devinit register_cpu(struct cpu *cpu, int num, struct node *root)
|
||||
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];
|
||||
|
@ -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);
|
||||
|
@ -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, dev_t dev, unsigned long range,
|
||||
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, dev_t dev, unsigned long range,
|
||||
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, dev_t dev, unsigned long range)
|
||||
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, dev_t dev, unsigned long range)
|
||||
}
|
||||
}
|
||||
}
|
||||
up(domain->sem);
|
||||
mutex_unlock(domain->lock);
|
||||
kfree(found);
|
||||
}
|
||||
|
||||
@ -99,7 +100,7 @@ struct kobject *kobj_lookup(struct kobj_map *domain, dev_t dev, int *index)
|
||||
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_probe_t *base_probe, struct semaphore *sem)
|
||||
base->get = base_probe;
|
||||
for (i = 0; i < 255; i++)
|
||||
p->probes[i] = base;
|
||||
p->sem = sem;
|
||||
p->lock = lock;
|
||||
return p;
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ int platform_get_irq(struct platform_device *dev, unsigned int num)
|
||||
{
|
||||
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 platform_device *dev, char *name)
|
||||
{
|
||||
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);
|
||||
|
||||
|
@ -448,13 +448,13 @@ static int s3c2410_rtc_probe(struct platform_device *pdev)
|
||||
/* 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;
|
||||
}
|
||||
|
@ -338,6 +338,10 @@ static int __devinit mpcore_wdt_probe(struct platform_device *dev)
|
||||
|
||||
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;
|
||||
|
@ -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 *pdev)
|
||||
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) {
|
||||
|
@ -302,6 +302,10 @@ static int fsl_i2c_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
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_device *pdev)
|
||||
fail_irq:
|
||||
iounmap(i2c->base);
|
||||
fail_map:
|
||||
fail_get_irq:
|
||||
kfree(i2c);
|
||||
return result;
|
||||
};
|
||||
|
@ -516,6 +516,10 @@ mv64xxx_i2c_probe(struct platform_device *pd)
|
||||
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;
|
||||
|
@ -674,6 +674,11 @@ static int au_ide_probe(struct device *dev)
|
||||
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);
|
||||
|
@ -438,7 +438,7 @@ static int pxamci_probe(struct platform_device *pdev)
|
||||
|
||||
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);
|
||||
|
@ -696,7 +696,9 @@ static int __init am79c961_probe(struct platform_device *pdev)
|
||||
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;
|
||||
|
||||
|
@ -118,6 +118,8 @@ static int do_pd_setup(struct fs_enet_private *fep)
|
||||
|
||||
/* 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");
|
||||
|
@ -144,6 +144,8 @@ static int do_pd_setup(struct fs_enet_private *fep)
|
||||
|
||||
/* 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;
|
||||
|
@ -118,6 +118,8 @@ static int do_pd_setup(struct fs_enet_private *fep)
|
||||
|
||||
/* 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;
|
||||
|
@ -193,8 +193,12 @@ static int gfar_probe(struct platform_device *pdev)
|
||||
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 */
|
||||
|
@ -2221,6 +2221,10 @@ static int smc_drv_probe(struct platform_device *pdev)
|
||||
|
||||
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)
|
||||
|
@ -218,7 +218,7 @@ static int __init omap_cf_probe(struct device *dev)
|
||||
|
||||
/* 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);
|
||||
|
@ -1066,6 +1066,8 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
|
||||
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");
|
||||
|
||||
|
@ -378,7 +378,7 @@ const struct usb_device_id *usb_match_id(struct usb_interface *interface,
|
||||
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(usb_match_id);
|
||||
EXPORT_SYMBOL_GPL_FUTURE(usb_match_id);
|
||||
|
||||
int usb_device_match(struct device *dev, struct device_driver *drv)
|
||||
{
|
||||
@ -446,7 +446,7 @@ int usb_register_driver(struct usb_driver *new_driver, struct module *owner)
|
||||
|
||||
return retval;
|
||||
}
|
||||
EXPORT_SYMBOL(usb_register_driver);
|
||||
EXPORT_SYMBOL_GPL_FUTURE(usb_register_driver);
|
||||
|
||||
/**
|
||||
* usb_deregister - unregister a USB driver
|
||||
@ -469,4 +469,4 @@ void usb_deregister(struct usb_driver *driver)
|
||||
|
||||
usbfs_update_special();
|
||||
}
|
||||
EXPORT_SYMBOL(usb_deregister);
|
||||
EXPORT_SYMBOL_GPL_FUTURE(usb_deregister);
|
||||
|
@ -286,7 +286,7 @@ void usb_hcd_omap_remove (struct usb_hcd *, struct platform_device *);
|
||||
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_driver *driver,
|
||||
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;
|
||||
|
||||
|
@ -607,6 +607,7 @@ static void clearfb16(struct fb_info *info)
|
||||
|
||||
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)
|
||||
|
@ -1457,7 +1457,7 @@ static int __init sa1100fb_probe(struct platform_device *pdev)
|
||||
int ret, irq;
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq <= 0)
|
||||
if (irq < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (!request_mem_region(0xb0100000, 0x10000, "LCD"))
|
||||
|
@ -401,6 +401,7 @@ static int __init vfb_setup(char *options)
|
||||
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)
|
||||
|
@ -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 major, unsigned int baseminor,
|
||||
|
||||
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 major, unsigned int baseminor,
|
||||
}
|
||||
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 major, unsigned baseminor, int minorct)
|
||||
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 major, unsigned baseminor, int minorct)
|
||||
cd = *cp;
|
||||
*cp = cd->next;
|
||||
}
|
||||
up(&chrdevs_lock);
|
||||
mutex_unlock(&chrdevs_lock);
|
||||
return cd;
|
||||
}
|
||||
|
||||
|
@ -251,3 +251,49 @@ struct dentry *debugfs_create_bool(const char *name, mode_t mode,
|
||||
}
|
||||
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);
|
||||
|
@ -50,6 +50,32 @@ static struct sysfs_dirent * sysfs_new_dirent(struct sysfs_dirent * parent_sd,
|
||||
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, struct dentry * p,
|
||||
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) {
|
||||
@ -302,6 +332,7 @@ void sysfs_remove_dir(struct kobject * kobj)
|
||||
* Drop reference from dget() on entrance.
|
||||
*/
|
||||
dput(dentry);
|
||||
kobj->dentry = NULL;
|
||||
}
|
||||
|
||||
int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
|
||||
@ -479,7 +510,3 @@ struct file_operations sysfs_dir_operations = {
|
||||
.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);
|
||||
|
@ -301,9 +301,8 @@ static int check_perm(struct inode * inode, struct file * file)
|
||||
/* 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;
|
||||
@ -362,10 +361,12 @@ int sysfs_add_file(struct dentry * dir, const struct attribute * attr, int type)
|
||||
{
|
||||
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;
|
||||
|
@ -54,11 +54,10 @@ int sysfs_setattr(struct dentry * dentry, struct iattr * iattr)
|
||||
|
||||
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;
|
||||
@ -227,12 +226,16 @@ void sysfs_drop_dentry(struct sysfs_dirent * sd, struct dentry * parent)
|
||||
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)
|
||||
|
@ -66,6 +66,7 @@ static int sysfs_add_link(struct dentry * parent, const char * name, struct kobj
|
||||
if (!error)
|
||||
return 0;
|
||||
|
||||
kobject_put(target);
|
||||
kfree(sl->link_name);
|
||||
exit2:
|
||||
kfree(sl);
|
||||
@ -82,12 +83,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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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) \
|
||||
|
@ -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
|
||||
|
@ -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 char *name, mode_t mode,
|
||||
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_create_bool(const char *name, mode_t mode,
|
||||
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
|
||||
|
@ -424,6 +424,8 @@ extern void firmware_unregister(struct subsystem *);
|
||||
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,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, unsigned long, struct module *,
|
||||
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
|
||||
|
@ -80,6 +80,8 @@ extern void kobject_unregister(struct kobject *);
|
||||
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 {
|
||||
@ -255,7 +257,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,
|
||||
|
@ -198,6 +198,9 @@ void *__symbol_get_gpl(const char *symbol);
|
||||
#define EXPORT_SYMBOL_GPL(sym) \
|
||||
__EXPORT_SYMBOL(sym, "_gpl")
|
||||
|
||||
#define EXPORT_SYMBOL_GPL_FUTURE(sym) \
|
||||
__EXPORT_SYMBOL(sym, "_gpl_future")
|
||||
|
||||
#endif
|
||||
|
||||
struct module_ref
|
||||
@ -242,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;
|
||||
|
||||
@ -255,6 +259,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 +450,7 @@ void module_remove_driver(struct device_driver *);
|
||||
#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 *
|
||||
|
@ -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)
|
||||
|
||||
|
199
kernel/module.c
199
kernel/module.c
@ -126,8 +126,11 @@ extern const struct kernel_symbol __start___ksymtab[];
|
||||
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
|
||||
@ -135,6 +138,18 @@ extern const unsigned long __start___kcrctab_gpl[];
|
||||
#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,41 +157,76 @@ static unsigned long __find_symbol(const char *name,
|
||||
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;
|
||||
}
|
||||
}
|
||||
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) {
|
||||
*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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
@ -379,7 +429,6 @@ static inline void percpu_modcopy(void *pcpudst, const void *src,
|
||||
}
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
#ifdef CONFIG_MODULE_UNLOAD
|
||||
#define MODINFO_ATTR(field) \
|
||||
static void setup_modinfo_##field(struct module *mod, const char *s) \
|
||||
{ \
|
||||
@ -411,12 +460,7 @@ static struct module_attribute modinfo_##field = { \
|
||||
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)
|
||||
{
|
||||
@ -731,6 +775,15 @@ static inline void module_unload_init(struct module *mod)
|
||||
}
|
||||
#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)
|
||||
@ -1056,37 +1109,28 @@ static inline void remove_sect_attrs(struct module *mod)
|
||||
}
|
||||
#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;
|
||||
}
|
||||
@ -1096,12 +1140,16 @@ static void module_remove_modinfo_attrs(struct module *mod)
|
||||
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,
|
||||
@ -1119,19 +1167,13 @@ static int mod_sysfs_setup(struct module *mod,
|
||||
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;
|
||||
|
||||
@ -1143,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);
|
||||
@ -1424,7 +1463,6 @@ static char *get_modinfo(Elf_Shdr *sechdrs,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MODULE_UNLOAD
|
||||
static void setup_modinfo(struct module *mod, Elf_Shdr *sechdrs,
|
||||
unsigned int infoindex)
|
||||
{
|
||||
@ -1439,23 +1477,17 @@ static void setup_modinfo(struct module *mod, Elf_Shdr *sechdrs,
|
||||
attr->attr.name));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#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 */
|
||||
@ -1537,7 +1569,8 @@ static struct module *load_module(void __user *umod,
|
||||
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;
|
||||
@ -1618,8 +1651,10 @@ static struct module *load_module(void __user *umod,
|
||||
/* 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");
|
||||
@ -1755,10 +1790,8 @@ static struct module *load_module(void __user *umod,
|
||||
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,
|
||||
@ -1775,10 +1808,16 @@ static struct module *load_module(void __user *umod,
|
||||
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);
|
||||
|
@ -638,13 +638,8 @@ static ssize_t module_attr_show(struct kobject *kobj,
|
||||
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 kobject *kobj,
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
@ -379,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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -52,7 +52,12 @@ int kref_put(struct kref *kref, void (*release)(struct kref *kref))
|
||||
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;
|
||||
}
|
||||
|
@ -52,9 +52,9 @@ is_reserved_hash (register const char *str, register unsigned int len)
|
||||
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 *str, register unsigned int len)
|
||||
{
|
||||
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 *str, register unsigned int len)
|
||||
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"
|
||||
{"__attribute", ATTRIBUTE_KEYW},
|
||||
#line 11 "scripts/genksyms/keywords.gperf"
|
||||
{"__const", CONST_KEYW},
|
||||
#line 10 "scripts/genksyms/keywords.gperf"
|
||||
{"__attribute__", ATTRIBUTE_KEYW},
|
||||
{"__attribute", ATTRIBUTE_KEYW},
|
||||
#line 12 "scripts/genksyms/keywords.gperf"
|
||||
{"__const", CONST_KEYW},
|
||||
#line 11 "scripts/genksyms/keywords.gperf"
|
||||
{"__attribute__", ATTRIBUTE_KEYW},
|
||||
#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"
|
||||
{"enum", ENUM_KEYW},
|
||||
#line 17 "scripts/genksyms/keywords.gperf"
|
||||
{"__volatile", VOLATILE_KEYW},
|
||||
#line 34 "scripts/genksyms/keywords.gperf"
|
||||
{"extern", EXTERN_KEYW},
|
||||
{"enum", ENUM_KEYW},
|
||||
#line 18 "scripts/genksyms/keywords.gperf"
|
||||
{"__volatile", VOLATILE_KEYW},
|
||||
#line 35 "scripts/genksyms/keywords.gperf"
|
||||
{"extern", EXTERN_KEYW},
|
||||
#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"
|
||||
{"__inline", INLINE_KEYW},
|
||||
#line 29 "scripts/genksyms/keywords.gperf"
|
||||
{"auto", AUTO_KEYW},
|
||||
#line 14 "scripts/genksyms/keywords.gperf"
|
||||
{"__inline", INLINE_KEYW},
|
||||
#line 30 "scripts/genksyms/keywords.gperf"
|
||||
{"auto", AUTO_KEYW},
|
||||
#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}
|
||||
};
|
||||
|
||||
|
@ -4,6 +4,7 @@ struct resword { const char *name; int token; }
|
||||
%%
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user