Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-2.6

Trivial manual merge fixup for usb_find_interface clashes.
This commit is contained in:
Linus Torvalds 2006-01-04 18:44:12 -08:00
commit db9edfd7e3
64 changed files with 878 additions and 823 deletions

View file

@ -115,7 +115,7 @@ Current PPC64 Linux EEH Implementation
At this time, a generic EEH recovery mechanism has been implemented,
so that individual device drivers do not need to be modified to support
EEH recovery. This generic mechanism piggy-backs on the PCI hotplug
infrastructure, and percolates events up through the hotplug/udev
infrastructure, and percolates events up through the userspace/udev
infrastructure. Followiing is a detailed description of how this is
accomplished.
@ -172,7 +172,7 @@ A handler for the EEH notifier_block events is implemented in
drivers/pci/hotplug/pSeries_pci.c, called handle_eeh_events().
It saves the device BAR's and then calls rpaphp_unconfig_pci_adapter().
This last call causes the device driver for the card to be stopped,
which causes hotplug events to go out to user space. This triggers
which causes uevents to go out to user space. This triggers
user-space scripts that might issue commands such as "ifdown eth0"
for ethernet cards, and so on. This handler then sleeps for 5 seconds,
hoping to give the user-space scripts enough time to complete.
@ -258,29 +258,30 @@ rpa_php_unconfig_pci_adapter() { // in rpaphp_pci.c
calls
pci_destroy_dev (struct pci_dev *) {
calls
device_unregister (&dev->dev) { // in /drivers/base/core.c
device_unregister (&dev->dev) { // in /drivers/base/core.c
calls
device_del(struct device * dev) { // in /drivers/base/core.c
device_del(struct device * dev) { // in /drivers/base/core.c
calls
kobject_del() { //in /libs/kobject.c
kobject_del() { //in /libs/kobject.c
calls
kobject_hotplug() { // in /libs/kobject.c
kobject_uevent() { // in /libs/kobject.c
calls
kset_hotplug() { // in /lib/kobject.c
kset_uevent() { // in /lib/kobject.c
calls
kset->hotplug_ops->hotplug() which is really just
kset->uevent_ops->uevent() // which is really just
a call to
dev_hotplug() { // in /drivers/base/core.c
dev_uevent() { // in /drivers/base/core.c
calls
dev->bus->hotplug() which is really just a call to
pci_hotplug () { // in drivers/pci/hotplug.c
dev->bus->uevent() which is really just a call to
pci_uevent () { // in drivers/pci/hotplug.c
which prints device name, etc....
}
}
then kset_hotplug() calls
call_usermodehelper () with
argv[0]=hotplug_path[] which is "/sbin/hotplug"
--> event to userspace,
then kobject_uevent() sends a netlink uevent to userspace
--> userspace uevent
(during early boot, nobody listens to netlink events and
kobject_uevent() executes uevent_helper[], which runs the
event process /sbin/hotplug)
}
}
kobject_del() then calls sysfs_remove_dir(), which would

View file

@ -1480,12 +1480,6 @@ W: http://nfs.sourceforge.net/
W: http://www.cse.unsw.edu.au/~neilb/patches/linux-devel/
S: Maintained
KERNEL EVENT LAYER (KOBJECT_UEVENT)
P: Robert Love
M: rml@novell.com
L: linux-kernel@vger.kernel.org
S: Maintained
KEXEC
P: Eric Biederman
P: Randy Dunlap

View file

@ -45,7 +45,7 @@ static int amba_match(struct device *dev, struct device_driver *drv)
}
#ifdef CONFIG_HOTPLUG
static int amba_hotplug(struct device *dev, char **envp, int nr_env, char *buf, int bufsz)
static int amba_uevent(struct device *dev, char **envp, int nr_env, char *buf, int bufsz)
{
struct amba_device *pcdev = to_amba_device(dev);
@ -58,7 +58,7 @@ static int amba_hotplug(struct device *dev, char **envp, int nr_env, char *buf,
return 0;
}
#else
#define amba_hotplug NULL
#define amba_uevent NULL
#endif
static int amba_suspend(struct device *dev, pm_message_t state)
@ -88,7 +88,7 @@ static int amba_resume(struct device *dev)
static struct bus_type amba_bustype = {
.name = "amba",
.match = amba_match,
.hotplug = amba_hotplug,
.uevent = amba_uevent,
.suspend = amba_suspend,
.resume = amba_resume,
};

View file

@ -65,7 +65,7 @@ static int tiocx_match(struct device *dev, struct device_driver *drv)
}
static int tiocx_hotplug(struct device *dev, char **envp, int num_envp,
static int tiocx_uevent(struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size)
{
return -ENODEV;
@ -79,7 +79,7 @@ static void tiocx_bus_release(struct device *dev)
struct bus_type tiocx_bus_type = {
.name = "tiocx",
.match = tiocx_match,
.hotplug = tiocx_hotplug,
.uevent = tiocx_uevent,
};
/**

View file

@ -293,6 +293,6 @@ static int vio_hotplug(struct device *dev, char **envp, int num_envp,
struct bus_type vio_bus_type = {
.name = "vio",
.hotplug = vio_hotplug,
.uevent = vio_hotplug,
.match = vio_bus_match,
};

View file

@ -358,7 +358,7 @@ static struct sysfs_ops disk_sysfs_ops = {
static ssize_t disk_uevent_store(struct gendisk * disk,
const char *buf, size_t count)
{
kobject_hotplug(&disk->kobj, KOBJ_ADD);
kobject_uevent(&disk->kobj, KOBJ_ADD);
return count;
}
static ssize_t disk_dev_read(struct gendisk * disk, char *page)
@ -455,14 +455,14 @@ static struct kobj_type ktype_block = {
extern struct kobj_type ktype_part;
static int block_hotplug_filter(struct kset *kset, struct kobject *kobj)
static int block_uevent_filter(struct kset *kset, struct kobject *kobj)
{
struct kobj_type *ktype = get_ktype(kobj);
return ((ktype == &ktype_block) || (ktype == &ktype_part));
}
static int block_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
static int block_uevent(struct kset *kset, struct kobject *kobj, char **envp,
int num_envp, char *buffer, int buffer_size)
{
struct kobj_type *ktype = get_ktype(kobj);
@ -474,40 +474,40 @@ static int block_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
if (ktype == &ktype_block) {
disk = container_of(kobj, struct gendisk, kobj);
add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size,
&length, "MINOR=%u", disk->first_minor);
add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
&length, "MINOR=%u", disk->first_minor);
} else if (ktype == &ktype_part) {
disk = container_of(kobj->parent, struct gendisk, kobj);
part = container_of(kobj, struct hd_struct, kobj);
add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size,
&length, "MINOR=%u",
disk->first_minor + part->partno);
add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
&length, "MINOR=%u",
disk->first_minor + part->partno);
} else
return 0;
add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &length,
"MAJOR=%u", disk->major);
add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
"MAJOR=%u", disk->major);
/* add physical device, backing this device */
physdev = disk->driverfs_dev;
if (physdev) {
char *path = kobject_get_path(&physdev->kobj, GFP_KERNEL);
add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size,
&length, "PHYSDEVPATH=%s", path);
add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
&length, "PHYSDEVPATH=%s", path);
kfree(path);
if (physdev->bus)
add_hotplug_env_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"PHYSDEVBUS=%s",
physdev->bus->name);
add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"PHYSDEVBUS=%s",
physdev->bus->name);
if (physdev->driver)
add_hotplug_env_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"PHYSDEVDRIVER=%s",
physdev->driver->name);
add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"PHYSDEVDRIVER=%s",
physdev->driver->name);
}
/* terminate, set to next free slot, shrink available space */
@ -520,13 +520,13 @@ static int block_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
return 0;
}
static struct kset_hotplug_ops block_hotplug_ops = {
.filter = block_hotplug_filter,
.hotplug = block_hotplug,
static struct kset_uevent_ops block_uevent_ops = {
.filter = block_uevent_filter,
.uevent = block_uevent,
};
/* declare block_subsys. */
static decl_subsys(block, &ktype_block, &block_hotplug_ops);
static decl_subsys(block, &ktype_block, &block_uevent_ops);
/*

View file

@ -172,21 +172,21 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
if (ACPI_FAILURE(status) || !device) {
result = container_device_add(&device, handle);
if (!result)
kobject_hotplug(&device->kobj,
KOBJ_ONLINE);
kobject_uevent(&device->kobj,
KOBJ_ONLINE);
else
printk("Failed to add container\n");
}
} else {
if (ACPI_SUCCESS(status)) {
/* device exist and this is a remove request */
kobject_hotplug(&device->kobj, KOBJ_OFFLINE);
kobject_uevent(&device->kobj, KOBJ_OFFLINE);
}
}
break;
case ACPI_NOTIFY_EJECT_REQUEST:
if (!acpi_bus_get_device(handle, &device) && device) {
kobject_hotplug(&device->kobj, KOBJ_OFFLINE);
kobject_uevent(&device->kobj, KOBJ_OFFLINE);
}
break;
default:

View file

@ -748,7 +748,7 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
return_VALUE(-ENODEV);
if ((pr->id >= 0) && (pr->id < NR_CPUS)) {
kobject_hotplug(&(*device)->kobj, KOBJ_ONLINE);
kobject_uevent(&(*device)->kobj, KOBJ_ONLINE);
}
return_VALUE(0);
}
@ -788,13 +788,13 @@ acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data)
}
if (pr->id >= 0 && (pr->id < NR_CPUS)) {
kobject_hotplug(&device->kobj, KOBJ_OFFLINE);
kobject_uevent(&device->kobj, KOBJ_OFFLINE);
break;
}
result = acpi_processor_start(device);
if ((!result) && ((pr->id >= 0) && (pr->id < NR_CPUS))) {
kobject_hotplug(&device->kobj, KOBJ_ONLINE);
kobject_uevent(&device->kobj, KOBJ_ONLINE);
} else {
ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
"Device [%s] failed to start\n",
@ -818,7 +818,7 @@ acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data)
}
if ((pr->id < NR_CPUS) && (cpu_present(pr->id)))
kobject_hotplug(&device->kobj, KOBJ_OFFLINE);
kobject_uevent(&device->kobj, KOBJ_OFFLINE);
break;
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,

View file

@ -78,7 +78,7 @@ static struct kobj_type ktype_acpi_ns = {
.release = acpi_device_release,
};
static int namespace_hotplug(struct kset *kset, struct kobject *kobj,
static int namespace_uevent(struct kset *kset, struct kobject *kobj,
char **envp, int num_envp, char *buffer,
int buffer_size)
{
@ -89,8 +89,8 @@ static int namespace_hotplug(struct kset *kset, struct kobject *kobj,
if (!dev->driver)
return 0;
if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &len,
"PHYSDEVDRIVER=%s", dev->driver->name))
if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
"PHYSDEVDRIVER=%s", dev->driver->name))
return -ENOMEM;
envp[i] = NULL;
@ -98,8 +98,8 @@ static int namespace_hotplug(struct kset *kset, struct kobject *kobj,
return 0;
}
static struct kset_hotplug_ops namespace_hotplug_ops = {
.hotplug = &namespace_hotplug,
static struct kset_uevent_ops namespace_uevent_ops = {
.uevent = &namespace_uevent,
};
static struct kset acpi_namespace_kset = {
@ -108,7 +108,7 @@ static struct kset acpi_namespace_kset = {
},
.subsys = &acpi_subsys,
.ktype = &ktype_acpi_ns,
.hotplug_ops = &namespace_hotplug_ops,
.uevent_ops = &namespace_uevent_ops,
};
static void acpi_device_register(struct acpi_device *device,
@ -347,7 +347,7 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
}
/* --------------------------------------------------------------------------
ACPI hotplug sysfs device file support
ACPI sysfs device file support
-------------------------------------------------------------------------- */
static ssize_t acpi_eject_store(struct acpi_device *device,
const char *buf, size_t count);

View file

@ -19,11 +19,11 @@ config PREVENT_FIRMWARE_BUILD
If unsure say Y here.
config FW_LOADER
tristate "Hotplug firmware loading support"
tristate "Userspace firmware loading support"
select HOTPLUG
---help---
This option is provided for the case where no in-kernel-tree modules
require hotplug firmware loading support, but a module built outside
require userspace firmware loading support, but a module built outside
the kernel tree does.
config DEBUG_DRIVER

View file

@ -152,7 +152,11 @@ static ssize_t driver_unbind(struct device_driver *drv,
dev = bus_find_device(bus, NULL, (void *)buf, driver_helper);
if (dev && dev->driver == drv) {
if (dev->parent) /* Needed for USB */
down(&dev->parent->sem);
device_release_driver(dev);
if (dev->parent)
up(&dev->parent->sem);
err = count;
}
put_device(dev);
@ -175,9 +179,13 @@ static ssize_t driver_bind(struct device_driver *drv,
dev = bus_find_device(bus, NULL, (void *)buf, driver_helper);
if (dev && dev->driver == NULL) {
if (dev->parent) /* Needed for USB */
down(&dev->parent->sem);
down(&dev->sem);
err = driver_probe_device(drv, dev);
up(&dev->sem);
if (dev->parent)
up(&dev->parent->sem);
}
put_device(dev);
put_bus(bus);
@ -420,6 +428,26 @@ static void driver_remove_attrs(struct bus_type * bus, struct device_driver * dr
}
}
#ifdef CONFIG_HOTPLUG
/*
* Thanks to drivers making their tables __devinit, we can't allow manual
* bind and unbind from userspace unless CONFIG_HOTPLUG is enabled.
*/
static void add_bind_files(struct device_driver *drv)
{
driver_create_file(drv, &driver_attr_unbind);
driver_create_file(drv, &driver_attr_bind);
}
static void remove_bind_files(struct device_driver *drv)
{
driver_remove_file(drv, &driver_attr_bind);
driver_remove_file(drv, &driver_attr_unbind);
}
#else
static inline void add_bind_files(struct device_driver *drv) {}
static inline void remove_bind_files(struct device_driver *drv) {}
#endif
/**
* bus_add_driver - Add a driver to the bus.
@ -449,8 +477,7 @@ int bus_add_driver(struct device_driver * drv)
module_add_driver(drv->owner, drv);
driver_add_attrs(bus, drv);
driver_create_file(drv, &driver_attr_unbind);
driver_create_file(drv, &driver_attr_bind);
add_bind_files(drv);
}
return error;
}
@ -468,8 +495,7 @@ int bus_add_driver(struct device_driver * drv)
void bus_remove_driver(struct device_driver * drv)
{
if (drv->bus) {
driver_remove_file(drv, &driver_attr_bind);
driver_remove_file(drv, &driver_attr_unbind);
remove_bind_files(drv);
driver_remove_attrs(drv->bus, drv);
klist_remove(&drv->knode_bus);
pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name);
@ -484,8 +510,13 @@ void bus_remove_driver(struct device_driver * drv)
/* Helper for bus_rescan_devices's iter */
static int bus_rescan_devices_helper(struct device *dev, void *data)
{
if (!dev->driver)
if (!dev->driver) {
if (dev->parent) /* Needed for USB */
down(&dev->parent->sem);
device_attach(dev);
if (dev->parent)
up(&dev->parent->sem);
}
return 0;
}

View file

@ -178,7 +178,7 @@ static void class_device_create_release(struct class_device *class_dev)
}
/* needed to allow these devices to have parent class devices */
static int class_device_create_hotplug(struct class_device *class_dev,
static int class_device_create_uevent(struct class_device *class_dev,
char **envp, int num_envp,
char *buffer, int buffer_size)
{
@ -331,7 +331,7 @@ static struct kobj_type ktype_class_device = {
.release = class_dev_release,
};
static int class_hotplug_filter(struct kset *kset, struct kobject *kobj)
static int class_uevent_filter(struct kset *kset, struct kobject *kobj)
{
struct kobj_type *ktype = get_ktype(kobj);
@ -343,14 +343,14 @@ static int class_hotplug_filter(struct kset *kset, struct kobject *kobj)
return 0;
}
static const char *class_hotplug_name(struct kset *kset, struct kobject *kobj)
static const char *class_uevent_name(struct kset *kset, struct kobject *kobj)
{
struct class_device *class_dev = to_class_dev(kobj);
return class_dev->class->name;
}
static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp,
int num_envp, char *buffer, int buffer_size)
{
struct class_device *class_dev = to_class_dev(kobj);
@ -365,29 +365,29 @@ static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
struct device *dev = class_dev->dev;
char *path = kobject_get_path(&dev->kobj, GFP_KERNEL);
add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size,
&length, "PHYSDEVPATH=%s", path);
add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
&length, "PHYSDEVPATH=%s", path);
kfree(path);
if (dev->bus)
add_hotplug_env_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"PHYSDEVBUS=%s", dev->bus->name);
add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"PHYSDEVBUS=%s", dev->bus->name);
if (dev->driver)
add_hotplug_env_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"PHYSDEVDRIVER=%s", dev->driver->name);
add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"PHYSDEVDRIVER=%s", dev->driver->name);
}
if (MAJOR(class_dev->devt)) {
add_hotplug_env_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"MAJOR=%u", MAJOR(class_dev->devt));
add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"MAJOR=%u", MAJOR(class_dev->devt));
add_hotplug_env_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"MINOR=%u", MINOR(class_dev->devt));
add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"MINOR=%u", MINOR(class_dev->devt));
}
/* terminate, set to next free slot, shrink available space */
@ -397,30 +397,30 @@ static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
buffer = &buffer[length];
buffer_size -= length;
if (class_dev->hotplug) {
if (class_dev->uevent) {
/* have the class device specific function add its stuff */
retval = class_dev->hotplug(class_dev, envp, num_envp,
retval = class_dev->uevent(class_dev, envp, num_envp,
buffer, buffer_size);
if (retval)
pr_debug("class_dev->hotplug() returned %d\n", retval);
} else if (class_dev->class->hotplug) {
pr_debug("class_dev->uevent() returned %d\n", retval);
} else if (class_dev->class->uevent) {
/* have the class specific function add its stuff */
retval = class_dev->class->hotplug(class_dev, envp, num_envp,
retval = class_dev->class->uevent(class_dev, envp, num_envp,
buffer, buffer_size);
if (retval)
pr_debug("class->hotplug() returned %d\n", retval);
pr_debug("class->uevent() returned %d\n", retval);
}
return retval;
}
static struct kset_hotplug_ops class_hotplug_ops = {
.filter = class_hotplug_filter,
.name = class_hotplug_name,
.hotplug = class_hotplug,
static struct kset_uevent_ops class_uevent_ops = {
.filter = class_uevent_filter,
.name = class_uevent_name,
.uevent = class_uevent,
};
static decl_subsys(class_obj, &ktype_class_device, &class_hotplug_ops);
static decl_subsys(class_obj, &ktype_class_device, &class_uevent_ops);
static int class_device_add_attrs(struct class_device * cd)
@ -464,7 +464,7 @@ static ssize_t show_dev(struct class_device *class_dev, char *buf)
static ssize_t store_uevent(struct class_device *class_dev,
const char *buf, size_t count)
{
kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
kobject_uevent(&class_dev->kobj, KOBJ_ADD);
return count;
}
@ -559,7 +559,7 @@ int class_device_add(struct class_device *class_dev)
class_name);
}
kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
kobject_uevent(&class_dev->kobj, KOBJ_ADD);
/* notify any interfaces this device is now here */
if (parent_class) {
@ -632,7 +632,7 @@ struct class_device *class_device_create(struct class *cls,
class_dev->class = cls;
class_dev->parent = parent;
class_dev->release = class_device_create_release;
class_dev->hotplug = class_device_create_hotplug;
class_dev->uevent = class_device_create_uevent;
va_start(args, fmt);
vsnprintf(class_dev->class_id, BUS_ID_SIZE, fmt, args);
@ -674,7 +674,7 @@ void class_device_del(struct class_device *class_dev)
class_device_remove_file(class_dev, class_dev->devt_attr);
class_device_remove_attrs(class_dev);
kobject_hotplug(&class_dev->kobj, KOBJ_REMOVE);
kobject_uevent(&class_dev->kobj, KOBJ_REMOVE);
kobject_del(&class_dev->kobj);
class_device_put(parent_device);

View file

@ -90,7 +90,7 @@ static struct kobj_type ktype_device = {
};
static int dev_hotplug_filter(struct kset *kset, struct kobject *kobj)
static int dev_uevent_filter(struct kset *kset, struct kobject *kobj)
{
struct kobj_type *ktype = get_ktype(kobj);
@ -102,14 +102,14 @@ static int dev_hotplug_filter(struct kset *kset, struct kobject *kobj)
return 0;
}
static const char *dev_hotplug_name(struct kset *kset, struct kobject *kobj)
static const char *dev_uevent_name(struct kset *kset, struct kobject *kobj)
{
struct device *dev = to_dev(kobj);
return dev->bus->name;
}
static int dev_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
int num_envp, char *buffer, int buffer_size)
{
struct device *dev = to_dev(kobj);
@ -119,15 +119,15 @@ static int dev_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
/* add bus name of physical device */
if (dev->bus)
add_hotplug_env_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"PHYSDEVBUS=%s", dev->bus->name);
add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"PHYSDEVBUS=%s", dev->bus->name);
/* add driver name of physical device */
if (dev->driver)
add_hotplug_env_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"PHYSDEVDRIVER=%s", dev->driver->name);
add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"PHYSDEVDRIVER=%s", dev->driver->name);
/* terminate, set to next free slot, shrink available space */
envp[i] = NULL;
@ -136,11 +136,11 @@ static int dev_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
buffer = &buffer[length];
buffer_size -= length;
if (dev->bus && dev->bus->hotplug) {
if (dev->bus && dev->bus->uevent) {
/* have the bus specific function add its stuff */
retval = dev->bus->hotplug (dev, envp, num_envp, buffer, buffer_size);
retval = dev->bus->uevent(dev, envp, num_envp, buffer, buffer_size);
if (retval) {
pr_debug ("%s - hotplug() returned %d\n",
pr_debug ("%s - uevent() returned %d\n",
__FUNCTION__, retval);
}
}
@ -148,16 +148,16 @@ static int dev_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
return retval;
}
static struct kset_hotplug_ops device_hotplug_ops = {
.filter = dev_hotplug_filter,
.name = dev_hotplug_name,
.hotplug = dev_hotplug,
static struct kset_uevent_ops device_uevent_ops = {
.filter = dev_uevent_filter,
.name = dev_uevent_name,
.uevent = dev_uevent,
};
static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
kobject_hotplug(&dev->kobj, KOBJ_ADD);
kobject_uevent(&dev->kobj, KOBJ_ADD);
return count;
}
@ -165,7 +165,7 @@ static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
* device_subsys - structure to be registered with kobject core.
*/
decl_subsys(devices, &ktype_device, &device_hotplug_ops);
decl_subsys(devices, &ktype_device, &device_uevent_ops);
/**
@ -274,7 +274,7 @@ int device_add(struct device *dev)
dev->uevent_attr.store = store_uevent;
device_create_file(dev, &dev->uevent_attr);
kobject_hotplug(&dev->kobj, KOBJ_ADD);
kobject_uevent(&dev->kobj, KOBJ_ADD);
if ((error = device_pm_add(dev)))
goto PMError;
if ((error = bus_add_device(dev)))
@ -291,7 +291,7 @@ int device_add(struct device *dev)
BusError:
device_pm_remove(dev);
PMError:
kobject_hotplug(&dev->kobj, KOBJ_REMOVE);
kobject_uevent(&dev->kobj, KOBJ_REMOVE);
kobject_del(&dev->kobj);
Error:
if (parent)
@ -374,7 +374,7 @@ void device_del(struct device * dev)
platform_notify_remove(dev);
bus_remove_device(dev);
device_pm_remove(dev);
kobject_hotplug(&dev->kobj, KOBJ_REMOVE);
kobject_uevent(&dev->kobj, KOBJ_REMOVE);
kobject_del(&dev->kobj);
if (parent)
put_device(parent);

View file

@ -41,14 +41,14 @@ static ssize_t store_online(struct sys_device *dev, const char *buf,
case '0':
ret = cpu_down(cpu->sysdev.id);
if (!ret)
kobject_hotplug(&dev->kobj, KOBJ_OFFLINE);
kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
break;
case '1':
ret = smp_prepare_cpu(cpu->sysdev.id);
if (!ret)
ret = cpu_up(cpu->sysdev.id);
if (!ret)
kobject_hotplug(&dev->kobj, KOBJ_ONLINE);
kobject_uevent(&dev->kobj, KOBJ_ONLINE);
break;
default:
ret = -EINVAL;

View file

@ -65,7 +65,8 @@ void device_bind_driver(struct device * dev)
* This function returns 1 if a match is found, an error if one
* occurs (that is not -ENODEV or -ENXIO), and 0 otherwise.
*
* This function must be called with @dev->sem held.
* This function must be called with @dev->sem held. When called
* for a USB interface, @dev->parent->sem must be held as well.
*/
int driver_probe_device(struct device_driver * drv, struct device * dev)
{
@ -123,6 +124,8 @@ static int __device_attach(struct device_driver * drv, void * data)
*
* Returns 1 if the device was bound to a driver;
* 0 if no matching device was found; error code otherwise.
*
* When called for a USB interface, @dev->parent->sem must be held.
*/
int device_attach(struct device * dev)
{
@ -152,10 +155,14 @@ static int __driver_attach(struct device * dev, void * data)
* is an error.
*/
if (dev->parent) /* Needed for USB */
down(&dev->parent->sem);
down(&dev->sem);
if (!dev->driver)
driver_probe_device(drv, dev);
up(&dev->sem);
if (dev->parent)
up(&dev->parent->sem);
return 0;
}
@ -181,6 +188,8 @@ void driver_attach(struct device_driver * drv)
* Manually detach device from driver.
*
* __device_release_driver() must be called with @dev->sem held.
* When called for a USB interface, @dev->parent->sem must be held
* as well.
*/
static void __device_release_driver(struct device * dev)
@ -233,10 +242,14 @@ void driver_detach(struct device_driver * drv)
get_device(dev);
spin_unlock(&drv->klist_devices.k_lock);
if (dev->parent) /* Needed for USB */
down(&dev->parent->sem);
down(&dev->sem);
if (dev->driver == drv)
__device_release_driver(dev);
up(&dev->sem);
if (dev->parent)
up(&dev->parent->sem);
put_device(dev);
}
}

