Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6: (28 commits) sysfs: Shadow directory support Driver Core: Increase the default timeout value of the firmware subsystem Driver core: allow to delay the uevent at device creation time Driver core: add device_type to struct device Driver core: add uevent vars for devices of a class SYSFS: Fix missing include of list.h in sysfs.h HOWTO: Add a reference to Harbison and Steele sysfs: error handling in sysfs, fill_read_buffer() kobject: kobject_put cleanup sysfs: kobject_put cleanup sysfs: suppress lockdep warnings Driver core: fix race in sysfs between sysfs_remove_file() and read()/write() driver core: Change function call order in device_bind_driver(). driver core: Don't stop probing on ->probe errors. driver core fixes: device_register() retval check in platform.c driver core fixes: make_class_name() retval checks /sys/modules/*/holders USB: add the sysfs driver name to all modules SERIO: add the sysfs driver name to all modules PCI: add the sysfs driver name to all modules ...
This commit is contained in:
commit
f2aca47dc3
69 changed files with 1286 additions and 709 deletions
|
@ -30,6 +30,7 @@ are not a good substitute for a solid C education and/or years of
|
|||
experience, the following books are good for, if anything, reference:
|
||||
- "The C Programming Language" by Kernighan and Ritchie [Prentice Hall]
|
||||
- "Practical C Programming" by Steve Oualline [O'Reilly]
|
||||
- "C: A Reference Manual" by Harbison and Steele [Prentice Hall]
|
||||
|
||||
The kernel is written using GNU C and the GNU toolchain. While it
|
||||
adheres to the ISO C89 standard, it uses a number of extensions that are
|
||||
|
|
|
@ -364,7 +364,7 @@ char *make_class_name(const char *name, struct kobject *kobj)
|
|||
|
||||
class_name = kmalloc(size, GFP_KERNEL);
|
||||
if (!class_name)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
return NULL;
|
||||
|
||||
strcpy(class_name, name);
|
||||
strcat(class_name, ":");
|
||||
|
@ -411,8 +411,11 @@ static int make_deprecated_class_device_links(struct class_device *class_dev)
|
|||
return 0;
|
||||
|
||||
class_name = make_class_name(class_dev->class->name, &class_dev->kobj);
|
||||
error = sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj,
|
||||
class_name);
|
||||
if (class_name)
|
||||
error = sysfs_create_link(&class_dev->dev->kobj,
|
||||
&class_dev->kobj, class_name);
|
||||
else
|
||||
error = -ENOMEM;
|
||||
kfree(class_name);
|
||||
return error;
|
||||
}
|
||||
|
@ -425,7 +428,8 @@ static void remove_deprecated_class_device_links(struct class_device *class_dev)
|
|||
return;
|
||||
|
||||
class_name = make_class_name(class_dev->class->name, &class_dev->kobj);
|
||||
sysfs_remove_link(&class_dev->dev->kobj, class_name);
|
||||
if (class_name)
|
||||
sysfs_remove_link(&class_dev->dev->kobj, class_name);
|
||||
kfree(class_name);
|
||||
}
|
||||
#else
|
||||
|
@ -863,9 +867,12 @@ int class_device_rename(struct class_device *class_dev, char *new_name)
|
|||
if (class_dev->dev) {
|
||||
new_class_name = make_class_name(class_dev->class->name,
|
||||
&class_dev->kobj);
|
||||
sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj,
|
||||
new_class_name);
|
||||
sysfs_remove_link(&class_dev->dev->kobj, old_class_name);
|
||||
if (new_class_name)
|
||||
sysfs_create_link(&class_dev->dev->kobj,
|
||||
&class_dev->kobj, new_class_name);
|
||||
if (old_class_name)
|
||||
sysfs_remove_link(&class_dev->dev->kobj,
|
||||
old_class_name);
|
||||
}
|
||||
#endif
|
||||
class_device_put(class_dev);
|
||||
|
|
|
@ -95,6 +95,8 @@ static void device_release(struct kobject * kobj)
|
|||
|
||||
if (dev->release)
|
||||
dev->release(dev);
|
||||
else if (dev->type && dev->type->release)
|
||||
dev->type->release(dev);
|
||||
else if (dev->class && dev->class->dev_release)
|
||||
dev->class->dev_release(dev);
|
||||
else {
|
||||
|
@ -154,25 +156,47 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
|
|||
"MINOR=%u", MINOR(dev->devt));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYSFS_DEPRECATED
|
||||
/* add bus name (same as SUBSYSTEM, deprecated) */
|
||||
if (dev->bus)
|
||||
add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"PHYSDEVBUS=%s", dev->bus->name);
|
||||
#endif
|
||||
|
||||
/* add driver name (PHYSDEV* values are deprecated)*/
|
||||
if (dev->driver) {
|
||||
if (dev->driver)
|
||||
add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"DRIVER=%s", dev->driver->name);
|
||||
|
||||
#ifdef CONFIG_SYSFS_DEPRECATED
|
||||
if (dev->class) {
|
||||
struct device *parent = dev->parent;
|
||||
|
||||
/* find first bus device in parent chain */
|
||||
while (parent && !parent->bus)
|
||||
parent = parent->parent;
|
||||
if (parent && parent->bus) {
|
||||
const char *path;
|
||||
|
||||
path = kobject_get_path(&parent->kobj, GFP_KERNEL);
|
||||
add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"PHYSDEVPATH=%s", path);
|
||||
kfree(path);
|
||||
|
||||
add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"PHYSDEVBUS=%s", parent->bus->name);
|
||||
|
||||
if (parent->driver)
|
||||
add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"PHYSDEVDRIVER=%s", parent->driver->name);
|
||||
}
|
||||
} else if (dev->bus) {
|
||||
add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"PHYSDEVDRIVER=%s", dev->driver->name);
|
||||
#endif
|
||||
"PHYSDEVBUS=%s", dev->bus->name);
|
||||
|
||||
if (dev->driver)
|
||||
add_uevent_var(envp, num_envp, &i,
|
||||
buffer, buffer_size, &length,
|
||||
"PHYSDEVDRIVER=%s", dev->driver->name);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* terminate, set to next free slot, shrink available space */
|
||||
envp[i] = NULL;
|
||||
|
@ -184,19 +208,25 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
|
|||
if (dev->bus && dev->bus->uevent) {
|
||||
/* have the bus specific function add its stuff */
|
||||
retval = dev->bus->uevent(dev, envp, num_envp, buffer, buffer_size);
|
||||
if (retval) {
|
||||
pr_debug ("%s - uevent() returned %d\n",
|
||||
if (retval)
|
||||
pr_debug ("%s: bus uevent() returned %d\n",
|
||||
__FUNCTION__, retval);
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->class && dev->class->dev_uevent) {
|
||||
/* have the class specific function add its stuff */
|
||||
retval = dev->class->dev_uevent(dev, envp, num_envp, buffer, buffer_size);
|
||||
if (retval) {
|
||||
pr_debug("%s - dev_uevent() returned %d\n",
|
||||
__FUNCTION__, retval);
|
||||
}
|
||||
if (retval)
|
||||
pr_debug("%s: class uevent() returned %d\n",
|
||||
__FUNCTION__, retval);
|
||||
}
|
||||
|
||||
if (dev->type && dev->type->uevent) {
|
||||
/* have the device type specific fuction add its stuff */
|
||||
retval = dev->type->uevent(dev, envp, num_envp, buffer, buffer_size);
|
||||
if (retval)
|
||||
pr_debug("%s: dev_type uevent() returned %d\n",
|
||||
__FUNCTION__, retval);
|
||||
}
|
||||
|
||||
return retval;
|
||||
|
@ -247,37 +277,50 @@ static void device_remove_groups(struct device *dev)
|
|||
static int device_add_attrs(struct device *dev)
|
||||
{
|
||||
struct class *class = dev->class;
|
||||
struct device_type *type = dev->type;
|
||||
int error = 0;
|
||||
int i;
|
||||
|
||||
if (!class)
|
||||
return 0;
|
||||
|
||||
if (class->dev_attrs) {
|
||||
if (class && class->dev_attrs) {
|
||||
for (i = 0; attr_name(class->dev_attrs[i]); i++) {
|
||||
error = device_create_file(dev, &class->dev_attrs[i]);
|
||||
if (error)
|
||||
break;
|
||||
}
|
||||
if (error)
|
||||
while (--i >= 0)
|
||||
device_remove_file(dev, &class->dev_attrs[i]);
|
||||
}
|
||||
if (error)
|
||||
while (--i >= 0)
|
||||
device_remove_file(dev, &class->dev_attrs[i]);
|
||||
|
||||
if (type && type->attrs) {
|
||||
for (i = 0; attr_name(type->attrs[i]); i++) {
|
||||
error = device_create_file(dev, &type->attrs[i]);
|
||||
if (error)
|
||||
break;
|
||||
}
|
||||
if (error)
|
||||
while (--i >= 0)
|
||||
device_remove_file(dev, &type->attrs[i]);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static void device_remove_attrs(struct device *dev)
|
||||
{
|
||||
struct class *class = dev->class;
|
||||
struct device_type *type = dev->type;
|
||||
int i;
|
||||
|
||||
if (!class)
|
||||
return;
|
||||
|
||||
if (class->dev_attrs) {
|
||||
if (class && class->dev_attrs) {
|
||||
for (i = 0; attr_name(class->dev_attrs[i]); i++)
|
||||
device_remove_file(dev, &class->dev_attrs[i]);
|
||||
}
|
||||
|
||||
if (type && type->attrs) {
|
||||
for (i = 0; attr_name(type->attrs[i]); i++)
|
||||
device_remove_file(dev, &type->attrs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -390,22 +433,23 @@ void device_initialize(struct device *dev)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_SYSFS_DEPRECATED
|
||||
static int setup_parent(struct device *dev, struct device *parent)
|
||||
static struct kobject * get_device_parent(struct device *dev,
|
||||
struct device *parent)
|
||||
{
|
||||
/* Set the parent to the class, not the parent device */
|
||||
/* this keeps sysfs from having a symlink to make old udevs happy */
|
||||
if (dev->class)
|
||||
dev->kobj.parent = &dev->class->subsys.kset.kobj;
|
||||
return &dev->class->subsys.kset.kobj;
|
||||
else if (parent)
|
||||
dev->kobj.parent = &parent->kobj;
|
||||
return &parent->kobj;
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
static int virtual_device_parent(struct device *dev)
|
||||
static struct kobject * virtual_device_parent(struct device *dev)
|
||||
{
|
||||
if (!dev->class)
|
||||
return -ENODEV;
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
if (!dev->class->virtual_dir) {
|
||||
static struct kobject *virtual_dir = NULL;
|
||||
|
@ -415,25 +459,31 @@ static int virtual_device_parent(struct device *dev)
|
|||
dev->class->virtual_dir = kobject_add_dir(virtual_dir, dev->class->name);
|
||||
}
|
||||
|
||||
dev->kobj.parent = dev->class->virtual_dir;
|
||||
return 0;
|
||||
return dev->class->virtual_dir;
|
||||
}
|
||||
|
||||
static int setup_parent(struct device *dev, struct device *parent)
|
||||
static struct kobject * get_device_parent(struct device *dev,
|
||||
struct device *parent)
|
||||
{
|
||||
int error;
|
||||
|
||||
/* if this is a class device, and has no parent, create one */
|
||||
if ((dev->class) && (parent == NULL)) {
|
||||
error = virtual_device_parent(dev);
|
||||
if (error)
|
||||
return error;
|
||||
return virtual_device_parent(dev);
|
||||
} else if (parent)
|
||||
dev->kobj.parent = &parent->kobj;
|
||||
return &parent->kobj;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
static int setup_parent(struct device *dev, struct device *parent)
|
||||
{
|
||||
struct kobject *kobj;
|
||||
kobj = get_device_parent(dev, parent);
|
||||
if (IS_ERR(kobj))
|
||||
return PTR_ERR(kobj);
|
||||
if (kobj)
|
||||
dev->kobj.parent = kobj;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* device_add - add device to device hierarchy.
|
||||
|
@ -520,9 +570,13 @@ int device_add(struct device *dev)
|
|||
&dev->kobj, dev->bus_id);
|
||||
#ifdef CONFIG_SYSFS_DEPRECATED
|
||||
if (parent) {
|
||||
sysfs_create_link(&dev->kobj, &dev->parent->kobj, "device");
|
||||
class_name = make_class_name(dev->class->name, &dev->kobj);
|
||||
sysfs_create_link(&dev->parent->kobj, &dev->kobj, class_name);
|
||||
sysfs_create_link(&dev->kobj, &dev->parent->kobj,
|
||||
"device");
|
||||
class_name = make_class_name(dev->class->name,
|
||||
&dev->kobj);
|
||||
if (class_name)
|
||||
sysfs_create_link(&dev->parent->kobj,
|
||||
&dev->kobj, class_name);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -535,7 +589,8 @@ int device_add(struct device *dev)
|
|||
goto PMError;
|
||||
if ((error = bus_add_device(dev)))
|
||||
goto BusError;
|
||||
kobject_uevent(&dev->kobj, KOBJ_ADD);
|
||||
if (!dev->uevent_suppress)
|
||||
kobject_uevent(&dev->kobj, KOBJ_ADD);
|
||||
if ((error = bus_attach_device(dev)))
|
||||
goto AttachError;
|
||||
if (parent)
|
||||
|
@ -665,7 +720,9 @@ void device_del(struct device * dev)
|
|||
if (parent) {
|
||||
char *class_name = make_class_name(dev->class->name,
|
||||
&dev->kobj);
|
||||
sysfs_remove_link(&dev->parent->kobj, class_name);
|
||||
if (class_name)
|
||||
sysfs_remove_link(&dev->parent->kobj,
|
||||
class_name);
|
||||
kfree(class_name);
|
||||
sysfs_remove_link(&dev->kobj, "device");
|
||||
}
|
||||
|
@ -968,20 +1025,25 @@ static int device_move_class_links(struct device *dev,
|
|||
|
||||
class_name = make_class_name(dev->class->name, &dev->kobj);
|
||||
if (!class_name) {
|
||||
error = PTR_ERR(class_name);
|
||||
class_name = NULL;
|
||||
error = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
if (old_parent) {
|
||||
sysfs_remove_link(&dev->kobj, "device");
|
||||
sysfs_remove_link(&old_parent->kobj, class_name);
|
||||
}
|
||||
error = sysfs_create_link(&dev->kobj, &new_parent->kobj, "device");
|
||||
if (error)
|
||||
goto out;
|
||||
error = sysfs_create_link(&new_parent->kobj, &dev->kobj, class_name);
|
||||
if (error)
|
||||
sysfs_remove_link(&dev->kobj, "device");
|
||||
if (new_parent) {
|
||||
error = sysfs_create_link(&dev->kobj, &new_parent->kobj,
|
||||
"device");
|
||||
if (error)
|
||||
goto out;
|
||||
error = sysfs_create_link(&new_parent->kobj, &dev->kobj,
|
||||
class_name);
|
||||
if (error)
|
||||
sysfs_remove_link(&dev->kobj, "device");
|
||||
}
|
||||
else
|
||||
error = 0;
|
||||
out:
|
||||
kfree(class_name);
|
||||
return error;
|
||||
|
@ -993,29 +1055,28 @@ static int device_move_class_links(struct device *dev,
|
|||
/**
|
||||
* device_move - moves a device to a new parent
|
||||
* @dev: the pointer to the struct device to be moved
|
||||
* @new_parent: the new parent of the device
|
||||
* @new_parent: the new parent of the device (can by NULL)
|
||||
*/
|
||||
int device_move(struct device *dev, struct device *new_parent)
|
||||
{
|
||||
int error;
|
||||
struct device *old_parent;
|
||||
struct kobject *new_parent_kobj;
|
||||
|
||||
dev = get_device(dev);
|
||||
if (!dev)
|
||||
return -EINVAL;
|
||||
|
||||
if (!device_is_registered(dev)) {
|
||||
error = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
new_parent = get_device(new_parent);
|
||||
if (!new_parent) {
|
||||
error = -EINVAL;
|
||||
new_parent_kobj = get_device_parent (dev, new_parent);
|
||||
if (IS_ERR(new_parent_kobj)) {
|
||||
error = PTR_ERR(new_parent_kobj);
|
||||
put_device(new_parent);
|
||||
goto out;
|
||||
}
|
||||
pr_debug("DEVICE: moving '%s' to '%s'\n", dev->bus_id,
|
||||
new_parent->bus_id);
|
||||
error = kobject_move(&dev->kobj, &new_parent->kobj);
|
||||
new_parent ? new_parent->bus_id : "<NULL>");
|
||||
error = kobject_move(&dev->kobj, new_parent_kobj);
|
||||
if (error) {
|
||||
put_device(new_parent);
|
||||
goto out;
|
||||
|
@ -1024,7 +1085,8 @@ int device_move(struct device *dev, struct device *new_parent)
|
|||
dev->parent = new_parent;
|
||||
if (old_parent)
|
||||
klist_remove(&dev->knode_parent);
|
||||
klist_add_tail(&dev->knode_parent, &new_parent->klist_children);
|
||||
if (new_parent)
|
||||
klist_add_tail(&dev->knode_parent, &new_parent->klist_children);
|
||||
if (!dev->class)
|
||||
goto out_put;
|
||||
error = device_move_class_links(dev, old_parent, new_parent);
|
||||
|
@ -1032,7 +1094,8 @@ int device_move(struct device *dev, struct device *new_parent)
|
|||
/* We ignore errors on cleanup since we're hosed anyway... */
|
||||
device_move_class_links(dev, new_parent, old_parent);
|
||||
if (!kobject_move(&dev->kobj, &old_parent->kobj)) {
|
||||
klist_remove(&dev->knode_parent);
|
||||
if (new_parent)
|
||||
klist_remove(&dev->knode_parent);
|
||||
if (old_parent)
|
||||
klist_add_tail(&dev->knode_parent,
|
||||
&old_parent->klist_children);
|
||||
|
|
|
@ -86,8 +86,12 @@ static void driver_sysfs_remove(struct device *dev)
|
|||
*/
|
||||
int device_bind_driver(struct device *dev)
|
||||
{
|
||||
driver_bound(dev);
|
||||
return driver_sysfs_add(dev);
|
||||
int ret;
|
||||
|
||||
ret = driver_sysfs_add(dev);
|
||||
if (!ret)
|
||||
driver_bound(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct stupid_thread_structure {
|
||||
|
@ -136,18 +140,17 @@ static int really_probe(void *void_data)
|
|||
driver_sysfs_remove(dev);
|
||||
dev->driver = NULL;
|
||||
|
||||
if (ret == -ENODEV || ret == -ENXIO) {
|
||||
/* Driver matched, but didn't support device
|
||||
* or device not found.
|
||||
* Not an error; keep going.
|
||||
*/
|
||||
ret = 0;
|
||||
} else {
|
||||
if (ret != -ENODEV && ret != -ENXIO) {
|
||||
/* driver matched but the probe failed */
|
||||
printk(KERN_WARNING
|
||||
"%s: probe of %s failed with error %d\n",
|
||||
drv->name, dev->bus_id, ret);
|
||||
}
|
||||
/*
|
||||
* Ignore errors returned by ->probe so that the next driver can try
|
||||
* its luck.
|
||||
*/
|
||||
ret = 0;
|
||||
done:
|
||||
kfree(data);
|
||||
atomic_dec(&probe_count);
|
||||
|
|
|
@ -35,7 +35,7 @@ enum {
|
|||
FW_STATUS_READY_NOHOTPLUG,
|
||||
};
|
||||
|
||||
static int loading_timeout = 10; /* In seconds */
|
||||
static int loading_timeout = 60; /* In seconds */
|
||||
|
||||
/* fw_lock could be moved to 'struct firmware_priv' but since it is just
|
||||
* guarding for corner cases a global lock should be OK */
|
||||
|
|
|
@ -611,8 +611,15 @@ EXPORT_SYMBOL_GPL(platform_bus_type);
|
|||
|
||||
int __init platform_bus_init(void)
|
||||
{
|
||||
device_register(&platform_bus);
|
||||
return bus_register(&platform_bus_type);
|
||||
int error;
|
||||
|
||||
error = device_register(&platform_bus);
|
||||
if (error)
|
||||
return error;
|
||||
error = bus_register(&platform_bus_type);
|
||||
if (error)
|
||||
device_unregister(&platform_bus);
|
||||
return error;
|
||||
}
|
||||
|
||||
#ifndef ARCH_HAS_DMA_GET_REQUIRED_MASK
|
||||
|
|
|
@ -783,10 +783,11 @@ static LIST_HEAD(ide_pci_drivers);
|
|||
* Returns are the same as for pci_register_driver
|
||||
*/
|
||||
|
||||
int __ide_pci_register_driver(struct pci_driver *driver, struct module *module)
|
||||
int __ide_pci_register_driver(struct pci_driver *driver, struct module *module,
|
||||
const char *mod_name)
|
||||
{
|
||||
if(!pre_init)
|
||||
return __pci_register_driver(driver, module);
|
||||
return __pci_register_driver(driver, module, mod_name);
|
||||
driver->driver.owner = module;
|
||||
list_add_tail(&driver->node, &ide_pci_drivers);
|
||||
return 0;
|
||||
|
@ -862,6 +863,6 @@ void __init ide_scan_pcibus (int scan_direction)
|
|||
{
|
||||
list_del(l);
|
||||
d = list_entry(l, struct pci_driver, node);
|
||||
__pci_register_driver(d, d->driver.owner);
|
||||
__pci_register_driver(d, d->driver.owner, d->driver.mod_name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -958,16 +958,17 @@ struct ipoib_dev_priv *ipoib_intf_alloc(const char *name)
|
|||
return netdev_priv(dev);
|
||||
}
|
||||
|
||||
static ssize_t show_pkey(struct class_device *cdev, char *buf)
|
||||
static ssize_t show_pkey(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct ipoib_dev_priv *priv =
|
||||
netdev_priv(container_of(cdev, struct net_device, class_dev));
|
||||
struct ipoib_dev_priv *priv = netdev_priv(to_net_dev(dev));
|
||||
|
||||
return sprintf(buf, "0x%04x\n", priv->pkey);
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(pkey, S_IRUGO, show_pkey, NULL);
|
||||
static DEVICE_ATTR(pkey, S_IRUGO, show_pkey, NULL);
|
||||
|
||||
static ssize_t create_child(struct class_device *cdev,
|
||||
static ssize_t create_child(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int pkey;
|
||||
|
@ -985,14 +986,14 @@ static ssize_t create_child(struct class_device *cdev,
|
|||
*/
|
||||
pkey |= 0x8000;
|
||||
|
||||
ret = ipoib_vlan_add(container_of(cdev, struct net_device, class_dev),
|
||||
pkey);
|
||||
ret = ipoib_vlan_add(to_net_dev(dev), pkey);
|
||||
|
||||
return ret ? ret : count;
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(create_child, S_IWUGO, NULL, create_child);
|
||||
static DEVICE_ATTR(create_child, S_IWUGO, NULL, create_child);
|
||||
|
||||
static ssize_t delete_child(struct class_device *cdev,
|
||||
static ssize_t delete_child(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int pkey;
|
||||
|
@ -1004,18 +1005,16 @@ static ssize_t delete_child(struct class_device *cdev,
|
|||
if (pkey < 0 || pkey > 0xffff)
|
||||
return -EINVAL;
|
||||
|
||||
ret = ipoib_vlan_delete(container_of(cdev, struct net_device, class_dev),
|
||||
pkey);
|
||||
ret = ipoib_vlan_delete(to_net_dev(dev), pkey);
|
||||
|
||||
return ret ? ret : count;
|
||||
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(delete_child, S_IWUGO, NULL, delete_child);
|
||||
static DEVICE_ATTR(delete_child, S_IWUGO, NULL, delete_child);
|
||||
|
||||
int ipoib_add_pkey_attr(struct net_device *dev)
|
||||
{
|
||||
return class_device_create_file(&dev->class_dev,
|
||||
&class_device_attr_pkey);
|
||||
return device_create_file(&dev->dev, &dev_attr_pkey);
|
||||
}
|
||||
|
||||
static struct net_device *ipoib_add_port(const char *format,
|
||||
|
@ -1083,11 +1082,9 @@ static struct net_device *ipoib_add_port(const char *format,
|
|||
|
||||
if (ipoib_add_pkey_attr(priv->dev))
|
||||
goto sysfs_failed;
|
||||
if (class_device_create_file(&priv->dev->class_dev,
|
||||
&class_device_attr_create_child))
|
||||
if (device_create_file(&priv->dev->dev, &dev_attr_create_child))
|
||||
goto sysfs_failed;
|
||||
if (class_device_create_file(&priv->dev->class_dev,
|
||||
&class_device_attr_delete_child))
|
||||
if (device_create_file(&priv->dev->dev, &dev_attr_delete_child))
|
||||
goto sysfs_failed;
|
||||
|
||||
return priv->dev;
|
||||
|
|
|
@ -42,15 +42,15 @@
|
|||
|
||||
#include "ipoib.h"
|
||||
|
||||
static ssize_t show_parent(struct class_device *class_dev, char *buf)
|
||||
static ssize_t show_parent(struct device *d, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct net_device *dev =
|
||||
container_of(class_dev, struct net_device, class_dev);
|
||||
struct net_device *dev = to_net_dev(d);
|
||||
struct ipoib_dev_priv *priv = netdev_priv(dev);
|
||||
|
||||
return sprintf(buf, "%s\n", priv->parent->name);
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(parent, S_IRUGO, show_parent, NULL);
|
||||
static DEVICE_ATTR(parent, S_IRUGO, show_parent, NULL);
|
||||
|
||||
int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
|
||||
{
|
||||
|
@ -118,8 +118,7 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
|
|||
if (ipoib_add_pkey_attr(priv->dev))
|
||||
goto sysfs_failed;
|
||||
|
||||
if (class_device_create_file(&priv->dev->class_dev,
|
||||
&class_device_attr_parent))
|
||||
if (device_create_file(&priv->dev->dev, &dev_attr_parent))
|
||||
goto sysfs_failed;
|
||||
|
||||
list_add_tail(&priv->list, &ppriv->child_intfs);
|
||||
|
|
|
@ -45,7 +45,7 @@ EXPORT_SYMBOL(serio_interrupt);
|
|||
EXPORT_SYMBOL(__serio_register_port);
|
||||
EXPORT_SYMBOL(serio_unregister_port);
|
||||
EXPORT_SYMBOL(serio_unregister_child_port);
|
||||
EXPORT_SYMBOL(serio_register_driver);
|
||||
EXPORT_SYMBOL(__serio_register_driver);
|
||||
EXPORT_SYMBOL(serio_unregister_driver);
|
||||
EXPORT_SYMBOL(serio_open);
|
||||
EXPORT_SYMBOL(serio_close);
|
||||
|
@ -789,12 +789,14 @@ static void serio_attach_driver(struct serio_driver *drv)
|
|||
drv->driver.name, error);
|
||||
}
|
||||
|
||||
int serio_register_driver(struct serio_driver *drv)
|
||||
int __serio_register_driver(struct serio_driver *drv, struct module *owner, const char *mod_name)
|
||||
{
|
||||
int manual_bind = drv->manual_bind;
|
||||
int error;
|
||||
|
||||
drv->driver.bus = &serio_bus;
|
||||
drv->driver.owner = owner;
|
||||
drv->driver.mod_name = mod_name;
|
||||
|
||||
/*
|
||||
* Temporarily disable automatic binding because probing
|
||||
|
|
|
@ -641,7 +641,7 @@ static void at91ether_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo
|
|||
{
|
||||
strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
|
||||
strlcpy(info->version, DRV_VERSION, sizeof(info->version));
|
||||
strlcpy(info->bus_info, dev->class_dev.dev->bus_id, sizeof(info->bus_info));
|
||||
strlcpy(info->bus_info, dev->dev.parent->bus_id, sizeof(info->bus_info));
|
||||
}
|
||||
|
||||
static const struct ethtool_ops at91ether_ethtool_ops = {
|
||||
|
|
|
@ -587,7 +587,7 @@ static void etherh_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *i
|
|||
{
|
||||
strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
|
||||
strlcpy(info->version, DRV_VERSION, sizeof(info->version));
|
||||
strlcpy(info->bus_info, dev->class_dev.dev->bus_id,
|
||||
strlcpy(info->bus_info, dev->dev.parent->bus_id,
|
||||
sizeof(info->bus_info));
|
||||
}
|
||||
|
||||
|
|
|
@ -39,8 +39,7 @@
|
|||
|
||||
/* #define BONDING_DEBUG 1 */
|
||||
#include "bonding.h"
|
||||
#define to_class_dev(obj) container_of(obj,struct class_device,kobj)
|
||||
#define to_net_dev(class) container_of(class, struct net_device, class_dev)
|
||||
#define to_dev(obj) container_of(obj,struct device,kobj)
|
||||
#define to_bond(cd) ((struct bonding *)(to_net_dev(cd)->priv))
|
||||
|
||||
/*---------------------------- Declarations -------------------------------*/
|
||||
|
@ -154,7 +153,7 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
|
|||
* If it's > expected, then there's a file open,
|
||||
* and we have to fail.
|
||||
*/
|
||||
if (atomic_read(&bond->dev->class_dev.kobj.kref.refcount)
|
||||
if (atomic_read(&bond->dev->dev.kobj.kref.refcount)
|
||||
> expected_refcount){
|
||||
rtnl_unlock();
|
||||
printk(KERN_INFO DRV_NAME
|
||||
|
@ -201,13 +200,13 @@ int bond_create_slave_symlinks(struct net_device *master, struct net_device *sla
|
|||
int ret = 0;
|
||||
|
||||
/* first, create a link from the slave back to the master */
|
||||
ret = sysfs_create_link(&(slave->class_dev.kobj), &(master->class_dev.kobj),
|
||||
ret = sysfs_create_link(&(slave->dev.kobj), &(master->dev.kobj),
|
||||
"master");
|
||||
if (ret)
|
||||
return ret;
|
||||
/* next, create a link from the master to the slave */
|
||||
sprintf(linkname,"slave_%s",slave->name);
|
||||
ret = sysfs_create_link(&(master->class_dev.kobj), &(slave->class_dev.kobj),
|
||||
ret = sysfs_create_link(&(master->dev.kobj), &(slave->dev.kobj),
|
||||
linkname);
|
||||
return ret;
|
||||
|
||||
|
@ -217,20 +216,21 @@ void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *s
|
|||
{
|
||||
char linkname[IFNAMSIZ+7];
|
||||
|
||||
sysfs_remove_link(&(slave->class_dev.kobj), "master");
|
||||
sysfs_remove_link(&(slave->dev.kobj), "master");
|
||||
sprintf(linkname,"slave_%s",slave->name);
|
||||
sysfs_remove_link(&(master->class_dev.kobj), linkname);
|
||||
sysfs_remove_link(&(master->dev.kobj), linkname);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Show the slaves in the current bond.
|
||||
*/
|
||||
static ssize_t bonding_show_slaves(struct class_device *cd, char *buf)
|
||||
static ssize_t bonding_show_slaves(struct device *d,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct slave *slave;
|
||||
int i, res = 0;
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
read_lock_bh(&bond->lock);
|
||||
bond_for_each_slave(bond, slave, i) {
|
||||
|
@ -254,14 +254,16 @@ static ssize_t bonding_show_slaves(struct class_device *cd, char *buf)
|
|||
* up for this to succeed.
|
||||
* This function is largely the same flow as bonding_update_bonds().
|
||||
*/
|
||||
static ssize_t bonding_store_slaves(struct class_device *cd, const char *buffer, size_t count)
|
||||
static ssize_t bonding_store_slaves(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
const char *buffer, size_t count)
|
||||
{
|
||||
char command[IFNAMSIZ + 1] = { 0, };
|
||||
char *ifname;
|
||||
int i, res, found, ret = count;
|
||||
struct slave *slave;
|
||||
struct net_device *dev = NULL;
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
/* Quick sanity check -- is the bond interface up? */
|
||||
if (!(bond->dev->flags & IFF_UP)) {
|
||||
|
@ -387,25 +389,28 @@ static ssize_t bonding_store_slaves(struct class_device *cd, const char *buffer,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static CLASS_DEVICE_ATTR(slaves, S_IRUGO | S_IWUSR, bonding_show_slaves, bonding_store_slaves);
|
||||
static DEVICE_ATTR(slaves, S_IRUGO | S_IWUSR, bonding_show_slaves, bonding_store_slaves);
|
||||
|
||||
/*
|
||||
* Show and set the bonding mode. The bond interface must be down to
|
||||
* change the mode.
|
||||
*/
|
||||
static ssize_t bonding_show_mode(struct class_device *cd, char *buf)
|
||||
static ssize_t bonding_show_mode(struct device *d,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
return sprintf(buf, "%s %d\n",
|
||||
bond_mode_tbl[bond->params.mode].modename,
|
||||
bond->params.mode) + 1;
|
||||
}
|
||||
|
||||
static ssize_t bonding_store_mode(struct class_device *cd, const char *buf, size_t count)
|
||||
static ssize_t bonding_store_mode(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int new_value, ret = count;
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
if (bond->dev->flags & IFF_UP) {
|
||||
printk(KERN_ERR DRV_NAME
|
||||
|
@ -438,16 +443,18 @@ static ssize_t bonding_store_mode(struct class_device *cd, const char *buf, size
|
|||
out:
|
||||
return ret;
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, bonding_show_mode, bonding_store_mode);
|
||||
static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, bonding_show_mode, bonding_store_mode);
|
||||
|
||||
/*
|
||||
* Show and set the bonding transmit hash method. The bond interface must be down to
|
||||
* change the xmit hash policy.
|
||||
*/
|
||||
static ssize_t bonding_show_xmit_hash(struct class_device *cd, char *buf)
|
||||
static ssize_t bonding_show_xmit_hash(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int count;
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
if ((bond->params.mode != BOND_MODE_XOR) &&
|
||||
(bond->params.mode != BOND_MODE_8023AD)) {
|
||||
|
@ -462,10 +469,12 @@ static ssize_t bonding_show_xmit_hash(struct class_device *cd, char *buf)
|
|||
return count;
|
||||
}
|
||||
|
||||
static ssize_t bonding_store_xmit_hash(struct class_device *cd, const char *buf, size_t count)
|
||||
static ssize_t bonding_store_xmit_hash(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int new_value, ret = count;
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
if (bond->dev->flags & IFF_UP) {
|
||||
printk(KERN_ERR DRV_NAME
|
||||
|
@ -501,24 +510,28 @@ static ssize_t bonding_store_xmit_hash(struct class_device *cd, const char *buf,
|
|||
out:
|
||||
return ret;
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(xmit_hash_policy, S_IRUGO | S_IWUSR, bonding_show_xmit_hash, bonding_store_xmit_hash);
|
||||
static DEVICE_ATTR(xmit_hash_policy, S_IRUGO | S_IWUSR, bonding_show_xmit_hash, bonding_store_xmit_hash);
|
||||
|
||||
/*
|
||||
* Show and set arp_validate.
|
||||
*/
|
||||
static ssize_t bonding_show_arp_validate(struct class_device *cd, char *buf)
|
||||
static ssize_t bonding_show_arp_validate(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
return sprintf(buf, "%s %d\n",
|
||||
arp_validate_tbl[bond->params.arp_validate].modename,
|
||||
bond->params.arp_validate) + 1;
|
||||
}
|
||||
|
||||
static ssize_t bonding_store_arp_validate(struct class_device *cd, const char *buf, size_t count)
|
||||
static ssize_t bonding_store_arp_validate(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int new_value;
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
new_value = bond_parse_parm((char *)buf, arp_validate_tbl);
|
||||
if (new_value < 0) {
|
||||
|
@ -548,7 +561,7 @@ static ssize_t bonding_store_arp_validate(struct class_device *cd, const char *b
|
|||
return count;
|
||||
}
|
||||
|
||||
static CLASS_DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate, bonding_store_arp_validate);
|
||||
static DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate, bonding_store_arp_validate);
|
||||
|
||||
/*
|
||||
* Show and set the arp timer interval. There are two tricky bits
|
||||
|
@ -556,17 +569,21 @@ static CLASS_DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_valid
|
|||
* MII monitoring. Second, if the ARP timer isn't running, we must
|
||||
* start it.
|
||||
*/
|
||||
static ssize_t bonding_show_arp_interval(struct class_device *cd, char *buf)
|
||||
static ssize_t bonding_show_arp_interval(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
return sprintf(buf, "%d\n", bond->params.arp_interval) + 1;
|
||||
}
|
||||
|
||||
static ssize_t bonding_store_arp_interval(struct class_device *cd, const char *buf, size_t count)
|
||||
static ssize_t bonding_store_arp_interval(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int new_value, ret = count;
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
if (sscanf(buf, "%d", &new_value) != 1) {
|
||||
printk(KERN_ERR DRV_NAME
|
||||
|
@ -638,15 +655,17 @@ static ssize_t bonding_store_arp_interval(struct class_device *cd, const char *b
|
|||
out:
|
||||
return ret;
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR , bonding_show_arp_interval, bonding_store_arp_interval);
|
||||
static DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR , bonding_show_arp_interval, bonding_store_arp_interval);
|
||||
|
||||
/*
|
||||
* Show and set the arp targets.
|
||||
*/
|
||||
static ssize_t bonding_show_arp_targets(struct class_device *cd, char *buf)
|
||||
static ssize_t bonding_show_arp_targets(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int i, res = 0;
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
for (i = 0; i < BOND_MAX_ARP_TARGETS; i++) {
|
||||
if (bond->params.arp_targets[i])
|
||||
|
@ -660,11 +679,13 @@ static ssize_t bonding_show_arp_targets(struct class_device *cd, char *buf)
|
|||
return res;
|
||||
}
|
||||
|
||||
static ssize_t bonding_store_arp_targets(struct class_device *cd, const char *buf, size_t count)
|
||||
static ssize_t bonding_store_arp_targets(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
u32 newtarget;
|
||||
int i = 0, done = 0, ret = count;
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
u32 *targets;
|
||||
|
||||
targets = bond->params.arp_targets;
|
||||
|
@ -742,24 +763,28 @@ static ssize_t bonding_store_arp_targets(struct class_device *cd, const char *bu
|
|||
out:
|
||||
return ret;
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(arp_ip_target, S_IRUGO | S_IWUSR , bonding_show_arp_targets, bonding_store_arp_targets);
|
||||
static DEVICE_ATTR(arp_ip_target, S_IRUGO | S_IWUSR , bonding_show_arp_targets, bonding_store_arp_targets);
|
||||
|
||||
/*
|
||||
* Show and set the up and down delays. These must be multiples of the
|
||||
* MII monitoring value, and are stored internally as the multiplier.
|
||||
* Thus, we must translate to MS for the real world.
|
||||
*/
|
||||
static ssize_t bonding_show_downdelay(struct class_device *cd, char *buf)
|
||||
static ssize_t bonding_show_downdelay(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
return sprintf(buf, "%d\n", bond->params.downdelay * bond->params.miimon) + 1;
|
||||
}
|
||||
|
||||
static ssize_t bonding_store_downdelay(struct class_device *cd, const char *buf, size_t count)
|
||||
static ssize_t bonding_store_downdelay(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int new_value, ret = count;
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
if (!(bond->params.miimon)) {
|
||||
printk(KERN_ERR DRV_NAME
|
||||
|
@ -800,20 +825,24 @@ static ssize_t bonding_store_downdelay(struct class_device *cd, const char *buf,
|
|||
out:
|
||||
return ret;
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(downdelay, S_IRUGO | S_IWUSR , bonding_show_downdelay, bonding_store_downdelay);
|
||||
static DEVICE_ATTR(downdelay, S_IRUGO | S_IWUSR , bonding_show_downdelay, bonding_store_downdelay);
|
||||
|
||||
static ssize_t bonding_show_updelay(struct class_device *cd, char *buf)
|
||||
static ssize_t bonding_show_updelay(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
return sprintf(buf, "%d\n", bond->params.updelay * bond->params.miimon) + 1;
|
||||
|
||||
}
|
||||
|
||||
static ssize_t bonding_store_updelay(struct class_device *cd, const char *buf, size_t count)
|
||||
static ssize_t bonding_store_updelay(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int new_value, ret = count;
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
if (!(bond->params.miimon)) {
|
||||
printk(KERN_ERR DRV_NAME
|
||||
|
@ -854,25 +883,29 @@ static ssize_t bonding_store_updelay(struct class_device *cd, const char *buf, s
|
|||
out:
|
||||
return ret;
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(updelay, S_IRUGO | S_IWUSR , bonding_show_updelay, bonding_store_updelay);
|
||||
static DEVICE_ATTR(updelay, S_IRUGO | S_IWUSR , bonding_show_updelay, bonding_store_updelay);
|
||||
|
||||
/*
|
||||
* Show and set the LACP interval. Interface must be down, and the mode
|
||||
* must be set to 802.3ad mode.
|
||||
*/
|
||||
static ssize_t bonding_show_lacp(struct class_device *cd, char *buf)
|
||||
static ssize_t bonding_show_lacp(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
return sprintf(buf, "%s %d\n",
|
||||
bond_lacp_tbl[bond->params.lacp_fast].modename,
|
||||
bond->params.lacp_fast) + 1;
|
||||
}
|
||||
|
||||
static ssize_t bonding_store_lacp(struct class_device *cd, const char *buf, size_t count)
|
||||
static ssize_t bonding_store_lacp(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int new_value, ret = count;
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
if (bond->dev->flags & IFF_UP) {
|
||||
printk(KERN_ERR DRV_NAME
|
||||
|
@ -906,7 +939,7 @@ static ssize_t bonding_store_lacp(struct class_device *cd, const char *buf, size
|
|||
out:
|
||||
return ret;
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR, bonding_show_lacp, bonding_store_lacp);
|
||||
static DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR, bonding_show_lacp, bonding_store_lacp);
|
||||
|
||||
/*
|
||||
* Show and set the MII monitor interval. There are two tricky bits
|
||||
|
@ -914,17 +947,21 @@ static CLASS_DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR, bonding_show_lacp, bondin
|
|||
* ARP monitoring. Second, if the timer isn't running, we must
|
||||
* start it.
|
||||
*/
|
||||
static ssize_t bonding_show_miimon(struct class_device *cd, char *buf)
|
||||
static ssize_t bonding_show_miimon(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
return sprintf(buf, "%d\n", bond->params.miimon) + 1;
|
||||
}
|
||||
|
||||
static ssize_t bonding_store_miimon(struct class_device *cd, const char *buf, size_t count)
|
||||
static ssize_t bonding_store_miimon(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int new_value, ret = count;
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
if (sscanf(buf, "%d", &new_value) != 1) {
|
||||
printk(KERN_ERR DRV_NAME
|
||||
|
@ -1000,7 +1037,7 @@ static ssize_t bonding_store_miimon(struct class_device *cd, const char *buf, si
|
|||
out:
|
||||
return ret;
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR, bonding_show_miimon, bonding_store_miimon);
|
||||
static DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR, bonding_show_miimon, bonding_store_miimon);
|
||||
|
||||
/*
|
||||
* Show and set the primary slave. The store function is much
|
||||
|
@ -1009,10 +1046,12 @@ static CLASS_DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR, bonding_show_miimon, bonding
|
|||
* The bond must be a mode that supports a primary for this be
|
||||
* set.
|
||||
*/
|
||||
static ssize_t bonding_show_primary(struct class_device *cd, char *buf)
|
||||
static ssize_t bonding_show_primary(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int count = 0;
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
if (bond->primary_slave)
|
||||
count = sprintf(buf, "%s\n", bond->primary_slave->dev->name) + 1;
|
||||
|
@ -1022,11 +1061,13 @@ static ssize_t bonding_show_primary(struct class_device *cd, char *buf)
|
|||
return count;
|
||||
}
|
||||
|
||||
static ssize_t bonding_store_primary(struct class_device *cd, const char *buf, size_t count)
|
||||
static ssize_t bonding_store_primary(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int i;
|
||||
struct slave *slave;
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
write_lock_bh(&bond->lock);
|
||||
if (!USES_PRIMARY(bond->params.mode)) {
|
||||
|
@ -1065,22 +1106,26 @@ static ssize_t bonding_store_primary(struct class_device *cd, const char *buf, s
|
|||
write_unlock_bh(&bond->lock);
|
||||
return count;
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(primary, S_IRUGO | S_IWUSR, bonding_show_primary, bonding_store_primary);
|
||||
static DEVICE_ATTR(primary, S_IRUGO | S_IWUSR, bonding_show_primary, bonding_store_primary);
|
||||
|
||||
/*
|
||||
* Show and set the use_carrier flag.
|
||||
*/
|
||||
static ssize_t bonding_show_carrier(struct class_device *cd, char *buf)
|
||||
static ssize_t bonding_show_carrier(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
return sprintf(buf, "%d\n", bond->params.use_carrier) + 1;
|
||||
}
|
||||
|
||||
static ssize_t bonding_store_carrier(struct class_device *cd, const char *buf, size_t count)
|
||||
static ssize_t bonding_store_carrier(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int new_value, ret = count;
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
|
||||
if (sscanf(buf, "%d", &new_value) != 1) {
|
||||
|
@ -1102,16 +1147,18 @@ static ssize_t bonding_store_carrier(struct class_device *cd, const char *buf, s
|
|||
out:
|
||||
return count;
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(use_carrier, S_IRUGO | S_IWUSR, bonding_show_carrier, bonding_store_carrier);
|
||||
static DEVICE_ATTR(use_carrier, S_IRUGO | S_IWUSR, bonding_show_carrier, bonding_store_carrier);
|
||||
|
||||
|
||||
/*
|
||||
* Show and set currently active_slave.
|
||||
*/
|
||||
static ssize_t bonding_show_active_slave(struct class_device *cd, char *buf)
|
||||
static ssize_t bonding_show_active_slave(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct slave *curr;
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
int count;
|
||||
|
||||
|
||||
|
@ -1126,13 +1173,15 @@ static ssize_t bonding_show_active_slave(struct class_device *cd, char *buf)
|
|||
return count;
|
||||
}
|
||||
|
||||
static ssize_t bonding_store_active_slave(struct class_device *cd, const char *buf, size_t count)
|
||||
static ssize_t bonding_store_active_slave(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int i;
|
||||
struct slave *slave;
|
||||
struct slave *old_active = NULL;
|
||||
struct slave *new_active = NULL;
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
write_lock_bh(&bond->lock);
|
||||
if (!USES_PRIMARY(bond->params.mode)) {
|
||||
|
@ -1194,16 +1243,18 @@ static ssize_t bonding_store_active_slave(struct class_device *cd, const char *b
|
|||
return count;
|
||||
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(active_slave, S_IRUGO | S_IWUSR, bonding_show_active_slave, bonding_store_active_slave);
|
||||
static DEVICE_ATTR(active_slave, S_IRUGO | S_IWUSR, bonding_show_active_slave, bonding_store_active_slave);
|
||||
|
||||
|
||||
/*
|
||||
* Show link status of the bond interface.
|
||||
*/
|
||||
static ssize_t bonding_show_mii_status(struct class_device *cd, char *buf)
|
||||
static ssize_t bonding_show_mii_status(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct slave *curr;
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
read_lock(&bond->curr_slave_lock);
|
||||
curr = bond->curr_active_slave;
|
||||
|
@ -1211,16 +1262,18 @@ static ssize_t bonding_show_mii_status(struct class_device *cd, char *buf)
|
|||
|
||||
return sprintf(buf, "%s\n", (curr) ? "up" : "down") + 1;
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(mii_status, S_IRUGO, bonding_show_mii_status, NULL);
|
||||
static DEVICE_ATTR(mii_status, S_IRUGO, bonding_show_mii_status, NULL);
|
||||
|
||||
|
||||
/*
|
||||
* Show current 802.3ad aggregator ID.
|
||||
*/
|
||||
static ssize_t bonding_show_ad_aggregator(struct class_device *cd, char *buf)
|
||||
static ssize_t bonding_show_ad_aggregator(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int count = 0;
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
if (bond->params.mode == BOND_MODE_8023AD) {
|
||||
struct ad_info ad_info;
|
||||
|
@ -1231,16 +1284,18 @@ static ssize_t bonding_show_ad_aggregator(struct class_device *cd, char *buf)
|
|||
|
||||
return count;
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(ad_aggregator, S_IRUGO, bonding_show_ad_aggregator, NULL);
|
||||
static DEVICE_ATTR(ad_aggregator, S_IRUGO, bonding_show_ad_aggregator, NULL);
|
||||
|
||||
|
||||
/*
|
||||
* Show number of active 802.3ad ports.
|
||||
*/
|
||||
static ssize_t bonding_show_ad_num_ports(struct class_device *cd, char *buf)
|
||||
static ssize_t bonding_show_ad_num_ports(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int count = 0;
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
if (bond->params.mode == BOND_MODE_8023AD) {
|
||||
struct ad_info ad_info;
|
||||
|
@ -1251,16 +1306,18 @@ static ssize_t bonding_show_ad_num_ports(struct class_device *cd, char *buf)
|
|||
|
||||
return count;
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(ad_num_ports, S_IRUGO, bonding_show_ad_num_ports, NULL);
|
||||
static DEVICE_ATTR(ad_num_ports, S_IRUGO, bonding_show_ad_num_ports, NULL);
|
||||
|
||||
|
||||
/*
|
||||
* Show current 802.3ad actor key.
|
||||
*/
|
||||
static ssize_t bonding_show_ad_actor_key(struct class_device *cd, char *buf)
|
||||
static ssize_t bonding_show_ad_actor_key(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int count = 0;
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
if (bond->params.mode == BOND_MODE_8023AD) {
|
||||
struct ad_info ad_info;
|
||||
|
@ -1271,16 +1328,18 @@ static ssize_t bonding_show_ad_actor_key(struct class_device *cd, char *buf)
|
|||
|
||||
return count;
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(ad_actor_key, S_IRUGO, bonding_show_ad_actor_key, NULL);
|
||||
static DEVICE_ATTR(ad_actor_key, S_IRUGO, bonding_show_ad_actor_key, NULL);
|
||||
|
||||
|
||||
/*
|
||||
* Show current 802.3ad partner key.
|
||||
*/
|
||||
static ssize_t bonding_show_ad_partner_key(struct class_device *cd, char *buf)
|
||||
static ssize_t bonding_show_ad_partner_key(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int count = 0;
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
if (bond->params.mode == BOND_MODE_8023AD) {
|
||||
struct ad_info ad_info;
|
||||
|
@ -1291,16 +1350,18 @@ static ssize_t bonding_show_ad_partner_key(struct class_device *cd, char *buf)
|
|||
|
||||
return count;
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(ad_partner_key, S_IRUGO, bonding_show_ad_partner_key, NULL);
|
||||
static DEVICE_ATTR(ad_partner_key, S_IRUGO, bonding_show_ad_partner_key, NULL);
|
||||
|
||||
|
||||
/*
|
||||
* Show current 802.3ad partner mac.
|
||||
*/
|
||||
static ssize_t bonding_show_ad_partner_mac(struct class_device *cd, char *buf)
|
||||
static ssize_t bonding_show_ad_partner_mac(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
int count = 0;
|
||||
struct bonding *bond = to_bond(cd);
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
if (bond->params.mode == BOND_MODE_8023AD) {
|
||||
struct ad_info ad_info;
|
||||
|
@ -1319,30 +1380,30 @@ static ssize_t bonding_show_ad_partner_mac(struct class_device *cd, char *buf)
|
|||
|
||||
return count;
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, NULL);
|
||||
static DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, NULL);
|
||||
|
||||
|
||||
|
||||
static struct attribute *per_bond_attrs[] = {
|
||||
&class_device_attr_slaves.attr,
|
||||
&class_device_attr_mode.attr,
|
||||
&class_device_attr_arp_validate.attr,
|
||||
&class_device_attr_arp_interval.attr,
|
||||
&class_device_attr_arp_ip_target.attr,
|
||||
&class_device_attr_downdelay.attr,
|
||||
&class_device_attr_updelay.attr,
|
||||
&class_device_attr_lacp_rate.attr,
|
||||
&class_device_attr_xmit_hash_policy.attr,
|
||||
&class_device_attr_miimon.attr,
|
||||
&class_device_attr_primary.attr,
|
||||
&class_device_attr_use_carrier.attr,
|
||||
&class_device_attr_active_slave.attr,
|
||||
&class_device_attr_mii_status.attr,
|
||||
&class_device_attr_ad_aggregator.attr,
|
||||
&class_device_attr_ad_num_ports.attr,
|
||||
&class_device_attr_ad_actor_key.attr,
|
||||
&class_device_attr_ad_partner_key.attr,
|
||||
&class_device_attr_ad_partner_mac.attr,
|
||||
&dev_attr_slaves.attr,
|
||||
&dev_attr_mode.attr,
|
||||
&dev_attr_arp_validate.attr,
|
||||
&dev_attr_arp_interval.attr,
|
||||
&dev_attr_arp_ip_target.attr,
|
||||
&dev_attr_downdelay.attr,
|
||||
&dev_attr_updelay.attr,
|
||||
&dev_attr_lacp_rate.attr,
|
||||
&dev_attr_xmit_hash_policy.attr,
|
||||
&dev_attr_miimon.attr,
|
||||
&dev_attr_primary.attr,
|
||||
&dev_attr_use_carrier.attr,
|
||||
&dev_attr_active_slave.attr,
|
||||
&dev_attr_mii_status.attr,
|
||||
&dev_attr_ad_aggregator.attr,
|
||||
&dev_attr_ad_num_ports.attr,
|
||||
&dev_attr_ad_actor_key.attr,
|
||||
&dev_attr_ad_partner_key.attr,
|
||||
&dev_attr_ad_partner_mac.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
@ -1367,7 +1428,7 @@ int bond_create_sysfs(void)
|
|||
if (!firstbond)
|
||||
return -ENODEV;
|
||||
|
||||
netdev_class = firstbond->dev->class_dev.class;
|
||||
netdev_class = firstbond->dev->dev.class;
|
||||
if (!netdev_class)
|
||||
return -ENODEV;
|
||||
|
||||
|
@ -1410,13 +1471,13 @@ int bond_create_sysfs_entry(struct bonding *bond)
|
|||
struct net_device *dev = bond->dev;
|
||||
int err;
|
||||
|
||||
err = sysfs_create_group(&(dev->class_dev.kobj), &bonding_group);
|
||||
err = sysfs_create_group(&(dev->dev.kobj), &bonding_group);
|
||||
if (err) {
|
||||
printk(KERN_EMERG "eek! didn't create group!\n");
|
||||
}
|
||||
|
||||
if (expected_refcount < 1)
|
||||
expected_refcount = atomic_read(&bond->dev->class_dev.kobj.kref.refcount);
|
||||
expected_refcount = atomic_read(&bond->dev->dev.kobj.kref.refcount);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -1427,6 +1488,6 @@ void bond_destroy_sysfs_entry(struct bonding *bond)
|
|||
{
|
||||
struct net_device *dev = bond->dev;
|
||||
|
||||
sysfs_remove_group(&(dev->class_dev.kobj), &bonding_group);
|
||||
sysfs_remove_group(&(dev->dev.kobj), &bonding_group);
|
||||
}
|
||||
|
||||
|
|
|
@ -1102,7 +1102,7 @@ static struct net_device * __init veth_probe_one(int vlan,
|
|||
}
|
||||
|
||||
kobject_init(&port->kobject);
|
||||
port->kobject.parent = &dev->class_dev.kobj;
|
||||
port->kobject.parent = &dev->dev.kobj;
|
||||
port->kobject.ktype = &veth_port_ktype;
|
||||
kobject_set_name(&port->kobject, "veth_port");
|
||||
if (0 != kobject_add(&port->kobject))
|
||||
|
|
|
@ -27,8 +27,6 @@
|
|||
|
||||
#include "macb.h"
|
||||
|
||||
#define to_net_dev(class) container_of(class, struct net_device, class_dev)
|
||||
|
||||
#define RX_BUFFER_SIZE 128
|
||||
#define RX_RING_SIZE 512
|
||||
#define RX_RING_BYTES (sizeof(struct dma_desc) * RX_RING_SIZE)
|
||||
|
@ -945,10 +943,10 @@ static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t macb_mii_show(const struct class_device *cd, char *buf,
|
||||
static ssize_t macb_mii_show(const struct device *_dev, char *buf,
|
||||
unsigned long addr)
|
||||
{
|
||||
struct net_device *dev = to_net_dev(cd);
|
||||
struct net_device *dev = to_net_dev(_dev);
|
||||
struct macb *bp = netdev_priv(dev);
|
||||
ssize_t ret = -EINVAL;
|
||||
|
||||
|
@ -962,11 +960,13 @@ static ssize_t macb_mii_show(const struct class_device *cd, char *buf,
|
|||
}
|
||||
|
||||
#define MII_ENTRY(name, addr) \
|
||||
static ssize_t show_##name(struct class_device *cd, char *buf) \
|
||||
static ssize_t show_##name(struct device *_dev, \
|
||||
struct device_attribute *attr, \
|
||||
char *buf) \
|
||||
{ \
|
||||
return macb_mii_show(cd, buf, addr); \
|
||||
return macb_mii_show(_dev, buf, addr); \
|
||||
} \
|
||||
static CLASS_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
|
||||
static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
|
||||
|
||||
MII_ENTRY(bmcr, MII_BMCR);
|
||||
MII_ENTRY(bmsr, MII_BMSR);
|
||||
|
@ -977,13 +977,13 @@ MII_ENTRY(lpa, MII_LPA);
|
|||
MII_ENTRY(expansion, MII_EXPANSION);
|
||||
|
||||
static struct attribute *macb_mii_attrs[] = {
|
||||
&class_device_attr_bmcr.attr,
|
||||
&class_device_attr_bmsr.attr,
|
||||
&class_device_attr_physid1.attr,
|
||||
&class_device_attr_physid2.attr,
|
||||
&class_device_attr_advertise.attr,
|
||||
&class_device_attr_lpa.attr,
|
||||
&class_device_attr_expansion.attr,
|
||||
&dev_attr_bmcr.attr,
|
||||
&dev_attr_bmsr.attr,
|
||||
&dev_attr_physid1.attr,
|
||||
&dev_attr_physid2.attr,
|
||||
&dev_attr_advertise.attr,
|
||||
&dev_attr_lpa.attr,
|
||||
&dev_attr_expansion.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
@ -994,17 +994,17 @@ static struct attribute_group macb_mii_group = {
|
|||
|
||||
static void macb_unregister_sysfs(struct net_device *net)
|
||||
{
|
||||
struct class_device *class_dev = &net->class_dev;
|
||||
struct device *_dev = &net->dev;
|
||||
|
||||
sysfs_remove_group(&class_dev->kobj, &macb_mii_group);
|
||||
sysfs_remove_group(&_dev->kobj, &macb_mii_group);
|
||||
}
|
||||
|
||||
static int macb_register_sysfs(struct net_device *net)
|
||||
{
|
||||
struct class_device *class_dev = &net->class_dev;
|
||||
struct device *_dev = &net->dev;
|
||||
int ret;
|
||||
|
||||
ret = sysfs_create_group(&class_dev->kobj, &macb_mii_group);
|
||||
ret = sysfs_create_group(&_dev->kobj, &macb_mii_group);
|
||||
if (ret)
|
||||
printk(KERN_WARNING
|
||||
"%s: sysfs mii attribute registration failed: %d\n",
|
||||
|
|
|
@ -1659,7 +1659,7 @@ smc911x_ethtool_getdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
|
|||
{
|
||||
strncpy(info->driver, CARDNAME, sizeof(info->driver));
|
||||
strncpy(info->version, version, sizeof(info->version));
|
||||
strncpy(info->bus_info, dev->class_dev.dev->bus_id, sizeof(info->bus_info));
|
||||
strncpy(info->bus_info, dev->dev.parent->bus_id, sizeof(info->bus_info));
|
||||
}
|
||||
|
||||
static int smc911x_ethtool_nwayreset(struct net_device *dev)
|
||||
|
|
|
@ -1712,7 +1712,7 @@ smc_ethtool_getdrvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
|
|||
{
|
||||
strncpy(info->driver, CARDNAME, sizeof(info->driver));
|
||||
strncpy(info->version, version, sizeof(info->version));
|
||||
strncpy(info->bus_info, dev->class_dev.dev->bus_id, sizeof(info->bus_info));
|
||||
strncpy(info->bus_info, dev->dev.parent->bus_id, sizeof(info->bus_info));
|
||||
}
|
||||
|
||||
static int smc_ethtool_nwayreset(struct net_device *dev)
|
||||
|
|
|
@ -84,7 +84,7 @@ struct net_device * hostap_add_interface(struct local_info *local,
|
|||
if (strchr(dev->name, '%'))
|
||||
ret = dev_alloc_name(dev, dev->name);
|
||||
|
||||
SET_NETDEV_DEV(dev, mdev->class_dev.dev);
|
||||
SET_NETDEV_DEV(dev, mdev->dev.parent);
|
||||
if (ret >= 0)
|
||||
ret = register_netdevice(dev);
|
||||
|
||||
|
|
|
@ -4293,8 +4293,8 @@ static void orinoco_get_drvinfo(struct net_device *dev,
|
|||
strncpy(info->driver, DRIVER_NAME, sizeof(info->driver) - 1);
|
||||
strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 1);
|
||||
strncpy(info->fw_version, priv->fw_name, sizeof(info->fw_version) - 1);
|
||||
if (dev->class_dev.dev)
|
||||
strncpy(info->bus_info, dev->class_dev.dev->bus_id,
|
||||
if (dev->dev.parent)
|
||||
strncpy(info->bus_info, dev->dev.parent->bus_id,
|
||||
sizeof(info->bus_info) - 1);
|
||||
else
|
||||
snprintf(info->bus_info, sizeof(info->bus_info) - 1,
|
||||
|
|
|
@ -332,7 +332,7 @@ orinoco_cs_config(struct pcmcia_device *link)
|
|||
|
||||
/* Finally, report what we've done */
|
||||
printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s, irq %d, io "
|
||||
"0x%04x-0x%04x\n", dev->name, dev->class_dev.dev->bus_id,
|
||||
"0x%04x-0x%04x\n", dev->name, dev->dev.parent->bus_id,
|
||||
link->irq.AssignedIRQ, link->io.BasePort1,
|
||||
link->io.BasePort1 + link->io.NumPorts1 - 1);
|
||||
|
||||
|
|
|
@ -806,7 +806,7 @@ spectrum_cs_config(struct pcmcia_device *link)
|
|||
|
||||
/* Finally, report what we've done */
|
||||
printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s, irq %d, io "
|
||||
"0x%04x-0x%04x\n", dev->name, dev->class_dev.dev->bus_id,
|
||||
"0x%04x-0x%04x\n", dev->name, dev->dev.parent->bus_id,
|
||||
link->irq.AssignedIRQ, link->io.BasePort1,
|
||||
link->io.BasePort1 + link->io.NumPorts1 - 1);
|
||||
|
||||
|
|
|
@ -422,7 +422,8 @@ static struct kobj_type pci_driver_kobj_type = {
|
|||
* If no error occurred, the driver remains registered even if
|
||||
* no device was claimed during registration.
|
||||
*/
|
||||
int __pci_register_driver(struct pci_driver *drv, struct module *owner)
|
||||
int __pci_register_driver(struct pci_driver *drv, struct module *owner,
|
||||
const char *mod_name)
|
||||
{
|
||||
int error;
|
||||
|
||||
|
@ -430,6 +431,7 @@ int __pci_register_driver(struct pci_driver *drv, struct module *owner)
|
|||
drv->driver.name = drv->name;
|
||||
drv->driver.bus = &pci_bus_type;
|
||||
drv->driver.owner = owner;
|
||||
drv->driver.mod_name = mod_name;
|
||||
drv->driver.kobj.ktype = &pci_driver_kobj_type;
|
||||
|
||||
if (pci_multithread_probe)
|
||||
|
|
|
@ -110,7 +110,7 @@ int pcmcia_socket_dev_suspend(struct device *dev, pm_message_t state)
|
|||
|
||||
down_read(&pcmcia_socket_list_rwsem);
|
||||
list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
|
||||
if (socket->dev.dev != dev)
|
||||
if (socket->dev.parent != dev)
|
||||
continue;
|
||||
mutex_lock(&socket->skt_mutex);
|
||||
socket_suspend(socket);
|
||||
|
@ -128,7 +128,7 @@ int pcmcia_socket_dev_resume(struct device *dev)
|
|||
|
||||
down_read(&pcmcia_socket_list_rwsem);
|
||||
list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
|
||||
if (socket->dev.dev != dev)
|
||||
if (socket->dev.parent != dev)
|
||||
continue;
|
||||
mutex_lock(&socket->skt_mutex);
|
||||
socket_resume(socket);
|
||||
|
@ -143,12 +143,12 @@ EXPORT_SYMBOL(pcmcia_socket_dev_resume);
|
|||
|
||||
struct pcmcia_socket * pcmcia_get_socket(struct pcmcia_socket *skt)
|
||||
{
|
||||
struct class_device *cl_dev = class_device_get(&skt->dev);
|
||||
if (!cl_dev)
|
||||
struct device *dev = get_device(&skt->dev);
|
||||
if (!dev)
|
||||
return NULL;
|
||||
skt = class_get_devdata(cl_dev);
|
||||
skt = dev_get_drvdata(dev);
|
||||
if (!try_module_get(skt->owner)) {
|
||||
class_device_put(&skt->dev);
|
||||
put_device(&skt->dev);
|
||||
return NULL;
|
||||
}
|
||||
return (skt);
|
||||
|
@ -159,14 +159,14 @@ EXPORT_SYMBOL(pcmcia_get_socket);
|
|||
void pcmcia_put_socket(struct pcmcia_socket *skt)
|
||||
{
|
||||
module_put(skt->owner);
|
||||
class_device_put(&skt->dev);
|
||||
put_device(&skt->dev);
|
||||
}
|
||||
EXPORT_SYMBOL(pcmcia_put_socket);
|
||||
|
||||
|
||||
static void pcmcia_release_socket(struct class_device *class_dev)
|
||||
static void pcmcia_release_socket(struct device *dev)
|
||||
{
|
||||
struct pcmcia_socket *socket = class_get_devdata(class_dev);
|
||||
struct pcmcia_socket *socket = dev_get_drvdata(dev);
|
||||
|
||||
complete(&socket->socket_released);
|
||||
}
|
||||
|
@ -181,7 +181,7 @@ int pcmcia_register_socket(struct pcmcia_socket *socket)
|
|||
struct task_struct *tsk;
|
||||
int ret;
|
||||
|
||||
if (!socket || !socket->ops || !socket->dev.dev || !socket->resource_ops)
|
||||
if (!socket || !socket->ops || !socket->dev.parent || !socket->resource_ops)
|
||||
return -EINVAL;
|
||||
|
||||
cs_dbg(socket, 0, "pcmcia_register_socket(0x%p)\n", socket->ops);
|
||||
|
@ -226,9 +226,9 @@ int pcmcia_register_socket(struct pcmcia_socket *socket)
|
|||
#endif
|
||||
|
||||
/* set proper values in socket->dev */
|
||||
socket->dev.class_data = socket;
|
||||
dev_set_drvdata(&socket->dev, socket);
|
||||
socket->dev.class = &pcmcia_socket_class;
|
||||
snprintf(socket->dev.class_id, BUS_ID_SIZE, "pcmcia_socket%u", socket->sock);
|
||||
snprintf(socket->dev.bus_id, BUS_ID_SIZE, "pcmcia_socket%u", socket->sock);
|
||||
|
||||
/* base address = 0, map = 0 */
|
||||
socket->cis_mem.flags = 0;
|
||||
|
@ -640,7 +640,7 @@ static int pccardd(void *__skt)
|
|||
skt->ops->set_socket(skt, &skt->socket);
|
||||
|
||||
/* register with the device core */
|
||||
ret = class_device_register(&skt->dev);
|
||||
ret = device_register(&skt->dev);
|
||||
if (ret) {
|
||||
printk(KERN_WARNING "PCMCIA: unable to register socket 0x%p\n",
|
||||
skt);
|
||||
|
@ -689,7 +689,7 @@ static int pccardd(void *__skt)
|
|||
remove_wait_queue(&skt->thread_wait, &wait);
|
||||
|
||||
/* remove from the device core */
|
||||
class_device_unregister(&skt->dev);
|
||||
device_unregister(&skt->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -904,7 +904,7 @@ int pcmcia_insert_card(struct pcmcia_socket *skt)
|
|||
EXPORT_SYMBOL(pcmcia_insert_card);
|
||||
|
||||
|
||||
static int pcmcia_socket_uevent(struct class_device *dev, char **envp,
|
||||
static int pcmcia_socket_uevent(struct device *dev, char **envp,
|
||||
int num_envp, char *buffer, int buffer_size)
|
||||
{
|
||||
struct pcmcia_socket *s = container_of(dev, struct pcmcia_socket, dev);
|
||||
|
@ -930,8 +930,8 @@ static void pcmcia_release_socket_class(struct class *data)
|
|||
|
||||
struct class pcmcia_socket_class = {
|
||||
.name = "pcmcia_socket",
|
||||
.uevent = pcmcia_socket_uevent,
|
||||
.release = pcmcia_release_socket,
|
||||
.dev_uevent = pcmcia_socket_uevent,
|
||||
.dev_release = pcmcia_release_socket,
|
||||
.class_release = pcmcia_release_socket_class,
|
||||
};
|
||||
EXPORT_SYMBOL(pcmcia_socket_class);
|
||||
|
|
|
@ -142,7 +142,7 @@ struct pcmcia_callback{
|
|||
|
||||
int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c);
|
||||
|
||||
#define cs_socket_name(skt) ((skt)->dev.class_id)
|
||||
#define cs_socket_name(skt) ((skt)->dev.bus_id)
|
||||
|
||||
#ifdef DEBUG
|
||||
extern int cs_debug_level(int);
|
||||
|
@ -158,6 +158,6 @@ extern int cs_debug_level(int);
|
|||
#endif
|
||||
|
||||
#define cs_err(skt, fmt, arg...) \
|
||||
printk(KERN_ERR "cs: %s: " fmt, (skt)->dev.class_id , ## arg)
|
||||
printk(KERN_ERR "cs: %s: " fmt, (skt)->dev.bus_id , ## arg)
|
||||
|
||||
#endif /* _LINUX_CS_INTERNAL_H */
|
||||
|
|
|
@ -572,7 +572,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
|
|||
p_dev->func = function;
|
||||
|
||||
p_dev->dev.bus = &pcmcia_bus_type;
|
||||
p_dev->dev.parent = s->dev.dev;
|
||||
p_dev->dev.parent = s->dev.parent;
|
||||
p_dev->dev.release = pcmcia_release_dev;
|
||||
bus_id_len = sprintf (p_dev->dev.bus_id, "%d.%d", p_dev->socket->sock, p_dev->device_no);
|
||||
|
||||
|
@ -1328,10 +1328,10 @@ static struct pcmcia_callback pcmcia_bus_callback = {
|
|||
.resume = pcmcia_bus_resume,
|
||||
};
|
||||
|
||||
static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev,
|
||||
static int __devinit pcmcia_bus_add_socket(struct device *dev,
|
||||
struct class_interface *class_intf)
|
||||
{
|
||||
struct pcmcia_socket *socket = class_get_devdata(class_dev);
|
||||
struct pcmcia_socket *socket = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
socket = pcmcia_get_socket(socket);
|
||||
|
@ -1364,10 +1364,10 @@ static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void pcmcia_bus_remove_socket(struct class_device *class_dev,
|
||||
static void pcmcia_bus_remove_socket(struct device *dev,
|
||||
struct class_interface *class_intf)
|
||||
{
|
||||
struct pcmcia_socket *socket = class_get_devdata(class_dev);
|
||||
struct pcmcia_socket *socket = dev_get_drvdata(dev);
|
||||
|
||||
if (!socket)
|
||||
return;
|
||||
|
@ -1389,8 +1389,8 @@ static void pcmcia_bus_remove_socket(struct class_device *class_dev,
|
|||
/* the pcmcia_bus_interface is used to handle pcmcia socket devices */
|
||||
static struct class_interface pcmcia_bus_interface = {
|
||||
.class = &pcmcia_socket_class,
|
||||
.add = &pcmcia_bus_add_socket,
|
||||
.remove = &pcmcia_bus_remove_socket,
|
||||
.add_dev = &pcmcia_bus_add_socket,
|
||||
.remove_dev = &pcmcia_bus_remove_socket,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -161,7 +161,7 @@ static int __devinit i82092aa_pci_probe(struct pci_dev *dev, const struct pci_de
|
|||
pci_set_drvdata(dev, &sockets[i].socket);
|
||||
|
||||
for (i = 0; i<socket_count; i++) {
|
||||
sockets[i].socket.dev.dev = &dev->dev;
|
||||
sockets[i].socket.dev.parent = &dev->dev;
|
||||
sockets[i].socket.ops = &i82092aa_operations;
|
||||
sockets[i].socket.resource_ops = &pccard_nonstatic_ops;
|
||||
ret = pcmcia_register_socket(&sockets[i].socket);
|
||||
|
|
|
@ -1298,7 +1298,7 @@ static int __init init_i82365(void)
|
|||
|
||||
/* register sockets with the pcmcia core */
|
||||
for (i = 0; i < sockets; i++) {
|
||||
socket[i].socket.dev.dev = &i82365_device->dev;
|
||||
socket[i].socket.dev.parent = &i82365_device->dev;
|
||||
socket[i].socket.ops = &pcic_operations;
|
||||
socket[i].socket.resource_ops = &pccard_nonstatic_ops;
|
||||
socket[i].socket.owner = THIS_MODULE;
|
||||
|
|
|
@ -59,7 +59,6 @@ typedef struct user_info_t {
|
|||
|
||||
#ifdef DEBUG
|
||||
extern int ds_pc_debug;
|
||||
#define cs_socket_name(skt) ((skt)->dev.class_id)
|
||||
|
||||
#define ds_dbg(lvl, fmt, arg...) do { \
|
||||
if (ds_pc_debug >= lvl) \
|
||||
|
|
|
@ -48,7 +48,6 @@ static u8 pcmcia_used_irq[NR_IRQS];
|
|||
|
||||
#ifdef DEBUG
|
||||
extern int ds_pc_debug;
|
||||
#define cs_socket_name(skt) ((skt)->dev.class_id)
|
||||
|
||||
#define ds_dbg(skt, lvl, fmt, arg...) do { \
|
||||
if (ds_pc_debug >= lvl) \
|
||||
|
|
|
@ -682,7 +682,7 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
|
|||
|
||||
socket[i].socket.ops = &pd6729_operations;
|
||||
socket[i].socket.resource_ops = &pccard_nonstatic_ops;
|
||||
socket[i].socket.dev.dev = &dev->dev;
|
||||
socket[i].socket.dev.parent = &dev->dev;
|
||||
socket[i].socket.driver_data = &socket[i];
|
||||
}
|
||||
|
||||
|
|
|
@ -616,7 +616,7 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star
|
|||
static struct resource *nonstatic_find_io_region(unsigned long base, int num,
|
||||
unsigned long align, struct pcmcia_socket *s)
|
||||
{
|
||||
struct resource *res = make_resource(0, num, IORESOURCE_IO, s->dev.class_id);
|
||||
struct resource *res = make_resource(0, num, IORESOURCE_IO, s->dev.bus_id);
|
||||
struct socket_data *s_data = s->resource_data;
|
||||
struct pcmcia_align_data data;
|
||||
unsigned long min = base;
|
||||
|
@ -650,7 +650,7 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num,
|
|||
static struct resource * nonstatic_find_mem_region(u_long base, u_long num,
|
||||
u_long align, int low, struct pcmcia_socket *s)
|
||||
{
|
||||
struct resource *res = make_resource(0, num, IORESOURCE_MEM, s->dev.class_id);
|
||||
struct resource *res = make_resource(0, num, IORESOURCE_MEM, s->dev.bus_id);
|
||||
struct socket_data *s_data = s->resource_data;
|
||||
struct pcmcia_align_data data;
|
||||
unsigned long min, max;
|
||||
|
@ -897,9 +897,10 @@ EXPORT_SYMBOL(pccard_nonstatic_ops);
|
|||
|
||||
/* sysfs interface to the resource database */
|
||||
|
||||
static ssize_t show_io_db(struct class_device *class_dev, char *buf)
|
||||
static ssize_t show_io_db(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct pcmcia_socket *s = class_get_devdata(class_dev);
|
||||
struct pcmcia_socket *s = dev_get_drvdata(dev);
|
||||
struct socket_data *data;
|
||||
struct resource_map *p;
|
||||
ssize_t ret = 0;
|
||||
|
@ -920,9 +921,11 @@ static ssize_t show_io_db(struct class_device *class_dev, char *buf)
|
|||
return (ret);
|
||||
}
|
||||
|
||||
static ssize_t store_io_db(struct class_device *class_dev, const char *buf, size_t count)
|
||||
static ssize_t store_io_db(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct pcmcia_socket *s = class_get_devdata(class_dev);
|
||||
struct pcmcia_socket *s = dev_get_drvdata(dev);
|
||||
unsigned long start_addr, end_addr;
|
||||
unsigned int add = ADD_MANAGED_RESOURCE;
|
||||
ssize_t ret = 0;
|
||||
|
@ -947,11 +950,12 @@ static ssize_t store_io_db(struct class_device *class_dev, const char *buf, size
|
|||
|
||||
return ret ? ret : count;
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(available_resources_io, 0600, show_io_db, store_io_db);
|
||||
static DEVICE_ATTR(available_resources_io, 0600, show_io_db, store_io_db);
|
||||
|
||||
static ssize_t show_mem_db(struct class_device *class_dev, char *buf)
|
||||
static ssize_t show_mem_db(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct pcmcia_socket *s = class_get_devdata(class_dev);
|
||||
struct pcmcia_socket *s = dev_get_drvdata(dev);
|
||||
struct socket_data *data;
|
||||
struct resource_map *p;
|
||||
ssize_t ret = 0;
|
||||
|
@ -972,9 +976,11 @@ static ssize_t show_mem_db(struct class_device *class_dev, char *buf)
|
|||
return (ret);
|
||||
}
|
||||
|
||||
static ssize_t store_mem_db(struct class_device *class_dev, const char *buf, size_t count)
|
||||
static ssize_t store_mem_db(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct pcmcia_socket *s = class_get_devdata(class_dev);
|
||||
struct pcmcia_socket *s = dev_get_drvdata(dev);
|
||||
unsigned long start_addr, end_addr;
|
||||
unsigned int add = ADD_MANAGED_RESOURCE;
|
||||
ssize_t ret = 0;
|
||||
|
@ -999,25 +1005,25 @@ static ssize_t store_mem_db(struct class_device *class_dev, const char *buf, siz
|
|||
|
||||
return ret ? ret : count;
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(available_resources_mem, 0600, show_mem_db, store_mem_db);
|
||||
static DEVICE_ATTR(available_resources_mem, 0600, show_mem_db, store_mem_db);
|
||||
|
||||
static struct class_device_attribute *pccard_rsrc_attributes[] = {
|
||||
&class_device_attr_available_resources_io,
|
||||
&class_device_attr_available_resources_mem,
|
||||
static struct device_attribute *pccard_rsrc_attributes[] = {
|
||||
&dev_attr_available_resources_io,
|
||||
&dev_attr_available_resources_mem,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static int __devinit pccard_sysfs_add_rsrc(struct class_device *class_dev,
|
||||
static int __devinit pccard_sysfs_add_rsrc(struct device *dev,
|
||||
struct class_interface *class_intf)
|
||||
{
|
||||
struct pcmcia_socket *s = class_get_devdata(class_dev);
|
||||
struct class_device_attribute **attr;
|
||||
struct pcmcia_socket *s = dev_get_drvdata(dev);
|
||||
struct device_attribute **attr;
|
||||
int ret = 0;
|
||||
if (s->resource_ops != &pccard_nonstatic_ops)
|
||||
return 0;
|
||||
|
||||
for (attr = pccard_rsrc_attributes; *attr; attr++) {
|
||||
ret = class_device_create_file(class_dev, *attr);
|
||||
ret = device_create_file(dev, *attr);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
@ -1025,23 +1031,23 @@ static int __devinit pccard_sysfs_add_rsrc(struct class_device *class_dev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void __devexit pccard_sysfs_remove_rsrc(struct class_device *class_dev,
|
||||
static void __devexit pccard_sysfs_remove_rsrc(struct device *dev,
|
||||
struct class_interface *class_intf)
|
||||
{
|
||||
struct pcmcia_socket *s = class_get_devdata(class_dev);
|
||||
struct class_device_attribute **attr;
|
||||
struct pcmcia_socket *s = dev_get_drvdata(dev);
|
||||
struct device_attribute **attr;
|
||||
|
||||
if (s->resource_ops != &pccard_nonstatic_ops)
|
||||
return;
|
||||
|
||||
for (attr = pccard_rsrc_attributes; *attr; attr++)
|
||||
class_device_remove_file(class_dev, *attr);
|
||||
device_remove_file(dev, *attr);
|
||||
}
|
||||
|
||||
static struct class_interface pccard_rsrc_interface = {
|
||||
.class = &pcmcia_socket_class,
|
||||
.add = &pccard_sysfs_add_rsrc,
|
||||
.remove = __devexit_p(&pccard_sysfs_remove_rsrc),
|
||||
.add_dev = &pccard_sysfs_add_rsrc,
|
||||
.remove_dev = __devexit_p(&pccard_sysfs_remove_rsrc),
|
||||
};
|
||||
|
||||
static int __init nonstatic_sysfs_init(void)
|
||||
|
|
|
@ -478,10 +478,10 @@ dump_bits(char **p, const char *prefix, unsigned int val, struct bittbl *bits, i
|
|||
*
|
||||
* Returns: the number of characters added to the buffer
|
||||
*/
|
||||
static ssize_t show_status(struct class_device *class_dev, char *buf)
|
||||
static ssize_t show_status(struct device *dev, char *buf)
|
||||
{
|
||||
struct soc_pcmcia_socket *skt =
|
||||
container_of(class_dev, struct soc_pcmcia_socket, socket.dev);
|
||||
container_of(dev, struct soc_pcmcia_socket, socket.dev);
|
||||
char *p = buf;
|
||||
|
||||
p+=sprintf(p, "slot : %d\n", skt->nr);
|
||||
|
@ -747,7 +747,7 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops
|
|||
|
||||
add_timer(&skt->poll_timer);
|
||||
|
||||
class_device_create_file(&skt->socket.dev, &class_device_attr_status);
|
||||
device_create_file(&skt->socket.dev, &device_attr_status);
|
||||
}
|
||||
|
||||
dev_set_drvdata(dev, sinfo);
|
||||
|
|
|
@ -40,7 +40,8 @@
|
|||
|
||||
#define to_socket(_dev) container_of(_dev, struct pcmcia_socket, dev)
|
||||
|
||||
static ssize_t pccard_show_type(struct class_device *dev, char *buf)
|
||||
static ssize_t pccard_show_type(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct pcmcia_socket *s = to_socket(dev);
|
||||
|
||||
|
@ -50,9 +51,10 @@ static ssize_t pccard_show_type(struct class_device *dev, char *buf)
|
|||
return sprintf(buf, "32-bit\n");
|
||||
return sprintf(buf, "16-bit\n");
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(card_type, 0444, pccard_show_type, NULL);
|
||||
static DEVICE_ATTR(card_type, 0444, pccard_show_type, NULL);
|
||||
|
||||
static ssize_t pccard_show_voltage(struct class_device *dev, char *buf)
|
||||
static ssize_t pccard_show_voltage(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct pcmcia_socket *s = to_socket(dev);
|
||||
|
||||
|
@ -63,28 +65,31 @@ static ssize_t pccard_show_voltage(struct class_device *dev, char *buf)
|
|||
s->socket.Vcc % 10);
|
||||
return sprintf(buf, "X.XV\n");
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(card_voltage, 0444, pccard_show_voltage, NULL);
|
||||
static DEVICE_ATTR(card_voltage, 0444, pccard_show_voltage, NULL);
|
||||
|
||||
static ssize_t pccard_show_vpp(struct class_device *dev, char *buf)
|
||||
static ssize_t pccard_show_vpp(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct pcmcia_socket *s = to_socket(dev);
|
||||
if (!(s->state & SOCKET_PRESENT))
|
||||
return -ENODEV;
|
||||
return sprintf(buf, "%d.%dV\n", s->socket.Vpp / 10, s->socket.Vpp % 10);
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(card_vpp, 0444, pccard_show_vpp, NULL);
|
||||
static DEVICE_ATTR(card_vpp, 0444, pccard_show_vpp, NULL);
|
||||
|
||||
static ssize_t pccard_show_vcc(struct class_device *dev, char *buf)
|
||||
static ssize_t pccard_show_vcc(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct pcmcia_socket *s = to_socket(dev);
|
||||
if (!(s->state & SOCKET_PRESENT))
|
||||
return -ENODEV;
|
||||
return sprintf(buf, "%d.%dV\n", s->socket.Vcc / 10, s->socket.Vcc % 10);
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(card_vcc, 0444, pccard_show_vcc, NULL);
|
||||
static DEVICE_ATTR(card_vcc, 0444, pccard_show_vcc, NULL);
|
||||
|
||||
|
||||
static ssize_t pccard_store_insert(struct class_device *dev, const char *buf, size_t count)
|
||||
static ssize_t pccard_store_insert(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
ssize_t ret;
|
||||
struct pcmcia_socket *s = to_socket(dev);
|
||||
|
@ -96,16 +101,20 @@ static ssize_t pccard_store_insert(struct class_device *dev, const char *buf, si
|
|||
|
||||
return ret ? ret : count;
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(card_insert, 0200, NULL, pccard_store_insert);
|
||||
static DEVICE_ATTR(card_insert, 0200, NULL, pccard_store_insert);
|
||||
|
||||
|
||||
static ssize_t pccard_show_card_pm_state(struct class_device *dev, char *buf)
|
||||
static ssize_t pccard_show_card_pm_state(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct pcmcia_socket *s = to_socket(dev);
|
||||
return sprintf(buf, "%s\n", s->state & SOCKET_SUSPEND ? "off" : "on");
|
||||
}
|
||||
|
||||
static ssize_t pccard_store_card_pm_state(struct class_device *dev, const char *buf, size_t count)
|
||||
static ssize_t pccard_store_card_pm_state(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
ssize_t ret = -EINVAL;
|
||||
struct pcmcia_socket *s = to_socket(dev);
|
||||
|
@ -120,9 +129,11 @@ static ssize_t pccard_store_card_pm_state(struct class_device *dev, const char *
|
|||
|
||||
return ret ? -ENODEV : count;
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(card_pm_state, 0644, pccard_show_card_pm_state, pccard_store_card_pm_state);
|
||||
static DEVICE_ATTR(card_pm_state, 0644, pccard_show_card_pm_state, pccard_store_card_pm_state);
|
||||
|
||||
static ssize_t pccard_store_eject(struct class_device *dev, const char *buf, size_t count)
|
||||
static ssize_t pccard_store_eject(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
ssize_t ret;
|
||||
struct pcmcia_socket *s = to_socket(dev);
|
||||
|
@ -134,16 +145,20 @@ static ssize_t pccard_store_eject(struct class_device *dev, const char *buf, siz
|
|||
|
||||
return ret ? ret : count;
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(card_eject, 0200, NULL, pccard_store_eject);
|
||||
static DEVICE_ATTR(card_eject, 0200, NULL, pccard_store_eject);
|
||||
|
||||
|
||||
static ssize_t pccard_show_irq_mask(struct class_device *dev, char *buf)
|
||||
static ssize_t pccard_show_irq_mask(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct pcmcia_socket *s = to_socket(dev);
|
||||
return sprintf(buf, "0x%04x\n", s->irq_mask);
|
||||
}
|
||||
|
||||
static ssize_t pccard_store_irq_mask(struct class_device *dev, const char *buf, size_t count)
|
||||
static ssize_t pccard_store_irq_mask(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
ssize_t ret;
|
||||
struct pcmcia_socket *s = to_socket(dev);
|
||||
|
@ -161,16 +176,19 @@ static ssize_t pccard_store_irq_mask(struct class_device *dev, const char *buf,
|
|||
|
||||
return ret ? ret : count;
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(card_irq_mask, 0600, pccard_show_irq_mask, pccard_store_irq_mask);
|
||||
static DEVICE_ATTR(card_irq_mask, 0600, pccard_show_irq_mask, pccard_store_irq_mask);
|
||||
|
||||
|
||||
static ssize_t pccard_show_resource(struct class_device *dev, char *buf)
|
||||
static ssize_t pccard_show_resource(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct pcmcia_socket *s = to_socket(dev);
|
||||
return sprintf(buf, "%s\n", s->resource_setup_done ? "yes" : "no");
|
||||
}
|
||||
|
||||
static ssize_t pccard_store_resource(struct class_device *dev, const char *buf, size_t count)
|
||||
static ssize_t pccard_store_resource(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct pcmcia_socket *s = to_socket(dev);
|
||||
|
@ -196,7 +214,7 @@ static ssize_t pccard_store_resource(struct class_device *dev, const char *buf,
|
|||
|
||||
return count;
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(available_resources_setup_done, 0600, pccard_show_resource, pccard_store_resource);
|
||||
static DEVICE_ATTR(available_resources_setup_done, 0600, pccard_show_resource, pccard_store_resource);
|
||||
|
||||
|
||||
static ssize_t pccard_extract_cis(struct pcmcia_socket *s, char *buf, loff_t off, size_t count)
|
||||
|
@ -279,7 +297,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj, char *buf, loff_t off, size
|
|||
if (off + count > size)
|
||||
count = size - off;
|
||||
|
||||
s = to_socket(container_of(kobj, struct class_device, kobj));
|
||||
s = to_socket(container_of(kobj, struct device, kobj));
|
||||
|
||||
if (!(s->state & SOCKET_PRESENT))
|
||||
return -ENODEV;
|
||||
|
@ -296,7 +314,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj, char *buf, loff_t off, size
|
|||
|
||||
static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, size_t count)
|
||||
{
|
||||
struct pcmcia_socket *s = to_socket(container_of(kobj, struct class_device, kobj));
|
||||
struct pcmcia_socket *s = to_socket(container_of(kobj, struct device, kobj));
|
||||
cisdump_t *cis;
|
||||
int error;
|
||||
|
||||
|
@ -335,16 +353,16 @@ static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, siz
|
|||
}
|
||||
|
||||
|
||||
static struct class_device_attribute *pccard_socket_attributes[] = {
|
||||
&class_device_attr_card_type,
|
||||
&class_device_attr_card_voltage,
|
||||
&class_device_attr_card_vpp,
|
||||
&class_device_attr_card_vcc,
|
||||
&class_device_attr_card_insert,
|
||||
&class_device_attr_card_pm_state,
|
||||
&class_device_attr_card_eject,
|
||||
&class_device_attr_card_irq_mask,
|
||||
&class_device_attr_available_resources_setup_done,
|
||||
static struct device_attribute *pccard_socket_attributes[] = {
|
||||
&dev_attr_card_type,
|
||||
&dev_attr_card_voltage,
|
||||
&dev_attr_card_vpp,
|
||||
&dev_attr_card_vcc,
|
||||
&dev_attr_card_insert,
|
||||
&dev_attr_card_pm_state,
|
||||
&dev_attr_card_eject,
|
||||
&dev_attr_card_irq_mask,
|
||||
&dev_attr_available_resources_setup_done,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
@ -355,35 +373,35 @@ static struct bin_attribute pccard_cis_attr = {
|
|||
.write = pccard_store_cis,
|
||||
};
|
||||
|
||||
static int __devinit pccard_sysfs_add_socket(struct class_device *class_dev,
|
||||
static int __devinit pccard_sysfs_add_socket(struct device *dev,
|
||||
struct class_interface *class_intf)
|
||||
{
|
||||
struct class_device_attribute **attr;
|
||||
struct device_attribute **attr;
|
||||
int ret = 0;
|
||||
|
||||
for (attr = pccard_socket_attributes; *attr; attr++) {
|
||||
ret = class_device_create_file(class_dev, *attr);
|
||||
ret = device_create_file(dev, *attr);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
if (!ret)
|
||||
ret = sysfs_create_bin_file(&class_dev->kobj, &pccard_cis_attr);
|
||||
ret = sysfs_create_bin_file(&dev->kobj, &pccard_cis_attr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __devexit pccard_sysfs_remove_socket(struct class_device *class_dev,
|
||||
static void __devexit pccard_sysfs_remove_socket(struct device *dev,
|
||||
struct class_interface *class_intf)
|
||||
{
|
||||
struct class_device_attribute **attr;
|
||||
struct device_attribute **attr;
|
||||
|
||||
sysfs_remove_bin_file(&class_dev->kobj, &pccard_cis_attr);
|
||||
sysfs_remove_bin_file(&dev->kobj, &pccard_cis_attr);
|
||||
for (attr = pccard_socket_attributes; *attr; attr++)
|
||||
class_device_remove_file(class_dev, *attr);
|
||||
device_remove_file(dev, *attr);
|
||||
}
|
||||
|
||||
struct class_interface pccard_sysfs_interface = {
|
||||
.class = &pcmcia_socket_class,
|
||||
.add = &pccard_sysfs_add_socket,
|
||||
.remove = __devexit_p(&pccard_sysfs_remove_socket),
|
||||
.add_dev = &pccard_sysfs_add_socket,
|
||||
.remove_dev = __devexit_p(&pccard_sysfs_remove_socket),
|
||||
};
|
||||
|
|
|
@ -512,7 +512,7 @@ static int __init init_tcic(void)
|
|||
for (i = 0; i < sockets; i++) {
|
||||
socket_table[i].socket.ops = &tcic_operations;
|
||||
socket_table[i].socket.resource_ops = &pccard_nonstatic_ops;
|
||||
socket_table[i].socket.dev.dev = &tcic_device.dev;
|
||||
socket_table[i].socket.dev.parent = &tcic_device.dev;
|
||||
ret = pcmcia_register_socket(&socket_table[i].socket);
|
||||
if (ret && i)
|
||||
pcmcia_unregister_socket(&socket_table[0].socket);
|
||||
|
|
|
@ -1104,7 +1104,7 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i
|
|||
/* prepare pcmcia_socket */
|
||||
socket->socket.ops = ¥ta_socket_operations;
|
||||
socket->socket.resource_ops = &pccard_nonstatic_ops;
|
||||
socket->socket.dev.dev = &dev->dev;
|
||||
socket->socket.dev.parent = &dev->dev;
|
||||
socket->socket.driver_data = socket;
|
||||
socket->socket.owner = THIS_MODULE;
|
||||
socket->socket.features = SS_CAP_PAGE_REGS | SS_CAP_PCCARD;
|
||||
|
|
|
@ -1234,7 +1234,7 @@ static int init_queue(struct driver_data *drv_data)
|
|||
|
||||
INIT_WORK(&drv_data->pump_messages, pump_messages);
|
||||
drv_data->workqueue = create_singlethread_workqueue(
|
||||
drv_data->master->cdev.dev->bus_id);
|
||||
drv_data->master->dev.parent->bus_id);
|
||||
if (drv_data->workqueue == NULL)
|
||||
return -EBUSY;
|
||||
|
||||
|
|
|
@ -193,7 +193,7 @@ struct spi_device *__init_or_module
|
|||
spi_new_device(struct spi_master *master, struct spi_board_info *chip)
|
||||
{
|
||||
struct spi_device *proxy;
|
||||
struct device *dev = master->cdev.dev;
|
||||
struct device *dev = &master->dev;
|
||||
int status;
|
||||
|
||||
/* NOTE: caller did any chip->bus_num checks necessary */
|
||||
|
@ -215,7 +215,7 @@ spi_new_device(struct spi_master *master, struct spi_board_info *chip)
|
|||
proxy->modalias = chip->modalias;
|
||||
|
||||
snprintf(proxy->dev.bus_id, sizeof proxy->dev.bus_id,
|
||||
"%s.%u", master->cdev.class_id,
|
||||
"%s.%u", master->dev.bus_id,
|
||||
chip->chip_select);
|
||||
proxy->dev.parent = dev;
|
||||
proxy->dev.bus = &spi_bus_type;
|
||||
|
@ -290,7 +290,7 @@ static void __init_or_module
|
|||
scan_boardinfo(struct spi_master *master)
|
||||
{
|
||||
struct boardinfo *bi;
|
||||
struct device *dev = master->cdev.dev;
|
||||
struct device *dev = master->dev.parent;
|
||||
|
||||
down(&board_lock);
|
||||
list_for_each_entry(bi, &board_list, list) {
|
||||
|
@ -319,18 +319,18 @@ scan_boardinfo(struct spi_master *master)
|
|||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static void spi_master_release(struct class_device *cdev)
|
||||
static void spi_master_release(struct device *dev)
|
||||
{
|
||||
struct spi_master *master;
|
||||
|
||||
master = container_of(cdev, struct spi_master, cdev);
|
||||
master = container_of(dev, struct spi_master, dev);
|
||||
kfree(master);
|
||||
}
|
||||
|
||||
static struct class spi_master_class = {
|
||||
.name = "spi_master",
|
||||
.owner = THIS_MODULE,
|
||||
.release = spi_master_release,
|
||||
.dev_release = spi_master_release,
|
||||
};
|
||||
|
||||
|
||||
|
@ -364,9 +364,9 @@ spi_alloc_master(struct device *dev, unsigned size)
|
|||
if (!master)
|
||||
return NULL;
|
||||
|
||||
class_device_initialize(&master->cdev);
|
||||
master->cdev.class = &spi_master_class;
|
||||
master->cdev.dev = get_device(dev);
|
||||
device_initialize(&master->dev);
|
||||
master->dev.class = &spi_master_class;
|
||||
master->dev.parent = get_device(dev);
|
||||
spi_master_set_devdata(master, &master[1]);
|
||||
|
||||
return master;
|
||||
|
@ -396,7 +396,7 @@ int __init_or_module
|
|||
spi_register_master(struct spi_master *master)
|
||||
{
|
||||
static atomic_t dyn_bus_id = ATOMIC_INIT((1<<16) - 1);
|
||||
struct device *dev = master->cdev.dev;
|
||||
struct device *dev = master->dev.parent;
|
||||
int status = -ENODEV;
|
||||
int dynamic = 0;
|
||||
|
||||
|
@ -412,12 +412,12 @@ spi_register_master(struct spi_master *master)
|
|||
/* register the device, then userspace will see it.
|
||||
* registration fails if the bus ID is in use.
|
||||
*/
|
||||
snprintf(master->cdev.class_id, sizeof master->cdev.class_id,
|
||||
snprintf(master->dev.bus_id, sizeof master->dev.bus_id,
|
||||
"spi%u", master->bus_num);
|
||||
status = class_device_add(&master->cdev);
|
||||
status = device_add(&master->dev);
|
||||
if (status < 0)
|
||||
goto done;
|
||||
dev_dbg(dev, "registered master %s%s\n", master->cdev.class_id,
|
||||
dev_dbg(dev, "registered master %s%s\n", master->dev.bus_id,
|
||||
dynamic ? " (dynamic)" : "");
|
||||
|
||||
/* populate children from any spi device tables */
|
||||
|
@ -449,8 +449,8 @@ void spi_unregister_master(struct spi_master *master)
|
|||
{
|
||||
int dummy;
|
||||
|
||||
dummy = device_for_each_child(master->cdev.dev, NULL, __unregister);
|
||||
class_device_unregister(&master->cdev);
|
||||
dummy = device_for_each_child(&master->dev, NULL, __unregister);
|
||||
device_unregister(&master->dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(spi_unregister_master);
|
||||
|
||||
|
@ -471,7 +471,7 @@ struct spi_master *spi_busnum_to_master(u16 bus_num)
|
|||
|
||||
down(&spi_master_class.sem);
|
||||
list_for_each_entry(cdev, &spi_master_class.children, node) {
|
||||
m = container_of(cdev, struct spi_master, cdev);
|
||||
m = container_of(cdev, struct spi_master, dev.kobj);
|
||||
if (m->bus_num == bus_num) {
|
||||
master = spi_master_get(m);
|
||||
break;
|
||||
|
|
|
@ -479,7 +479,7 @@ int spi_bitbang_start(struct spi_bitbang *bitbang)
|
|||
/* this task is the only thing to touch the SPI bits */
|
||||
bitbang->busy = 0;
|
||||
bitbang->workqueue = create_singlethread_workqueue(
|
||||
bitbang->master->cdev.dev->bus_id);
|
||||
bitbang->master->dev.parent->bus_id);
|
||||
if (bitbang->workqueue == NULL) {
|
||||
status = -EBUSY;
|
||||
goto err1;
|
||||
|
@ -513,14 +513,14 @@ int spi_bitbang_stop(struct spi_bitbang *bitbang)
|
|||
while (!list_empty(&bitbang->queue) && limit--) {
|
||||
spin_unlock_irq(&bitbang->lock);
|
||||
|
||||
dev_dbg(bitbang->master->cdev.dev, "wait for queue\n");
|
||||
dev_dbg(&bitbang->master->dev, "wait for queue\n");
|
||||
msleep(10);
|
||||
|
||||
spin_lock_irq(&bitbang->lock);
|
||||
}
|
||||
spin_unlock_irq(&bitbang->lock);
|
||||
if (!list_empty(&bitbang->queue)) {
|
||||
dev_err(bitbang->master->cdev.dev, "queue didn't empty\n");
|
||||
dev_err(&bitbang->master->dev, "queue didn't empty\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
|
|
|
@ -246,7 +246,7 @@ static void butterfly_attach(struct parport *p)
|
|||
* and no way to be selective about what it binds to.
|
||||
*/
|
||||
|
||||
/* FIXME where should master->cdev.dev come from?
|
||||
/* FIXME where should master->dev.parent come from?
|
||||
* e.g. /sys/bus/pnp0/00:0b, some PCI thing, etc
|
||||
* setting up a platform device like this is an ugly kluge...
|
||||
*/
|
||||
|
@ -386,7 +386,7 @@ static void butterfly_detach(struct parport *p)
|
|||
butterfly = NULL;
|
||||
|
||||
/* stop() unregisters child devices too */
|
||||
pdev = to_platform_device(pp->bitbang.master->cdev.dev);
|
||||
pdev = to_platform_device(pp->bitbang.master->dev.parent);
|
||||
status = spi_bitbang_stop(&pp->bitbang);
|
||||
|
||||
/* turn off VCC */
|
||||
|
|
|
@ -750,7 +750,8 @@ EXPORT_SYMBOL_GPL(usb_deregister_device_driver);
|
|||
* usb_register_dev() to enable that functionality. This function no longer
|
||||
* takes care of that.
|
||||
*/
|
||||
int usb_register_driver(struct usb_driver *new_driver, struct module *owner)
|
||||
int usb_register_driver(struct usb_driver *new_driver, struct module *owner,
|
||||
const char *mod_name)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
|
@ -763,6 +764,7 @@ int usb_register_driver(struct usb_driver *new_driver, struct module *owner)
|
|||
new_driver->drvwrap.driver.probe = usb_probe_interface;
|
||||
new_driver->drvwrap.driver.remove = usb_unbind_interface;
|
||||
new_driver->drvwrap.driver.owner = owner;
|
||||
new_driver->drvwrap.driver.mod_name = mod_name;
|
||||
spin_lock_init(&new_driver->dynids.lock);
|
||||
INIT_LIST_HEAD(&new_driver->dynids.list);
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include <linux/hid.h>
|
||||
#include "usbhid.h"
|
||||
|
||||
struct device_type {
|
||||
struct dev_type {
|
||||
u16 idVendor;
|
||||
u16 idProduct;
|
||||
const signed short *ff;
|
||||
|
@ -48,7 +48,7 @@ static const signed short ff_joystick[] = {
|
|||
-1
|
||||
};
|
||||
|
||||
static const struct device_type devices[] = {
|
||||
static const struct dev_type devices[] = {
|
||||
{ 0x046d, 0xc211, ff_rumble },
|
||||
{ 0x046d, 0xc219, ff_rumble },
|
||||
{ 0x046d, 0xc283, ff_joystick },
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <linux/slab.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/semaphore.h>
|
||||
|
||||
#include "sysfs.h"
|
||||
|
||||
|
@ -146,7 +147,7 @@ static int open(struct inode * inode, struct file * file)
|
|||
Error:
|
||||
module_put(attr->attr.owner);
|
||||
Done:
|
||||
if (error && kobj)
|
||||
if (error)
|
||||
kobject_put(kobj);
|
||||
return error;
|
||||
}
|
||||
|
@ -157,8 +158,7 @@ static int release(struct inode * inode, struct file * file)
|
|||
struct bin_attribute * attr = to_bin_attr(file->f_path.dentry);
|
||||
u8 * buffer = file->private_data;
|
||||
|
||||
if (kobj)
|
||||
kobject_put(kobj);
|
||||
kobject_put(kobj);
|
||||
module_put(attr->attr.owner);
|
||||
kfree(buffer);
|
||||
return 0;
|
||||
|
|
214
fs/sysfs/dir.c
214
fs/sysfs/dir.c
|
@ -9,6 +9,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/kobject.h>
|
||||
#include <linux/namei.h>
|
||||
#include <asm/semaphore.h>
|
||||
#include "sysfs.h"
|
||||
|
||||
DECLARE_RWSEM(sysfs_rename_sem);
|
||||
|
@ -32,8 +33,7 @@ static struct dentry_operations sysfs_dentry_ops = {
|
|||
/*
|
||||
* Allocates a new sysfs_dirent and links it to the parent sysfs_dirent
|
||||
*/
|
||||
static struct sysfs_dirent * sysfs_new_dirent(struct sysfs_dirent * parent_sd,
|
||||
void * element)
|
||||
static struct sysfs_dirent * __sysfs_new_dirent(void * element)
|
||||
{
|
||||
struct sysfs_dirent * sd;
|
||||
|
||||
|
@ -45,12 +45,28 @@ static struct sysfs_dirent * sysfs_new_dirent(struct sysfs_dirent * parent_sd,
|
|||
atomic_set(&sd->s_count, 1);
|
||||
atomic_set(&sd->s_event, 1);
|
||||
INIT_LIST_HEAD(&sd->s_children);
|
||||
list_add(&sd->s_sibling, &parent_sd->s_children);
|
||||
INIT_LIST_HEAD(&sd->s_sibling);
|
||||
sd->s_element = element;
|
||||
|
||||
return sd;
|
||||
}
|
||||
|
||||
static void __sysfs_list_dirent(struct sysfs_dirent *parent_sd,
|
||||
struct sysfs_dirent *sd)
|
||||
{
|
||||
if (sd)
|
||||
list_add(&sd->s_sibling, &parent_sd->s_children);
|
||||
}
|
||||
|
||||
static struct sysfs_dirent * sysfs_new_dirent(struct sysfs_dirent *parent_sd,
|
||||
void * element)
|
||||
{
|
||||
struct sysfs_dirent *sd;
|
||||
sd = __sysfs_new_dirent(element);
|
||||
__sysfs_list_dirent(parent_sd, sd);
|
||||
return sd;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* Return -EEXIST if there is already a sysfs element with the same name for
|
||||
|
@ -77,14 +93,14 @@ int sysfs_dirent_exist(struct sysfs_dirent *parent_sd,
|
|||
}
|
||||
|
||||
|
||||
int sysfs_make_dirent(struct sysfs_dirent * parent_sd, struct dentry * dentry,
|
||||
void * element, umode_t mode, int type)
|
||||
static struct sysfs_dirent *
|
||||
__sysfs_make_dirent(struct dentry *dentry, void *element, mode_t mode, int type)
|
||||
{
|
||||
struct sysfs_dirent * sd;
|
||||
|
||||
sd = sysfs_new_dirent(parent_sd, element);
|
||||
sd = __sysfs_new_dirent(element);
|
||||
if (!sd)
|
||||
return -ENOMEM;
|
||||
goto out;
|
||||
|
||||
sd->s_mode = mode;
|
||||
sd->s_type = type;
|
||||
|
@ -94,7 +110,19 @@ int sysfs_make_dirent(struct sysfs_dirent * parent_sd, struct dentry * dentry,
|
|||
dentry->d_op = &sysfs_dentry_ops;
|
||||
}
|
||||
|
||||
return 0;
|
||||
out:
|
||||
return sd;
|
||||
}
|
||||
|
||||
int sysfs_make_dirent(struct sysfs_dirent * parent_sd, struct dentry * dentry,
|
||||
void * element, umode_t mode, int type)
|
||||
{
|
||||
struct sysfs_dirent *sd;
|
||||
|
||||
sd = __sysfs_make_dirent(dentry, element, mode, type);
|
||||
__sysfs_list_dirent(parent_sd, sd);
|
||||
|
||||
return sd ? 0 : -ENOMEM;
|
||||
}
|
||||
|
||||
static int init_dir(struct inode * inode)
|
||||
|
@ -165,11 +193,11 @@ int sysfs_create_subdir(struct kobject * k, const char * n, struct dentry ** d)
|
|||
|
||||
/**
|
||||
* sysfs_create_dir - create a directory for an object.
|
||||
* @parent: parent parent object.
|
||||
* @kobj: object we're creating directory for.
|
||||
* @shadow_parent: parent parent object.
|
||||
*/
|
||||
|
||||
int sysfs_create_dir(struct kobject * kobj)
|
||||
int sysfs_create_dir(struct kobject * kobj, struct dentry *shadow_parent)
|
||||
{
|
||||
struct dentry * dentry = NULL;
|
||||
struct dentry * parent;
|
||||
|
@ -177,7 +205,9 @@ int sysfs_create_dir(struct kobject * kobj)
|
|||
|
||||
BUG_ON(!kobj);
|
||||
|
||||
if (kobj->parent)
|
||||
if (shadow_parent)
|
||||
parent = shadow_parent;
|
||||
else if (kobj->parent)
|
||||
parent = kobj->parent->dentry;
|
||||
else if (sysfs_mount && sysfs_mount->mnt_sb)
|
||||
parent = sysfs_mount->mnt_sb->s_root;
|
||||
|
@ -298,21 +328,12 @@ void sysfs_remove_subdir(struct dentry * d)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* sysfs_remove_dir - remove an object's directory.
|
||||
* @kobj: object.
|
||||
*
|
||||
* The only thing special about this is that we remove any files in
|
||||
* the directory before we remove the directory, and we've inlined
|
||||
* what used to be sysfs_rmdir() below, instead of calling separately.
|
||||
*/
|
||||
|
||||
void sysfs_remove_dir(struct kobject * kobj)
|
||||
static void __sysfs_remove_dir(struct dentry *dentry)
|
||||
{
|
||||
struct dentry * dentry = dget(kobj->dentry);
|
||||
struct sysfs_dirent * parent_sd;
|
||||
struct sysfs_dirent * sd, * tmp;
|
||||
|
||||
dget(dentry);
|
||||
if (!dentry)
|
||||
return;
|
||||
|
||||
|
@ -333,32 +354,60 @@ void sysfs_remove_dir(struct kobject * kobj)
|
|||
* Drop reference from dget() on entrance.
|
||||
*/
|
||||
dput(dentry);
|
||||
}
|
||||
|
||||
/**
|
||||
* sysfs_remove_dir - remove an object's directory.
|
||||
* @kobj: object.
|
||||
*
|
||||
* The only thing special about this is that we remove any files in
|
||||
* the directory before we remove the directory, and we've inlined
|
||||
* what used to be sysfs_rmdir() below, instead of calling separately.
|
||||
*/
|
||||
|
||||
void sysfs_remove_dir(struct kobject * kobj)
|
||||
{
|
||||
__sysfs_remove_dir(kobj->dentry);
|
||||
kobj->dentry = NULL;
|
||||
}
|
||||
|
||||
int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
|
||||
int sysfs_rename_dir(struct kobject * kobj, struct dentry *new_parent,
|
||||
const char *new_name)
|
||||
{
|
||||
int error = 0;
|
||||
struct dentry * new_dentry, * parent;
|
||||
struct dentry * new_dentry;
|
||||
|
||||
if (!strcmp(kobject_name(kobj), new_name))
|
||||
return -EINVAL;
|
||||
|
||||
if (!kobj->parent)
|
||||
return -EINVAL;
|
||||
if (!new_parent)
|
||||
return -EFAULT;
|
||||
|
||||
down_write(&sysfs_rename_sem);
|
||||
parent = kobj->parent->dentry;
|
||||
mutex_lock(&new_parent->d_inode->i_mutex);
|
||||
|
||||
mutex_lock(&parent->d_inode->i_mutex);
|
||||
|
||||
new_dentry = lookup_one_len(new_name, parent, strlen(new_name));
|
||||
new_dentry = lookup_one_len(new_name, new_parent, strlen(new_name));
|
||||
if (!IS_ERR(new_dentry)) {
|
||||
if (!new_dentry->d_inode) {
|
||||
/* By allowing two different directories with the
|
||||
* same d_parent we allow this routine to move
|
||||
* between different shadows of the same directory
|
||||
*/
|
||||
if (kobj->dentry->d_parent->d_inode != new_parent->d_inode)
|
||||
return -EINVAL;
|
||||
else if (new_dentry->d_parent->d_inode != new_parent->d_inode)
|
||||
error = -EINVAL;
|
||||
else if (new_dentry == kobj->dentry)
|
||||
error = -EINVAL;
|
||||
else if (!new_dentry->d_inode) {
|
||||
error = kobject_set_name(kobj, "%s", new_name);
|
||||
if (!error) {
|
||||
struct sysfs_dirent *sd, *parent_sd;
|
||||
|
||||
d_add(new_dentry, NULL);
|
||||
d_move(kobj->dentry, new_dentry);
|
||||
|
||||
sd = kobj->dentry->d_fsdata;
|
||||
parent_sd = new_parent->d_fsdata;
|
||||
|
||||
list_del_init(&sd->s_sibling);
|
||||
list_add(&sd->s_sibling, &parent_sd->s_children);
|
||||
}
|
||||
else
|
||||
d_drop(new_dentry);
|
||||
|
@ -366,7 +415,7 @@ int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
|
|||
error = -EEXIST;
|
||||
dput(new_dentry);
|
||||
}
|
||||
mutex_unlock(&parent->d_inode->i_mutex);
|
||||
mutex_unlock(&new_parent->d_inode->i_mutex);
|
||||
up_write(&sysfs_rename_sem);
|
||||
|
||||
return error;
|
||||
|
@ -378,12 +427,10 @@ int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent)
|
|||
struct sysfs_dirent *new_parent_sd, *sd;
|
||||
int error;
|
||||
|
||||
if (!new_parent)
|
||||
return -EINVAL;
|
||||
|
||||
old_parent_dentry = kobj->parent ?
|
||||
kobj->parent->dentry : sysfs_mount->mnt_sb->s_root;
|
||||
new_parent_dentry = new_parent->dentry;
|
||||
new_parent_dentry = new_parent ?
|
||||
new_parent->dentry : sysfs_mount->mnt_sb->s_root;
|
||||
|
||||
again:
|
||||
mutex_lock(&old_parent_dentry->d_inode->i_mutex);
|
||||
|
@ -547,6 +594,95 @@ static loff_t sysfs_dir_lseek(struct file * file, loff_t offset, int origin)
|
|||
return offset;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* sysfs_make_shadowed_dir - Setup so a directory can be shadowed
|
||||
* @kobj: object we're creating shadow of.
|
||||
*/
|
||||
|
||||
int sysfs_make_shadowed_dir(struct kobject *kobj,
|
||||
void * (*follow_link)(struct dentry *, struct nameidata *))
|
||||
{
|
||||
struct inode *inode;
|
||||
struct inode_operations *i_op;
|
||||
|
||||
inode = kobj->dentry->d_inode;
|
||||
if (inode->i_op != &sysfs_dir_inode_operations)
|
||||
return -EINVAL;
|
||||
|
||||
i_op = kmalloc(sizeof(*i_op), GFP_KERNEL);
|
||||
if (!i_op)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(i_op, &sysfs_dir_inode_operations, sizeof(*i_op));
|
||||
i_op->follow_link = follow_link;
|
||||
|
||||
/* Locking of inode->i_op?
|
||||
* Since setting i_op is a single word write and they
|
||||
* are atomic we should be ok here.
|
||||
*/
|
||||
inode->i_op = i_op;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* sysfs_create_shadow_dir - create a shadow directory for an object.
|
||||
* @kobj: object we're creating directory for.
|
||||
*
|
||||
* sysfs_make_shadowed_dir must already have been called on this
|
||||
* directory.
|
||||
*/
|
||||
|
||||
struct dentry *sysfs_create_shadow_dir(struct kobject *kobj)
|
||||
{
|
||||
struct sysfs_dirent *sd;
|
||||
struct dentry *parent, *dir, *shadow;
|
||||
struct inode *inode;
|
||||
|
||||
dir = kobj->dentry;
|
||||
inode = dir->d_inode;
|
||||
parent = dir->d_parent;
|
||||
shadow = ERR_PTR(-EINVAL);
|
||||
if (!sysfs_is_shadowed_inode(inode))
|
||||
goto out;
|
||||
|
||||
shadow = d_alloc(parent, &dir->d_name);
|
||||
if (!shadow)
|
||||
goto nomem;
|
||||
|
||||
sd = __sysfs_make_dirent(shadow, kobj, inode->i_mode, SYSFS_DIR);
|
||||
if (!sd)
|
||||
goto nomem;
|
||||
|
||||
d_instantiate(shadow, igrab(inode));
|
||||
inc_nlink(inode);
|
||||
inc_nlink(parent->d_inode);
|
||||
shadow->d_op = &sysfs_dentry_ops;
|
||||
|
||||
dget(shadow); /* Extra count - pin the dentry in core */
|
||||
|
||||
out:
|
||||
return shadow;
|
||||
nomem:
|
||||
dput(shadow);
|
||||
shadow = ERR_PTR(-ENOMEM);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/**
|
||||
* sysfs_remove_shadow_dir - remove an object's directory.
|
||||
* @shadow: dentry of shadow directory
|
||||
*
|
||||
* The only thing special about this is that we remove any files in
|
||||
* the directory before we remove the directory, and we've inlined
|
||||
* what used to be sysfs_rmdir() below, instead of calling separately.
|
||||
*/
|
||||
|
||||
void sysfs_remove_shadow_dir(struct dentry *shadow)
|
||||
{
|
||||
__sysfs_remove_dir(shadow);
|
||||
}
|
||||
|
||||
const struct file_operations sysfs_dir_operations = {
|
||||
.open = sysfs_dir_open,
|
||||
.release = sysfs_dir_close,
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <linux/kobject.h>
|
||||
#include <linux/namei.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/list.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/semaphore.h>
|
||||
|
||||
|
@ -50,17 +51,29 @@ static struct sysfs_ops subsys_sysfs_ops = {
|
|||
.store = subsys_attr_store,
|
||||
};
|
||||
|
||||
/**
|
||||
* add_to_collection - add buffer to a collection
|
||||
* @buffer: buffer to be added
|
||||
* @node inode of set to add to
|
||||
*/
|
||||
|
||||
struct sysfs_buffer {
|
||||
size_t count;
|
||||
loff_t pos;
|
||||
char * page;
|
||||
struct sysfs_ops * ops;
|
||||
struct semaphore sem;
|
||||
int needs_read_fill;
|
||||
int event;
|
||||
};
|
||||
static inline void
|
||||
add_to_collection(struct sysfs_buffer *buffer, struct inode *node)
|
||||
{
|
||||
struct sysfs_buffer_collection *set = node->i_private;
|
||||
|
||||
mutex_lock(&node->i_mutex);
|
||||
list_add(&buffer->associates, &set->associates);
|
||||
mutex_unlock(&node->i_mutex);
|
||||
}
|
||||
|
||||
static inline void
|
||||
remove_from_collection(struct sysfs_buffer *buffer, struct inode *node)
|
||||
{
|
||||
mutex_lock(&node->i_mutex);
|
||||
list_del(&buffer->associates);
|
||||
mutex_unlock(&node->i_mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* fill_read_buffer - allocate and fill buffer from object.
|
||||
|
@ -70,7 +83,8 @@ struct sysfs_buffer {
|
|||
* Allocate @buffer->page, if it hasn't been already, then call the
|
||||
* kobject's show() method to fill the buffer with this attribute's
|
||||
* data.
|
||||
* This is called only once, on the file's first read.
|
||||
* This is called only once, on the file's first read unless an error
|
||||
* is returned.
|
||||
*/
|
||||
static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer)
|
||||
{
|
||||
|
@ -88,12 +102,13 @@ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer
|
|||
|
||||
buffer->event = atomic_read(&sd->s_event);
|
||||
count = ops->show(kobj,attr,buffer->page);
|
||||
buffer->needs_read_fill = 0;
|
||||
BUG_ON(count > (ssize_t)PAGE_SIZE);
|
||||
if (count >= 0)
|
||||
if (count >= 0) {
|
||||
buffer->needs_read_fill = 0;
|
||||
buffer->count = count;
|
||||
else
|
||||
} else {
|
||||
ret = count;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -153,6 +168,10 @@ sysfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos)
|
|||
ssize_t retval = 0;
|
||||
|
||||
down(&buffer->sem);
|
||||
if (buffer->orphaned) {
|
||||
retval = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
if (buffer->needs_read_fill) {
|
||||
if ((retval = fill_read_buffer(file->f_path.dentry,buffer)))
|
||||
goto out;
|
||||
|
@ -165,7 +184,6 @@ sysfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos)
|
|||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* fill_write_buffer - copy buffer from userspace.
|
||||
* @buffer: data buffer for file.
|
||||
|
@ -243,19 +261,25 @@ sysfs_write_file(struct file *file, const char __user *buf, size_t count, loff_t
|
|||
ssize_t len;
|
||||
|
||||
down(&buffer->sem);
|
||||
if (buffer->orphaned) {
|
||||
len = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
len = fill_write_buffer(buffer, buf, count);
|
||||
if (len > 0)
|
||||
len = flush_write_buffer(file->f_path.dentry, buffer, len);
|
||||
if (len > 0)
|
||||
*ppos += len;
|
||||
out:
|
||||
up(&buffer->sem);
|
||||
return len;
|
||||
}
|
||||
|
||||
static int check_perm(struct inode * inode, struct file * file)
|
||||
static int sysfs_open_file(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct kobject *kobj = sysfs_get_kobject(file->f_path.dentry->d_parent);
|
||||
struct attribute * attr = to_attr(file->f_path.dentry);
|
||||
struct sysfs_buffer_collection *set;
|
||||
struct sysfs_buffer * buffer;
|
||||
struct sysfs_ops * ops = NULL;
|
||||
int error = 0;
|
||||
|
@ -285,6 +309,18 @@ static int check_perm(struct inode * inode, struct file * file)
|
|||
if (!ops)
|
||||
goto Eaccess;
|
||||
|
||||
/* make sure we have a collection to add our buffers to */
|
||||
mutex_lock(&inode->i_mutex);
|
||||
if (!(set = inode->i_private)) {
|
||||
if (!(set = inode->i_private = kmalloc(sizeof(struct sysfs_buffer_collection), GFP_KERNEL))) {
|
||||
error = -ENOMEM;
|
||||
goto Done;
|
||||
} else {
|
||||
INIT_LIST_HEAD(&set->associates);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
|
||||
/* File needs write support.
|
||||
* The inode's perms must say it's ok,
|
||||
* and we must have a store method.
|
||||
|
@ -310,9 +346,11 @@ static int check_perm(struct inode * inode, struct file * file)
|
|||
*/
|
||||
buffer = kzalloc(sizeof(struct sysfs_buffer), GFP_KERNEL);
|
||||
if (buffer) {
|
||||
INIT_LIST_HEAD(&buffer->associates);
|
||||
init_MUTEX(&buffer->sem);
|
||||
buffer->needs_read_fill = 1;
|
||||
buffer->ops = ops;
|
||||
add_to_collection(buffer, inode);
|
||||
file->private_data = buffer;
|
||||
} else
|
||||
error = -ENOMEM;
|
||||
|
@ -325,16 +363,11 @@ static int check_perm(struct inode * inode, struct file * file)
|
|||
error = -EACCES;
|
||||
module_put(attr->owner);
|
||||
Done:
|
||||
if (error && kobj)
|
||||
if (error)
|
||||
kobject_put(kobj);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int sysfs_open_file(struct inode * inode, struct file * filp)
|
||||
{
|
||||
return check_perm(inode,filp);
|
||||
}
|
||||
|
||||
static int sysfs_release(struct inode * inode, struct file * filp)
|
||||
{
|
||||
struct kobject * kobj = to_kobj(filp->f_path.dentry->d_parent);
|
||||
|
@ -342,8 +375,9 @@ static int sysfs_release(struct inode * inode, struct file * filp)
|
|||
struct module * owner = attr->owner;
|
||||
struct sysfs_buffer * buffer = filp->private_data;
|
||||
|
||||
if (kobj)
|
||||
kobject_put(kobj);
|
||||
if (buffer)
|
||||
remove_from_collection(buffer, inode);
|
||||
kobject_put(kobj);
|
||||
/* After this point, attr should not be accessed. */
|
||||
module_put(owner);
|
||||
|
||||
|
@ -548,7 +582,7 @@ EXPORT_SYMBOL_GPL(sysfs_chmod_file);
|
|||
|
||||
void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr)
|
||||
{
|
||||
sysfs_hash_and_remove(kobj->dentry,attr->name);
|
||||
sysfs_hash_and_remove(kobj->dentry, attr->name);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include <linux/dcache.h>
|
||||
#include <linux/namei.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/fs.h>
|
||||
#include <asm/semaphore.h>
|
||||
#include "sysfs.h"
|
||||
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <linux/backing-dev.h>
|
||||
#include <linux/capability.h>
|
||||
#include <linux/errno.h>
|
||||
#include <asm/semaphore.h>
|
||||
#include "sysfs.h"
|
||||
|
||||
extern struct super_block * sysfs_sb;
|
||||
|
@ -32,6 +33,16 @@ static struct inode_operations sysfs_inode_operations ={
|
|||
.setattr = sysfs_setattr,
|
||||
};
|
||||
|
||||
void sysfs_delete_inode(struct inode *inode)
|
||||
{
|
||||
/* Free the shadowed directory inode operations */
|
||||
if (sysfs_is_shadowed_inode(inode)) {
|
||||
kfree(inode->i_op);
|
||||
inode->i_op = NULL;
|
||||
}
|
||||
return generic_delete_inode(inode);
|
||||
}
|
||||
|
||||
int sysfs_setattr(struct dentry * dentry, struct iattr * iattr)
|
||||
{
|
||||
struct inode * inode = dentry->d_inode;
|
||||
|
@ -209,6 +220,22 @@ const unsigned char * sysfs_get_name(struct sysfs_dirent *sd)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static inline void orphan_all_buffers(struct inode *node)
|
||||
{
|
||||
struct sysfs_buffer_collection *set = node->i_private;
|
||||
struct sysfs_buffer *buf;
|
||||
|
||||
mutex_lock_nested(&node->i_mutex, I_MUTEX_CHILD);
|
||||
if (node->i_private) {
|
||||
list_for_each_entry(buf, &set->associates, associates) {
|
||||
down(&buf->sem);
|
||||
buf->orphaned = 1;
|
||||
up(&buf->sem);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&node->i_mutex);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Unhashes the dentry corresponding to given sysfs_dirent
|
||||
|
@ -217,16 +244,23 @@ const unsigned char * sysfs_get_name(struct sysfs_dirent *sd)
|
|||
void sysfs_drop_dentry(struct sysfs_dirent * sd, struct dentry * parent)
|
||||
{
|
||||
struct dentry * dentry = sd->s_dentry;
|
||||
struct inode *inode;
|
||||
|
||||
if (dentry) {
|
||||
spin_lock(&dcache_lock);
|
||||
spin_lock(&dentry->d_lock);
|
||||
if (!(d_unhashed(dentry) && dentry->d_inode)) {
|
||||
inode = dentry->d_inode;
|
||||
spin_lock(&inode->i_lock);
|
||||
__iget(inode);
|
||||
spin_unlock(&inode->i_lock);
|
||||
dget_locked(dentry);
|
||||
__d_drop(dentry);
|
||||
spin_unlock(&dentry->d_lock);
|
||||
spin_unlock(&dcache_lock);
|
||||
simple_unlink(parent->d_inode, dentry);
|
||||
orphan_all_buffers(inode);
|
||||
iput(inode);
|
||||
} else {
|
||||
spin_unlock(&dentry->d_lock);
|
||||
spin_unlock(&dcache_lock);
|
||||
|
@ -248,7 +282,7 @@ int sysfs_hash_and_remove(struct dentry * dir, const char * name)
|
|||
return -ENOENT;
|
||||
|
||||
parent_sd = dir->d_fsdata;
|
||||
mutex_lock(&dir->d_inode->i_mutex);
|
||||
mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
|
||||
list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
|
||||
if (!sd->s_element)
|
||||
continue;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <linux/mount.h>
|
||||
#include <linux/pagemap.h>
|
||||
#include <linux/init.h>
|
||||
#include <asm/semaphore.h>
|
||||
|
||||
#include "sysfs.h"
|
||||
|
||||
|
@ -18,9 +19,12 @@ struct vfsmount *sysfs_mount;
|
|||
struct super_block * sysfs_sb = NULL;
|
||||
struct kmem_cache *sysfs_dir_cachep;
|
||||
|
||||
static void sysfs_clear_inode(struct inode *inode);
|
||||
|
||||
static struct super_operations sysfs_ops = {
|
||||
.statfs = simple_statfs,
|
||||
.drop_inode = generic_delete_inode,
|
||||
.drop_inode = sysfs_delete_inode,
|
||||
.clear_inode = sysfs_clear_inode,
|
||||
};
|
||||
|
||||
static struct sysfs_dirent sysfs_root = {
|
||||
|
@ -31,6 +35,11 @@ static struct sysfs_dirent sysfs_root = {
|
|||
.s_iattr = NULL,
|
||||
};
|
||||
|
||||
static void sysfs_clear_inode(struct inode *inode)
|
||||
{
|
||||
kfree(inode->i_private);
|
||||
}
|
||||
|
||||
static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
|
||||
{
|
||||
struct inode *inode;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/kobject.h>
|
||||
#include <linux/namei.h>
|
||||
#include <asm/semaphore.h>
|
||||
|
||||
#include "sysfs.h"
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
extern struct vfsmount * sysfs_mount;
|
||||
extern struct kmem_cache *sysfs_dir_cachep;
|
||||
|
||||
extern void sysfs_delete_inode(struct inode *inode);
|
||||
extern struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent *);
|
||||
extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *));
|
||||
|
||||
|
@ -33,6 +34,22 @@ struct sysfs_symlink {
|
|||
struct kobject * target_kobj;
|
||||
};
|
||||
|
||||
struct sysfs_buffer {
|
||||
struct list_head associates;
|
||||
size_t count;
|
||||
loff_t pos;
|
||||
char * page;
|
||||
struct sysfs_ops * ops;
|
||||
struct semaphore sem;
|
||||
int orphaned;
|
||||
int needs_read_fill;
|
||||
int event;
|
||||
};
|
||||
|
||||
struct sysfs_buffer_collection {
|
||||
struct list_head associates;
|
||||
};
|
||||
|
||||
static inline struct kobject * to_kobj(struct dentry * dentry)
|
||||
{
|
||||
struct sysfs_dirent * sd = dentry->d_fsdata;
|
||||
|
@ -96,3 +113,7 @@ static inline void sysfs_put(struct sysfs_dirent * sd)
|
|||
release_sysfs_dirent(sd);
|
||||
}
|
||||
|
||||
static inline int sysfs_is_shadowed_inode(struct inode *inode)
|
||||
{
|
||||
return S_ISDIR(inode->i_mode) && inode->i_op->follow_link;
|
||||
}
|
||||
|
|
|
@ -126,6 +126,7 @@ struct device_driver {
|
|||
struct klist_node knode_bus;
|
||||
|
||||
struct module * owner;
|
||||
const char * mod_name; /* used for built-in modules */
|
||||
|
||||
int (*probe) (struct device * dev);
|
||||
int (*remove) (struct device * dev);
|
||||
|
@ -327,6 +328,13 @@ extern struct class_device *class_device_create(struct class *cls,
|
|||
__attribute__((format(printf,5,6)));
|
||||
extern void class_device_destroy(struct class *cls, dev_t devt);
|
||||
|
||||
struct device_type {
|
||||
struct device_attribute *attrs;
|
||||
int (*uevent)(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size);
|
||||
void (*release)(struct device *dev);
|
||||
};
|
||||
|
||||
/* interface for exporting device attributes */
|
||||
struct device_attribute {
|
||||
struct attribute attr;
|
||||
|
@ -355,6 +363,7 @@ struct device {
|
|||
|
||||
struct kobject kobj;
|
||||
char bus_id[BUS_ID_SIZE]; /* position on parent bus */
|
||||
struct device_type *type;
|
||||
unsigned is_registered:1;
|
||||
struct device_attribute uevent_attr;
|
||||
struct device_attribute *devt_attr;
|
||||
|
@ -390,9 +399,10 @@ struct device {
|
|||
|
||||
/* class_device migration path */
|
||||
struct list_head node;
|
||||
struct class *class; /* optional*/
|
||||
struct class *class;
|
||||
dev_t devt; /* dev_t, creates the sysfs "dev" */
|
||||
struct attribute_group **groups; /* optional groups */
|
||||
int uevent_suppress;
|
||||
|
||||
void (*release)(struct device * dev);
|
||||
};
|
||||
|
|
|
@ -1192,8 +1192,8 @@ void ide_init_disk(struct gendisk *, ide_drive_t *);
|
|||
extern int ideprobe_init(void);
|
||||
|
||||
extern void ide_scan_pcibus(int scan_direction) __init;
|
||||
extern int __ide_pci_register_driver(struct pci_driver *driver, struct module *owner);
|
||||
#define ide_pci_register_driver(d) __ide_pci_register_driver(d, THIS_MODULE)
|
||||
extern int __ide_pci_register_driver(struct pci_driver *driver, struct module *owner, const char *mod_name);
|
||||
#define ide_pci_register_driver(d) __ide_pci_register_driver(d, THIS_MODULE, KBUILD_MODNAME)
|
||||
void ide_pci_setup_ports(struct pci_dev *, struct ide_pci_device_s *, int, ata_index_t *);
|
||||
extern void ide_setup_pci_noise (struct pci_dev *dev, struct ide_pci_device_s *d);
|
||||
|
||||
|
|
|
@ -74,9 +74,13 @@ extern void kobject_init(struct kobject *);
|
|||
extern void kobject_cleanup(struct kobject *);
|
||||
|
||||
extern int __must_check kobject_add(struct kobject *);
|
||||
extern int __must_check kobject_shadow_add(struct kobject *, struct dentry *);
|
||||
extern void kobject_del(struct kobject *);
|
||||
|
||||
extern int __must_check kobject_rename(struct kobject *, const char *new_name);
|
||||
extern int __must_check kobject_shadow_rename(struct kobject *kobj,
|
||||
struct dentry *new_parent,
|
||||
const char *new_name);
|
||||
extern int __must_check kobject_move(struct kobject *, struct kobject *);
|
||||
|
||||
extern int __must_check kobject_register(struct kobject *);
|
||||
|
|
|
@ -58,6 +58,7 @@ struct module_kobject
|
|||
{
|
||||
struct kobject kobj;
|
||||
struct module *mod;
|
||||
struct kobject *drivers_dir;
|
||||
};
|
||||
|
||||
/* These are either module local, or the kernel's dummy ones. */
|
||||
|
@ -263,7 +264,7 @@ struct module
|
|||
struct module_attribute *modinfo_attrs;
|
||||
const char *version;
|
||||
const char *srcversion;
|
||||
struct kobject *drivers_dir;
|
||||
struct kobject *holders_dir;
|
||||
|
||||
/* Exported symbols */
|
||||
const struct kernel_symbol *syms;
|
||||
|
|
|
@ -529,10 +529,11 @@ struct net_device
|
|||
struct net_bridge_port *br_port;
|
||||
|
||||
/* class/net/name entry */
|
||||
struct class_device class_dev;
|
||||
struct device dev;
|
||||
/* space for optional statistics and wireless sysfs groups */
|
||||
struct attribute_group *sysfs_groups[3];
|
||||
};
|
||||
#define to_net_dev(d) container_of(d, struct net_device, dev)
|
||||
|
||||
#define NETDEV_ALIGN 32
|
||||
#define NETDEV_ALIGN_CONST (NETDEV_ALIGN - 1)
|
||||
|
@ -548,7 +549,7 @@ static inline void *netdev_priv(struct net_device *dev)
|
|||
/* Set the sysfs physical device reference for the network logical device
|
||||
* if set prior to registration will cause a symlink during initialization.
|
||||
*/
|
||||
#define SET_NETDEV_DEV(net, pdev) ((net)->class_dev.dev = (pdev))
|
||||
#define SET_NETDEV_DEV(net, pdev) ((net)->dev.parent = (pdev))
|
||||
|
||||
struct packet_type {
|
||||
__be16 type; /* This is really htons(ether_type). */
|
||||
|
|
|
@ -573,10 +573,11 @@ int __must_check pci_bus_alloc_resource(struct pci_bus *bus,
|
|||
void pci_enable_bridges(struct pci_bus *bus);
|
||||
|
||||
/* Proper probing supporting hot-pluggable devices */
|
||||
int __must_check __pci_register_driver(struct pci_driver *, struct module *);
|
||||
int __must_check __pci_register_driver(struct pci_driver *, struct module *,
|
||||
const char *mod_name);
|
||||
static inline int __must_check pci_register_driver(struct pci_driver *driver)
|
||||
{
|
||||
return __pci_register_driver(driver, THIS_MODULE);
|
||||
return __pci_register_driver(driver, THIS_MODULE, KBUILD_MODNAME);
|
||||
}
|
||||
|
||||
void pci_unregister_driver(struct pci_driver *);
|
||||
|
|
|
@ -86,6 +86,11 @@ static inline void serio_register_port(struct serio *serio)
|
|||
void serio_unregister_port(struct serio *serio);
|
||||
void serio_unregister_child_port(struct serio *serio);
|
||||
|
||||
int __serio_register_driver(struct serio_driver *drv, struct module *owner, const char *mod_name);
|
||||
static inline int serio_register_driver(struct serio_driver *drv)
|
||||
{
|
||||
return __serio_register_driver(drv, THIS_MODULE, KBUILD_MODNAME);
|
||||
}
|
||||
int serio_register_driver(struct serio_driver *drv);
|
||||
void serio_unregister_driver(struct serio_driver *drv);
|
||||
|
||||
|
|
|
@ -170,7 +170,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
|
|||
* message's completion function when the transaction completes.
|
||||
*/
|
||||
struct spi_master {
|
||||
struct class_device cdev;
|
||||
struct device dev;
|
||||
|
||||
/* other than negative (== assign one dynamically), bus_num is fully
|
||||
* board-specific. usually that simplifies to being SOC-specific.
|
||||
|
@ -216,17 +216,17 @@ struct spi_master {
|
|||
|
||||
static inline void *spi_master_get_devdata(struct spi_master *master)
|
||||
{
|
||||
return class_get_devdata(&master->cdev);
|
||||
return dev_get_drvdata(&master->dev);
|
||||
}
|
||||
|
||||
static inline void spi_master_set_devdata(struct spi_master *master, void *data)
|
||||
{
|
||||
class_set_devdata(&master->cdev, data);
|
||||
dev_set_drvdata(&master->dev, data);
|
||||
}
|
||||
|
||||
static inline struct spi_master *spi_master_get(struct spi_master *master)
|
||||
{
|
||||
if (!master || !class_device_get(&master->cdev))
|
||||
if (!master || !get_device(&master->dev))
|
||||
return NULL;
|
||||
return master;
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ static inline struct spi_master *spi_master_get(struct spi_master *master)
|
|||
static inline void spi_master_put(struct spi_master *master)
|
||||
{
|
||||
if (master)
|
||||
class_device_put(&master->cdev);
|
||||
put_device(&master->dev);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -11,10 +11,12 @@
|
|||
#define _SYSFS_H_
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/list.h>
|
||||
#include <asm/atomic.h>
|
||||
|
||||
struct kobject;
|
||||
struct module;
|
||||
struct nameidata;
|
||||
|
||||
struct attribute {
|
||||
const char * name;
|
||||
|
@ -88,13 +90,13 @@ struct sysfs_dirent {
|
|||
#ifdef CONFIG_SYSFS
|
||||
|
||||
extern int __must_check
|
||||
sysfs_create_dir(struct kobject *);
|
||||
sysfs_create_dir(struct kobject *, struct dentry *);
|
||||
|
||||
extern void
|
||||
sysfs_remove_dir(struct kobject *);
|
||||
|
||||
extern int __must_check
|
||||
sysfs_rename_dir(struct kobject *, const char *new_name);
|
||||
sysfs_rename_dir(struct kobject *, struct dentry *, const char *new_name);
|
||||
|
||||
extern int __must_check
|
||||
sysfs_move_dir(struct kobject *, struct kobject *);
|
||||
|
@ -126,11 +128,17 @@ int __must_check sysfs_create_group(struct kobject *,
|
|||
void sysfs_remove_group(struct kobject *, const struct attribute_group *);
|
||||
void sysfs_notify(struct kobject * k, char *dir, char *attr);
|
||||
|
||||
|
||||
extern int sysfs_make_shadowed_dir(struct kobject *kobj,
|
||||
void * (*follow_link)(struct dentry *, struct nameidata *));
|
||||
extern struct dentry *sysfs_create_shadow_dir(struct kobject *kobj);
|
||||
extern void sysfs_remove_shadow_dir(struct dentry *dir);
|
||||
|
||||
extern int __must_check sysfs_init(void);
|
||||
|
||||
#else /* CONFIG_SYSFS */
|
||||
|
||||
static inline int sysfs_create_dir(struct kobject * k)
|
||||
static inline int sysfs_create_dir(struct kobject * k, struct dentry *shadow)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -140,7 +148,9 @@ static inline void sysfs_remove_dir(struct kobject * k)
|
|||
;
|
||||
}
|
||||
|
||||
static inline int sysfs_rename_dir(struct kobject * k, const char *new_name)
|
||||
static inline int sysfs_rename_dir(struct kobject * k,
|
||||
struct dentry *new_parent,
|
||||
const char *new_name)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -204,6 +214,12 @@ static inline void sysfs_notify(struct kobject * k, char *dir, char *attr)
|
|||
{
|
||||
}
|
||||
|
||||
static inline int sysfs_make_shadowed_dir(struct kobject *kobj,
|
||||
void * (*follow_link)(struct dentry *, struct nameidata *))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int __must_check sysfs_init(void)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
@ -868,10 +868,11 @@ struct usb_class_driver {
|
|||
* use these in module_init()/module_exit()
|
||||
* and don't forget MODULE_DEVICE_TABLE(usb, ...)
|
||||
*/
|
||||
extern int usb_register_driver(struct usb_driver *, struct module *);
|
||||
extern int usb_register_driver(struct usb_driver *, struct module *,
|
||||
const char *);
|
||||
static inline int usb_register(struct usb_driver *driver)
|
||||
{
|
||||
return usb_register_driver(driver, THIS_MODULE);
|
||||
return usb_register_driver(driver, THIS_MODULE, KBUILD_MODNAME);
|
||||
}
|
||||
extern void usb_deregister(struct usb_driver *);
|
||||
|
||||
|
|
|
@ -284,7 +284,7 @@ struct pcmcia_socket {
|
|||
#endif
|
||||
|
||||
/* socket device */
|
||||
struct class_device dev;
|
||||
struct device dev;
|
||||
void *driver_data; /* data internal to the socket driver */
|
||||
|
||||
};
|
||||
|
|
|
@ -537,6 +537,8 @@ static int already_uses(struct module *a, struct module *b)
|
|||
static int use_module(struct module *a, struct module *b)
|
||||
{
|
||||
struct module_use *use;
|
||||
int no_warn;
|
||||
|
||||
if (b == NULL || already_uses(a, b)) return 1;
|
||||
|
||||
if (!strong_try_module_get(b))
|
||||
|
@ -552,6 +554,7 @@ static int use_module(struct module *a, struct module *b)
|
|||
|
||||
use->module_which_uses = a;
|
||||
list_add(&use->list, &b->modules_which_use_me);
|
||||
no_warn = sysfs_create_link(b->holders_dir, &a->mkobj.kobj, a->name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -569,6 +572,7 @@ static void module_unload_free(struct module *mod)
|
|||
module_put(i);
|
||||
list_del(&use->list);
|
||||
kfree(use);
|
||||
sysfs_remove_link(i->holders_dir, mod->name);
|
||||
/* There can be at most one match. */
|
||||
break;
|
||||
}
|
||||
|
@ -1106,9 +1110,7 @@ static void module_remove_modinfo_attrs(struct module *mod)
|
|||
kfree(mod->modinfo_attrs);
|
||||
}
|
||||
|
||||
static int mod_sysfs_setup(struct module *mod,
|
||||
struct kernel_param *kparam,
|
||||
unsigned int num_params)
|
||||
static int mod_sysfs_init(struct module *mod)
|
||||
{
|
||||
int err;
|
||||
|
||||
|
@ -1125,21 +1127,30 @@ static int mod_sysfs_setup(struct module *mod,
|
|||
kobj_set_kset_s(&mod->mkobj, module_subsys);
|
||||
mod->mkobj.mod = mod;
|
||||
|
||||
/* delay uevent until full sysfs population */
|
||||
kobject_init(&mod->mkobj.kobj);
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int mod_sysfs_setup(struct module *mod,
|
||||
struct kernel_param *kparam,
|
||||
unsigned int num_params)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* delay uevent until full sysfs population */
|
||||
err = kobject_add(&mod->mkobj.kobj);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
mod->drivers_dir = kobject_add_dir(&mod->mkobj.kobj, "drivers");
|
||||
if (!mod->drivers_dir) {
|
||||
err = -ENOMEM;
|
||||
mod->holders_dir = kobject_add_dir(&mod->mkobj.kobj, "holders");
|
||||
if (!mod->holders_dir)
|
||||
goto out_unreg;
|
||||
}
|
||||
|
||||
err = module_param_sysfs_setup(mod, kparam, num_params);
|
||||
if (err)
|
||||
goto out_unreg_drivers;
|
||||
goto out_unreg_holders;
|
||||
|
||||
err = module_add_modinfo_attrs(mod);
|
||||
if (err)
|
||||
|
@ -1150,8 +1161,8 @@ static int mod_sysfs_setup(struct module *mod,
|
|||
|
||||
out_unreg_param:
|
||||
module_param_sysfs_remove(mod);
|
||||
out_unreg_drivers:
|
||||
kobject_unregister(mod->drivers_dir);
|
||||
out_unreg_holders:
|
||||
kobject_unregister(mod->holders_dir);
|
||||
out_unreg:
|
||||
kobject_del(&mod->mkobj.kobj);
|
||||
kobject_put(&mod->mkobj.kobj);
|
||||
|
@ -1163,7 +1174,10 @@ static void mod_kobject_remove(struct module *mod)
|
|||
{
|
||||
module_remove_modinfo_attrs(mod);
|
||||
module_param_sysfs_remove(mod);
|
||||
kobject_unregister(mod->drivers_dir);
|
||||
if (mod->mkobj.drivers_dir)
|
||||
kobject_unregister(mod->mkobj.drivers_dir);
|
||||
if (mod->holders_dir)
|
||||
kobject_unregister(mod->holders_dir);
|
||||
|
||||
kobject_unregister(&mod->mkobj.kobj);
|
||||
}
|
||||
|
@ -1768,6 +1782,10 @@ static struct module *load_module(void __user *umod,
|
|||
/* Now we've moved module, initialize linked lists, etc. */
|
||||
module_unload_init(mod);
|
||||
|
||||
/* Initialize kobject, so we can reference it. */
|
||||
if (mod_sysfs_init(mod) != 0)
|
||||
goto cleanup;
|
||||
|
||||
/* Set up license info based on the info section */
|
||||
set_license(mod, get_modinfo(sechdrs, infoindex, "license"));
|
||||
|
||||
|
@ -2340,19 +2358,43 @@ static char *make_driver_name(struct device_driver *drv)
|
|||
return driver_name;
|
||||
}
|
||||
|
||||
static void module_create_drivers_dir(struct module_kobject *mk)
|
||||
{
|
||||
if (!mk || mk->drivers_dir)
|
||||
return;
|
||||
|
||||
mk->drivers_dir = kobject_add_dir(&mk->kobj, "drivers");
|
||||
}
|
||||
|
||||
void module_add_driver(struct module *mod, struct device_driver *drv)
|
||||
{
|
||||
char *driver_name;
|
||||
int no_warn;
|
||||
struct module_kobject *mk = NULL;
|
||||
|
||||
if (!mod || !drv)
|
||||
if (!drv)
|
||||
return;
|
||||
|
||||
if (mod)
|
||||
mk = &mod->mkobj;
|
||||
else if (drv->mod_name) {
|
||||
struct kobject *mkobj;
|
||||
|
||||
/* Lookup built-in module entry in /sys/modules */
|
||||
mkobj = kset_find_obj(&module_subsys.kset, drv->mod_name);
|
||||
if (mkobj)
|
||||
mk = container_of(mkobj, struct module_kobject, kobj);
|
||||
}
|
||||
|
||||
if (!mk)
|
||||
return;
|
||||
|
||||
/* Don't check return codes; these calls are idempotent */
|
||||
no_warn = sysfs_create_link(&drv->kobj, &mod->mkobj.kobj, "module");
|
||||
no_warn = sysfs_create_link(&drv->kobj, &mk->kobj, "module");
|
||||
driver_name = make_driver_name(drv);
|
||||
if (driver_name) {
|
||||
no_warn = sysfs_create_link(mod->drivers_dir, &drv->kobj,
|
||||
module_create_drivers_dir(mk);
|
||||
no_warn = sysfs_create_link(mk->drivers_dir, &drv->kobj,
|
||||
driver_name);
|
||||
kfree(driver_name);
|
||||
}
|
||||
|
@ -2367,10 +2409,10 @@ void module_remove_driver(struct device_driver *drv)
|
|||
return;
|
||||
|
||||
sysfs_remove_link(&drv->kobj, "module");
|
||||
if (drv->owner && drv->owner->drivers_dir) {
|
||||
if (drv->owner && drv->owner->mkobj.drivers_dir) {
|
||||
driver_name = make_driver_name(drv);
|
||||
if (driver_name) {
|
||||
sysfs_remove_link(drv->owner->drivers_dir,
|
||||
sysfs_remove_link(drv->owner->mkobj.drivers_dir,
|
||||
driver_name);
|
||||
kfree(driver_name);
|
||||
}
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
#define DEBUGP(fmt, a...)
|
||||
#endif
|
||||
|
||||
static struct kobj_type module_ktype;
|
||||
|
||||
static inline char dash2underscore(char c)
|
||||
{
|
||||
if (c == '-')
|
||||
|
@ -561,14 +563,11 @@ static void __init kernel_param_sysfs_setup(const char *name,
|
|||
mk->mod = THIS_MODULE;
|
||||
kobj_set_kset_s(mk, module_subsys);
|
||||
kobject_set_name(&mk->kobj, name);
|
||||
ret = kobject_register(&mk->kobj);
|
||||
kobject_init(&mk->kobj);
|
||||
ret = kobject_add(&mk->kobj);
|
||||
BUG_ON(ret < 0);
|
||||
|
||||
/* no need to keep the kobject if no parameter is exported */
|
||||
if (!param_sysfs_setup(mk, kparam, num_params, name_skip)) {
|
||||
kobject_unregister(&mk->kobj);
|
||||
kfree(mk);
|
||||
}
|
||||
param_sysfs_setup(mk, kparam, num_params, name_skip);
|
||||
kobject_uevent(&mk->kobj, KOBJ_ADD);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -674,6 +673,19 @@ static struct sysfs_ops module_sysfs_ops = {
|
|||
.store = module_attr_store,
|
||||
};
|
||||
|
||||
static int uevent_filter(struct kset *kset, struct kobject *kobj)
|
||||
{
|
||||
struct kobj_type *ktype = get_ktype(kobj);
|
||||
|
||||
if (ktype == &module_ktype)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct kset_uevent_ops module_uevent_ops = {
|
||||
.filter = uevent_filter,
|
||||
};
|
||||
|
||||
#else
|
||||
static struct sysfs_ops module_sysfs_ops = {
|
||||
.show = NULL,
|
||||
|
@ -685,7 +697,7 @@ static struct kobj_type module_ktype = {
|
|||
.sysfs_ops = &module_sysfs_ops,
|
||||
};
|
||||
|
||||
decl_subsys(module, &module_ktype, NULL);
|
||||
decl_subsys(module, &module_ktype, &module_uevent_ops);
|
||||
|
||||
/*
|
||||
* param_sysfs_init - wrapper for built-in params support
|
||||
|
|
|
@ -44,11 +44,11 @@ static int populate_dir(struct kobject * kobj)
|
|||
return error;
|
||||
}
|
||||
|
||||
static int create_dir(struct kobject * kobj)
|
||||
static int create_dir(struct kobject * kobj, struct dentry *shadow_parent)
|
||||
{
|
||||
int error = 0;
|
||||
if (kobject_name(kobj)) {
|
||||
error = sysfs_create_dir(kobj);
|
||||
error = sysfs_create_dir(kobj, shadow_parent);
|
||||
if (!error) {
|
||||
if ((error = populate_dir(kobj)))
|
||||
sysfs_remove_dir(kobj);
|
||||
|
@ -126,6 +126,8 @@ EXPORT_SYMBOL_GPL(kobject_get_path);
|
|||
*/
|
||||
void kobject_init(struct kobject * kobj)
|
||||
{
|
||||
if (!kobj)
|
||||
return;
|
||||
kref_init(&kobj->kref);
|
||||
INIT_LIST_HEAD(&kobj->entry);
|
||||
init_waitqueue_head(&kobj->poll);
|
||||
|
@ -156,9 +158,10 @@ static void unlink(struct kobject * kobj)
|
|||
/**
|
||||
* kobject_add - add an object to the hierarchy.
|
||||
* @kobj: object.
|
||||
* @shadow_parent: sysfs directory to add to.
|
||||
*/
|
||||
|
||||
int kobject_add(struct kobject * kobj)
|
||||
int kobject_shadow_add(struct kobject * kobj, struct dentry *shadow_parent)
|
||||
{
|
||||
int error = 0;
|
||||
struct kobject * parent;
|
||||
|
@ -189,12 +192,11 @@ int kobject_add(struct kobject * kobj)
|
|||
}
|
||||
kobj->parent = parent;
|
||||
|
||||
error = create_dir(kobj);
|
||||
error = create_dir(kobj, shadow_parent);
|
||||
if (error) {
|
||||
/* unlink does the kobject_put() for us */
|
||||
unlink(kobj);
|
||||
if (parent)
|
||||
kobject_put(parent);
|
||||
kobject_put(parent);
|
||||
|
||||
/* be noisy on error issues */
|
||||
if (error == -EEXIST)
|
||||
|
@ -211,6 +213,15 @@ int kobject_add(struct kobject * kobj)
|
|||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* kobject_add - add an object to the hierarchy.
|
||||
* @kobj: object.
|
||||
*/
|
||||
int kobject_add(struct kobject * kobj)
|
||||
{
|
||||
return kobject_shadow_add(kobj, NULL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* kobject_register - initialize and add an object.
|
||||
|
@ -303,7 +314,29 @@ int kobject_rename(struct kobject * kobj, const char *new_name)
|
|||
kobj = kobject_get(kobj);
|
||||
if (!kobj)
|
||||
return -EINVAL;
|
||||
error = sysfs_rename_dir(kobj, new_name);
|
||||
if (!kobj->parent)
|
||||
return -EINVAL;
|
||||
error = sysfs_rename_dir(kobj, kobj->parent->dentry, new_name);
|
||||
kobject_put(kobj);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* kobject_rename - change the name of an object
|
||||
* @kobj: object in question.
|
||||
* @new_name: object's new name
|
||||
*/
|
||||
|
||||
int kobject_shadow_rename(struct kobject * kobj, struct dentry *new_parent,
|
||||
const char *new_name)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
kobj = kobject_get(kobj);
|
||||
if (!kobj)
|
||||
return -EINVAL;
|
||||
error = sysfs_rename_dir(kobj, new_parent, new_name);
|
||||
kobject_put(kobj);
|
||||
|
||||
return error;
|
||||
|
@ -312,7 +345,7 @@ int kobject_rename(struct kobject * kobj, const char *new_name)
|
|||
/**
|
||||
* kobject_move - move object to another parent
|
||||
* @kobj: object in question.
|
||||
* @new_parent: object's new parent
|
||||
* @new_parent: object's new parent (can be NULL)
|
||||
*/
|
||||
|
||||
int kobject_move(struct kobject *kobj, struct kobject *new_parent)
|
||||
|
@ -328,8 +361,8 @@ int kobject_move(struct kobject *kobj, struct kobject *new_parent)
|
|||
return -EINVAL;
|
||||
new_parent = kobject_get(new_parent);
|
||||
if (!new_parent) {
|
||||
error = -EINVAL;
|
||||
goto out;
|
||||
if (kobj->kset)
|
||||
new_parent = kobject_get(&kobj->kset->kobj);
|
||||
}
|
||||
/* old object path */
|
||||
devpath = kobject_get_path(kobj, GFP_KERNEL);
|
||||
|
@ -366,6 +399,8 @@ int kobject_move(struct kobject *kobj, struct kobject *new_parent)
|
|||
|
||||
void kobject_del(struct kobject * kobj)
|
||||
{
|
||||
if (!kobj)
|
||||
return;
|
||||
sysfs_remove_dir(kobj);
|
||||
unlink(kobj);
|
||||
}
|
||||
|
@ -377,6 +412,8 @@ void kobject_del(struct kobject * kobj)
|
|||
|
||||
void kobject_unregister(struct kobject * kobj)
|
||||
{
|
||||
if (!kobj)
|
||||
return;
|
||||
pr_debug("kobject %s: unregistering\n",kobject_name(kobj));
|
||||
kobject_uevent(kobj, KOBJ_REMOVE);
|
||||
kobject_del(kobj);
|
||||
|
@ -414,8 +451,7 @@ void kobject_cleanup(struct kobject * kobj)
|
|||
t->release(kobj);
|
||||
if (s)
|
||||
kset_put(s);
|
||||
if (parent)
|
||||
kobject_put(parent);
|
||||
kobject_put(parent);
|
||||
}
|
||||
|
||||
static void kobject_release(struct kref *kref)
|
||||
|
@ -523,6 +559,8 @@ int kset_add(struct kset * k)
|
|||
|
||||
int kset_register(struct kset * k)
|
||||
{
|
||||
if (!k)
|
||||
return -EINVAL;
|
||||
kset_init(k);
|
||||
return kset_add(k);
|
||||
}
|
||||
|
@ -535,6 +573,8 @@ int kset_register(struct kset * k)
|
|||
|
||||
void kset_unregister(struct kset * k)
|
||||
{
|
||||
if (!k)
|
||||
return;
|
||||
kobject_unregister(&k->kobj);
|
||||
}
|
||||
|
||||
|
@ -586,6 +626,9 @@ int subsystem_register(struct subsystem * s)
|
|||
{
|
||||
int error;
|
||||
|
||||
if (!s)
|
||||
return -EINVAL;
|
||||
|
||||
subsystem_init(s);
|
||||
pr_debug("subsystem %s: registering\n",s->kset.kobj.name);
|
||||
|
||||
|
@ -598,6 +641,8 @@ int subsystem_register(struct subsystem * s)
|
|||
|
||||
void subsystem_unregister(struct subsystem * s)
|
||||
{
|
||||
if (!s)
|
||||
return;
|
||||
pr_debug("subsystem %s: unregistering\n",s->kset.kobj.name);
|
||||
kset_unregister(&s->kset);
|
||||
}
|
||||
|
@ -612,6 +657,10 @@ void subsystem_unregister(struct subsystem * s)
|
|||
int subsys_create_file(struct subsystem * s, struct subsys_attribute * a)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
if (!s || !a)
|
||||
return -EINVAL;
|
||||
|
||||
if (subsys_get(s)) {
|
||||
error = sysfs_create_file(&s->kset.kobj,&a->attr);
|
||||
subsys_put(s);
|
||||
|
|
|
@ -286,7 +286,7 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br,
|
|||
kobject_init(&p->kobj);
|
||||
kobject_set_name(&p->kobj, SYSFS_BRIDGE_PORT_ATTR);
|
||||
p->kobj.ktype = &brport_ktype;
|
||||
p->kobj.parent = &(dev->class_dev.kobj);
|
||||
p->kobj.parent = &(dev->dev.kobj);
|
||||
p->kobj.kset = NULL;
|
||||
|
||||
return p;
|
||||
|
|
|
@ -21,18 +21,17 @@
|
|||
|
||||
#include "br_private.h"
|
||||
|
||||
#define to_class_dev(obj) container_of(obj,struct class_device,kobj)
|
||||
#define to_net_dev(class) container_of(class, struct net_device, class_dev)
|
||||
#define to_dev(obj) container_of(obj, struct device, kobj)
|
||||
#define to_bridge(cd) ((struct net_bridge *)(to_net_dev(cd)->priv))
|
||||
|
||||
/*
|
||||
* Common code for storing bridge parameters.
|
||||
*/
|
||||
static ssize_t store_bridge_parm(struct class_device *cd,
|
||||
static ssize_t store_bridge_parm(struct device *d,
|
||||
const char *buf, size_t len,
|
||||
void (*set)(struct net_bridge *, unsigned long))
|
||||
{
|
||||
struct net_bridge *br = to_bridge(cd);
|
||||
struct net_bridge *br = to_bridge(d);
|
||||
char *endp;
|
||||
unsigned long val;
|
||||
|
||||
|
@ -50,9 +49,10 @@ static ssize_t store_bridge_parm(struct class_device *cd,
|
|||
}
|
||||
|
||||
|
||||
static ssize_t show_forward_delay(struct class_device *cd, char *buf)
|
||||
static ssize_t show_forward_delay(struct device *d,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct net_bridge *br = to_bridge(cd);
|
||||
struct net_bridge *br = to_bridge(d);
|
||||
return sprintf(buf, "%lu\n", jiffies_to_clock_t(br->forward_delay));
|
||||
}
|
||||
|
||||
|
@ -64,18 +64,20 @@ static void set_forward_delay(struct net_bridge *br, unsigned long val)
|
|||
br->bridge_forward_delay = delay;
|
||||
}
|
||||
|
||||
static ssize_t store_forward_delay(struct class_device *cd, const char *buf,
|
||||
size_t len)
|
||||
static ssize_t store_forward_delay(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t len)
|
||||
{
|
||||
return store_bridge_parm(cd, buf, len, set_forward_delay);
|
||||
return store_bridge_parm(d, buf, len, set_forward_delay);
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(forward_delay, S_IRUGO | S_IWUSR,
|
||||
show_forward_delay, store_forward_delay);
|
||||
static DEVICE_ATTR(forward_delay, S_IRUGO | S_IWUSR,
|
||||
show_forward_delay, store_forward_delay);
|
||||
|
||||
static ssize_t show_hello_time(struct class_device *cd, char *buf)
|
||||
static ssize_t show_hello_time(struct device *d, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return sprintf(buf, "%lu\n",
|
||||
jiffies_to_clock_t(to_bridge(cd)->hello_time));
|
||||
jiffies_to_clock_t(to_bridge(d)->hello_time));
|
||||
}
|
||||
|
||||
static void set_hello_time(struct net_bridge *br, unsigned long val)
|
||||
|
@ -86,19 +88,20 @@ static void set_hello_time(struct net_bridge *br, unsigned long val)
|
|||
br->bridge_hello_time = t;
|
||||
}
|
||||
|
||||
static ssize_t store_hello_time(struct class_device *cd, const char *buf,
|
||||
static ssize_t store_hello_time(struct device *d,
|
||||
struct device_attribute *attr, const char *buf,
|
||||
size_t len)
|
||||
{
|
||||
return store_bridge_parm(cd, buf, len, set_hello_time);
|
||||
return store_bridge_parm(d, buf, len, set_hello_time);
|
||||
}
|
||||
static DEVICE_ATTR(hello_time, S_IRUGO | S_IWUSR, show_hello_time,
|
||||
store_hello_time);
|
||||
|
||||
static CLASS_DEVICE_ATTR(hello_time, S_IRUGO | S_IWUSR, show_hello_time,
|
||||
store_hello_time);
|
||||
|
||||
static ssize_t show_max_age(struct class_device *cd, char *buf)
|
||||
static ssize_t show_max_age(struct device *d, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return sprintf(buf, "%lu\n",
|
||||
jiffies_to_clock_t(to_bridge(cd)->max_age));
|
||||
jiffies_to_clock_t(to_bridge(d)->max_age));
|
||||
}
|
||||
|
||||
static void set_max_age(struct net_bridge *br, unsigned long val)
|
||||
|
@ -109,18 +112,17 @@ static void set_max_age(struct net_bridge *br, unsigned long val)
|
|||
br->bridge_max_age = t;
|
||||
}
|
||||
|
||||
static ssize_t store_max_age(struct class_device *cd, const char *buf,
|
||||
size_t len)
|
||||
static ssize_t store_max_age(struct device *d, struct device_attribute *attr,
|
||||
const char *buf, size_t len)
|
||||
{
|
||||
return store_bridge_parm(cd, buf, len, set_max_age);
|
||||
return store_bridge_parm(d, buf, len, set_max_age);
|
||||
}
|
||||
static DEVICE_ATTR(max_age, S_IRUGO | S_IWUSR, show_max_age, store_max_age);
|
||||
|
||||
static CLASS_DEVICE_ATTR(max_age, S_IRUGO | S_IWUSR, show_max_age,
|
||||
store_max_age);
|
||||
|
||||
static ssize_t show_ageing_time(struct class_device *cd, char *buf)
|
||||
static ssize_t show_ageing_time(struct device *d,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct net_bridge *br = to_bridge(cd);
|
||||
struct net_bridge *br = to_bridge(d);
|
||||
return sprintf(buf, "%lu\n", jiffies_to_clock_t(br->ageing_time));
|
||||
}
|
||||
|
||||
|
@ -129,17 +131,19 @@ static void set_ageing_time(struct net_bridge *br, unsigned long val)
|
|||
br->ageing_time = clock_t_to_jiffies(val);
|
||||
}
|
||||
|
||||
static ssize_t store_ageing_time(struct class_device *cd, const char *buf,
|
||||
size_t len)
|
||||
static ssize_t store_ageing_time(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t len)
|
||||
{
|
||||
return store_bridge_parm(cd, buf, len, set_ageing_time);
|
||||
return store_bridge_parm(d, buf, len, set_ageing_time);
|
||||
}
|
||||
static DEVICE_ATTR(ageing_time, S_IRUGO | S_IWUSR, show_ageing_time,
|
||||
store_ageing_time);
|
||||
|
||||
static CLASS_DEVICE_ATTR(ageing_time, S_IRUGO | S_IWUSR, show_ageing_time,
|
||||
store_ageing_time);
|
||||
static ssize_t show_stp_state(struct class_device *cd, char *buf)
|
||||
static ssize_t show_stp_state(struct device *d,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct net_bridge *br = to_bridge(cd);
|
||||
struct net_bridge *br = to_bridge(d);
|
||||
return sprintf(buf, "%d\n", br->stp_enabled);
|
||||
}
|
||||
|
||||
|
@ -148,18 +152,19 @@ static void set_stp_state(struct net_bridge *br, unsigned long val)
|
|||
br->stp_enabled = val;
|
||||
}
|
||||
|
||||
static ssize_t store_stp_state(struct class_device *cd,
|
||||
const char *buf, size_t len)
|
||||
static ssize_t store_stp_state(struct device *d,
|
||||
struct device_attribute *attr, const char *buf,
|
||||
size_t len)
|
||||
{
|
||||
return store_bridge_parm(cd, buf, len, set_stp_state);
|
||||
return store_bridge_parm(d, buf, len, set_stp_state);
|
||||
}
|
||||
static DEVICE_ATTR(stp_state, S_IRUGO | S_IWUSR, show_stp_state,
|
||||
store_stp_state);
|
||||
|
||||
static CLASS_DEVICE_ATTR(stp_state, S_IRUGO | S_IWUSR, show_stp_state,
|
||||
store_stp_state);
|
||||
|
||||
static ssize_t show_priority(struct class_device *cd, char *buf)
|
||||
static ssize_t show_priority(struct device *d, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct net_bridge *br = to_bridge(cd);
|
||||
struct net_bridge *br = to_bridge(d);
|
||||
return sprintf(buf, "%d\n",
|
||||
(br->bridge_id.prio[0] << 8) | br->bridge_id.prio[1]);
|
||||
}
|
||||
|
@ -169,92 +174,107 @@ static void set_priority(struct net_bridge *br, unsigned long val)
|
|||
br_stp_set_bridge_priority(br, (u16) val);
|
||||
}
|
||||
|
||||
static ssize_t store_priority(struct class_device *cd,
|
||||
static ssize_t store_priority(struct device *d, struct device_attribute *attr,
|
||||
const char *buf, size_t len)
|
||||
{
|
||||
return store_bridge_parm(cd, buf, len, set_priority);
|
||||
return store_bridge_parm(d, buf, len, set_priority);
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(priority, S_IRUGO | S_IWUSR, show_priority,
|
||||
store_priority);
|
||||
static DEVICE_ATTR(priority, S_IRUGO | S_IWUSR, show_priority, store_priority);
|
||||
|
||||
static ssize_t show_root_id(struct class_device *cd, char *buf)
|
||||
static ssize_t show_root_id(struct device *d, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return br_show_bridge_id(buf, &to_bridge(cd)->designated_root);
|
||||
return br_show_bridge_id(buf, &to_bridge(d)->designated_root);
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(root_id, S_IRUGO, show_root_id, NULL);
|
||||
static DEVICE_ATTR(root_id, S_IRUGO, show_root_id, NULL);
|
||||
|
||||
static ssize_t show_bridge_id(struct class_device *cd, char *buf)
|
||||
static ssize_t show_bridge_id(struct device *d, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return br_show_bridge_id(buf, &to_bridge(cd)->bridge_id);
|
||||
return br_show_bridge_id(buf, &to_bridge(d)->bridge_id);
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(bridge_id, S_IRUGO, show_bridge_id, NULL);
|
||||
static DEVICE_ATTR(bridge_id, S_IRUGO, show_bridge_id, NULL);
|
||||
|
||||
static ssize_t show_root_port(struct class_device *cd, char *buf)
|
||||
static ssize_t show_root_port(struct device *d, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n", to_bridge(cd)->root_port);
|
||||
return sprintf(buf, "%d\n", to_bridge(d)->root_port);
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(root_port, S_IRUGO, show_root_port, NULL);
|
||||
static DEVICE_ATTR(root_port, S_IRUGO, show_root_port, NULL);
|
||||
|
||||
static ssize_t show_root_path_cost(struct class_device *cd, char *buf)
|
||||
static ssize_t show_root_path_cost(struct device *d,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n", to_bridge(cd)->root_path_cost);
|
||||
return sprintf(buf, "%d\n", to_bridge(d)->root_path_cost);
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(root_path_cost, S_IRUGO, show_root_path_cost, NULL);
|
||||
static DEVICE_ATTR(root_path_cost, S_IRUGO, show_root_path_cost, NULL);
|
||||
|
||||
static ssize_t show_topology_change(struct class_device *cd, char *buf)
|
||||
static ssize_t show_topology_change(struct device *d,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf, "%d\n", to_bridge(cd)->topology_change);
|
||||
return sprintf(buf, "%d\n", to_bridge(d)->topology_change);
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(topology_change, S_IRUGO, show_topology_change, NULL);
|
||||
static DEVICE_ATTR(topology_change, S_IRUGO, show_topology_change, NULL);
|
||||
|
||||
static ssize_t show_topology_change_detected(struct class_device *cd, char *buf)
|
||||
static ssize_t show_topology_change_detected(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct net_bridge *br = to_bridge(cd);
|
||||
struct net_bridge *br = to_bridge(d);
|
||||
return sprintf(buf, "%d\n", br->topology_change_detected);
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(topology_change_detected, S_IRUGO, show_topology_change_detected, NULL);
|
||||
static DEVICE_ATTR(topology_change_detected, S_IRUGO,
|
||||
show_topology_change_detected, NULL);
|
||||
|
||||
static ssize_t show_hello_timer(struct class_device *cd, char *buf)
|
||||
static ssize_t show_hello_timer(struct device *d,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct net_bridge *br = to_bridge(cd);
|
||||
struct net_bridge *br = to_bridge(d);
|
||||
return sprintf(buf, "%ld\n", br_timer_value(&br->hello_timer));
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(hello_timer, S_IRUGO, show_hello_timer, NULL);
|
||||
static DEVICE_ATTR(hello_timer, S_IRUGO, show_hello_timer, NULL);
|
||||
|
||||
static ssize_t show_tcn_timer(struct class_device *cd, char *buf)
|
||||
static ssize_t show_tcn_timer(struct device *d, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct net_bridge *br = to_bridge(cd);
|
||||
struct net_bridge *br = to_bridge(d);
|
||||
return sprintf(buf, "%ld\n", br_timer_value(&br->tcn_timer));
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(tcn_timer, S_IRUGO, show_tcn_timer, NULL);
|
||||
static DEVICE_ATTR(tcn_timer, S_IRUGO, show_tcn_timer, NULL);
|
||||
|
||||
static ssize_t show_topology_change_timer(struct class_device *cd, char *buf)
|
||||
static ssize_t show_topology_change_timer(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct net_bridge *br = to_bridge(cd);
|
||||
struct net_bridge *br = to_bridge(d);
|
||||
return sprintf(buf, "%ld\n", br_timer_value(&br->topology_change_timer));
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(topology_change_timer, S_IRUGO, show_topology_change_timer, NULL);
|
||||
static DEVICE_ATTR(topology_change_timer, S_IRUGO, show_topology_change_timer,
|
||||
NULL);
|
||||
|
||||
static ssize_t show_gc_timer(struct class_device *cd, char *buf)
|
||||
static ssize_t show_gc_timer(struct device *d, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct net_bridge *br = to_bridge(cd);
|
||||
struct net_bridge *br = to_bridge(d);
|
||||
return sprintf(buf, "%ld\n", br_timer_value(&br->gc_timer));
|
||||
}
|
||||
static CLASS_DEVICE_ATTR(gc_timer, S_IRUGO, show_gc_timer, NULL);
|
||||
static DEVICE_ATTR(gc_timer, S_IRUGO, show_gc_timer, NULL);
|
||||
|
||||
static ssize_t show_group_addr(struct class_device *cd, char *buf)
|
||||
static ssize_t show_group_addr(struct device *d,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct net_bridge *br = to_bridge(cd);
|
||||
struct net_bridge *br = to_bridge(d);
|
||||
return sprintf(buf, "%x:%x:%x:%x:%x:%x\n",
|
||||
br->group_addr[0], br->group_addr[1],
|
||||
br->group_addr[2], br->group_addr[3],
|
||||
br->group_addr[4], br->group_addr[5]);
|
||||
}
|
||||
|
||||
static ssize_t store_group_addr(struct class_device *cd, const char *buf,
|
||||
size_t len)
|
||||
static ssize_t store_group_addr(struct device *d,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t len)
|
||||
{
|
||||
struct net_bridge *br = to_bridge(cd);
|
||||
struct net_bridge *br = to_bridge(d);
|
||||
unsigned new_addr[6];
|
||||
int i;
|
||||
|
||||
|
@ -286,28 +306,28 @@ static ssize_t store_group_addr(struct class_device *cd, const char *buf,
|
|||
return len;
|
||||
}
|
||||
|
||||
static CLASS_DEVICE_ATTR(group_addr, S_IRUGO | S_IWUSR,
|
||||
show_group_addr, store_group_addr);
|
||||
static DEVICE_ATTR(group_addr, S_IRUGO | S_IWUSR,
|
||||
show_group_addr, store_group_addr);
|
||||
|
||||
|
||||
static struct attribute *bridge_attrs[] = {
|
||||
&class_device_attr_forward_delay.attr,
|
||||
&class_device_attr_hello_time.attr,
|
||||
&class_device_attr_max_age.attr,
|
||||
&class_device_attr_ageing_time.attr,
|
||||
&class_device_attr_stp_state.attr,
|
||||
&class_device_attr_priority.attr,
|
||||
&class_device_attr_bridge_id.attr,
|
||||
&class_device_attr_root_id.attr,
|
||||
&class_device_attr_root_path_cost.attr,
|
||||
&class_device_attr_root_port.attr,
|
||||
&class_device_attr_topology_change.attr,
|
||||
&class_device_attr_topology_change_detected.attr,
|
||||
&class_device_attr_hello_timer.attr,
|
||||
&class_device_attr_tcn_timer.attr,
|
||||
&class_device_attr_topology_change_timer.attr,
|
||||
&class_device_attr_gc_timer.attr,
|
||||
&class_device_attr_group_addr.attr,
|
||||
&dev_attr_forward_delay.attr,
|
||||
&dev_attr_hello_time.attr,
|
||||
&dev_attr_max_age.attr,
|
||||
&dev_attr_ageing_time.attr,
|
||||
&dev_attr_stp_state.attr,
|
||||
&dev_attr_priority.attr,
|
||||
&dev_attr_bridge_id.attr,
|
||||
&dev_attr_root_id.attr,
|
||||
&dev_attr_root_path_cost.attr,
|
||||
&dev_attr_root_port.attr,
|
||||
&dev_attr_topology_change.attr,
|
||||
&dev_attr_topology_change_detected.attr,
|
||||
&dev_attr_hello_timer.attr,
|
||||
&dev_attr_tcn_timer.attr,
|
||||
&dev_attr_topology_change_timer.attr,
|
||||
&dev_attr_gc_timer.attr,
|
||||
&dev_attr_group_addr.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -325,8 +345,8 @@ static struct attribute_group bridge_group = {
|
|||
static ssize_t brforward_read(struct kobject *kobj, char *buf,
|
||||
loff_t off, size_t count)
|
||||
{
|
||||
struct class_device *cdev = to_class_dev(kobj);
|
||||
struct net_bridge *br = to_bridge(cdev);
|
||||
struct device *dev = to_dev(kobj);
|
||||
struct net_bridge *br = to_bridge(dev);
|
||||
int n;
|
||||
|
||||
/* must read whole records */
|
||||
|
@ -363,7 +383,7 @@ static struct bin_attribute bridge_forward = {
|
|||
*/
|
||||
int br_sysfs_addbr(struct net_device *dev)
|
||||
{
|
||||
struct kobject *brobj = &dev->class_dev.kobj;
|
||||
struct kobject *brobj = &dev->dev.kobj;
|
||||
struct net_bridge *br = netdev_priv(dev);
|
||||
int err;
|
||||
|
||||
|
@ -395,9 +415,9 @@ int br_sysfs_addbr(struct net_device *dev)
|
|||
}
|
||||
return 0;
|
||||
out3:
|
||||
sysfs_remove_bin_file(&dev->class_dev.kobj, &bridge_forward);
|
||||
sysfs_remove_bin_file(&dev->dev.kobj, &bridge_forward);
|
||||
out2:
|
||||
sysfs_remove_group(&dev->class_dev.kobj, &bridge_group);
|
||||
sysfs_remove_group(&dev->dev.kobj, &bridge_group);
|
||||
out1:
|
||||
return err;
|
||||
|
||||
|
@ -405,7 +425,7 @@ int br_sysfs_addbr(struct net_device *dev)
|
|||
|
||||
void br_sysfs_delbr(struct net_device *dev)
|
||||
{
|
||||
struct kobject *kobj = &dev->class_dev.kobj;
|
||||
struct kobject *kobj = &dev->dev.kobj;
|
||||
struct net_bridge *br = netdev_priv(dev);
|
||||
|
||||
kobject_unregister(&br->ifobj);
|
||||
|
|
|
@ -211,7 +211,7 @@ int br_sysfs_addif(struct net_bridge_port *p)
|
|||
struct brport_attribute **a;
|
||||
int err;
|
||||
|
||||
err = sysfs_create_link(&p->kobj, &br->dev->class_dev.kobj,
|
||||
err = sysfs_create_link(&p->kobj, &br->dev->dev.kobj,
|
||||
SYSFS_BRIDGE_PORT_LINK);
|
||||
if (err)
|
||||
goto out2;
|
||||
|
|
|
@ -751,7 +751,7 @@ int dev_change_name(struct net_device *dev, char *newname)
|
|||
else
|
||||
strlcpy(dev->name, newname, IFNAMSIZ);
|
||||
|
||||
err = class_device_rename(&dev->class_dev, dev->name);
|
||||
err = device_rename(&dev->dev, dev->name);
|
||||
if (!err) {
|
||||
hlist_del(&dev->name_hlist);
|
||||
hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name));
|
||||
|
@ -3221,8 +3221,8 @@ void free_netdev(struct net_device *dev)
|
|||
BUG_ON(dev->reg_state != NETREG_UNREGISTERED);
|
||||
dev->reg_state = NETREG_RELEASED;
|
||||
|
||||
/* will free via class release */
|
||||
class_device_put(&dev->class_dev);
|
||||
/* will free via device release */
|
||||
put_device(&dev->dev);
|
||||
#else
|
||||
kfree((char *)dev - dev->padded);
|
||||
#endif
|
||||
|
|
|
@ -18,9 +18,6 @@
|
|||
#include <linux/wireless.h>
|
||||
#include <net/iw_handler.h>
|
||||
|
||||
#define to_class_dev(obj) container_of(obj,struct class_device,kobj)
|
||||
#define to_net_dev(class) container_of(class, struct net_device, class_dev)
|
||||
|
||||
static const char fmt_hex[] = "%#x\n";
|
||||
static const char fmt_long_hex[] = "%#lx\n";
|
||||
static const char fmt_dec[] = "%d\n";
|
||||
|
@ -32,10 +29,11 @@ static inline int dev_isalive(const struct net_device *dev)
|
|||
}
|
||||
|
||||
/* use same locking rules as GIF* ioctl's */
|
||||
static ssize_t netdev_show(const struct class_device *cd, char *buf,
|
||||
static ssize_t netdev_show(const struct device *dev,
|
||||
struct device_attribute *attr, char *buf,
|
||||
ssize_t (*format)(const struct net_device *, char *))
|
||||
{
|
||||
struct net_device *net = to_net_dev(cd);
|
||||
struct net_device *net = to_net_dev(dev);
|
||||
ssize_t ret = -EINVAL;
|
||||
|
||||
read_lock(&dev_base_lock);
|
||||
|
@ -52,14 +50,15 @@ static ssize_t format_##field(const struct net_device *net, char *buf) \
|
|||
{ \
|
||||
return sprintf(buf, format_string, net->field); \
|
||||
} \
|
||||
static ssize_t show_##field(struct class_device *cd, char *buf) \
|
||||
static ssize_t show_##field(struct device *dev, \
|
||||
struct device_attribute *attr, char *buf) \
|
||||
{ \
|
||||
return netdev_show(cd, buf, format_##field); \
|
||||
return netdev_show(dev, attr, buf, format_##field); \
|
||||
}
|
||||
|
||||
|
||||
/* use same locking and permission rules as SIF* ioctl's */
|
||||
static ssize_t netdev_store(struct class_device *dev,
|
||||
static ssize_t netdev_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t len,
|
||||
int (*set)(struct net_device *, unsigned long))
|
||||
{
|
||||
|
@ -104,7 +103,8 @@ static ssize_t format_addr(char *buf, const unsigned char *addr, int len)
|
|||
return cp - buf;
|
||||
}
|
||||
|
||||
static ssize_t show_address(struct class_device *dev, char *buf)
|
||||
static ssize_t show_address(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct net_device *net = to_net_dev(dev);
|
||||
ssize_t ret = -EINVAL;
|
||||
|
@ -116,7 +116,8 @@ static ssize_t show_address(struct class_device *dev, char *buf)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t show_broadcast(struct class_device *dev, char *buf)
|
||||
static ssize_t show_broadcast(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct net_device *net = to_net_dev(dev);
|
||||
if (dev_isalive(net))
|
||||
|
@ -124,7 +125,8 @@ static ssize_t show_broadcast(struct class_device *dev, char *buf)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
static ssize_t show_carrier(struct class_device *dev, char *buf)
|
||||
static ssize_t show_carrier(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct net_device *netdev = to_net_dev(dev);
|
||||
if (netif_running(netdev)) {
|
||||
|
@ -133,7 +135,8 @@ static ssize_t show_carrier(struct class_device *dev, char *buf)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
static ssize_t show_dormant(struct class_device *dev, char *buf)
|
||||
static ssize_t show_dormant(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct net_device *netdev = to_net_dev(dev);
|
||||
|
||||
|
@ -153,7 +156,8 @@ static const char *operstates[] = {
|
|||
"up"
|
||||
};
|
||||
|
||||
static ssize_t show_operstate(struct class_device *dev, char *buf)
|
||||
static ssize_t show_operstate(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
const struct net_device *netdev = to_net_dev(dev);
|
||||
unsigned char operstate;
|
||||
|
@ -178,9 +182,10 @@ static int change_mtu(struct net_device *net, unsigned long new_mtu)
|
|||
return dev_set_mtu(net, (int) new_mtu);
|
||||
}
|
||||
|
||||
static ssize_t store_mtu(struct class_device *dev, const char *buf, size_t len)
|
||||
static ssize_t store_mtu(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t len)
|
||||
{
|
||||
return netdev_store(dev, buf, len, change_mtu);
|
||||
return netdev_store(dev, attr, buf, len, change_mtu);
|
||||
}
|
||||
|
||||
NETDEVICE_SHOW(flags, fmt_hex);
|
||||
|
@ -190,9 +195,10 @@ static int change_flags(struct net_device *net, unsigned long new_flags)
|
|||
return dev_change_flags(net, (unsigned) new_flags);
|
||||
}
|
||||
|
||||
static ssize_t store_flags(struct class_device *dev, const char *buf, size_t len)
|
||||
static ssize_t store_flags(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t len)
|
||||
{
|
||||
return netdev_store(dev, buf, len, change_flags);
|
||||
return netdev_store(dev, attr, buf, len, change_flags);
|
||||
}
|
||||
|
||||
NETDEVICE_SHOW(tx_queue_len, fmt_ulong);
|
||||
|
@ -203,9 +209,11 @@ static int change_tx_queue_len(struct net_device *net, unsigned long new_len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t store_tx_queue_len(struct class_device *dev, const char *buf, size_t len)
|
||||
static ssize_t store_tx_queue_len(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t len)
|
||||
{
|
||||
return netdev_store(dev, buf, len, change_tx_queue_len);
|
||||
return netdev_store(dev, attr, buf, len, change_tx_queue_len);
|
||||
}
|
||||
|
||||
NETDEVICE_SHOW(weight, fmt_dec);
|
||||
|
@ -216,12 +224,13 @@ static int change_weight(struct net_device *net, unsigned long new_weight)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t store_weight(struct class_device *dev, const char *buf, size_t len)
|
||||
static ssize_t store_weight(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t len)
|
||||
{
|
||||
return netdev_store(dev, buf, len, change_weight);
|
||||
return netdev_store(dev, attr, buf, len, change_weight);
|
||||
}
|
||||
|
||||
static struct class_device_attribute net_class_attributes[] = {
|
||||
static struct 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),
|
||||
|
@ -242,10 +251,11 @@ static struct class_device_attribute net_class_attributes[] = {
|
|||
};
|
||||
|
||||
/* Show a given an attribute in the statistics group */
|
||||
static ssize_t netstat_show(const struct class_device *cd, char *buf,
|
||||
static ssize_t netstat_show(const struct device *d,
|
||||
struct device_attribute *attr, char *buf,
|
||||
unsigned long offset)
|
||||
{
|
||||
struct net_device *dev = to_net_dev(cd);
|
||||
struct net_device *dev = to_net_dev(d);
|
||||
struct net_device_stats *stats;
|
||||
ssize_t ret = -EINVAL;
|
||||
|
||||
|
@ -265,12 +275,13 @@ static ssize_t netstat_show(const struct class_device *cd, char *buf,
|
|||
|
||||
/* generate a read-only statistics attribute */
|
||||
#define NETSTAT_ENTRY(name) \
|
||||
static ssize_t show_##name(struct class_device *cd, char *buf) \
|
||||
static ssize_t show_##name(struct device *d, \
|
||||
struct device_attribute *attr, char *buf) \
|
||||
{ \
|
||||
return netstat_show(cd, buf, \
|
||||
return netstat_show(d, attr, buf, \
|
||||
offsetof(struct net_device_stats, name)); \
|
||||
} \
|
||||
static CLASS_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
|
||||
static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
|
||||
|
||||
NETSTAT_ENTRY(rx_packets);
|
||||
NETSTAT_ENTRY(tx_packets);
|
||||
|
@ -297,29 +308,29 @@ NETSTAT_ENTRY(rx_compressed);
|
|||
NETSTAT_ENTRY(tx_compressed);
|
||||
|
||||
static struct attribute *netstat_attrs[] = {
|
||||
&class_device_attr_rx_packets.attr,
|
||||
&class_device_attr_tx_packets.attr,
|
||||
&class_device_attr_rx_bytes.attr,
|
||||
&class_device_attr_tx_bytes.attr,
|
||||
&class_device_attr_rx_errors.attr,
|
||||
&class_device_attr_tx_errors.attr,
|
||||
&class_device_attr_rx_dropped.attr,
|
||||
&class_device_attr_tx_dropped.attr,
|
||||
&class_device_attr_multicast.attr,
|
||||
&class_device_attr_collisions.attr,
|
||||
&class_device_attr_rx_length_errors.attr,
|
||||
&class_device_attr_rx_over_errors.attr,
|
||||
&class_device_attr_rx_crc_errors.attr,
|
||||
&class_device_attr_rx_frame_errors.attr,
|
||||
&class_device_attr_rx_fifo_errors.attr,
|
||||
&class_device_attr_rx_missed_errors.attr,
|
||||
&class_device_attr_tx_aborted_errors.attr,
|
||||
&class_device_attr_tx_carrier_errors.attr,
|
||||
&class_device_attr_tx_fifo_errors.attr,
|
||||
&class_device_attr_tx_heartbeat_errors.attr,
|
||||
&class_device_attr_tx_window_errors.attr,
|
||||
&class_device_attr_rx_compressed.attr,
|
||||
&class_device_attr_tx_compressed.attr,
|
||||
&dev_attr_rx_packets.attr,
|
||||
&dev_attr_tx_packets.attr,
|
||||
&dev_attr_rx_bytes.attr,
|
||||
&dev_attr_tx_bytes.attr,
|
||||
&dev_attr_rx_errors.attr,
|
||||
&dev_attr_tx_errors.attr,
|
||||
&dev_attr_rx_dropped.attr,
|
||||
&dev_attr_tx_dropped.attr,
|
||||
&dev_attr_multicast.attr,
|
||||
&dev_attr_collisions.attr,
|
||||
&dev_attr_rx_length_errors.attr,
|
||||
&dev_attr_rx_over_errors.attr,
|
||||
&dev_attr_rx_crc_errors.attr,
|
||||
&dev_attr_rx_frame_errors.attr,
|
||||
&dev_attr_rx_fifo_errors.attr,
|
||||
&dev_attr_rx_missed_errors.attr,
|
||||
&dev_attr_tx_aborted_errors.attr,
|
||||
&dev_attr_tx_carrier_errors.attr,
|
||||
&dev_attr_tx_fifo_errors.attr,
|
||||
&dev_attr_tx_heartbeat_errors.attr,
|
||||
&dev_attr_tx_window_errors.attr,
|
||||
&dev_attr_rx_compressed.attr,
|
||||
&dev_attr_tx_compressed.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -331,11 +342,11 @@ static struct attribute_group netstat_group = {
|
|||
|
||||
#ifdef WIRELESS_EXT
|
||||
/* helper function that does all the locking etc for wireless stats */
|
||||
static ssize_t wireless_show(struct class_device *cd, char *buf,
|
||||
static ssize_t wireless_show(struct device *d, char *buf,
|
||||
ssize_t (*format)(const struct iw_statistics *,
|
||||
char *))
|
||||
{
|
||||
struct net_device *dev = to_net_dev(cd);
|
||||
struct net_device *dev = to_net_dev(d);
|
||||
const struct iw_statistics *iw = NULL;
|
||||
ssize_t ret = -EINVAL;
|
||||
|
||||
|
@ -358,11 +369,12 @@ static ssize_t format_iw_##name(const struct iw_statistics *iw, char *buf) \
|
|||
{ \
|
||||
return sprintf(buf, format_string, iw->field); \
|
||||
} \
|
||||
static ssize_t show_iw_##name(struct class_device *cd, char *buf) \
|
||||
static ssize_t show_iw_##name(struct device *d, \
|
||||
struct device_attribute *attr, char *buf) \
|
||||
{ \
|
||||
return wireless_show(cd, buf, format_iw_##name); \
|
||||
return wireless_show(d, buf, format_iw_##name); \
|
||||
} \
|
||||
static CLASS_DEVICE_ATTR(name, S_IRUGO, show_iw_##name, NULL)
|
||||
static DEVICE_ATTR(name, S_IRUGO, show_iw_##name, NULL)
|
||||
|
||||
WIRELESS_SHOW(status, status, fmt_hex);
|
||||
WIRELESS_SHOW(link, qual.qual, fmt_dec);
|
||||
|
@ -376,16 +388,16 @@ WIRELESS_SHOW(retries, discard.retries, fmt_dec);
|
|||
WIRELESS_SHOW(beacon, miss.beacon, fmt_dec);
|
||||
|
||||
static struct attribute *wireless_attrs[] = {
|
||||
&class_device_attr_status.attr,
|
||||
&class_device_attr_link.attr,
|
||||
&class_device_attr_level.attr,
|
||||
&class_device_attr_noise.attr,
|
||||
&class_device_attr_nwid.attr,
|
||||
&class_device_attr_crypt.attr,
|
||||
&class_device_attr_fragment.attr,
|
||||
&class_device_attr_retries.attr,
|
||||
&class_device_attr_misc.attr,
|
||||
&class_device_attr_beacon.attr,
|
||||
&dev_attr_status.attr,
|
||||
&dev_attr_link.attr,
|
||||
&dev_attr_level.attr,
|
||||
&dev_attr_noise.attr,
|
||||
&dev_attr_nwid.attr,
|
||||
&dev_attr_crypt.attr,
|
||||
&dev_attr_fragment.attr,
|
||||
&dev_attr_retries.attr,
|
||||
&dev_attr_misc.attr,
|
||||
&dev_attr_beacon.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -396,10 +408,10 @@ static struct attribute_group wireless_group = {
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_HOTPLUG
|
||||
static int netdev_uevent(struct class_device *cd, char **envp,
|
||||
static int netdev_uevent(struct device *d, char **envp,
|
||||
int num_envp, char *buf, int size)
|
||||
{
|
||||
struct net_device *dev = to_net_dev(cd);
|
||||
struct net_device *dev = to_net_dev(d);
|
||||
int i = 0;
|
||||
int n;
|
||||
|
||||
|
@ -419,12 +431,11 @@ static int netdev_uevent(struct class_device *cd, char **envp,
|
|||
|
||||
/*
|
||||
* netdev_release -- destroy and free a dead device.
|
||||
* Called when last reference to class_device kobject is gone.
|
||||
* Called when last reference to device kobject is gone.
|
||||
*/
|
||||
static void netdev_release(struct class_device *cd)
|
||||
static void netdev_release(struct device *d)
|
||||
{
|
||||
struct net_device *dev
|
||||
= container_of(cd, struct net_device, class_dev);
|
||||
struct net_device *dev = to_net_dev(d);
|
||||
|
||||
BUG_ON(dev->reg_state != NETREG_RELEASED);
|
||||
|
||||
|
@ -433,31 +444,31 @@ static void netdev_release(struct class_device *cd)
|
|||
|
||||
static struct class net_class = {
|
||||
.name = "net",
|
||||
.release = netdev_release,
|
||||
.class_dev_attrs = net_class_attributes,
|
||||
.dev_release = netdev_release,
|
||||
.dev_attrs = net_class_attributes,
|
||||
#ifdef CONFIG_HOTPLUG
|
||||
.uevent = netdev_uevent,
|
||||
.dev_uevent = netdev_uevent,
|
||||
#endif
|
||||
};
|
||||
|
||||
void netdev_unregister_sysfs(struct net_device * net)
|
||||
{
|
||||
class_device_del(&(net->class_dev));
|
||||
device_del(&(net->dev));
|
||||
}
|
||||
|
||||
/* Create sysfs entries for network device. */
|
||||
int netdev_register_sysfs(struct net_device *net)
|
||||
{
|
||||
struct class_device *class_dev = &(net->class_dev);
|
||||
struct device *dev = &(net->dev);
|
||||
struct attribute_group **groups = net->sysfs_groups;
|
||||
|
||||
class_device_initialize(class_dev);
|
||||
class_dev->class = &net_class;
|
||||
class_dev->class_data = net;
|
||||
class_dev->groups = groups;
|
||||
device_initialize(dev);
|
||||
dev->class = &net_class;
|
||||
dev->platform_data = net;
|
||||
dev->groups = groups;
|
||||
|
||||
BUILD_BUG_ON(BUS_ID_SIZE < IFNAMSIZ);
|
||||
strlcpy(class_dev->class_id, net->name, BUS_ID_SIZE);
|
||||
strlcpy(dev->bus_id, net->name, BUS_ID_SIZE);
|
||||
|
||||
if (net->get_stats)
|
||||
*groups++ = &netstat_group;
|
||||
|
@ -467,7 +478,7 @@ int netdev_register_sysfs(struct net_device *net)
|
|||
*groups++ = &wireless_group;
|
||||
#endif
|
||||
|
||||
return class_device_add(class_dev);
|
||||
return device_add(dev);
|
||||
}
|
||||
|
||||
int netdev_sysfs_init(void)
|
||||
|
|
|
@ -268,7 +268,7 @@ struct sk_buff *alloc_skb_from_cache(struct kmem_cache *cp,
|
|||
struct sk_buff *__netdev_alloc_skb(struct net_device *dev,
|
||||
unsigned int length, gfp_t gfp_mask)
|
||||
{
|
||||
int node = dev->class_dev.dev ? dev_to_node(dev->class_dev.dev) : -1;
|
||||
int node = dev->dev.parent ? dev_to_node(dev->dev.parent) : -1;
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask, 0, node);
|
||||
|
|
Loading…
Reference in a new issue