View file

@ -85,17 +85,17 @@ firmware_timeout_store(struct class *class, const char *buf, size_t count)
static CLASS_ATTR(timeout, 0644, firmware_timeout_show, firmware_timeout_store);
static void fw_class_dev_release(struct class_device *class_dev);
int firmware_class_hotplug(struct class_device *dev, char **envp,
int firmware_class_uevent(struct class_device *dev, char **envp,
int num_envp, char *buffer, int buffer_size);
static struct class firmware_class = {
.name = "firmware",
.hotplug = firmware_class_hotplug,
.uevent = firmware_class_uevent,
.release = fw_class_dev_release,
};
int
firmware_class_hotplug(struct class_device *class_dev, char **envp,
firmware_class_uevent(struct class_device *class_dev, char **envp,
int num_envp, char *buffer, int buffer_size)
{
struct firmware_priv *fw_priv = class_get_devdata(class_dev);
@ -104,13 +104,12 @@ firmware_class_hotplug(struct class_device *class_dev, char **envp,
if (!test_bit(FW_STATUS_READY, &fw_priv->status))
return -ENODEV;
if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &len,
"FIRMWARE=%s", fw_priv->fw_id))
if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
"FIRMWARE=%s", fw_priv->fw_id))
return -ENOMEM;
if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &len,
"TIMEOUT=%i", loading_timeout))
if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len,
"TIMEOUT=%i", loading_timeout))
return -ENOMEM;
envp[i] = NULL;
return 0;
@ -352,7 +351,7 @@ error_kfree:
static int
fw_setup_class_device(struct firmware *fw, struct class_device **class_dev_p,
const char *fw_name, struct device *device, int hotplug)
const char *fw_name, struct device *device, int uevent)
{
struct class_device *class_dev;
struct firmware_priv *fw_priv;
@ -384,7 +383,7 @@ fw_setup_class_device(struct firmware *fw, struct class_device **class_dev_p,
goto error_unreg;
}
if (hotplug)
if (uevent)
set_bit(FW_STATUS_READY, &fw_priv->status);
else
set_bit(FW_STATUS_READY_NOHOTPLUG, &fw_priv->status);
@ -399,7 +398,7 @@ out:
static int
_request_firmware(const struct firmware **firmware_p, const char *name,
struct device *device, int hotplug)
struct device *device, int uevent)
{
struct class_device *class_dev;
struct firmware_priv *fw_priv;
@ -418,19 +417,19 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
}
retval = fw_setup_class_device(firmware, &class_dev, name, device,
hotplug);
uevent);
if (retval)
goto error_kfree_fw;
fw_priv = class_get_devdata(class_dev);
if (hotplug) {
if (uevent) {
if (loading_timeout > 0) {
fw_priv->timeout.expires = jiffies + loading_timeout * HZ;
add_timer(&fw_priv->timeout);
}
kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
kobject_uevent(&class_dev->kobj, KOBJ_ADD);
wait_for_completion(&fw_priv->completion);
set_bit(FW_STATUS_DONE, &fw_priv->status);
del_timer_sync(&fw_priv->timeout);
@ -456,7 +455,7 @@ out:
}
/**
* request_firmware: - request firmware to hotplug and wait for it
* request_firmware: - send firmware request and wait for it
* @firmware_p: pointer to firmware image
* @name: name of firmware file
* @device: device for which firmware is being loaded
@ -466,7 +465,7 @@ out:
*
* Should be called from user context where sleeping is allowed.
*
* @name will be used as $FIRMWARE in the hotplug environment and
* @name will be used as $FIRMWARE in the uevent environment and
* should be distinctive enough not to be confused with any other
* firmware image for this or any other device.
**/
@ -474,8 +473,8 @@ int
request_firmware(const struct firmware **firmware_p, const char *name,
struct device *device)
{
int hotplug = 1;
return _request_firmware(firmware_p, name, device, hotplug);
int uevent = 1;
return _request_firmware(firmware_p, name, device, uevent);
}
/**
@ -518,7 +517,7 @@ struct firmware_work {
struct device *device;
void *context;
void (*cont)(const struct firmware *fw, void *context);
int hotplug;
int uevent;
};
static int
@ -533,7 +532,7 @@ request_firmware_work_func(void *arg)
}
daemonize("%s/%s", "firmware", fw_work->name);
ret = _request_firmware(&fw, fw_work->name, fw_work->device,
fw_work->hotplug);
fw_work->uevent);
if (ret < 0)
fw_work->cont(NULL, fw_work->context);
else {
@ -548,7 +547,7 @@ request_firmware_work_func(void *arg)
/**
* request_firmware_nowait: asynchronous version of request_firmware
* @module: module requesting the firmware
* @hotplug: invokes hotplug event to copy the firmware image if this flag
* @uevent: sends uevent to copy the firmware image if this flag
* is non-zero else the firmware copy must be done manually.
* @name: name of firmware file
* @device: device for which firmware is being loaded
@ -562,7 +561,7 @@ request_firmware_work_func(void *arg)
**/
int
request_firmware_nowait(
struct module *module, int hotplug,
struct module *module, int uevent,
const char *name, struct device *device, void *context,
void (*cont)(const struct firmware *fw, void *context))
{
@ -583,7 +582,7 @@ request_firmware_nowait(
.device = device,
.context = context,
.cont = cont,
.hotplug = hotplug,
.uevent = uevent,
};
ret = kernel_thread(request_firmware_work_func, fw_work,

View file

@ -29,12 +29,12 @@ static struct sysdev_class memory_sysdev_class = {
set_kset_name(MEMORY_CLASS_NAME),
};
static char *memory_hotplug_name(struct kset *kset, struct kobject *kobj)
static const char *memory_uevent_name(struct kset *kset, struct kobject *kobj)
{
return MEMORY_CLASS_NAME;
}
static int memory_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
static int memory_uevent(struct kset *kset, struct kobject *kobj, char **envp,
int num_envp, char *buffer, int buffer_size)
{
int retval = 0;
@ -42,9 +42,9 @@ static int memory_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
return retval;
}
static struct kset_hotplug_ops memory_hotplug_ops = {
.name = memory_hotplug_name,
.hotplug = memory_hotplug,
static struct kset_uevent_ops memory_uevent_ops = {
.name = memory_uevent_name,
.uevent = memory_uevent,
};
static struct notifier_block *memory_chain;
@ -431,7 +431,7 @@ int __init memory_dev_init(void)
unsigned int i;
int ret;
memory_sysdev_class.kset.hotplug_ops = &memory_hotplug_ops;
memory_sysdev_class.kset.uevent_ops = &memory_uevent_ops;
ret = sysdev_class_register(&memory_sysdev_class);
/*

View file

@ -25,6 +25,7 @@
struct device platform_bus = {
.bus_id = "platform",
};
EXPORT_SYMBOL_GPL(platform_bus);
/**
* platform_get_resource - get a resource for a device
@ -49,6 +50,7 @@ platform_get_resource(struct platform_device *dev, unsigned int type,
}
return NULL;
}
EXPORT_SYMBOL_GPL(platform_get_resource);
/**
* platform_get_irq - get an IRQ for a device
@ -61,6 +63,7 @@ int platform_get_irq(struct platform_device *dev, unsigned int num)
return r ? r->start : 0;
}
EXPORT_SYMBOL_GPL(platform_get_irq);
/**
* platform_get_resource_byname - get a resource for a device by name
@ -84,6 +87,7 @@ platform_get_resource_byname(struct platform_device *dev, unsigned int type,
}
return NULL;
}
EXPORT_SYMBOL_GPL(platform_get_resource_byname);
/**
* platform_get_irq - get an IRQ for a device
@ -96,6 +100,7 @@ int platform_get_irq_byname(struct platform_device *dev, char *name)
return r ? r->start : 0;
}
EXPORT_SYMBOL_GPL(platform_get_irq_byname);
/**
* platform_add_devices - add a numbers of platform devices
@ -117,6 +122,7 @@ int platform_add_devices(struct platform_device **devs, int num)
return ret;
}
EXPORT_SYMBOL_GPL(platform_add_devices);
struct platform_object {
struct platform_device pdev;
@ -168,7 +174,7 @@ struct platform_device *platform_device_alloc(const char *name, unsigned int id)
pa->pdev.dev.release = platform_device_release;
}
return pa ? &pa->pdev : NULL;
return pa ? &pa->pdev : NULL;
}
EXPORT_SYMBOL_GPL(platform_device_alloc);
@ -257,7 +263,7 @@ int platform_device_add(struct platform_device *pdev)
p = &ioport_resource;
}
if (p && request_resource(p, r)) {
if (p && insert_resource(p, r)) {
printk(KERN_ERR
"%s: failed to claim resource %d\n",
pdev->dev.bus_id, i);
@ -282,24 +288,13 @@ int platform_device_add(struct platform_device *pdev)
EXPORT_SYMBOL_GPL(platform_device_add);
/**
* platform_device_register - add a platform-level device
* @pdev: platform device we're adding
*
*/
int platform_device_register(struct platform_device * pdev)
{
device_initialize(&pdev->dev);
return platform_device_add(pdev);
}
/**
* platform_device_unregister - remove a platform-level device
* platform_device_del - remove a platform-level device
* @pdev: platform device we're removing
*
* Note that this function will also release all memory- and port-based
* resources owned by the device (@dev->resource).
*/
void platform_device_unregister(struct platform_device * pdev)
void platform_device_del(struct platform_device *pdev)
{
int i;
@ -310,9 +305,37 @@ void platform_device_unregister(struct platform_device * pdev)
release_resource(r);
}
device_unregister(&pdev->dev);
device_del(&pdev->dev);
}
}
EXPORT_SYMBOL_GPL(platform_device_del);
/**
* platform_device_register - add a platform-level device
* @pdev: platform device we're adding
*
*/
int platform_device_register(struct platform_device * pdev)
{
device_initialize(&pdev->dev);
return platform_device_add(pdev);
}
EXPORT_SYMBOL_GPL(platform_device_register);
/**
* platform_device_unregister - unregister a platform-level device
* @pdev: platform device we're unregistering
*
* Unregistration is done in 2 steps. Fisrt we release all resources
* and remove it from the sybsystem, then we drop reference count by
* calling platform_device_put().
*/
void platform_device_unregister(struct platform_device * pdev)
{
platform_device_del(pdev);
platform_device_put(pdev);
}
EXPORT_SYMBOL_GPL(platform_device_unregister);
/**
* platform_device_register_simple
@ -355,6 +378,7 @@ error:
platform_device_put(pdev);
return ERR_PTR(retval);
}
EXPORT_SYMBOL_GPL(platform_device_register_simple);
static int platform_drv_probe(struct device *_dev)
{
@ -476,6 +500,7 @@ struct bus_type platform_bus_type = {
.suspend = platform_suspend,
.resume = platform_resume,
};
EXPORT_SYMBOL_GPL(platform_bus_type);
int __init platform_bus_init(void)
{
@ -504,14 +529,3 @@ u64 dma_get_required_mask(struct device *dev)
}
EXPORT_SYMBOL_GPL(dma_get_required_mask);
#endif
EXPORT_SYMBOL_GPL(platform_bus);
EXPORT_SYMBOL_GPL(platform_bus_type);
EXPORT_SYMBOL_GPL(platform_add_devices);
EXPORT_SYMBOL_GPL(platform_device_register);
EXPORT_SYMBOL_GPL(platform_device_register_simple);
EXPORT_SYMBOL_GPL(platform_device_unregister);
EXPORT_SYMBOL_GPL(platform_get_irq);
EXPORT_SYMBOL_GPL(platform_get_resource);
EXPORT_SYMBOL_GPL(platform_get_irq_byname);
EXPORT_SYMBOL_GPL(platform_get_resource_byname);

View file

@ -64,6 +64,7 @@ int dpm_runtime_suspend(struct device * dev, pm_message_t state)
}
#if 0
/**
* dpm_set_power_state - Update power_state field.
* @dev: Device.
@ -80,3 +81,4 @@ void dpm_set_power_state(struct device * dev, pm_message_t state)
dev->power.power_state = state;
up(&dpm_sem);
}
#endif /* 0 */

View file

@ -3509,6 +3509,7 @@ static int __init ide_cdrom_init(void)
return driver_register(&ide_cdrom_driver.gen_driver);
}
MODULE_ALIAS("ide:*m-cdrom*");
module_init(ide_cdrom_init);
module_exit(ide_cdrom_exit);
MODULE_LICENSE("GPL");

View file

@ -1271,6 +1271,7 @@ static int __init idedisk_init(void)
return driver_register(&idedisk_driver.gen_driver);
}
MODULE_ALIAS("ide:*m-disk*");
module_init(idedisk_init);
module_exit(idedisk_exit);
MODULE_LICENSE("GPL");

View file

@ -2197,6 +2197,7 @@ static int __init idefloppy_init(void)
return driver_register(&idefloppy_driver.gen_driver);
}
MODULE_ALIAS("ide:*m-floppy*");
module_init(idefloppy_init);
module_exit(idefloppy_exit);
MODULE_LICENSE("GPL");

View file

@ -4947,6 +4947,7 @@ out:
return error;
}
MODULE_ALIAS("ide:*m-tape*");
module_init(idetape_init);
module_exit(idetape_exit);
MODULE_ALIAS_CHARDEV_MAJOR(IDETAPE_MAJOR);

View file

@ -1904,9 +1904,69 @@ static int ide_bus_match(struct device *dev, struct device_driver *drv)
return 1;
}
static char *media_string(ide_drive_t *drive)
{
switch (drive->media) {
case ide_disk:
return "disk";
case ide_cdrom:
return "cdrom";
case ide_tape:
return "tape";
case ide_floppy:
return "floppy";
default:
return "UNKNOWN";
}
}
static ssize_t media_show(struct device *dev, struct device_attribute *attr, char *buf)
{
ide_drive_t *drive = to_ide_device(dev);
return sprintf(buf, "%s\n", media_string(drive));
}
static ssize_t drivename_show(struct device *dev, struct device_attribute *attr, char *buf)
{
ide_drive_t *drive = to_ide_device(dev);
return sprintf(buf, "%s\n", drive->name);
}
static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
{
ide_drive_t *drive = to_ide_device(dev);
return sprintf(buf, "ide:m-%s\n", media_string(drive));
}
static struct device_attribute ide_dev_attrs[] = {
__ATTR_RO(media),
__ATTR_RO(drivename),
__ATTR_RO(modalias),
__ATTR_NULL
};
static int ide_uevent(struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size)
{
ide_drive_t *drive = to_ide_device(dev);
int i = 0;
int length = 0;
add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
"MEDIA=%s", media_string(drive));
add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
"DRIVENAME=%s", drive->name);
add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length,
"MODALIAS=ide:m-%s", media_string(drive));
envp[i] = NULL;
return 0;
}
struct bus_type ide_bus_type = {
.name = "ide",
.match = ide_bus_match,
.uevent = ide_uevent,
.dev_attrs = ide_dev_attrs,
.suspend = generic_ide_suspend,
.resume = generic_ide_resume,
};

View file

@ -121,8 +121,8 @@ struct host_info {
};
static int nodemgr_bus_match(struct device * dev, struct device_driver * drv);
static int nodemgr_hotplug(struct class_device *cdev, char **envp, int num_envp,
char *buffer, int buffer_size);
static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp,
char *buffer, int buffer_size);
static void nodemgr_resume_ne(struct node_entry *ne);
static void nodemgr_remove_ne(struct node_entry *ne);
static struct node_entry *find_entry_by_guid(u64 guid);
@ -162,7 +162,7 @@ static void ud_cls_release(struct class_device *class_dev)
static struct class nodemgr_ud_class = {
.name = "ieee1394",
.release = ud_cls_release,
.hotplug = nodemgr_hotplug,
.uevent = nodemgr_uevent,
};
static struct hpsb_highlevel nodemgr_highlevel;
@ -966,7 +966,7 @@ static struct unit_directory *nodemgr_process_unit_directory
if (ud_child == NULL)
break;
/* inherit unspecified values so hotplug picks it up */
/* inherit unspecified values, the driver core picks it up */
if ((ud->flags & UNIT_DIRECTORY_MODEL_ID) &&
!(ud_child->flags & UNIT_DIRECTORY_MODEL_ID))
{
@ -1062,8 +1062,8 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent
#ifdef CONFIG_HOTPLUG
static int nodemgr_hotplug(struct class_device *cdev, char **envp, int num_envp,
char *buffer, int buffer_size)
static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp,
char *buffer, int buffer_size)
{
struct unit_directory *ud;
int i = 0;
@ -1112,8 +1112,8 @@ do { \
#else
static int nodemgr_hotplug(struct class_device *cdev, char **envp, int num_envp,
char *buffer, int buffer_size)
static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp,
char *buffer, int buffer_size)
{
return -ENODEV;
}
@ -1618,8 +1618,8 @@ static int nodemgr_host_thread(void *__hi)
/* Scan our nodes to get the bus options and create node
* entries. This does not do the sysfs stuff, since that
* would trigger hotplug callbacks and such, which is a
* bad idea at this point. */
* would trigger uevents and such, which is a bad idea at
* this point. */
nodemgr_node_scan(hi, generation);
/* This actually does the full probe, with sysfs

View file

@ -434,24 +434,24 @@ static void ib_device_release(struct class_device *cdev)
kfree(dev);
}
static int ib_device_hotplug(struct class_device *cdev, char **envp,
int num_envp, char *buf, int size)
static int ib_device_uevent(struct class_device *cdev, char **envp,
int num_envp, char *buf, int size)
{
struct ib_device *dev = container_of(cdev, struct ib_device, class_dev);
int i = 0, len = 0;
if (add_hotplug_env_var(envp, num_envp, &i, buf, size, &len,
"NAME=%s", dev->name))
if (add_uevent_var(envp, num_envp, &i, buf, size, &len,
"NAME=%s", dev->name))
return -ENOMEM;
/*
* It might be nice to pass the node GUID to hotplug, but
* It might be nice to pass the node GUID with the event, but
* right now the only way to get it is to query the device
* provider, and this can crash during device removal because
* we are will be running after driver removal has started.
* We could add a node_guid field to struct ib_device, or we
* could just let the hotplug script read the node GUID from
* sysfs when devices are added.
* could just let userspace read the node GUID from sysfs when
* devices are added.
*/
envp[i] = NULL;
@ -653,7 +653,7 @@ static struct class_device_attribute *ib_class_attributes[] = {
static struct class ib_class = {
.name = "infiniband",
.release = ib_device_release,
.hotplug = ib_device_hotplug,
.uevent = ib_device_uevent,
};
int ib_device_register_sysfs(struct ib_device *device)

View file

@ -18,7 +18,6 @@
#include <linux/random.h>
#include <linux/major.h>
#include <linux/proc_fs.h>
#include <linux/kobject_uevent.h>
#include <linux/interrupt.h>
#include <linux/poll.h>
#include <linux/device.h>
@ -529,10 +528,49 @@ INPUT_DEV_STRING_ATTR_SHOW(name);
INPUT_DEV_STRING_ATTR_SHOW(phys);
INPUT_DEV_STRING_ATTR_SHOW(uniq);
static int print_modalias_bits(char *buf, char prefix, unsigned long *arr,
unsigned int min, unsigned int max)
{
int len, i;
len = sprintf(buf, "%c", prefix);
for (i = min; i < max; i++)
if (arr[LONG(i)] & BIT(i))
len += sprintf(buf+len, "%X,", i);
return len;
}
static ssize_t input_dev_show_modalias(struct class_device *dev, char *buf)
{
struct input_dev *id = to_input_dev(dev);
ssize_t len = 0;
len += sprintf(buf+len, "input:b%04Xv%04Xp%04Xe%04X-",
id->id.bustype,
id->id.vendor,
id->id.product,
id->id.version);
len += print_modalias_bits(buf+len, 'e', id->evbit, 0, EV_MAX);
len += print_modalias_bits(buf+len, 'k', id->keybit,
KEY_MIN_INTERESTING, KEY_MAX);
len += print_modalias_bits(buf+len, 'r', id->relbit, 0, REL_MAX);
len += print_modalias_bits(buf+len, 'a', id->absbit, 0, ABS_MAX);
len += print_modalias_bits(buf+len, 'm', id->mscbit, 0, MSC_MAX);
len += print_modalias_bits(buf+len, 'l', id->ledbit, 0, LED_MAX);
len += print_modalias_bits(buf+len, 's', id->sndbit, 0, SND_MAX);
len += print_modalias_bits(buf+len, 'f', id->ffbit, 0, FF_MAX);
len += print_modalias_bits(buf+len, 'w', id->swbit, 0, SW_MAX);
len += sprintf(buf+len, "\n");
return len;
}
static CLASS_DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL);
static struct attribute *input_dev_attrs[] = {
&class_device_attr_name.attr,
&class_device_attr_phys.attr,
&class_device_attr_uniq.attr,
&class_device_attr_modalias.attr,
NULL
};
@ -611,10 +649,10 @@ static void input_dev_release(struct class_device *class_dev)
}
/*
* Input hotplugging interface - loading event handlers based on
* Input uevent interface - loading event handlers based on
* device bitfields.
*/
static int input_add_hotplug_bm_var(char **envp, int num_envp, int *cur_index,
static int input_add_uevent_bm_var(char **envp, int num_envp, int *cur_index,
char *buffer, int buffer_size, int *cur_len,
const char *name, unsigned long *bitmap, int max)
{
@ -639,7 +677,7 @@ static int input_add_hotplug_bm_var(char **envp, int num_envp, int *cur_index,
#define INPUT_ADD_HOTPLUG_VAR(fmt, val...) \
do { \
int err = add_hotplug_env_var(envp, num_envp, &i, \
int err = add_uevent_var(envp, num_envp, &i, \
buffer, buffer_size, &len, \
fmt, val); \
if (err) \
@ -648,15 +686,15 @@ static int input_add_hotplug_bm_var(char **envp, int num_envp, int *cur_index,
#define INPUT_ADD_HOTPLUG_BM_VAR(name, bm, max) \
do { \
int err = input_add_hotplug_bm_var(envp, num_envp, &i, \
int err = input_add_uevent_bm_var(envp, num_envp, &i, \
buffer, buffer_size, &len, \
name, bm, max); \
if (err) \
return err; \
} while (0)
static int input_dev_hotplug(struct class_device *cdev, char **envp,
int num_envp, char *buffer, int buffer_size)
static int input_dev_uevent(struct class_device *cdev, char **envp,
int num_envp, char *buffer, int buffer_size)
{
struct input_dev *dev = to_input_dev(cdev);
int i = 0;
@ -698,7 +736,7 @@ static int input_dev_hotplug(struct class_device *cdev, char **envp,
struct class input_class = {
.name = "input",
.release = input_dev_release,
.hotplug = input_dev_hotplug,
.uevent = input_dev_uevent,
};
struct input_dev *input_allocate_device(void)

View file

@ -800,16 +800,16 @@ static int serio_bus_match(struct device *dev, struct device_driver *drv)
#ifdef CONFIG_HOTPLUG
#define SERIO_ADD_HOTPLUG_VAR(fmt, val...) \
#define SERIO_ADD_UEVENT_VAR(fmt, val...) \
do { \
int err = add_hotplug_env_var(envp, num_envp, &i, \
int err = add_uevent_var(envp, num_envp, &i, \
buffer, buffer_size, &len, \
fmt, val); \
if (err) \
return err; \
} while (0)
static int serio_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
{
struct serio *serio;
int i = 0;
@ -820,21 +820,21 @@ static int serio_hotplug(struct device *dev, char **envp, int num_envp, char *bu
serio = to_serio_port(dev);
SERIO_ADD_HOTPLUG_VAR("SERIO_TYPE=%02x", serio->id.type);
SERIO_ADD_HOTPLUG_VAR("SERIO_PROTO=%02x", serio->id.proto);
SERIO_ADD_HOTPLUG_VAR("SERIO_ID=%02x", serio->id.id);
SERIO_ADD_HOTPLUG_VAR("SERIO_EXTRA=%02x", serio->id.extra);
SERIO_ADD_HOTPLUG_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X",
SERIO_ADD_UEVENT_VAR("SERIO_TYPE=%02x", serio->id.type);
SERIO_ADD_UEVENT_VAR("SERIO_PROTO=%02x", serio->id.proto);
SERIO_ADD_UEVENT_VAR("SERIO_ID=%02x", serio->id.id);
SERIO_ADD_UEVENT_VAR("SERIO_EXTRA=%02x", serio->id.extra);
SERIO_ADD_UEVENT_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X",
serio->id.type, serio->id.proto, serio->id.id, serio->id.extra);
envp[i] = NULL;
return 0;
}
#undef SERIO_ADD_HOTPLUG_VAR
#undef SERIO_ADD_UEVENT_VAR
#else
static int serio_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
static int serio_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
{
return -ENODEV;
}
@ -908,7 +908,7 @@ static int __init serio_init(void)
serio_bus.dev_attrs = serio_device_attrs;
serio_bus.drv_attrs = serio_driver_attrs;
serio_bus.match = serio_bus_match;
serio_bus.hotplug = serio_hotplug;
serio_bus.uevent = serio_uevent;
serio_bus.resume = serio_resume;
bus_register(&serio_bus);

View file

@ -128,7 +128,7 @@ static int macio_device_resume(struct device * dev)
return 0;
}
static int macio_hotplug (struct device *dev, char **envp, int num_envp,
static int macio_uevent(struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size)
{
struct macio_dev * macio_dev;
@ -203,7 +203,7 @@ extern struct device_attribute macio_dev_attrs[];
struct bus_type macio_bus_type = {
.name = "macio",
.match = macio_bus_match,
.hotplug = macio_hotplug,
.uevent = macio_uevent,
.suspend = macio_device_suspend,
.resume = macio_device_resume,
.dev_attrs = macio_dev_attrs,

View file

@ -80,7 +80,7 @@ static int mmc_bus_match(struct device *dev, struct device_driver *drv)
}
static int
mmc_bus_hotplug(struct device *dev, char **envp, int num_envp, char *buf,
mmc_bus_uevent(struct device *dev, char **envp, int num_envp, char *buf,
int buf_size)
{
struct mmc_card *card = dev_to_mmc_card(dev);
@ -140,7 +140,7 @@ static struct bus_type mmc_bus_type = {
.name = "mmc",
.dev_attrs = mmc_dev_attrs,
.match = mmc_bus_match,
.hotplug = mmc_bus_hotplug,
.uevent = mmc_bus_uevent,
.suspend = mmc_bus_suspend,
.resume = mmc_bus_resume,
};

View file

@ -3,8 +3,8 @@
#include <linux/module.h>
#include "pci.h"
int pci_hotplug (struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size)
int pci_uevent(struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size)
{
struct pci_dev *pdev;
int i = 0;
@ -17,34 +17,34 @@ int pci_hotplug (struct device *dev, char **envp, int num_envp,
if (!pdev)
return -ENODEV;
if (add_hotplug_env_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"PCI_CLASS=%04X", pdev->class))
if (add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"PCI_CLASS=%04X", pdev->class))
return -ENOMEM;
if (add_hotplug_env_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"PCI_ID=%04X:%04X", pdev->vendor, pdev->device))
if (add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"PCI_ID=%04X:%04X", pdev->vendor, pdev->device))
return -ENOMEM;
if (add_hotplug_env_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor,
pdev->subsystem_device))
if (add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"PCI_SUBSYS_ID=%04X:%04X", pdev->subsystem_vendor,
pdev->subsystem_device))
return -ENOMEM;
if (add_hotplug_env_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"PCI_SLOT_NAME=%s", pci_name(pdev)))
if (add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"PCI_SLOT_NAME=%s", pci_name(pdev)))
return -ENOMEM;
if (add_hotplug_env_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x",
pdev->vendor, pdev->device,
pdev->subsystem_vendor, pdev->subsystem_device,
(u8)(pdev->class >> 16), (u8)(pdev->class >> 8),
(u8)(pdev->class)))
if (add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x",
pdev->vendor, pdev->device,
pdev->subsystem_vendor, pdev->subsystem_device,
(u8)(pdev->class >> 16), (u8)(pdev->class >> 8),
(u8)(pdev->class)))
return -ENOMEM;
envp[i] = NULL;

View file

@ -502,8 +502,8 @@ void pci_dev_put(struct pci_dev *dev)
}
#ifndef CONFIG_HOTPLUG
int pci_hotplug (struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size)
int pci_uevent(struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size)
{
return -ENODEV;
}
@ -512,7 +512,7 @@ int pci_hotplug (struct device *dev, char **envp, int num_envp,
struct bus_type pci_bus_type = {
.name = "pci",
.match = pci_bus_match,
.hotplug = pci_hotplug,
.uevent = pci_uevent,
.suspend = pci_device_suspend,
.resume = pci_device_resume,
.dev_attrs = pci_dev_attrs,

View file

@ -1,7 +1,7 @@
/* Functions internal to the PCI core code */
extern int pci_hotplug (struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size);
extern int pci_uevent(struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size);
extern int pci_create_sysfs_dev_files(struct pci_dev *pdev);
extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
extern void pci_cleanup_rom(struct pci_dev *dev);

View file

@ -901,14 +901,14 @@ int pcmcia_insert_card(struct pcmcia_socket *skt)
EXPORT_SYMBOL(pcmcia_insert_card);
static int pcmcia_socket_hotplug(struct class_device *dev, char **envp,
int num_envp, char *buffer, int buffer_size)
static int pcmcia_socket_uevent(struct class_device *dev, char **envp,
int num_envp, char *buffer, int buffer_size)
{
struct pcmcia_socket *s = container_of(dev, struct pcmcia_socket, dev);
int i = 0, length = 0;
if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size,
&length, "SOCKET_NO=%u", s->sock))
if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
&length, "SOCKET_NO=%u", s->sock))
return -ENOMEM;
envp[i] = NULL;
@ -927,7 +927,7 @@ static void pcmcia_release_socket_class(struct class *data)
struct class pcmcia_socket_class = {
.name = "pcmcia_socket",
.hotplug = pcmcia_socket_hotplug,
.uevent = pcmcia_socket_uevent,
.release = pcmcia_release_socket,
.class_release = pcmcia_release_socket_class,
};

View file

@ -779,8 +779,8 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) {
#ifdef CONFIG_HOTPLUG
static int pcmcia_bus_hotplug(struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size)
static int pcmcia_bus_uevent(struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size)
{
struct pcmcia_device *p_dev;
int i, length = 0;
@ -800,31 +800,31 @@ static int pcmcia_bus_hotplug(struct device *dev, char **envp, int num_envp,
i = 0;
if (add_hotplug_env_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"SOCKET_NO=%u",
p_dev->socket->sock))
if (add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"SOCKET_NO=%u",
p_dev->socket->sock))
return -ENOMEM;
if (add_hotplug_env_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"DEVICE_NO=%02X",
p_dev->device_no))
if (add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"DEVICE_NO=%02X",
p_dev->device_no))
return -ENOMEM;
if (add_hotplug_env_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"MODALIAS=pcmcia:m%04Xc%04Xf%02Xfn%02Xpfn%02X"
"pa%08Xpb%08Xpc%08Xpd%08X",
p_dev->has_manf_id ? p_dev->manf_id : 0,
p_dev->has_card_id ? p_dev->card_id : 0,
p_dev->has_func_id ? p_dev->func_id : 0,
p_dev->func,
p_dev->device_no,
hash[0],
hash[1],
hash[2],
hash[3]))
if (add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"MODALIAS=pcmcia:m%04Xc%04Xf%02Xfn%02Xpfn%02X"
"pa%08Xpb%08Xpc%08Xpd%08X",
p_dev->has_manf_id ? p_dev->manf_id : 0,
p_dev->has_card_id ? p_dev->card_id : 0,
p_dev->has_func_id ? p_dev->func_id : 0,
p_dev->func,
p_dev->device_no,
hash[0],
hash[1],
hash[2],
hash[3]))
return -ENOMEM;
envp[i] = NULL;
@ -834,7 +834,7 @@ static int pcmcia_bus_hotplug(struct device *dev, char **envp, int num_envp,
#else
static int pcmcia_bus_hotplug(struct device *dev, char **envp, int num_envp,
static int pcmcia_bus_uevent(struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size)
{
return -ENODEV;
@ -1223,7 +1223,7 @@ static struct class_interface pcmcia_bus_interface = {
struct bus_type pcmcia_bus_type = {
.name = "pcmcia",
.hotplug = pcmcia_bus_hotplug,
.uevent = pcmcia_bus_uevent,
.match = pcmcia_bus_match,
.dev_attrs = pcmcia_dev_attrs,
};

View file

@ -56,7 +56,6 @@
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/slab.h>
#include <linux/kobject_uevent.h>
#include <linux/completion.h>
#include <linux/spinlock.h>
#include <linux/dmi.h>
@ -106,8 +105,6 @@ static int pnp_dock_event(int dock, struct pnp_docking_station_info *info)
char *argv [3], **envp, *buf, *scratch;
int i = 0, value;
if (!hotplug_path [0])
return -ENOENT;
if (!current->fs->root) {
return -EAGAIN;
}
@ -119,8 +116,9 @@ static int pnp_dock_event(int dock, struct pnp_docking_station_info *info)
return -ENOMEM;
}
/* only one standardized param to hotplug command: type */
argv [0] = hotplug_path;
/* FIXME: if there are actual users of this, it should be integrated into
* the driver core and use the usual infrastructure like sysfs and uevents */
argv [0] = "/sbin/pnpbios";
argv [1] = "dock";
argv [2] = NULL;

View file

@ -45,7 +45,7 @@ ccwgroup_bus_match (struct device * dev, struct device_driver * drv)
return 0;
}
static int
ccwgroup_hotplug (struct device *dev, char **envp, int num_envp, char *buffer,
ccwgroup_uevent (struct device *dev, char **envp, int num_envp, char *buffer,
int buffer_size)
{
/* TODO */
@ -55,7 +55,7 @@ ccwgroup_hotplug (struct device *dev, char **envp, int num_envp, char *buffer,
static struct bus_type ccwgroup_bus_type = {
.name = "ccwgroup",
.match = ccwgroup_bus_match,
.hotplug = ccwgroup_hotplug,
.uevent = ccwgroup_uevent,
};
static inline void

View file

@ -59,7 +59,7 @@ ccw_bus_match (struct device * dev, struct device_driver * drv)
* Heavily modeled on pci and usb hotplug.
*/
static int
ccw_hotplug (struct device *dev, char **envp, int num_envp,
ccw_uevent (struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size)
{
struct ccw_device *cdev = to_ccwdev(dev);
@ -110,7 +110,7 @@ ccw_hotplug (struct device *dev, char **envp, int num_envp,
struct bus_type ccw_bus_type = {
.name = "ccw",
.match = &ccw_bus_match,
.hotplug = &ccw_hotplug,
.uevent = &ccw_uevent,
};
static int io_subchannel_probe (struct device *);

View file

@ -34,7 +34,6 @@
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kobject_uevent.h>
#include <linux/proc_fs.h>
#include <linux/syscalls.h>
#include "z90crypt.h"

View file

@ -2132,7 +2132,7 @@ restart:
}
spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
kobject_uevent(&ioa_cfg->host->shost_classdev.kobj, KOBJ_CHANGE, NULL);
kobject_uevent(&ioa_cfg->host->shost_classdev.kobj, KOBJ_CHANGE);
LEAVE;
}

View file

@ -192,6 +192,7 @@ void usb_driver_release_interface(struct usb_driver *driver,
iface->condition = USB_INTERFACE_UNBOUND;
mark_quiesced(iface);
}
struct find_interface_arg {
int minor;
struct usb_interface *interface;
@ -236,10 +237,7 @@ struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor)
#ifdef CONFIG_HOTPLUG
/*
* USB hotplugging invokes what /proc/sys/kernel/hotplug says
* (normally /sbin/hotplug) when USB devices get added or removed.
*
* This invokes a user mode policy agent, typically helping to load driver
* This sends an uevent to userspace, typically helping to load driver
* or other modules, configure the device, and more. Drivers can provide
* a MODULE_DEVICE_TABLE to help with module loading subtasks.
*
@ -248,8 +246,8 @@ struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor)
* delays in event delivery. Use sysfs (and DEVPATH) to make sure the
* device (and this configuration!) are still present.
*/
static int usb_hotplug (struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size)
static int usb_uevent(struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size)
{
struct usb_interface *intf;
struct usb_device *usb_dev;
@ -261,7 +259,7 @@ static int usb_hotplug (struct device *dev, char **envp, int num_envp,
return -ENODEV;
/* driver is often null here; dev_dbg() would oops */
pr_debug ("usb %s: hotplug\n", dev->bus_id);
pr_debug ("usb %s: uevent\n", dev->bus_id);
/* Must check driver_data here, as on remove driver is always NULL */
if ((dev->driver == &usb_generic_driver) ||
@ -288,51 +286,51 @@ static int usb_hotplug (struct device *dev, char **envp, int num_envp,
*
* FIXME reduce hardwired intelligence here
*/
if (add_hotplug_env_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"DEVICE=/proc/bus/usb/%03d/%03d",
usb_dev->bus->busnum, usb_dev->devnum))
if (add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"DEVICE=/proc/bus/usb/%03d/%03d",
usb_dev->bus->busnum, usb_dev->devnum))
return -ENOMEM;
#endif
/* per-device configurations are common */
if (add_hotplug_env_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"PRODUCT=%x/%x/%x",
le16_to_cpu(usb_dev->descriptor.idVendor),
le16_to_cpu(usb_dev->descriptor.idProduct),
le16_to_cpu(usb_dev->descriptor.bcdDevice)))
if (add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"PRODUCT=%x/%x/%x",
le16_to_cpu(usb_dev->descriptor.idVendor),
le16_to_cpu(usb_dev->descriptor.idProduct),
le16_to_cpu(usb_dev->descriptor.bcdDevice)))
return -ENOMEM;
/* class-based driver binding models */
if (add_hotplug_env_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"TYPE=%d/%d/%d",
usb_dev->descriptor.bDeviceClass,
usb_dev->descriptor.bDeviceSubClass,
usb_dev->descriptor.bDeviceProtocol))
if (add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"TYPE=%d/%d/%d",
usb_dev->descriptor.bDeviceClass,
usb_dev->descriptor.bDeviceSubClass,
usb_dev->descriptor.bDeviceProtocol))
return -ENOMEM;
if (add_hotplug_env_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"INTERFACE=%d/%d/%d",
alt->desc.bInterfaceClass,
alt->desc.bInterfaceSubClass,
alt->desc.bInterfaceProtocol))
if (add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"INTERFACE=%d/%d/%d",
alt->desc.bInterfaceClass,
alt->desc.bInterfaceSubClass,
alt->desc.bInterfaceProtocol))
return -ENOMEM;
if (add_hotplug_env_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X",
le16_to_cpu(usb_dev->descriptor.idVendor),
le16_to_cpu(usb_dev->descriptor.idProduct),
le16_to_cpu(usb_dev->descriptor.bcdDevice),
usb_dev->descriptor.bDeviceClass,
usb_dev->descriptor.bDeviceSubClass,
usb_dev->descriptor.bDeviceProtocol,
alt->desc.bInterfaceClass,
alt->desc.bInterfaceSubClass,
alt->desc.bInterfaceProtocol))
if (add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length,
"MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X",
le16_to_cpu(usb_dev->descriptor.idVendor),
le16_to_cpu(usb_dev->descriptor.idProduct),
le16_to_cpu(usb_dev->descriptor.bcdDevice),
usb_dev->descriptor.bDeviceClass,
usb_dev->descriptor.bDeviceSubClass,
usb_dev->descriptor.bDeviceProtocol,
alt->desc.bInterfaceClass,
alt->desc.bInterfaceSubClass,
alt->desc.bInterfaceProtocol))
return -ENOMEM;
envp[i] = NULL;
@ -342,7 +340,7 @@ static int usb_hotplug (struct device *dev, char **envp, int num_envp,
#else
static int usb_hotplug (struct device *dev, char **envp,
static int usb_uevent(struct device *dev, char **envp,
int num_envp, char *buffer, int buffer_size)
{
return -ENODEV;
@ -1093,7 +1091,7 @@ static int usb_generic_resume(struct device *dev)
struct bus_type usb_bus_type = {
.name = "usb",
.match = usb_device_match,
.hotplug = usb_hotplug,
.uevent = usb_uevent,
.suspend = usb_generic_suspend,
.resume = usb_generic_resume,
};

View file

@ -4397,7 +4397,7 @@ static int __init etrax_usb_hc_init(void)
device_initialize(&fake_device);
kobject_set_name(&fake_device.kobj, "etrax_usb");
kobject_add(&fake_device.kobj);
kobject_hotplug(&fake_device.kobj, KOBJ_ADD);
kobject_uevent(&fake_device.kobj, KOBJ_ADD);
hc->bus->controller = &fake_device;
usb_register_bus(hc->bus);

View file

@ -142,12 +142,12 @@ static struct bin_attribute w1_slave_attr_bin_id = {
/* Default family */
static struct w1_family w1_default_family;
static int w1_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size);
static int w1_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size);
static struct bus_type w1_bus_type = {
.name = "w1",
.match = w1_master_match,
.hotplug = w1_hotplug,
.uevent = w1_uevent,
};
struct device_driver w1_master_driver = {
@ -361,7 +361,7 @@ void w1_destroy_master_attributes(struct w1_master *master)
}
#ifdef CONFIG_HOTPLUG
static int w1_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
static int w1_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
{
struct w1_master *md = NULL;
struct w1_slave *sl = NULL;
@ -377,7 +377,7 @@ static int w1_hotplug(struct device *dev, char **envp, int num_envp, char *buffe
event_owner = "slave";
name = sl->name;
} else {
dev_dbg(dev, "Unknown hotplug event.\n");
dev_dbg(dev, "Unknown event.\n");
return -EINVAL;
}
@ -386,18 +386,18 @@ static int w1_hotplug(struct device *dev, char **envp, int num_envp, char *buffe
if (dev->driver != &w1_slave_driver || !sl)
return 0;
err = add_hotplug_env_var(envp, num_envp, &cur_index, buffer, buffer_size, &cur_len, "W1_FID=%02X", sl->reg_num.family);
err = add_uevent_var(envp, num_envp, &cur_index, buffer, buffer_size, &cur_len, "W1_FID=%02X", sl->reg_num.family);
if (err)
return err;
err = add_hotplug_env_var(envp, num_envp, &cur_index, buffer, buffer_size, &cur_len, "W1_SLAVE_ID=%024LX", (u64)sl->reg_num.id);
err = add_uevent_var(envp, num_envp, &cur_index, buffer, buffer_size, &cur_len, "W1_SLAVE_ID=%024LX", (u64)sl->reg_num.id);
if (err)
return err;
return 0;
};
#else
static int w1_hotplug(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
static int w1_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
{
return 0;
}

View file

@ -226,7 +226,7 @@ static struct sysfs_ops part_sysfs_ops = {
static ssize_t part_uevent_store(struct hd_struct * p,
const char *page, size_t count)
{
kobject_hotplug(&p->kobj, KOBJ_ADD);
kobject_uevent(&p->kobj, KOBJ_ADD);
return count;
}
static ssize_t part_dev_read(struct hd_struct * p, char *page)
@ -336,12 +336,31 @@ void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len)
disk->part[part-1] = p;
}
static char *make_block_name(struct gendisk *disk)
{
char *name;
static char *block_str = "block:";
int size;
size = strlen(block_str) + strlen(disk->disk_name) + 1;
name = kmalloc(size, GFP_KERNEL);
if (!name)
return NULL;
strcpy(name, block_str);
strcat(name, disk->disk_name);
return name;
}
static void disk_sysfs_symlinks(struct gendisk *disk)
{
struct device *target = get_device(disk->driverfs_dev);
if (target) {
char *disk_name = make_block_name(disk);
sysfs_create_link(&disk->kobj,&target->kobj,"device");
sysfs_create_link(&target->kobj,&disk->kobj,"block");
if (disk_name) {
sysfs_create_link(&target->kobj,&disk->kobj,disk_name);
kfree(disk_name);
}
}
}
@ -360,7 +379,7 @@ void register_disk(struct gendisk *disk)
if ((err = kobject_add(&disk->kobj)))
return;
disk_sysfs_symlinks(disk);
kobject_hotplug(&disk->kobj, KOBJ_ADD);
kobject_uevent(&disk->kobj, KOBJ_ADD);
/* No minors to use for partitions */
if (disk->minors == 1) {
@ -461,10 +480,14 @@ void del_gendisk(struct gendisk *disk)
devfs_remove_disk(disk);
if (disk->driverfs_dev) {
char *disk_name = make_block_name(disk);
sysfs_remove_link(&disk->kobj, "device");
sysfs_remove_link(&disk->driverfs_dev->kobj, "block");
if (disk_name) {
sysfs_remove_link(&disk->driverfs_dev->kobj, disk_name);
kfree(disk_name);
}
put_device(disk->driverfs_dev);
}
kobject_hotplug(&disk->kobj, KOBJ_REMOVE);
kobject_uevent(&disk->kobj, KOBJ_REMOVE);
kobject_del(&disk->kobj);
}

View file

@ -665,16 +665,6 @@ static int test_bdev_super(struct super_block *s, void *data)
return (void *)s->s_bdev == data;
}
static void bdev_uevent(struct block_device *bdev, enum kobject_action action)
{
if (bdev->bd_disk) {
if (bdev->bd_part)
kobject_uevent(&bdev->bd_part->kobj, action, NULL);
else
kobject_uevent(&bdev->bd_disk->kobj, action, NULL);
}
}
struct super_block *get_sb_bdev(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data,
int (*fill_super)(struct super_block *, void *, int))
@ -717,10 +707,8 @@ struct super_block *get_sb_bdev(struct file_system_type *fs_type,
up_write(&s->s_umount);
deactivate_super(s);
s = ERR_PTR(error);
} else {
} else
s->s_flags |= MS_ACTIVE;
bdev_uevent(bdev, KOBJ_MOUNT);
}
}
return s;
@ -736,7 +724,6 @@ void kill_block_super(struct super_block *sb)
{
struct block_device *bdev = sb->s_bdev;
bdev_uevent(bdev, KOBJ_UMOUNT);
generic_shutdown_super(sb);
sync_blockdev(bdev);
close_bdev_excl(bdev);

View file

@ -112,7 +112,11 @@ static int create_dir(struct kobject * k, struct dentry * p,
}
}
if (error && (error != -EEXIST)) {
sysfs_put((*d)->d_fsdata);
struct sysfs_dirent *sd = (*d)->d_fsdata;
if (sd) {
list_del_init(&sd->s_sibling);
sysfs_put(sd);
}
d_drop(*d);
}
dput(*d);

View file

@ -47,8 +47,8 @@ struct bus_type {
struct driver_attribute * drv_attrs;
int (*match)(struct device * dev, struct device_driver * drv);
int (*hotplug) (struct device *dev, char **envp,
int num_envp, char *buffer, int buffer_size);
int (*uevent)(struct device *dev, char **envp,
int num_envp, char *buffer, int buffer_size);
int (*suspend)(struct device * dev, pm_message_t state);
int (*resume)(struct device * dev);
};
@ -151,7 +151,7 @@ struct class {
struct class_attribute * class_attrs;
struct class_device_attribute * class_dev_attrs;
int (*hotplug)(struct class_device *dev, char **envp,
int (*uevent)(struct class_device *dev, char **envp,
int num_envp, char *buffer, int buffer_size);
void (*release)(struct class_device *dev);
@ -209,9 +209,9 @@ extern int class_device_create_file(struct class_device *,
* set, this will be called instead of the class specific release function.
* Only use this if you want to override the default release function, like
* when you are nesting class_device structures.
* @hotplug: pointer to a hotplug function for this struct class_device. If
* set, this will be called instead of the class specific hotplug function.
* Only use this if you want to override the default hotplug function, like
* @uevent: pointer to a uevent function for this struct class_device. If
* set, this will be called instead of the class specific uevent function.
* Only use this if you want to override the default uevent function, like
* when you are nesting class_device structures.
*/
struct class_device {
@ -227,7 +227,7 @@ struct class_device {
struct class_device *parent; /* parent of this child device, if there is one */
void (*release)(struct class_device *dev);
int (*hotplug)(struct class_device *dev, char **envp,
int (*uevent)(struct class_device *dev, char **envp,
int num_envp, char *buffer, int buffer_size);
char class_id[BUS_ID_SIZE]; /* unique to this class */
};

View file

@ -14,7 +14,7 @@ struct device;
int request_firmware(const struct firmware **fw, const char *name,
struct device *device);
int request_firmware_nowait(
struct module *module, int hotplug,
struct module *module, int uevent,
const char *name, struct device *device, void *context,
void (*cont)(const struct firmware *fw, void *context));

View file

@ -13,6 +13,7 @@
#include <linux/time.h>
#include <linux/list.h>
#include <linux/device.h>
#include <linux/mod_devicetable.h>
#else
#include <sys/time.h>
#include <sys/ioctl.h>
@ -511,6 +512,8 @@ struct input_absinfo {
#define KEY_FN_S 0x1e3
#define KEY_FN_B 0x1e4
/* We avoid low common keys in module aliases so they don't get huge. */
#define KEY_MIN_INTERESTING KEY_MUTE
#define KEY_MAX 0x1ff
/*
@ -793,6 +796,44 @@ struct ff_effect {
#define FF_MAX 0x7f
struct input_device_id {
kernel_ulong_t flags;
struct input_id id;
kernel_ulong_t evbit[EV_MAX/BITS_PER_LONG+1];
kernel_ulong_t keybit[KEY_MAX/BITS_PER_LONG+1];
kernel_ulong_t relbit[REL_MAX/BITS_PER_LONG+1];
kernel_ulong_t absbit[ABS_MAX/BITS_PER_LONG+1];
kernel_ulong_t mscbit[MSC_MAX/BITS_PER_LONG+1];
kernel_ulong_t ledbit[LED_MAX/BITS_PER_LONG+1];
kernel_ulong_t sndbit[SND_MAX/BITS_PER_LONG+1];
kernel_ulong_t ffbit[FF_MAX/BITS_PER_LONG+1];
kernel_ulong_t swbit[SW_MAX/BITS_PER_LONG+1];
kernel_ulong_t driver_info;
};
/*
* Structure for hotplug & device<->driver matching.
*/
#define INPUT_DEVICE_ID_MATCH_BUS 1
#define INPUT_DEVICE_ID_MATCH_VENDOR 2
#define INPUT_DEVICE_ID_MATCH_PRODUCT 4
#define INPUT_DEVICE_ID_MATCH_VERSION 8
#define INPUT_DEVICE_ID_MATCH_EVBIT 0x010
#define INPUT_DEVICE_ID_MATCH_KEYBIT 0x020
#define INPUT_DEVICE_ID_MATCH_RELBIT 0x040
#define INPUT_DEVICE_ID_MATCH_ABSBIT 0x080
#define INPUT_DEVICE_ID_MATCH_MSCIT 0x100
#define INPUT_DEVICE_ID_MATCH_LEDBIT 0x200
#define INPUT_DEVICE_ID_MATCH_SNDBIT 0x400
#define INPUT_DEVICE_ID_MATCH_FFBIT 0x800
#define INPUT_DEVICE_ID_MATCH_SWBIT 0x1000
#ifdef __KERNEL__
/*
@ -901,49 +942,11 @@ struct input_dev {
};
#define to_input_dev(d) container_of(d, struct input_dev, cdev)
/*
* Structure for hotplug & device<->driver matching.
*/
#define INPUT_DEVICE_ID_MATCH_BUS 1
#define INPUT_DEVICE_ID_MATCH_VENDOR 2
#define INPUT_DEVICE_ID_MATCH_PRODUCT 4
#define INPUT_DEVICE_ID_MATCH_VERSION 8
#define INPUT_DEVICE_ID_MATCH_EVBIT 0x010
#define INPUT_DEVICE_ID_MATCH_KEYBIT 0x020
#define INPUT_DEVICE_ID_MATCH_RELBIT 0x040
#define INPUT_DEVICE_ID_MATCH_ABSBIT 0x080
#define INPUT_DEVICE_ID_MATCH_MSCIT 0x100
#define INPUT_DEVICE_ID_MATCH_LEDBIT 0x200
#define INPUT_DEVICE_ID_MATCH_SNDBIT 0x400
#define INPUT_DEVICE_ID_MATCH_FFBIT 0x800
#define INPUT_DEVICE_ID_MATCH_SWBIT 0x1000
#define INPUT_DEVICE_ID_MATCH_DEVICE\
(INPUT_DEVICE_ID_MATCH_BUS | INPUT_DEVICE_ID_MATCH_VENDOR | INPUT_DEVICE_ID_MATCH_PRODUCT)
#define INPUT_DEVICE_ID_MATCH_DEVICE_AND_VERSION\
(INPUT_DEVICE_ID_MATCH_DEVICE | INPUT_DEVICE_ID_MATCH_VERSION)
struct input_device_id {
unsigned long flags;
struct input_id id;
unsigned long evbit[NBITS(EV_MAX)];
unsigned long keybit[NBITS(KEY_MAX)];
unsigned long relbit[NBITS(REL_MAX)];
unsigned long absbit[NBITS(ABS_MAX)];
unsigned long mscbit[NBITS(MSC_MAX)];
unsigned long ledbit[NBITS(LED_MAX)];
unsigned long sndbit[NBITS(SND_MAX)];
unsigned long ffbit[NBITS(FF_MAX)];
unsigned long swbit[NBITS(SW_MAX)];
unsigned long driver_info;
};
struct input_handle;
struct input_handler {

View file

@ -23,14 +23,27 @@
#include <linux/spinlock.h>
#include <linux/rwsem.h>
#include <linux/kref.h>
#include <linux/kobject_uevent.h>
#include <linux/kernel.h>
#include <asm/atomic.h>
#define KOBJ_NAME_LEN 20
#define KOBJ_NAME_LEN 20
#define UEVENT_HELPER_PATH_LEN 256
/* counter to tag the hotplug event, read only except for the kobject core */
extern u64 hotplug_seqnum;
/* path to the userspace helper executed on an event */
extern char uevent_helper[];
/* counter to tag the uevent, read only except for the kobject core */
extern u64 uevent_seqnum;
/* the actions here must match the proper string in lib/kobject_uevent.c */
typedef int __bitwise kobject_action_t;
enum kobject_action {
KOBJ_ADD = (__force kobject_action_t) 0x01, /* exclusive to core */
KOBJ_REMOVE = (__force kobject_action_t) 0x02, /* exclusive to core */
KOBJ_CHANGE = (__force kobject_action_t) 0x03, /* device state change */
KOBJ_OFFLINE = (__force kobject_action_t) 0x04, /* device offline */
KOBJ_ONLINE = (__force kobject_action_t) 0x05, /* device online */
};
struct kobject {
const char * k_name;
@ -87,15 +100,14 @@ struct kobj_type {
* of object; multiple ksets can belong to one subsystem. All
* ksets of a subsystem share the subsystem's lock.
*
* Each kset can support hotplugging; if it does, it will be given
* the opportunity to filter out specific kobjects from being
* reported, as well as to add its own "data" elements to the
* environment being passed to the hotplug helper.
* Each kset can support specific event variables; it can
* supress the event generation or add subsystem specific
* variables carried with the event.
*/
struct kset_hotplug_ops {
struct kset_uevent_ops {
int (*filter)(struct kset *kset, struct kobject *kobj);
const char *(*name)(struct kset *kset, struct kobject *kobj);
int (*hotplug)(struct kset *kset, struct kobject *kobj, char **envp,
int (*uevent)(struct kset *kset, struct kobject *kobj, char **envp,
int num_envp, char *buffer, int buffer_size);
};
@ -105,7 +117,7 @@ struct kset {
struct list_head list;
spinlock_t list_lock;
struct kobject kobj;
struct kset_hotplug_ops * hotplug_ops;
struct kset_uevent_ops * uevent_ops;
};
@ -153,20 +165,20 @@ struct subsystem {
struct rw_semaphore rwsem;
};
#define decl_subsys(_name,_type,_hotplug_ops) \
#define decl_subsys(_name,_type,_uevent_ops) \
struct subsystem _name##_subsys = { \
.kset = { \
.kobj = { .name = __stringify(_name) }, \
.ktype = _type, \
.hotplug_ops =_hotplug_ops, \
.uevent_ops =_uevent_ops, \
} \
}
#define decl_subsys_name(_varname,_name,_type,_hotplug_ops) \
#define decl_subsys_name(_varname,_name,_type,_uevent_ops) \
struct subsystem _varname##_subsys = { \
.kset = { \
.kobj = { .name = __stringify(_name) }, \
.ktype = _type, \
.hotplug_ops =_hotplug_ops, \
.uevent_ops =_uevent_ops, \
} \
}
@ -241,15 +253,17 @@ struct subsys_attribute {
extern int subsys_create_file(struct subsystem * , struct subsys_attribute *);
extern void subsys_remove_file(struct subsystem * , struct subsys_attribute *);
#ifdef CONFIG_HOTPLUG
void kobject_hotplug(struct kobject *kobj, enum kobject_action action);
int add_hotplug_env_var(char **envp, int num_envp, int *cur_index,
#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,
char *buffer, int buffer_size, int *cur_len,
const char *format, ...)
__attribute__((format (printf, 7, 8)));
#else
static inline void kobject_hotplug(struct kobject *kobj, enum kobject_action action) { }
static inline int add_hotplug_env_var(char **envp, int num_envp, int *cur_index,
static inline void kobject_uevent(struct kobject *kobj, enum kobject_action action) { }
static inline int add_uevent_var(char **envp, int num_envp, int *cur_index,
char *buffer, int buffer_size, int *cur_len,
const char *format, ...)
{ return 0; }

View file

@ -1,57 +0,0 @@
/*
* kobject_uevent.h - list of kobject user events that can be generated
*
* Copyright (C) 2004 IBM Corp.
* Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
*
* This file is released under the GPLv2.
*
*/
#ifndef _KOBJECT_EVENT_H_
#define _KOBJECT_EVENT_H_
#define HOTPLUG_PATH_LEN 256
/* path to the hotplug userspace helper executed on an event */
extern char hotplug_path[];
/*
* If you add an action here, you must also add the proper string to the
* lib/kobject_uevent.c file.
*/
typedef int __bitwise kobject_action_t;
enum kobject_action {
KOBJ_ADD = (__force kobject_action_t) 0x01, /* add event, for hotplug */
KOBJ_REMOVE = (__force kobject_action_t) 0x02, /* remove event, for hotplug */
KOBJ_CHANGE = (__force kobject_action_t) 0x03, /* a sysfs attribute file has changed */
KOBJ_MOUNT = (__force kobject_action_t) 0x04, /* mount event for block devices */
KOBJ_UMOUNT = (__force kobject_action_t) 0x05, /* umount event for block devices */
KOBJ_OFFLINE = (__force kobject_action_t) 0x06, /* offline event for hotplug devices */
KOBJ_ONLINE = (__force kobject_action_t) 0x07, /* online event for hotplug devices */
};
#ifdef CONFIG_KOBJECT_UEVENT
int kobject_uevent(struct kobject *kobj,
enum kobject_action action,
struct attribute *attr);
int kobject_uevent_atomic(struct kobject *kobj,
enum kobject_action action,
struct attribute *attr);
#else
static inline int kobject_uevent(struct kobject *kobj,
enum kobject_action action,
struct attribute *attr)
{
return 0;
}
static inline int kobject_uevent_atomic(struct kobject *kobj,
enum kobject_action action,
struct attribute *attr)
{
return 0;
}
#endif
#endif

View file

@ -41,6 +41,7 @@ extern struct platform_device *platform_device_alloc(const char *name, unsigned
extern int platform_device_add_resources(struct platform_device *pdev, struct resource *res, unsigned int num);
extern int platform_device_add_data(struct platform_device *pdev, void *data, size_t size);
extern int platform_device_add(struct platform_device *pdev);
extern void platform_device_del(struct platform_device *pdev);
extern void platform_device_put(struct platform_device *pdev);
struct platform_driver {

View file

@ -124,7 +124,7 @@ enum
KERN_OVERFLOWUID=46, /* int: overflow UID */
KERN_OVERFLOWGID=47, /* int: overflow GID */
KERN_SHMPATH=48, /* string: path to shm fs */
KERN_HOTPLUG=49, /* string: path to hotplug policy agent */
KERN_HOTPLUG=49, /* string: path to uevent helper (deprecated) */
KERN_IEEE_EMULATION_WARNINGS=50, /* int: unimplemented ieee instructions */
KERN_S390_USER_DEBUG_LOGGING=51, /* int: dumps of user faults */
KERN_CORE_USES_PID=52, /* int: use core or core.%pid */

View file

@ -225,7 +225,7 @@ struct usb_interface_cache {
* Device drivers should not attempt to activate configurations. The choice
* of which configuration to install is a policy decision based on such
* considerations as available power, functionality provided, and the user's
* desires (expressed through hotplug scripts). However, drivers can call
* desires (expressed through userspace tools). However, drivers can call
* usb_reset_configuration() to reinitialize the current configuration and
* all its interfaces.
*/

View file

@ -197,33 +197,6 @@ config AUDITSYSCALL
can be used independently or with another kernel subsystem,
such as SELinux.
config HOTPLUG
bool "Support for hot-pluggable devices" if !ARCH_S390
default ARCH_S390
help
This option is provided for the case where no in-kernel-tree
modules require HOTPLUG functionality, but a module built
outside the kernel tree does. Such modules require Y here.
config KOBJECT_UEVENT
bool "Kernel Userspace Events" if EMBEDDED
depends on NET
default y
help
This option enables the kernel userspace event layer, which is a
simple mechanism for kernel-to-user communication over a netlink
socket.
The goal of the kernel userspace events layer is to provide a simple
and efficient events system, that notifies userspace about kobject
state changes. This will enable applications to just listen for
events instead of polling system devices and files.
Hotplug events (kobject addition and removal) are also available on
the netlink socket in addition to the execution of /sbin/hotplug if
CONFIG_HOTPLUG is enabled.
Say Y, unless you are building a system requiring minimal memory
consumption.
config IKCONFIG
bool "Kernel .config support"
---help---
@ -308,6 +281,15 @@ config KALLSYMS_EXTRA_PASS
you wait for kallsyms to be fixed.
config HOTPLUG
bool "Support for hot-pluggable devices" if EMBEDDED
default y
help
This option is provided for the case where no hotplug or uevent
capabilities is wanted by the kernel. You should only consider
disabling this option for embedded systems that do not use modules, a
dynamic /dev tree, or dynamic device discovery. Just say Y.
config PRINTK
default y
bool "Enable support for printk" if EMBEDDED

View file

@ -15,6 +15,9 @@
#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)
@ -23,11 +26,29 @@ static struct subsys_attribute _name##_attr = \
__ATTR(_name, 0644, _name##_show, _name##_store)
#ifdef CONFIG_HOTPLUG
static ssize_t hotplug_seqnum_show(struct subsystem *subsys, char *page)
/* current uevent sequence number */
static ssize_t uevent_seqnum_show(struct subsystem *subsys, char *page)
{
return sprintf(page, "%llu\n", (unsigned long long)hotplug_seqnum);
return sprintf(page, "%llu\n", (unsigned long long)uevent_seqnum);
}
KERNEL_ATTR_RO(hotplug_seqnum);
KERNEL_ATTR_RO(uevent_seqnum);
/* uevent helper program, used during early boo */
static ssize_t uevent_helper_show(struct subsystem *subsys, char *page)
{
return sprintf(page, "%s\n", uevent_helper);
}
static ssize_t uevent_helper_store(struct subsystem *subsys, const char *page, size_t count)
{
if (count+1 > UEVENT_HELPER_PATH_LEN)
return -ENOENT;
memcpy(uevent_helper, page, count);
uevent_helper[count] = '\0';
if (count && uevent_helper[count-1] == '\n')
uevent_helper[count-1] = '\0';
return count;
}
KERNEL_ATTR_RW(uevent_helper);
#endif
#ifdef CONFIG_KEXEC
@ -45,7 +66,8 @@ EXPORT_SYMBOL_GPL(kernel_subsys);
static struct attribute * kernel_attrs[] = {
#ifdef CONFIG_HOTPLUG
&hotplug_seqnum_attr.attr,
&uevent_seqnum_attr.attr,
&uevent_helper_attr.attr,
#endif
#ifdef CONFIG_KEXEC
&crash_notes_attr.attr,

View file

@ -31,6 +31,7 @@
#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/kobject.h>
#include <linux/net.h>
#include <linux/sysrq.h>
#include <linux/highuid.h>
@ -83,9 +84,6 @@ static int ngroups_max = NGROUPS_MAX;
#ifdef CONFIG_KMOD
extern char modprobe_path[];
#endif
#ifdef CONFIG_HOTPLUG
extern char hotplug_path[];
#endif
#ifdef CONFIG_CHR_DEV_SG
extern int sg_big_buff;
#endif
@ -397,8 +395,8 @@ static ctl_table kern_table[] = {
{
.ctl_name = KERN_HOTPLUG,
.procname = "hotplug",
.data = &hotplug_path,
.maxlen = HOTPLUG_PATH_LEN,
.data = &uevent_helper,
.maxlen = UEVENT_HELPER_PATH_LEN,
.mode = 0644,
.proc_handler = &proc_dostring,
.strategy = &sysctl_string,

View file

@ -199,6 +199,8 @@ void klist_iter_init_node(struct klist * k, struct klist_iter * i, struct klist_
i->i_klist = k;
i->i_head = &k->k_list;
i->i_cur = n;
if (n)
kref_get(&n->n_ref);
}
EXPORT_SYMBOL_GPL(klist_iter_init_node);

View file

@ -207,7 +207,7 @@ int kobject_register(struct kobject * kobj)
kobject_name(kobj),error);
dump_stack();
} else
kobject_hotplug(kobj, KOBJ_ADD);
kobject_uevent(kobj, KOBJ_ADD);
} else
error = -EINVAL;
return error;
@ -312,7 +312,7 @@ void kobject_del(struct kobject * kobj)
void kobject_unregister(struct kobject * kobj)
{
pr_debug("kobject %s: unregistering\n",kobject_name(kobj));
kobject_hotplug(kobj, KOBJ_REMOVE);
kobject_uevent(kobj, KOBJ_REMOVE);
kobject_del(kobj);
kobject_put(kobj);
}

View file

@ -19,14 +19,16 @@
#include <linux/skbuff.h>
#include <linux/netlink.h>
#include <linux/string.h>
#include <linux/kobject_uevent.h>
#include <linux/kobject.h>
#include <net/sock.h>
#define BUFFER_SIZE 1024 /* buffer for the hotplug env */
#define BUFFER_SIZE 1024 /* buffer for the variables */
#define NUM_ENVP 32 /* number of env pointers */
#if defined(CONFIG_KOBJECT_UEVENT) || defined(CONFIG_HOTPLUG)
#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
static DEFINE_SPINLOCK(sequence_lock);
static struct sock *uevent_sock;
static char *action_to_string(enum kobject_action action)
{
switch (action) {
@ -36,10 +38,6 @@ static char *action_to_string(enum kobject_action action)
return "remove";
case KOBJ_CHANGE:
return "change";
case KOBJ_MOUNT:
return "mount";
case KOBJ_UMOUNT:
return "umount";
case KOBJ_OFFLINE:
return "offline";
case KOBJ_ONLINE:
@ -48,306 +46,183 @@ static char *action_to_string(enum kobject_action action)
return NULL;
}
}
#endif
#ifdef CONFIG_KOBJECT_UEVENT
static struct sock *uevent_sock;
/**
* send_uevent - notify userspace by sending event through netlink socket
* kobject_uevent - notify userspace by ending an uevent
*
* @signal: signal name
* @obj: object path (kobject)
* @envp: possible hotplug environment to pass with the message
* @gfp_mask:
*/
static int send_uevent(const char *signal, const char *obj,
char **envp, gfp_t gfp_mask)
{
struct sk_buff *skb;
char *pos;
int len;
if (!uevent_sock)
return -EIO;
len = strlen(signal) + 1;
len += strlen(obj) + 1;
/* allocate buffer with the maximum possible message size */
skb = alloc_skb(len + BUFFER_SIZE, gfp_mask);
if (!skb)
return -ENOMEM;
pos = skb_put(skb, len);
sprintf(pos, "%s@%s", signal, obj);
/* copy the environment key by key to our continuous buffer */
if (envp) {
int i;
for (i = 2; envp[i]; i++) {
len = strlen(envp[i]) + 1;
pos = skb_put(skb, len);
strcpy(pos, envp[i]);
}
}
NETLINK_CB(skb).dst_group = 1;
return netlink_broadcast(uevent_sock, skb, 0, 1, gfp_mask);
}
static int do_kobject_uevent(struct kobject *kobj, enum kobject_action action,
struct attribute *attr, gfp_t gfp_mask)
{
char *path;
char *attrpath;
char *signal;
int len;
int rc = -ENOMEM;
path = kobject_get_path(kobj, gfp_mask);
if (!path)
return -ENOMEM;
signal = action_to_string(action);
if (!signal)
return -EINVAL;
if (attr) {
len = strlen(path);
len += strlen(attr->name) + 2;
attrpath = kmalloc(len, gfp_mask);
if (!attrpath)
goto exit;
sprintf(attrpath, "%s/%s", path, attr->name);
rc = send_uevent(signal, attrpath, NULL, gfp_mask);
kfree(attrpath);
} else
rc = send_uevent(signal, path, NULL, gfp_mask);
exit:
kfree(path);
return rc;
}
/**
* kobject_uevent - notify userspace by sending event through netlink socket
*
* @signal: signal name
* @kobj: struct kobject that the event is happening to
* @attr: optional struct attribute the event belongs to
*/
int kobject_uevent(struct kobject *kobj, enum kobject_action action,
struct attribute *attr)
{
return do_kobject_uevent(kobj, action, attr, GFP_KERNEL);
}
EXPORT_SYMBOL_GPL(kobject_uevent);
int kobject_uevent_atomic(struct kobject *kobj, enum kobject_action action,
struct attribute *attr)
{
return do_kobject_uevent(kobj, action, attr, GFP_ATOMIC);
}
EXPORT_SYMBOL_GPL(kobject_uevent_atomic);
static int __init kobject_uevent_init(void)
{
uevent_sock = netlink_kernel_create(NETLINK_KOBJECT_UEVENT, 1, NULL,
THIS_MODULE);
if (!uevent_sock) {
printk(KERN_ERR
"kobject_uevent: unable to create netlink socket!\n");
return -ENODEV;
}
return 0;
}
postcore_initcall(kobject_uevent_init);
#else
static inline int send_uevent(const char *signal, const char *obj,
char **envp, int gfp_mask)
{
return 0;
}
#endif /* CONFIG_KOBJECT_UEVENT */
#ifdef CONFIG_HOTPLUG
char hotplug_path[HOTPLUG_PATH_LEN] = "/sbin/hotplug";
u64 hotplug_seqnum;
static DEFINE_SPINLOCK(sequence_lock);
/**
* kobject_hotplug - notify userspace by executing /sbin/hotplug
*
* @action: action that is happening (usually "ADD" or "REMOVE")
* @action: action that is happening (usually KOBJ_ADD and KOBJ_REMOVE)
* @kobj: struct kobject that the action is happening to
*/
void kobject_hotplug(struct kobject *kobj, enum kobject_action action)
void kobject_uevent(struct kobject *kobj, enum kobject_action action)
{
char *argv [3];
char **envp = NULL;
char *buffer = NULL;
char *seq_buff;
char **envp;
char *buffer;
char *scratch;
const char *action_string;
const char *devpath = NULL;
const char *subsystem;
struct kobject *top_kobj;
struct kset *kset;
struct kset_uevent_ops *uevent_ops;
u64 seq;
char *seq_buff;
int i = 0;
int retval;
char *kobj_path = NULL;
const char *name = NULL;
char *action_string;
u64 seq;
struct kobject *top_kobj = kobj;
struct kset *kset;
static struct kset_hotplug_ops null_hotplug_ops;
struct kset_hotplug_ops *hotplug_ops = &null_hotplug_ops;
/* If this kobj does not belong to a kset,
try to find a parent that does. */
if (!top_kobj->kset && top_kobj->parent) {
do {
top_kobj = top_kobj->parent;
} while (!top_kobj->kset && top_kobj->parent);
}
if (top_kobj->kset)
kset = top_kobj->kset;
else
return;
if (kset->hotplug_ops)
hotplug_ops = kset->hotplug_ops;
/* If the kset has a filter operation, call it.
Skip the event, if the filter returns zero. */
if (hotplug_ops->filter) {
if (!hotplug_ops->filter(kset, kobj))
return;
}
pr_debug ("%s\n", __FUNCTION__);
pr_debug("%s\n", __FUNCTION__);
action_string = action_to_string(action);
if (!action_string)
return;
envp = kmalloc(NUM_ENVP * sizeof (char *), GFP_KERNEL);
/* search the kset we belong to */
top_kobj = kobj;
if (!top_kobj->kset && top_kobj->parent) {
do {
top_kobj = top_kobj->parent;
} while (!top_kobj->kset && top_kobj->parent);
}
if (!top_kobj->kset)
return;
kset = top_kobj->kset;
uevent_ops = kset->uevent_ops;
/* skip the event, if the filter returns zero. */
if (uevent_ops && uevent_ops->filter)
if (!uevent_ops->filter(kset, kobj))
return;
/* environment index */
envp = kzalloc(NUM_ENVP * sizeof (char *), GFP_KERNEL);
if (!envp)
return;
memset (envp, 0x00, NUM_ENVP * sizeof (char *));
/* environment values */
buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
if (!buffer)
goto exit;
if (hotplug_ops->name)
name = hotplug_ops->name(kset, kobj);
if (name == NULL)
name = kobject_name(&kset->kobj);
argv [0] = hotplug_path;
argv [1] = (char *)name; /* won't be changed but 'const' has to go */
argv [2] = NULL;
/* minimal command environment */
envp [i++] = "HOME=/";
envp [i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
scratch = buffer;
envp [i++] = scratch;
scratch += sprintf(scratch, "ACTION=%s", action_string) + 1;
kobj_path = kobject_get_path(kobj, GFP_KERNEL);
if (!kobj_path)
/* complete object path */
devpath = kobject_get_path(kobj, GFP_KERNEL);
if (!devpath)
goto exit;
envp [i++] = scratch;
scratch += sprintf (scratch, "DEVPATH=%s", kobj_path) + 1;
/* originating subsystem */
if (uevent_ops && uevent_ops->name)
subsystem = uevent_ops->name(kset, kobj);
else
subsystem = kobject_name(&kset->kobj);
envp [i++] = scratch;
scratch += sprintf(scratch, "SUBSYSTEM=%s", name) + 1;
/* event environemnt for helper process only */
envp[i++] = "HOME=/";
envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
/* reserve space for the sequence,
* put the real one in after the hotplug call */
/* default keys */
scratch = buffer;
envp [i++] = scratch;
scratch += sprintf(scratch, "ACTION=%s", action_string) + 1;
envp [i++] = scratch;
scratch += sprintf (scratch, "DEVPATH=%s", devpath) + 1;
envp [i++] = scratch;
scratch += sprintf(scratch, "SUBSYSTEM=%s", subsystem) + 1;
/* just reserve the space, overwrite it after kset call has returned */
envp[i++] = seq_buff = scratch;
scratch += strlen("SEQNUM=18446744073709551616") + 1;
if (hotplug_ops->hotplug) {
/* have the kset specific function add its stuff */
retval = hotplug_ops->hotplug (kset, kobj,
/* let the kset specific function add its stuff */
if (uevent_ops && uevent_ops->uevent) {
retval = uevent_ops->uevent(kset, kobj,
&envp[i], NUM_ENVP - i, scratch,
BUFFER_SIZE - (scratch - buffer));
if (retval) {
pr_debug ("%s - hotplug() returned %d\n",
pr_debug ("%s - uevent() returned %d\n",
__FUNCTION__, retval);
goto exit;
}
}
/* we will send an event, request a new sequence number */
spin_lock(&sequence_lock);
seq = ++hotplug_seqnum;
seq = ++uevent_seqnum;
spin_unlock(&sequence_lock);
sprintf(seq_buff, "SEQNUM=%llu", (unsigned long long)seq);
pr_debug ("%s: %s %s seq=%llu %s %s %s %s %s\n",
__FUNCTION__, argv[0], argv[1], (unsigned long long)seq,
envp[0], envp[1], envp[2], envp[3], envp[4]);
/* send netlink message */
if (uevent_sock) {
struct sk_buff *skb;
size_t len;
send_uevent(action_string, kobj_path, envp, GFP_KERNEL);
/* allocate message with the maximum possible size */
len = strlen(action_string) + strlen(devpath) + 2;
skb = alloc_skb(len + BUFFER_SIZE, GFP_KERNEL);
if (skb) {
/* add header */
scratch = skb_put(skb, len);
sprintf(scratch, "%s@%s", action_string, devpath);
if (!hotplug_path[0])
goto exit;
/* copy keys to our continuous event payload buffer */
for (i = 2; envp[i]; i++) {
len = strlen(envp[i]) + 1;
scratch = skb_put(skb, len);
strcpy(scratch, envp[i]);
}
retval = call_usermodehelper (argv[0], argv, envp, 0);
if (retval)
pr_debug ("%s - call_usermodehelper returned %d\n",
__FUNCTION__, retval);
NETLINK_CB(skb).dst_group = 1;
netlink_broadcast(uevent_sock, skb, 0, 1, GFP_KERNEL);
}
}
/* call uevent_helper, usually only enabled during early boot */
if (uevent_helper[0]) {
char *argv [3];
argv [0] = uevent_helper;
argv [1] = (char *)subsystem;
argv [2] = NULL;
call_usermodehelper (argv[0], argv, envp, 0);
}
exit:
kfree(kobj_path);
kfree(devpath);
kfree(buffer);
kfree(envp);
return;
}
EXPORT_SYMBOL(kobject_hotplug);
EXPORT_SYMBOL_GPL(kobject_uevent);
/**
* add_hotplug_env_var - helper for creating hotplug environment variables
* add_uevent_var - helper for creating event variables
* @envp: Pointer to table of environment variables, as passed into
* hotplug() method.
* uevent() method.
* @num_envp: Number of environment variable slots available, as
* passed into hotplug() method.
* passed into uevent() method.
* @cur_index: Pointer to current index into @envp. It should be
* initialized to 0 before the first call to add_hotplug_env_var(),
* initialized to 0 before the first call to add_uevent_var(),
* and will be incremented on success.
* @buffer: Pointer to buffer for environment variables, as passed
* into hotplug() method.
* @buffer_size: Length of @buffer, as passed into hotplug() method.
* into uevent() method.
* @buffer_size: Length of @buffer, as passed into uevent() method.
* @cur_len: Pointer to current length of space used in @buffer.
* Should be initialized to 0 before the first call to
* add_hotplug_env_var(), and will be incremented on success.
* add_uevent_var(), and will be incremented on success.
* @format: Format for creating environment variable (of the form
* "XXX=%x") for snprintf().
*
* Returns 0 if environment variable was added successfully or -ENOMEM
* if no space was available.
*/
int add_hotplug_env_var(char **envp, int num_envp, int *cur_index,
char *buffer, int buffer_size, int *cur_len,
const char *format, ...)
int add_uevent_var(char **envp, int num_envp, int *cur_index,
char *buffer, int buffer_size, int *cur_len,
const char *format, ...)
{
va_list args;
/*
* We check against num_envp - 1 to make sure there is at
* least one slot left after we return, since the hotplug
* method needs to set the last slot to NULL.
* least one slot left after we return, since kobject_uevent()
* needs to set the last slot to NULL.
*/
if (*cur_index >= num_envp - 1)
return -ENOMEM;
@ -366,6 +241,22 @@ int add_hotplug_env_var(char **envp, int num_envp, int *cur_index,
(*cur_index)++;
return 0;
}
EXPORT_SYMBOL(add_hotplug_env_var);
EXPORT_SYMBOL_GPL(add_uevent_var);
static int __init kobject_uevent_init(void)
{
uevent_sock = netlink_kernel_create(NETLINK_KOBJECT_UEVENT, 1, NULL,
THIS_MODULE);
if (!uevent_sock) {
printk(KERN_ERR
"kobject_uevent: unable to create netlink socket!\n");
return -ENODEV;
}
return 0;
}
postcore_initcall(kobject_uevent_init);
#endif /* CONFIG_HOTPLUG */

View file

@ -78,7 +78,7 @@ static struct class_device_attribute *bt_attrs[] = {
};
#ifdef CONFIG_HOTPLUG
static int bt_hotplug(struct class_device *cdev, char **envp, int num_envp, char *buf, int size)
static int bt_uevent(struct class_device *cdev, char **envp, int num_envp, char *buf, int size)
{
struct hci_dev *hdev = class_get_devdata(cdev);
int n, i = 0;
@ -107,7 +107,7 @@ struct class bt_class = {
.name = "bluetooth",
.release = bt_release,
#ifdef CONFIG_HOTPLUG
.hotplug = bt_hotplug,
.uevent = bt_uevent,
#endif
};

View file

@ -248,7 +248,7 @@ int br_sysfs_addif(struct net_bridge_port *p)
if (err)
goto out2;
kobject_hotplug(&p->kobj, KOBJ_ADD);
kobject_uevent(&p->kobj, KOBJ_ADD);
return 0;
out2:
kobject_del(&p->kobj);
@ -260,7 +260,7 @@ void br_sysfs_removeif(struct net_bridge_port *p)
{
pr_debug("br_sysfs_removeif\n");
sysfs_remove_link(&p->br->ifobj, p->dev->name);
kobject_hotplug(&p->kobj, KOBJ_REMOVE);
kobject_uevent(&p->kobj, KOBJ_REMOVE);
kobject_del(&p->kobj);
}

View file

@ -84,16 +84,11 @@ static ssize_t netdev_store(struct class_device *dev,
return ret;
}
/* generate a read-only network device class attribute */
#define NETDEVICE_ATTR(field, format_string) \
NETDEVICE_SHOW(field, format_string) \
static CLASS_DEVICE_ATTR(field, S_IRUGO, show_##field, NULL) \
NETDEVICE_ATTR(addr_len, fmt_dec);
NETDEVICE_ATTR(iflink, fmt_dec);
NETDEVICE_ATTR(ifindex, fmt_dec);
NETDEVICE_ATTR(features, fmt_long_hex);
NETDEVICE_ATTR(type, fmt_dec);
NETDEVICE_SHOW(addr_len, fmt_dec);
NETDEVICE_SHOW(iflink, fmt_dec);
NETDEVICE_SHOW(ifindex, fmt_dec);
NETDEVICE_SHOW(features, fmt_long_hex);
NETDEVICE_SHOW(type, fmt_dec);
/* use same locking rules as GIFHWADDR ioctl's */
static ssize_t format_addr(char *buf, const unsigned char *addr, int len)
@ -136,10 +131,6 @@ static ssize_t show_carrier(struct class_device *dev, char *buf)
return -EINVAL;
}
static CLASS_DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
static CLASS_DEVICE_ATTR(broadcast, S_IRUGO, show_broadcast, NULL);
static CLASS_DEVICE_ATTR(carrier, S_IRUGO, show_carrier, NULL);
/* read-write attributes */
NETDEVICE_SHOW(mtu, fmt_dec);
@ -153,8 +144,6 @@ static ssize_t store_mtu(struct class_device *dev, const char *buf, size_t len)
return netdev_store(dev, buf, len, change_mtu);
}
static CLASS_DEVICE_ATTR(mtu, S_IRUGO | S_IWUSR, show_mtu, store_mtu);
NETDEVICE_SHOW(flags, fmt_hex);
static int change_flags(struct net_device *net, unsigned long new_flags)
@ -167,8 +156,6 @@ static ssize_t store_flags(struct class_device *dev, const char *buf, size_t len
return netdev_store(dev, buf, len, change_flags);
}
static CLASS_DEVICE_ATTR(flags, S_IRUGO | S_IWUSR, show_flags, store_flags);
NETDEVICE_SHOW(tx_queue_len, fmt_ulong);
static int change_tx_queue_len(struct net_device *net, unsigned long new_len)
@ -182,9 +169,6 @@ static ssize_t store_tx_queue_len(struct class_device *dev, const char *buf, siz
return netdev_store(dev, buf, len, change_tx_queue_len);
}
static CLASS_DEVICE_ATTR(tx_queue_len, S_IRUGO | S_IWUSR, show_tx_queue_len,
store_tx_queue_len);
NETDEVICE_SHOW(weight, fmt_dec);
static int change_weight(struct net_device *net, unsigned long new_weight)
@ -198,24 +182,21 @@ static ssize_t store_weight(struct class_device *dev, const char *buf, size_t le
return netdev_store(dev, buf, len, change_weight);
}
static CLASS_DEVICE_ATTR(weight, S_IRUGO | S_IWUSR, show_weight,
store_weight);
static struct class_device_attribute *net_class_attributes[] = {
&class_device_attr_ifindex,
&class_device_attr_iflink,
&class_device_attr_addr_len,
&class_device_attr_tx_queue_len,
&class_device_attr_features,
&class_device_attr_mtu,
&class_device_attr_flags,
&class_device_attr_weight,
&class_device_attr_type,
&class_device_attr_address,
&class_device_attr_broadcast,
&class_device_attr_carrier,
NULL
static struct class_device_attribute net_class_attributes[] = {
__ATTR(addr_len, S_IRUGO, show_addr_len, NULL),
__ATTR(iflink, S_IRUGO, show_iflink, NULL),
__ATTR(ifindex, S_IRUGO, show_ifindex, NULL),
__ATTR(features, S_IRUGO, show_features, NULL),
__ATTR(type, S_IRUGO, show_type, NULL),
__ATTR(address, S_IRUGO, show_address, NULL),
__ATTR(broadcast, S_IRUGO, show_broadcast, NULL),
__ATTR(carrier, S_IRUGO, show_carrier, NULL),
__ATTR(mtu, S_IRUGO | S_IWUSR, show_mtu, store_mtu),
__ATTR(flags, S_IRUGO | S_IWUSR, show_flags, store_flags),
__ATTR(tx_queue_len, S_IRUGO | S_IWUSR, show_tx_queue_len,
store_tx_queue_len),
__ATTR(weight, S_IRUGO | S_IWUSR, show_weight, store_weight),
{}
};
/* Show a given an attribute in the statistics group */
@ -369,14 +350,14 @@ static struct attribute_group wireless_group = {
#endif
#ifdef CONFIG_HOTPLUG
static int netdev_hotplug(struct class_device *cd, char **envp,
int num_envp, char *buf, int size)
static int netdev_uevent(struct class_device *cd, char **envp,
int num_envp, char *buf, int size)
{
struct net_device *dev = to_net_dev(cd);
int i = 0;
int n;
/* pass interface in env to hotplug. */
/* pass interface to uevent. */
envp[i++] = buf;
n = snprintf(buf, size, "INTERFACE=%s", dev->name) + 1;
buf += n;
@ -407,8 +388,9 @@ static void netdev_release(struct class_device *cd)
static struct class net_class = {
.name = "net",
.release = netdev_release,
.class_dev_attrs = net_class_attributes,
#ifdef CONFIG_HOTPLUG
.hotplug = netdev_hotplug,
.uevent = netdev_uevent,
#endif
};
@ -431,8 +413,6 @@ void netdev_unregister_sysfs(struct net_device * net)
int netdev_register_sysfs(struct net_device *net)
{
struct class_device *class_dev = &(net->class_dev);
int i;
struct class_device_attribute *attr;
int ret;
class_dev->class = &net_class;
@ -442,12 +422,6 @@ int netdev_register_sysfs(struct net_device *net)
if ((ret = class_device_register(class_dev)))
goto out;
for (i = 0; (attr = net_class_attributes[i]) != NULL; i++) {
if ((ret = class_device_create_file(class_dev, attr)))
goto out_unreg;
}
if (net->get_stats &&
(ret = sysfs_create_group(&class_dev->kobj, &netstat_group)))
goto out_unreg;

View file

@ -16,8 +16,10 @@
* use either stdint.h or inttypes.h for the rest. */
#if KERNEL_ELFCLASS == ELFCLASS32
typedef Elf32_Addr kernel_ulong_t;
#define BITS_PER_LONG 32
#else
typedef Elf64_Addr kernel_ulong_t;
#define BITS_PER_LONG 64
#endif
#ifdef __sun__
#include <inttypes.h>
@ -35,6 +37,7 @@ typedef unsigned char __u8;
* even potentially has different endianness and word sizes, since
* we handle those differences explicitly below */
#include "../../include/linux/mod_devicetable.h"
#include "../../include/linux/input.h"
#define ADD(str, sep, cond, field) \
do { \
@ -366,6 +369,61 @@ static int do_i2c_entry(const char *filename, struct i2c_device_id *i2c, char *a
return 1;
}
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
static void do_input(char *alias,
kernel_ulong_t *arr, unsigned int min, unsigned int max)
{
unsigned int i;
for (i = min; i < max; i++) {
if (arr[i/BITS_PER_LONG] & (1 << (i%BITS_PER_LONG)))
sprintf(alias+strlen(alias), "%X,*", i);
}
}
/* input:b0v0p0e0-eXkXrXaXmXlXsXfXwX where X is comma-separated %02X. */
static int do_input_entry(const char *filename, struct input_device_id *id,
char *alias)
{
sprintf(alias, "input:");
ADD(alias, "b", id->flags&INPUT_DEVICE_ID_MATCH_BUS, id->id.bustype);
ADD(alias, "v", id->flags&INPUT_DEVICE_ID_MATCH_VENDOR, id->id.vendor);
ADD(alias, "p", id->flags&INPUT_DEVICE_ID_MATCH_PRODUCT,
id->id.product);
ADD(alias, "e", id->flags&INPUT_DEVICE_ID_MATCH_VERSION,
id->id.version);
sprintf(alias + strlen(alias), "-e*");
if (id->flags&INPUT_DEVICE_ID_MATCH_EVBIT)
do_input(alias, id->evbit, 0, EV_MAX);
sprintf(alias + strlen(alias), "k*");
if (id->flags&INPUT_DEVICE_ID_MATCH_KEYBIT)
do_input(alias, id->keybit, KEY_MIN_INTERESTING, KEY_MAX);
sprintf(alias + strlen(alias), "r*");
if (id->flags&INPUT_DEVICE_ID_MATCH_RELBIT)
do_input(alias, id->relbit, 0, REL_MAX);
sprintf(alias + strlen(alias), "a*");
if (id->flags&INPUT_DEVICE_ID_MATCH_ABSBIT)
do_input(alias, id->absbit, 0, ABS_MAX);
sprintf(alias + strlen(alias), "m*");
if (id->flags&INPUT_DEVICE_ID_MATCH_MSCIT)
do_input(alias, id->mscbit, 0, MSC_MAX);
sprintf(alias + strlen(alias), "l*");
if (id->flags&INPUT_DEVICE_ID_MATCH_LEDBIT)
do_input(alias, id->ledbit, 0, LED_MAX);
sprintf(alias + strlen(alias), "s*");
if (id->flags&INPUT_DEVICE_ID_MATCH_SNDBIT)
do_input(alias, id->sndbit, 0, SND_MAX);
sprintf(alias + strlen(alias), "f*");
if (id->flags&INPUT_DEVICE_ID_MATCH_FFBIT)
do_input(alias, id->ffbit, 0, SND_MAX);
sprintf(alias + strlen(alias), "w*");
if (id->flags&INPUT_DEVICE_ID_MATCH_SWBIT)
do_input(alias, id->swbit, 0, SW_MAX);
return 1;
}
/* Ignore any prefix, eg. v850 prepends _ */
static inline int sym_is(const char *symbol, const char *name)
{
@ -453,7 +511,9 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
else if (sym_is(symname, "__mod_i2c_device_table"))
do_table(symval, sym->st_size, sizeof(struct i2c_device_id),
do_i2c_entry, mod);
else if (sym_is(symname, "__mod_input_device_table"))
do_table(symval, sym->st_size, sizeof(struct input_device_id),
do_input_entry, mod);
}
/* Now add out buffered information to the generated C source */