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:
Linus Torvalds 2007-02-07 19:22:26 -08:00
Родитель 7677ced48e b592fcfe7f
Коммит f2aca47dc3
69 изменённых файлов: 1286 добавлений и 709 удалений

Просмотреть файл

@ -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: experience, the following books are good for, if anything, reference:
- "The C Programming Language" by Kernighan and Ritchie [Prentice Hall] - "The C Programming Language" by Kernighan and Ritchie [Prentice Hall]
- "Practical C Programming" by Steve Oualline [O'Reilly] - "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 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 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); class_name = kmalloc(size, GFP_KERNEL);
if (!class_name) if (!class_name)
return ERR_PTR(-ENOMEM); return NULL;
strcpy(class_name, name); strcpy(class_name, name);
strcat(class_name, ":"); strcat(class_name, ":");
@ -411,8 +411,11 @@ static int make_deprecated_class_device_links(struct class_device *class_dev)
return 0; return 0;
class_name = make_class_name(class_dev->class->name, &class_dev->kobj); class_name = make_class_name(class_dev->class->name, &class_dev->kobj);
error = sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj, if (class_name)
class_name); error = sysfs_create_link(&class_dev->dev->kobj,
&class_dev->kobj, class_name);
else
error = -ENOMEM;
kfree(class_name); kfree(class_name);
return error; return error;
} }
@ -425,7 +428,8 @@ static void remove_deprecated_class_device_links(struct class_device *class_dev)
return; return;
class_name = make_class_name(class_dev->class->name, &class_dev->kobj); 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); kfree(class_name);
} }
#else #else
@ -863,9 +867,12 @@ int class_device_rename(struct class_device *class_dev, char *new_name)
if (class_dev->dev) { if (class_dev->dev) {
new_class_name = make_class_name(class_dev->class->name, new_class_name = make_class_name(class_dev->class->name,
&class_dev->kobj); &class_dev->kobj);
sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj, if (new_class_name)
new_class_name); sysfs_create_link(&class_dev->dev->kobj,
sysfs_remove_link(&class_dev->dev->kobj, old_class_name); &class_dev->kobj, new_class_name);
if (old_class_name)
sysfs_remove_link(&class_dev->dev->kobj,
old_class_name);
} }
#endif #endif
class_device_put(class_dev); class_device_put(class_dev);

Просмотреть файл

@ -95,6 +95,8 @@ static void device_release(struct kobject * kobj)
if (dev->release) if (dev->release)
dev->release(dev); dev->release(dev);
else if (dev->type && dev->type->release)
dev->type->release(dev);
else if (dev->class && dev->class->dev_release) else if (dev->class && dev->class->dev_release)
dev->class->dev_release(dev); dev->class->dev_release(dev);
else { else {
@ -154,25 +156,47 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
"MINOR=%u", MINOR(dev->devt)); "MINOR=%u", MINOR(dev->devt));
} }
#ifdef CONFIG_SYSFS_DEPRECATED if (dev->driver)
/* 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) {
add_uevent_var(envp, num_envp, &i, add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length, buffer, buffer_size, &length,
"DRIVER=%s", dev->driver->name); "DRIVER=%s", dev->driver->name);
#ifdef CONFIG_SYSFS_DEPRECATED #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, add_uevent_var(envp, num_envp, &i,
buffer, buffer_size, &length, buffer, buffer_size, &length,
"PHYSDEVDRIVER=%s", dev->driver->name); "PHYSDEVBUS=%s", dev->bus->name);
#endif
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 */ /* terminate, set to next free slot, shrink available space */
envp[i] = NULL; 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) { if (dev->bus && dev->bus->uevent) {
/* have the bus specific function add its stuff */ /* have the bus specific function add its stuff */
retval = dev->bus->uevent(dev, envp, num_envp, buffer, buffer_size); retval = dev->bus->uevent(dev, envp, num_envp, buffer, buffer_size);
if (retval) { if (retval)
pr_debug ("%s - uevent() returned %d\n", pr_debug ("%s: bus uevent() returned %d\n",
__FUNCTION__, retval); __FUNCTION__, retval);
}
} }
if (dev->class && dev->class->dev_uevent) { if (dev->class && dev->class->dev_uevent) {
/* have the class specific function add its stuff */ /* have the class specific function add its stuff */
retval = dev->class->dev_uevent(dev, envp, num_envp, buffer, buffer_size); retval = dev->class->dev_uevent(dev, envp, num_envp, buffer, buffer_size);
if (retval) { if (retval)
pr_debug("%s - dev_uevent() returned %d\n", pr_debug("%s: class uevent() returned %d\n",
__FUNCTION__, retval); __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; return retval;
@ -247,37 +277,50 @@ static void device_remove_groups(struct device *dev)
static int device_add_attrs(struct device *dev) static int device_add_attrs(struct device *dev)
{ {
struct class *class = dev->class; struct class *class = dev->class;
struct device_type *type = dev->type;
int error = 0; int error = 0;
int i; int i;
if (!class) if (class && class->dev_attrs) {
return 0;
if (class->dev_attrs) {
for (i = 0; attr_name(class->dev_attrs[i]); i++) { for (i = 0; attr_name(class->dev_attrs[i]); i++) {
error = device_create_file(dev, &class->dev_attrs[i]); error = device_create_file(dev, &class->dev_attrs[i]);
if (error) if (error)
break; break;
} }
if (error)
while (--i >= 0)
device_remove_file(dev, &class->dev_attrs[i]);
} }
if (error)
while (--i >= 0) if (type && type->attrs) {
device_remove_file(dev, &class->dev_attrs[i]); 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; return error;
} }
static void device_remove_attrs(struct device *dev) static void device_remove_attrs(struct device *dev)
{ {
struct class *class = dev->class; struct class *class = dev->class;
struct device_type *type = dev->type;
int i; int i;
if (!class) if (class && class->dev_attrs) {
return;
if (class->dev_attrs) {
for (i = 0; attr_name(class->dev_attrs[i]); i++) for (i = 0; attr_name(class->dev_attrs[i]); i++)
device_remove_file(dev, &class->dev_attrs[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 #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 */ /* Set the parent to the class, not the parent device */
/* this keeps sysfs from having a symlink to make old udevs happy */ /* this keeps sysfs from having a symlink to make old udevs happy */
if (dev->class) if (dev->class)
dev->kobj.parent = &dev->class->subsys.kset.kobj; return &dev->class->subsys.kset.kobj;
else if (parent) else if (parent)
dev->kobj.parent = &parent->kobj; return &parent->kobj;
return 0; return NULL;
} }
#else #else
static int virtual_device_parent(struct device *dev) static struct kobject * virtual_device_parent(struct device *dev)
{ {
if (!dev->class) if (!dev->class)
return -ENODEV; return ERR_PTR(-ENODEV);
if (!dev->class->virtual_dir) { if (!dev->class->virtual_dir) {
static struct kobject *virtual_dir = NULL; 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->class->virtual_dir = kobject_add_dir(virtual_dir, dev->class->name);
} }
dev->kobj.parent = dev->class->virtual_dir; return dev->class->virtual_dir;
return 0;
} }
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 this is a class device, and has no parent, create one */
if ((dev->class) && (parent == NULL)) { if ((dev->class) && (parent == NULL)) {
error = virtual_device_parent(dev); return virtual_device_parent(dev);
if (error)
return error;
} else if (parent) } 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; return 0;
} }
#endif
/** /**
* device_add - add device to device hierarchy. * device_add - add device to device hierarchy.
@ -520,9 +570,13 @@ int device_add(struct device *dev)
&dev->kobj, dev->bus_id); &dev->kobj, dev->bus_id);
#ifdef CONFIG_SYSFS_DEPRECATED #ifdef CONFIG_SYSFS_DEPRECATED
if (parent) { if (parent) {
sysfs_create_link(&dev->kobj, &dev->parent->kobj, "device"); sysfs_create_link(&dev->kobj, &dev->parent->kobj,
class_name = make_class_name(dev->class->name, &dev->kobj); "device");
sysfs_create_link(&dev->parent->kobj, &dev->kobj, class_name); class_name = make_class_name(dev->class->name,
&dev->kobj);
if (class_name)
sysfs_create_link(&dev->parent->kobj,
&dev->kobj, class_name);
} }
#endif #endif
} }
@ -535,7 +589,8 @@ int device_add(struct device *dev)
goto PMError; goto PMError;
if ((error = bus_add_device(dev))) if ((error = bus_add_device(dev)))
goto BusError; goto BusError;
kobject_uevent(&dev->kobj, KOBJ_ADD); if (!dev->uevent_suppress)
kobject_uevent(&dev->kobj, KOBJ_ADD);
if ((error = bus_attach_device(dev))) if ((error = bus_attach_device(dev)))
goto AttachError; goto AttachError;
if (parent) if (parent)
@ -665,7 +720,9 @@ void device_del(struct device * dev)
if (parent) { if (parent) {
char *class_name = make_class_name(dev->class->name, char *class_name = make_class_name(dev->class->name,
&dev->kobj); &dev->kobj);
sysfs_remove_link(&dev->parent->kobj, class_name); if (class_name)
sysfs_remove_link(&dev->parent->kobj,
class_name);
kfree(class_name); kfree(class_name);
sysfs_remove_link(&dev->kobj, "device"); 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); class_name = make_class_name(dev->class->name, &dev->kobj);
if (!class_name) { if (!class_name) {
error = PTR_ERR(class_name); error = -ENOMEM;
class_name = NULL;
goto out; goto out;
} }
if (old_parent) { if (old_parent) {
sysfs_remove_link(&dev->kobj, "device"); sysfs_remove_link(&dev->kobj, "device");
sysfs_remove_link(&old_parent->kobj, class_name); sysfs_remove_link(&old_parent->kobj, class_name);
} }
error = sysfs_create_link(&dev->kobj, &new_parent->kobj, "device"); if (new_parent) {
if (error) error = sysfs_create_link(&dev->kobj, &new_parent->kobj,
goto out; "device");
error = sysfs_create_link(&new_parent->kobj, &dev->kobj, class_name); if (error)
if (error) goto out;
sysfs_remove_link(&dev->kobj, "device"); error = sysfs_create_link(&new_parent->kobj, &dev->kobj,
class_name);
if (error)
sysfs_remove_link(&dev->kobj, "device");
}
else
error = 0;
out: out:
kfree(class_name); kfree(class_name);
return error; return error;
@ -993,29 +1055,28 @@ out:
/** /**
* device_move - moves a device to a new parent * device_move - moves a device to a new parent
* @dev: the pointer to the struct device to be moved * @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 device_move(struct device *dev, struct device *new_parent)
{ {
int error; int error;
struct device *old_parent; struct device *old_parent;
struct kobject *new_parent_kobj;
dev = get_device(dev); dev = get_device(dev);
if (!dev) if (!dev)
return -EINVAL; return -EINVAL;
if (!device_is_registered(dev)) {
error = -EINVAL;
goto out;
}
new_parent = get_device(new_parent); new_parent = get_device(new_parent);
if (!new_parent) { new_parent_kobj = get_device_parent (dev, new_parent);
error = -EINVAL; if (IS_ERR(new_parent_kobj)) {
error = PTR_ERR(new_parent_kobj);
put_device(new_parent);
goto out; goto out;
} }
pr_debug("DEVICE: moving '%s' to '%s'\n", dev->bus_id, pr_debug("DEVICE: moving '%s' to '%s'\n", dev->bus_id,
new_parent->bus_id); new_parent ? new_parent->bus_id : "<NULL>");
error = kobject_move(&dev->kobj, &new_parent->kobj); error = kobject_move(&dev->kobj, new_parent_kobj);
if (error) { if (error) {
put_device(new_parent); put_device(new_parent);
goto out; goto out;
@ -1024,7 +1085,8 @@ int device_move(struct device *dev, struct device *new_parent)
dev->parent = new_parent; dev->parent = new_parent;
if (old_parent) if (old_parent)
klist_remove(&dev->knode_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) if (!dev->class)
goto out_put; goto out_put;
error = device_move_class_links(dev, old_parent, new_parent); 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... */ /* We ignore errors on cleanup since we're hosed anyway... */
device_move_class_links(dev, new_parent, old_parent); device_move_class_links(dev, new_parent, old_parent);
if (!kobject_move(&dev->kobj, &old_parent->kobj)) { if (!kobject_move(&dev->kobj, &old_parent->kobj)) {
klist_remove(&dev->knode_parent); if (new_parent)
klist_remove(&dev->knode_parent);
if (old_parent) if (old_parent)
klist_add_tail(&dev->knode_parent, klist_add_tail(&dev->knode_parent,
&old_parent->klist_children); &old_parent->klist_children);

Просмотреть файл

@ -86,8 +86,12 @@ static void driver_sysfs_remove(struct device *dev)
*/ */
int device_bind_driver(struct device *dev) int device_bind_driver(struct device *dev)
{ {
driver_bound(dev); int ret;
return driver_sysfs_add(dev);
ret = driver_sysfs_add(dev);
if (!ret)
driver_bound(dev);
return ret;
} }
struct stupid_thread_structure { struct stupid_thread_structure {
@ -136,18 +140,17 @@ probe_failed:
driver_sysfs_remove(dev); driver_sysfs_remove(dev);
dev->driver = NULL; dev->driver = NULL;
if (ret == -ENODEV || ret == -ENXIO) { if (ret != -ENODEV && ret != -ENXIO) {
/* Driver matched, but didn't support device
* or device not found.
* Not an error; keep going.
*/
ret = 0;
} else {
/* driver matched but the probe failed */ /* driver matched but the probe failed */
printk(KERN_WARNING printk(KERN_WARNING
"%s: probe of %s failed with error %d\n", "%s: probe of %s failed with error %d\n",
drv->name, dev->bus_id, ret); drv->name, dev->bus_id, ret);
} }
/*
* Ignore errors returned by ->probe so that the next driver can try
* its luck.
*/
ret = 0;
done: done:
kfree(data); kfree(data);
atomic_dec(&probe_count); atomic_dec(&probe_count);

Просмотреть файл

@ -35,7 +35,7 @@ enum {
FW_STATUS_READY_NOHOTPLUG, 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 /* fw_lock could be moved to 'struct firmware_priv' but since it is just
* guarding for corner cases a global lock should be OK */ * 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) int __init platform_bus_init(void)
{ {
device_register(&platform_bus); int error;
return bus_register(&platform_bus_type);
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 #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 * 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) if(!pre_init)
return __pci_register_driver(driver, module); return __pci_register_driver(driver, module, mod_name);
driver->driver.owner = module; driver->driver.owner = module;
list_add_tail(&driver->node, &ide_pci_drivers); list_add_tail(&driver->node, &ide_pci_drivers);
return 0; return 0;
@ -862,6 +863,6 @@ void __init ide_scan_pcibus (int scan_direction)
{ {
list_del(l); list_del(l);
d = list_entry(l, struct pci_driver, node); 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); 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 = struct ipoib_dev_priv *priv = netdev_priv(to_net_dev(dev));
netdev_priv(container_of(cdev, struct net_device, class_dev));
return sprintf(buf, "0x%04x\n", priv->pkey); 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) const char *buf, size_t count)
{ {
int pkey; int pkey;
@ -985,14 +986,14 @@ static ssize_t create_child(struct class_device *cdev,
*/ */
pkey |= 0x8000; pkey |= 0x8000;
ret = ipoib_vlan_add(container_of(cdev, struct net_device, class_dev), ret = ipoib_vlan_add(to_net_dev(dev), pkey);
pkey);
return ret ? ret : count; 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) const char *buf, size_t count)
{ {
int pkey; int pkey;
@ -1004,18 +1005,16 @@ static ssize_t delete_child(struct class_device *cdev,
if (pkey < 0 || pkey > 0xffff) if (pkey < 0 || pkey > 0xffff)
return -EINVAL; return -EINVAL;
ret = ipoib_vlan_delete(container_of(cdev, struct net_device, class_dev), ret = ipoib_vlan_delete(to_net_dev(dev), pkey);
pkey);
return ret ? ret : count; 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) int ipoib_add_pkey_attr(struct net_device *dev)
{ {
return class_device_create_file(&dev->class_dev, return device_create_file(&dev->dev, &dev_attr_pkey);
&class_device_attr_pkey);
} }
static struct net_device *ipoib_add_port(const char *format, 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)) if (ipoib_add_pkey_attr(priv->dev))
goto sysfs_failed; goto sysfs_failed;
if (class_device_create_file(&priv->dev->class_dev, if (device_create_file(&priv->dev->dev, &dev_attr_create_child))
&class_device_attr_create_child))
goto sysfs_failed; goto sysfs_failed;
if (class_device_create_file(&priv->dev->class_dev, if (device_create_file(&priv->dev->dev, &dev_attr_delete_child))
&class_device_attr_delete_child))
goto sysfs_failed; goto sysfs_failed;
return priv->dev; return priv->dev;

Просмотреть файл

@ -42,15 +42,15 @@
#include "ipoib.h" #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 = struct net_device *dev = to_net_dev(d);
container_of(class_dev, struct net_device, class_dev);
struct ipoib_dev_priv *priv = netdev_priv(dev); struct ipoib_dev_priv *priv = netdev_priv(dev);
return sprintf(buf, "%s\n", priv->parent->name); 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) 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)) if (ipoib_add_pkey_attr(priv->dev))
goto sysfs_failed; goto sysfs_failed;
if (class_device_create_file(&priv->dev->class_dev, if (device_create_file(&priv->dev->dev, &dev_attr_parent))
&class_device_attr_parent))
goto sysfs_failed; goto sysfs_failed;
list_add_tail(&priv->list, &ppriv->child_intfs); list_add_tail(&priv->list, &ppriv->child_intfs);

Просмотреть файл

@ -45,7 +45,7 @@ EXPORT_SYMBOL(serio_interrupt);
EXPORT_SYMBOL(__serio_register_port); EXPORT_SYMBOL(__serio_register_port);
EXPORT_SYMBOL(serio_unregister_port); EXPORT_SYMBOL(serio_unregister_port);
EXPORT_SYMBOL(serio_unregister_child_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_unregister_driver);
EXPORT_SYMBOL(serio_open); EXPORT_SYMBOL(serio_open);
EXPORT_SYMBOL(serio_close); EXPORT_SYMBOL(serio_close);
@ -789,12 +789,14 @@ static void serio_attach_driver(struct serio_driver *drv)
drv->driver.name, error); 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 manual_bind = drv->manual_bind;
int error; int error;
drv->driver.bus = &serio_bus; drv->driver.bus = &serio_bus;
drv->driver.owner = owner;
drv->driver.mod_name = mod_name;
/* /*
* Temporarily disable automatic binding because probing * 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->driver, DRV_NAME, sizeof(info->driver));
strlcpy(info->version, DRV_VERSION, sizeof(info->version)); 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 = { 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->driver, DRV_NAME, sizeof(info->driver));
strlcpy(info->version, DRV_VERSION, sizeof(info->version)); 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)); sizeof(info->bus_info));
} }

Просмотреть файл

@ -39,8 +39,7 @@
/* #define BONDING_DEBUG 1 */ /* #define BONDING_DEBUG 1 */
#include "bonding.h" #include "bonding.h"
#define to_class_dev(obj) container_of(obj,struct class_device,kobj) #define to_dev(obj) container_of(obj,struct device,kobj)
#define to_net_dev(class) container_of(class, struct net_device, class_dev)
#define to_bond(cd) ((struct bonding *)(to_net_dev(cd)->priv)) #define to_bond(cd) ((struct bonding *)(to_net_dev(cd)->priv))
/*---------------------------- Declarations -------------------------------*/ /*---------------------------- 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, * If it's > expected, then there's a file open,
* and we have to fail. * 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){ > expected_refcount){
rtnl_unlock(); rtnl_unlock();
printk(KERN_INFO DRV_NAME 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; int ret = 0;
/* first, create a link from the slave back to the master */ /* 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"); "master");
if (ret) if (ret)
return ret; return ret;
/* next, create a link from the master to the slave */ /* next, create a link from the master to the slave */
sprintf(linkname,"slave_%s",slave->name); 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); linkname);
return ret; return ret;
@ -217,20 +216,21 @@ void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *s
{ {
char linkname[IFNAMSIZ+7]; 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); 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. * 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; struct slave *slave;
int i, res = 0; int i, res = 0;
struct bonding *bond = to_bond(cd); struct bonding *bond = to_bond(d);
read_lock_bh(&bond->lock); read_lock_bh(&bond->lock);
bond_for_each_slave(bond, slave, i) { 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. * up for this to succeed.
* This function is largely the same flow as bonding_update_bonds(). * 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 command[IFNAMSIZ + 1] = { 0, };
char *ifname; char *ifname;
int i, res, found, ret = count; int i, res, found, ret = count;
struct slave *slave; struct slave *slave;
struct net_device *dev = NULL; 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? */ /* Quick sanity check -- is the bond interface up? */
if (!(bond->dev->flags & IFF_UP)) { if (!(bond->dev->flags & IFF_UP)) {
@ -387,25 +389,28 @@ out:
return ret; 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 * Show and set the bonding mode. The bond interface must be down to
* change the mode. * 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", return sprintf(buf, "%s %d\n",
bond_mode_tbl[bond->params.mode].modename, bond_mode_tbl[bond->params.mode].modename,
bond->params.mode) + 1; 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; int new_value, ret = count;
struct bonding *bond = to_bond(cd); struct bonding *bond = to_bond(d);
if (bond->dev->flags & IFF_UP) { if (bond->dev->flags & IFF_UP) {
printk(KERN_ERR DRV_NAME printk(KERN_ERR DRV_NAME
@ -438,16 +443,18 @@ static ssize_t bonding_store_mode(struct class_device *cd, const char *buf, size
out: out:
return ret; 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 * Show and set the bonding transmit hash method. The bond interface must be down to
* change the xmit hash policy. * 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; int count;
struct bonding *bond = to_bond(cd); struct bonding *bond = to_bond(d);
if ((bond->params.mode != BOND_MODE_XOR) && if ((bond->params.mode != BOND_MODE_XOR) &&
(bond->params.mode != BOND_MODE_8023AD)) { (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; 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; int new_value, ret = count;
struct bonding *bond = to_bond(cd); struct bonding *bond = to_bond(d);
if (bond->dev->flags & IFF_UP) { if (bond->dev->flags & IFF_UP) {
printk(KERN_ERR DRV_NAME printk(KERN_ERR DRV_NAME
@ -501,24 +510,28 @@ static ssize_t bonding_store_xmit_hash(struct class_device *cd, const char *buf,
out: out:
return ret; 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. * 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", return sprintf(buf, "%s %d\n",
arp_validate_tbl[bond->params.arp_validate].modename, arp_validate_tbl[bond->params.arp_validate].modename,
bond->params.arp_validate) + 1; 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; 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); new_value = bond_parse_parm((char *)buf, arp_validate_tbl);
if (new_value < 0) { if (new_value < 0) {
@ -548,7 +561,7 @@ static ssize_t bonding_store_arp_validate(struct class_device *cd, const char *b
return count; 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 * 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 * MII monitoring. Second, if the ARP timer isn't running, we must
* start it. * 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; 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; int new_value, ret = count;
struct bonding *bond = to_bond(cd); struct bonding *bond = to_bond(d);
if (sscanf(buf, "%d", &new_value) != 1) { if (sscanf(buf, "%d", &new_value) != 1) {
printk(KERN_ERR DRV_NAME printk(KERN_ERR DRV_NAME
@ -638,15 +655,17 @@ static ssize_t bonding_store_arp_interval(struct class_device *cd, const char *b
out: out:
return ret; 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. * 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; 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++) { for (i = 0; i < BOND_MAX_ARP_TARGETS; i++) {
if (bond->params.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; 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; u32 newtarget;
int i = 0, done = 0, ret = count; int i = 0, done = 0, ret = count;
struct bonding *bond = to_bond(cd); struct bonding *bond = to_bond(d);
u32 *targets; u32 *targets;
targets = bond->params.arp_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: out:
return ret; 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 * Show and set the up and down delays. These must be multiples of the
* MII monitoring value, and are stored internally as the multiplier. * MII monitoring value, and are stored internally as the multiplier.
* Thus, we must translate to MS for the real world. * 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; 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; int new_value, ret = count;
struct bonding *bond = to_bond(cd); struct bonding *bond = to_bond(d);
if (!(bond->params.miimon)) { if (!(bond->params.miimon)) {
printk(KERN_ERR DRV_NAME printk(KERN_ERR DRV_NAME
@ -800,20 +825,24 @@ static ssize_t bonding_store_downdelay(struct class_device *cd, const char *buf,
out: out:
return ret; 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; 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; int new_value, ret = count;
struct bonding *bond = to_bond(cd); struct bonding *bond = to_bond(d);
if (!(bond->params.miimon)) { if (!(bond->params.miimon)) {
printk(KERN_ERR DRV_NAME printk(KERN_ERR DRV_NAME
@ -854,25 +883,29 @@ static ssize_t bonding_store_updelay(struct class_device *cd, const char *buf, s
out: out:
return ret; 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 * Show and set the LACP interval. Interface must be down, and the mode
* must be set to 802.3ad 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", return sprintf(buf, "%s %d\n",
bond_lacp_tbl[bond->params.lacp_fast].modename, bond_lacp_tbl[bond->params.lacp_fast].modename,
bond->params.lacp_fast) + 1; 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; int new_value, ret = count;
struct bonding *bond = to_bond(cd); struct bonding *bond = to_bond(d);
if (bond->dev->flags & IFF_UP) { if (bond->dev->flags & IFF_UP) {
printk(KERN_ERR DRV_NAME printk(KERN_ERR DRV_NAME
@ -906,7 +939,7 @@ static ssize_t bonding_store_lacp(struct class_device *cd, const char *buf, size
out: out:
return ret; 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 * 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 * ARP monitoring. Second, if the timer isn't running, we must
* start it. * 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; 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; int new_value, ret = count;
struct bonding *bond = to_bond(cd); struct bonding *bond = to_bond(d);
if (sscanf(buf, "%d", &new_value) != 1) { if (sscanf(buf, "%d", &new_value) != 1) {
printk(KERN_ERR DRV_NAME printk(KERN_ERR DRV_NAME
@ -1000,7 +1037,7 @@ static ssize_t bonding_store_miimon(struct class_device *cd, const char *buf, si
out: out:
return ret; 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 * 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 * The bond must be a mode that supports a primary for this be
* set. * 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; int count = 0;
struct bonding *bond = to_bond(cd); struct bonding *bond = to_bond(d);
if (bond->primary_slave) if (bond->primary_slave)
count = sprintf(buf, "%s\n", bond->primary_slave->dev->name) + 1; 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; 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; int i;
struct slave *slave; struct slave *slave;
struct bonding *bond = to_bond(cd); struct bonding *bond = to_bond(d);
write_lock_bh(&bond->lock); write_lock_bh(&bond->lock);
if (!USES_PRIMARY(bond->params.mode)) { if (!USES_PRIMARY(bond->params.mode)) {
@ -1065,22 +1106,26 @@ out:
write_unlock_bh(&bond->lock); write_unlock_bh(&bond->lock);
return count; 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. * 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; 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; int new_value, ret = count;
struct bonding *bond = to_bond(cd); struct bonding *bond = to_bond(d);
if (sscanf(buf, "%d", &new_value) != 1) { 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: out:
return count; 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. * 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 slave *curr;
struct bonding *bond = to_bond(cd); struct bonding *bond = to_bond(d);
int count; int count;
@ -1126,13 +1173,15 @@ static ssize_t bonding_show_active_slave(struct class_device *cd, char *buf)
return count; 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; int i;
struct slave *slave; struct slave *slave;
struct slave *old_active = NULL; struct slave *old_active = NULL;
struct slave *new_active = NULL; struct slave *new_active = NULL;
struct bonding *bond = to_bond(cd); struct bonding *bond = to_bond(d);
write_lock_bh(&bond->lock); write_lock_bh(&bond->lock);
if (!USES_PRIMARY(bond->params.mode)) { if (!USES_PRIMARY(bond->params.mode)) {
@ -1194,16 +1243,18 @@ out:
return count; 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. * 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 slave *curr;
struct bonding *bond = to_bond(cd); struct bonding *bond = to_bond(d);
read_lock(&bond->curr_slave_lock); read_lock(&bond->curr_slave_lock);
curr = bond->curr_active_slave; 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; 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. * 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; int count = 0;
struct bonding *bond = to_bond(cd); struct bonding *bond = to_bond(d);
if (bond->params.mode == BOND_MODE_8023AD) { if (bond->params.mode == BOND_MODE_8023AD) {
struct ad_info ad_info; struct ad_info ad_info;
@ -1231,16 +1284,18 @@ static ssize_t bonding_show_ad_aggregator(struct class_device *cd, char *buf)
return count; 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. * 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; int count = 0;
struct bonding *bond = to_bond(cd); struct bonding *bond = to_bond(d);
if (bond->params.mode == BOND_MODE_8023AD) { if (bond->params.mode == BOND_MODE_8023AD) {
struct ad_info ad_info; 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; 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. * 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; int count = 0;
struct bonding *bond = to_bond(cd); struct bonding *bond = to_bond(d);
if (bond->params.mode == BOND_MODE_8023AD) { if (bond->params.mode == BOND_MODE_8023AD) {
struct ad_info ad_info; 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; 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. * 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; int count = 0;
struct bonding *bond = to_bond(cd); struct bonding *bond = to_bond(d);
if (bond->params.mode == BOND_MODE_8023AD) { if (bond->params.mode == BOND_MODE_8023AD) {
struct ad_info ad_info; 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; 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. * 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; int count = 0;
struct bonding *bond = to_bond(cd); struct bonding *bond = to_bond(d);
if (bond->params.mode == BOND_MODE_8023AD) { if (bond->params.mode == BOND_MODE_8023AD) {
struct ad_info ad_info; 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; 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[] = { static struct attribute *per_bond_attrs[] = {
&class_device_attr_slaves.attr, &dev_attr_slaves.attr,
&class_device_attr_mode.attr, &dev_attr_mode.attr,
&class_device_attr_arp_validate.attr, &dev_attr_arp_validate.attr,
&class_device_attr_arp_interval.attr, &dev_attr_arp_interval.attr,
&class_device_attr_arp_ip_target.attr, &dev_attr_arp_ip_target.attr,
&class_device_attr_downdelay.attr, &dev_attr_downdelay.attr,
&class_device_attr_updelay.attr, &dev_attr_updelay.attr,
&class_device_attr_lacp_rate.attr, &dev_attr_lacp_rate.attr,
&class_device_attr_xmit_hash_policy.attr, &dev_attr_xmit_hash_policy.attr,
&class_device_attr_miimon.attr, &dev_attr_miimon.attr,
&class_device_attr_primary.attr, &dev_attr_primary.attr,
&class_device_attr_use_carrier.attr, &dev_attr_use_carrier.attr,
&class_device_attr_active_slave.attr, &dev_attr_active_slave.attr,
&class_device_attr_mii_status.attr, &dev_attr_mii_status.attr,
&class_device_attr_ad_aggregator.attr, &dev_attr_ad_aggregator.attr,
&class_device_attr_ad_num_ports.attr, &dev_attr_ad_num_ports.attr,
&class_device_attr_ad_actor_key.attr, &dev_attr_ad_actor_key.attr,
&class_device_attr_ad_partner_key.attr, &dev_attr_ad_partner_key.attr,
&class_device_attr_ad_partner_mac.attr, &dev_attr_ad_partner_mac.attr,
NULL, NULL,
}; };
@ -1367,7 +1428,7 @@ int bond_create_sysfs(void)
if (!firstbond) if (!firstbond)
return -ENODEV; return -ENODEV;
netdev_class = firstbond->dev->class_dev.class; netdev_class = firstbond->dev->dev.class;
if (!netdev_class) if (!netdev_class)
return -ENODEV; return -ENODEV;
@ -1410,13 +1471,13 @@ int bond_create_sysfs_entry(struct bonding *bond)
struct net_device *dev = bond->dev; struct net_device *dev = bond->dev;
int err; int err;
err = sysfs_create_group(&(dev->class_dev.kobj), &bonding_group); err = sysfs_create_group(&(dev->dev.kobj), &bonding_group);
if (err) { if (err) {
printk(KERN_EMERG "eek! didn't create group!\n"); printk(KERN_EMERG "eek! didn't create group!\n");
} }
if (expected_refcount < 1) 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; return err;
} }
@ -1427,6 +1488,6 @@ void bond_destroy_sysfs_entry(struct bonding *bond)
{ {
struct net_device *dev = bond->dev; 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); kobject_init(&port->kobject);
port->kobject.parent = &dev->class_dev.kobj; port->kobject.parent = &dev->dev.kobj;
port->kobject.ktype = &veth_port_ktype; port->kobject.ktype = &veth_port_ktype;
kobject_set_name(&port->kobject, "veth_port"); kobject_set_name(&port->kobject, "veth_port");
if (0 != kobject_add(&port->kobject)) if (0 != kobject_add(&port->kobject))

Просмотреть файл

@ -27,8 +27,6 @@
#include "macb.h" #include "macb.h"
#define to_net_dev(class) container_of(class, struct net_device, class_dev)
#define RX_BUFFER_SIZE 128 #define RX_BUFFER_SIZE 128
#define RX_RING_SIZE 512 #define RX_RING_SIZE 512
#define RX_RING_BYTES (sizeof(struct dma_desc) * RX_RING_SIZE) #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; 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) 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); struct macb *bp = netdev_priv(dev);
ssize_t ret = -EINVAL; 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) \ #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(bmcr, MII_BMCR);
MII_ENTRY(bmsr, MII_BMSR); MII_ENTRY(bmsr, MII_BMSR);
@ -977,13 +977,13 @@ MII_ENTRY(lpa, MII_LPA);
MII_ENTRY(expansion, MII_EXPANSION); MII_ENTRY(expansion, MII_EXPANSION);
static struct attribute *macb_mii_attrs[] = { static struct attribute *macb_mii_attrs[] = {
&class_device_attr_bmcr.attr, &dev_attr_bmcr.attr,
&class_device_attr_bmsr.attr, &dev_attr_bmsr.attr,
&class_device_attr_physid1.attr, &dev_attr_physid1.attr,
&class_device_attr_physid2.attr, &dev_attr_physid2.attr,
&class_device_attr_advertise.attr, &dev_attr_advertise.attr,
&class_device_attr_lpa.attr, &dev_attr_lpa.attr,
&class_device_attr_expansion.attr, &dev_attr_expansion.attr,
NULL, NULL,
}; };
@ -994,17 +994,17 @@ static struct attribute_group macb_mii_group = {
static void macb_unregister_sysfs(struct net_device *net) 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) static int macb_register_sysfs(struct net_device *net)
{ {
struct class_device *class_dev = &net->class_dev; struct device *_dev = &net->dev;
int ret; int ret;
ret = sysfs_create_group(&class_dev->kobj, &macb_mii_group); ret = sysfs_create_group(&_dev->kobj, &macb_mii_group);
if (ret) if (ret)
printk(KERN_WARNING printk(KERN_WARNING
"%s: sysfs mii attribute registration failed: %d\n", "%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->driver, CARDNAME, sizeof(info->driver));
strncpy(info->version, version, sizeof(info->version)); 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) 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->driver, CARDNAME, sizeof(info->driver));
strncpy(info->version, version, sizeof(info->version)); 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) 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, '%')) if (strchr(dev->name, '%'))
ret = dev_alloc_name(dev, 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) if (ret >= 0)
ret = register_netdevice(dev); 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->driver, DRIVER_NAME, sizeof(info->driver) - 1);
strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 1); strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 1);
strncpy(info->fw_version, priv->fw_name, sizeof(info->fw_version) - 1); strncpy(info->fw_version, priv->fw_name, sizeof(info->fw_version) - 1);
if (dev->class_dev.dev) if (dev->dev.parent)
strncpy(info->bus_info, dev->class_dev.dev->bus_id, strncpy(info->bus_info, dev->dev.parent->bus_id,
sizeof(info->bus_info) - 1); sizeof(info->bus_info) - 1);
else else
snprintf(info->bus_info, sizeof(info->bus_info) - 1, 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 */ /* Finally, report what we've done */
printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s, irq %d, io " 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->irq.AssignedIRQ, link->io.BasePort1,
link->io.BasePort1 + link->io.NumPorts1 - 1); link->io.BasePort1 + link->io.NumPorts1 - 1);

Просмотреть файл

@ -806,7 +806,7 @@ spectrum_cs_config(struct pcmcia_device *link)
/* Finally, report what we've done */ /* Finally, report what we've done */
printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s, irq %d, io " 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->irq.AssignedIRQ, link->io.BasePort1,
link->io.BasePort1 + link->io.NumPorts1 - 1); 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 * If no error occurred, the driver remains registered even if
* no device was claimed during registration. * 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; int error;
@ -430,6 +431,7 @@ int __pci_register_driver(struct pci_driver *drv, struct module *owner)
drv->driver.name = drv->name; drv->driver.name = drv->name;
drv->driver.bus = &pci_bus_type; drv->driver.bus = &pci_bus_type;
drv->driver.owner = owner; drv->driver.owner = owner;
drv->driver.mod_name = mod_name;
drv->driver.kobj.ktype = &pci_driver_kobj_type; drv->driver.kobj.ktype = &pci_driver_kobj_type;
if (pci_multithread_probe) 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); down_read(&pcmcia_socket_list_rwsem);
list_for_each_entry(socket, &pcmcia_socket_list, socket_list) { list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
if (socket->dev.dev != dev) if (socket->dev.parent != dev)
continue; continue;
mutex_lock(&socket->skt_mutex); mutex_lock(&socket->skt_mutex);
socket_suspend(socket); socket_suspend(socket);
@ -128,7 +128,7 @@ int pcmcia_socket_dev_resume(struct device *dev)
down_read(&pcmcia_socket_list_rwsem); down_read(&pcmcia_socket_list_rwsem);
list_for_each_entry(socket, &pcmcia_socket_list, socket_list) { list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
if (socket->dev.dev != dev) if (socket->dev.parent != dev)
continue; continue;
mutex_lock(&socket->skt_mutex); mutex_lock(&socket->skt_mutex);
socket_resume(socket); socket_resume(socket);
@ -143,12 +143,12 @@ EXPORT_SYMBOL(pcmcia_socket_dev_resume);
struct pcmcia_socket * pcmcia_get_socket(struct pcmcia_socket *skt) struct pcmcia_socket * pcmcia_get_socket(struct pcmcia_socket *skt)
{ {
struct class_device *cl_dev = class_device_get(&skt->dev); struct device *dev = get_device(&skt->dev);
if (!cl_dev) if (!dev)
return NULL; return NULL;
skt = class_get_devdata(cl_dev); skt = dev_get_drvdata(dev);
if (!try_module_get(skt->owner)) { if (!try_module_get(skt->owner)) {
class_device_put(&skt->dev); put_device(&skt->dev);
return NULL; return NULL;
} }
return (skt); return (skt);
@ -159,14 +159,14 @@ EXPORT_SYMBOL(pcmcia_get_socket);
void pcmcia_put_socket(struct pcmcia_socket *skt) void pcmcia_put_socket(struct pcmcia_socket *skt)
{ {
module_put(skt->owner); module_put(skt->owner);
class_device_put(&skt->dev); put_device(&skt->dev);
} }
EXPORT_SYMBOL(pcmcia_put_socket); 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); complete(&socket->socket_released);
} }
@ -181,7 +181,7 @@ int pcmcia_register_socket(struct pcmcia_socket *socket)
struct task_struct *tsk; struct task_struct *tsk;
int ret; int ret;
if (!socket || !socket->ops || !socket->dev.dev || !socket->resource_ops) if (!socket || !socket->ops || !socket->dev.parent || !socket->resource_ops)
return -EINVAL; return -EINVAL;
cs_dbg(socket, 0, "pcmcia_register_socket(0x%p)\n", socket->ops); 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 #endif
/* set proper values in socket->dev */ /* set proper values in socket->dev */
socket->dev.class_data = socket; dev_set_drvdata(&socket->dev, socket);
socket->dev.class = &pcmcia_socket_class; 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 */ /* base address = 0, map = 0 */
socket->cis_mem.flags = 0; socket->cis_mem.flags = 0;
@ -640,7 +640,7 @@ static int pccardd(void *__skt)
skt->ops->set_socket(skt, &skt->socket); skt->ops->set_socket(skt, &skt->socket);
/* register with the device core */ /* register with the device core */
ret = class_device_register(&skt->dev); ret = device_register(&skt->dev);
if (ret) { if (ret) {
printk(KERN_WARNING "PCMCIA: unable to register socket 0x%p\n", printk(KERN_WARNING "PCMCIA: unable to register socket 0x%p\n",
skt); skt);
@ -689,7 +689,7 @@ static int pccardd(void *__skt)
remove_wait_queue(&skt->thread_wait, &wait); remove_wait_queue(&skt->thread_wait, &wait);
/* remove from the device core */ /* remove from the device core */
class_device_unregister(&skt->dev); device_unregister(&skt->dev);
return 0; return 0;
} }
@ -904,7 +904,7 @@ int pcmcia_insert_card(struct pcmcia_socket *skt)
EXPORT_SYMBOL(pcmcia_insert_card); 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) int num_envp, char *buffer, int buffer_size)
{ {
struct pcmcia_socket *s = container_of(dev, struct pcmcia_socket, dev); 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 = { struct class pcmcia_socket_class = {
.name = "pcmcia_socket", .name = "pcmcia_socket",
.uevent = pcmcia_socket_uevent, .dev_uevent = pcmcia_socket_uevent,
.release = pcmcia_release_socket, .dev_release = pcmcia_release_socket,
.class_release = pcmcia_release_socket_class, .class_release = pcmcia_release_socket_class,
}; };
EXPORT_SYMBOL(pcmcia_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); 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 #ifdef DEBUG
extern int cs_debug_level(int); extern int cs_debug_level(int);
@ -158,6 +158,6 @@ extern int cs_debug_level(int);
#endif #endif
#define cs_err(skt, fmt, arg...) \ #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 */ #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->func = function;
p_dev->dev.bus = &pcmcia_bus_type; 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; 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); 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, .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 class_interface *class_intf)
{ {
struct pcmcia_socket *socket = class_get_devdata(class_dev); struct pcmcia_socket *socket = dev_get_drvdata(dev);
int ret; int ret;
socket = pcmcia_get_socket(socket); socket = pcmcia_get_socket(socket);
@ -1364,10 +1364,10 @@ static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev,
return 0; 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 class_interface *class_intf)
{ {
struct pcmcia_socket *socket = class_get_devdata(class_dev); struct pcmcia_socket *socket = dev_get_drvdata(dev);
if (!socket) if (!socket)
return; 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 */ /* the pcmcia_bus_interface is used to handle pcmcia socket devices */
static struct class_interface pcmcia_bus_interface = { static struct class_interface pcmcia_bus_interface = {
.class = &pcmcia_socket_class, .class = &pcmcia_socket_class,
.add = &pcmcia_bus_add_socket, .add_dev = &pcmcia_bus_add_socket,
.remove = &pcmcia_bus_remove_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); pci_set_drvdata(dev, &sockets[i].socket);
for (i = 0; i<socket_count; i++) { 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.ops = &i82092aa_operations;
sockets[i].socket.resource_ops = &pccard_nonstatic_ops; sockets[i].socket.resource_ops = &pccard_nonstatic_ops;
ret = pcmcia_register_socket(&sockets[i].socket); ret = pcmcia_register_socket(&sockets[i].socket);

Просмотреть файл

@ -1298,7 +1298,7 @@ static int __init init_i82365(void)
/* register sockets with the pcmcia core */ /* register sockets with the pcmcia core */
for (i = 0; i < sockets; i++) { 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.ops = &pcic_operations;
socket[i].socket.resource_ops = &pccard_nonstatic_ops; socket[i].socket.resource_ops = &pccard_nonstatic_ops;
socket[i].socket.owner = THIS_MODULE; socket[i].socket.owner = THIS_MODULE;

Просмотреть файл

@ -59,7 +59,6 @@ typedef struct user_info_t {
#ifdef DEBUG #ifdef DEBUG
extern int ds_pc_debug; extern int ds_pc_debug;
#define cs_socket_name(skt) ((skt)->dev.class_id)
#define ds_dbg(lvl, fmt, arg...) do { \ #define ds_dbg(lvl, fmt, arg...) do { \
if (ds_pc_debug >= lvl) \ if (ds_pc_debug >= lvl) \

Просмотреть файл

@ -48,7 +48,6 @@ static u8 pcmcia_used_irq[NR_IRQS];
#ifdef DEBUG #ifdef DEBUG
extern int ds_pc_debug; extern int ds_pc_debug;
#define cs_socket_name(skt) ((skt)->dev.class_id)
#define ds_dbg(skt, lvl, fmt, arg...) do { \ #define ds_dbg(skt, lvl, fmt, arg...) do { \
if (ds_pc_debug >= lvl) \ 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.ops = &pd6729_operations;
socket[i].socket.resource_ops = &pccard_nonstatic_ops; 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]; 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, static struct resource *nonstatic_find_io_region(unsigned long base, int num,
unsigned long align, struct pcmcia_socket *s) 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 socket_data *s_data = s->resource_data;
struct pcmcia_align_data data; struct pcmcia_align_data data;
unsigned long min = base; 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, static struct resource * nonstatic_find_mem_region(u_long base, u_long num,
u_long align, int low, struct pcmcia_socket *s) 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 socket_data *s_data = s->resource_data;
struct pcmcia_align_data data; struct pcmcia_align_data data;
unsigned long min, max; unsigned long min, max;
@ -897,9 +897,10 @@ EXPORT_SYMBOL(pccard_nonstatic_ops);
/* sysfs interface to the resource database */ /* 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 socket_data *data;
struct resource_map *p; struct resource_map *p;
ssize_t ret = 0; ssize_t ret = 0;
@ -920,9 +921,11 @@ static ssize_t show_io_db(struct class_device *class_dev, char *buf)
return (ret); 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 long start_addr, end_addr;
unsigned int add = ADD_MANAGED_RESOURCE; unsigned int add = ADD_MANAGED_RESOURCE;
ssize_t ret = 0; 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; 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 socket_data *data;
struct resource_map *p; struct resource_map *p;
ssize_t ret = 0; ssize_t ret = 0;
@ -972,9 +976,11 @@ static ssize_t show_mem_db(struct class_device *class_dev, char *buf)
return (ret); 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 long start_addr, end_addr;
unsigned int add = ADD_MANAGED_RESOURCE; unsigned int add = ADD_MANAGED_RESOURCE;
ssize_t ret = 0; 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; 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[] = { static struct device_attribute *pccard_rsrc_attributes[] = {
&class_device_attr_available_resources_io, &dev_attr_available_resources_io,
&class_device_attr_available_resources_mem, &dev_attr_available_resources_mem,
NULL, 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 class_interface *class_intf)
{ {
struct pcmcia_socket *s = class_get_devdata(class_dev); struct pcmcia_socket *s = dev_get_drvdata(dev);
struct class_device_attribute **attr; struct device_attribute **attr;
int ret = 0; int ret = 0;
if (s->resource_ops != &pccard_nonstatic_ops) if (s->resource_ops != &pccard_nonstatic_ops)
return 0; return 0;
for (attr = pccard_rsrc_attributes; *attr; attr++) { for (attr = pccard_rsrc_attributes; *attr; attr++) {
ret = class_device_create_file(class_dev, *attr); ret = device_create_file(dev, *attr);
if (ret) if (ret)
break; break;
} }
@ -1025,23 +1031,23 @@ static int __devinit pccard_sysfs_add_rsrc(struct class_device *class_dev,
return ret; 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 class_interface *class_intf)
{ {
struct pcmcia_socket *s = class_get_devdata(class_dev); struct pcmcia_socket *s = dev_get_drvdata(dev);
struct class_device_attribute **attr; struct device_attribute **attr;
if (s->resource_ops != &pccard_nonstatic_ops) if (s->resource_ops != &pccard_nonstatic_ops)
return; return;
for (attr = pccard_rsrc_attributes; *attr; attr++) 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 = { static struct class_interface pccard_rsrc_interface = {
.class = &pcmcia_socket_class, .class = &pcmcia_socket_class,
.add = &pccard_sysfs_add_rsrc, .add_dev = &pccard_sysfs_add_rsrc,
.remove = __devexit_p(&pccard_sysfs_remove_rsrc), .remove_dev = __devexit_p(&pccard_sysfs_remove_rsrc),
}; };
static int __init nonstatic_sysfs_init(void) 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 * 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 = 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; char *p = buf;
p+=sprintf(p, "slot : %d\n", skt->nr); 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); 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); dev_set_drvdata(dev, sinfo);

Просмотреть файл

@ -40,7 +40,8 @@
#define to_socket(_dev) container_of(_dev, struct pcmcia_socket, dev) #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); 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, "32-bit\n");
return sprintf(buf, "16-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); 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); s->socket.Vcc % 10);
return sprintf(buf, "X.XV\n"); 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); struct pcmcia_socket *s = to_socket(dev);
if (!(s->state & SOCKET_PRESENT)) if (!(s->state & SOCKET_PRESENT))
return -ENODEV; return -ENODEV;
return sprintf(buf, "%d.%dV\n", s->socket.Vpp / 10, s->socket.Vpp % 10); 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); struct pcmcia_socket *s = to_socket(dev);
if (!(s->state & SOCKET_PRESENT)) if (!(s->state & SOCKET_PRESENT))
return -ENODEV; return -ENODEV;
return sprintf(buf, "%d.%dV\n", s->socket.Vcc / 10, s->socket.Vcc % 10); 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; ssize_t ret;
struct pcmcia_socket *s = to_socket(dev); 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; 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); struct pcmcia_socket *s = to_socket(dev);
return sprintf(buf, "%s\n", s->state & SOCKET_SUSPEND ? "off" : "on"); 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; ssize_t ret = -EINVAL;
struct pcmcia_socket *s = to_socket(dev); 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; 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; ssize_t ret;
struct pcmcia_socket *s = to_socket(dev); 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; 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); struct pcmcia_socket *s = to_socket(dev);
return sprintf(buf, "0x%04x\n", s->irq_mask); 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; ssize_t ret;
struct pcmcia_socket *s = to_socket(dev); 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; 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); struct pcmcia_socket *s = to_socket(dev);
return sprintf(buf, "%s\n", s->resource_setup_done ? "yes" : "no"); 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; unsigned long flags;
struct pcmcia_socket *s = to_socket(dev); 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; 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) 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) if (off + count > size)
count = size - off; 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)) if (!(s->state & SOCKET_PRESENT))
return -ENODEV; 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) 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; cisdump_t *cis;
int error; 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[] = { static struct device_attribute *pccard_socket_attributes[] = {
&class_device_attr_card_type, &dev_attr_card_type,
&class_device_attr_card_voltage, &dev_attr_card_voltage,
&class_device_attr_card_vpp, &dev_attr_card_vpp,
&class_device_attr_card_vcc, &dev_attr_card_vcc,
&class_device_attr_card_insert, &dev_attr_card_insert,
&class_device_attr_card_pm_state, &dev_attr_card_pm_state,
&class_device_attr_card_eject, &dev_attr_card_eject,
&class_device_attr_card_irq_mask, &dev_attr_card_irq_mask,
&class_device_attr_available_resources_setup_done, &dev_attr_available_resources_setup_done,
NULL, NULL,
}; };
@ -355,35 +373,35 @@ static struct bin_attribute pccard_cis_attr = {
.write = pccard_store_cis, .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_interface *class_intf)
{ {
struct class_device_attribute **attr; struct device_attribute **attr;
int ret = 0; int ret = 0;
for (attr = pccard_socket_attributes; *attr; attr++) { for (attr = pccard_socket_attributes; *attr; attr++) {
ret = class_device_create_file(class_dev, *attr); ret = device_create_file(dev, *attr);
if (ret) if (ret)
break; break;
} }
if (!ret) 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; 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_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++) 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 = { struct class_interface pccard_sysfs_interface = {
.class = &pcmcia_socket_class, .class = &pcmcia_socket_class,
.add = &pccard_sysfs_add_socket, .add_dev = &pccard_sysfs_add_socket,
.remove = __devexit_p(&pccard_sysfs_remove_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++) { for (i = 0; i < sockets; i++) {
socket_table[i].socket.ops = &tcic_operations; socket_table[i].socket.ops = &tcic_operations;
socket_table[i].socket.resource_ops = &pccard_nonstatic_ops; 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); ret = pcmcia_register_socket(&socket_table[i].socket);
if (ret && i) if (ret && i)
pcmcia_unregister_socket(&socket_table[0].socket); 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 */ /* prepare pcmcia_socket */
socket->socket.ops = &yenta_socket_operations; socket->socket.ops = &yenta_socket_operations;
socket->socket.resource_ops = &pccard_nonstatic_ops; 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.driver_data = socket;
socket->socket.owner = THIS_MODULE; socket->socket.owner = THIS_MODULE;
socket->socket.features = SS_CAP_PAGE_REGS | SS_CAP_PCCARD; 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); INIT_WORK(&drv_data->pump_messages, pump_messages);
drv_data->workqueue = create_singlethread_workqueue( 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) if (drv_data->workqueue == NULL)
return -EBUSY; return -EBUSY;

Просмотреть файл

@ -193,7 +193,7 @@ struct spi_device *__init_or_module
spi_new_device(struct spi_master *master, struct spi_board_info *chip) spi_new_device(struct spi_master *master, struct spi_board_info *chip)
{ {
struct spi_device *proxy; struct spi_device *proxy;
struct device *dev = master->cdev.dev; struct device *dev = &master->dev;
int status; int status;
/* NOTE: caller did any chip->bus_num checks necessary */ /* 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; proxy->modalias = chip->modalias;
snprintf(proxy->dev.bus_id, sizeof proxy->dev.bus_id, 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); chip->chip_select);
proxy->dev.parent = dev; proxy->dev.parent = dev;
proxy->dev.bus = &spi_bus_type; proxy->dev.bus = &spi_bus_type;
@ -290,7 +290,7 @@ static void __init_or_module
scan_boardinfo(struct spi_master *master) scan_boardinfo(struct spi_master *master)
{ {
struct boardinfo *bi; struct boardinfo *bi;
struct device *dev = master->cdev.dev; struct device *dev = master->dev.parent;
down(&board_lock); down(&board_lock);
list_for_each_entry(bi, &board_list, list) { 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; struct spi_master *master;
master = container_of(cdev, struct spi_master, cdev); master = container_of(dev, struct spi_master, dev);
kfree(master); kfree(master);
} }
static struct class spi_master_class = { static struct class spi_master_class = {
.name = "spi_master", .name = "spi_master",
.owner = THIS_MODULE, .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) if (!master)
return NULL; return NULL;
class_device_initialize(&master->cdev); device_initialize(&master->dev);
master->cdev.class = &spi_master_class; master->dev.class = &spi_master_class;
master->cdev.dev = get_device(dev); master->dev.parent = get_device(dev);
spi_master_set_devdata(master, &master[1]); spi_master_set_devdata(master, &master[1]);
return master; return master;
@ -396,7 +396,7 @@ int __init_or_module
spi_register_master(struct spi_master *master) spi_register_master(struct spi_master *master)
{ {
static atomic_t dyn_bus_id = ATOMIC_INIT((1<<16) - 1); 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 status = -ENODEV;
int dynamic = 0; int dynamic = 0;
@ -412,12 +412,12 @@ spi_register_master(struct spi_master *master)
/* register the device, then userspace will see it. /* register the device, then userspace will see it.
* registration fails if the bus ID is in use. * 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); "spi%u", master->bus_num);
status = class_device_add(&master->cdev); status = device_add(&master->dev);
if (status < 0) if (status < 0)
goto done; 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)" : ""); dynamic ? " (dynamic)" : "");
/* populate children from any spi device tables */ /* populate children from any spi device tables */
@ -449,8 +449,8 @@ void spi_unregister_master(struct spi_master *master)
{ {
int dummy; int dummy;
dummy = device_for_each_child(master->cdev.dev, NULL, __unregister); dummy = device_for_each_child(&master->dev, NULL, __unregister);
class_device_unregister(&master->cdev); device_unregister(&master->dev);
} }
EXPORT_SYMBOL_GPL(spi_unregister_master); 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); down(&spi_master_class.sem);
list_for_each_entry(cdev, &spi_master_class.children, node) { 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) { if (m->bus_num == bus_num) {
master = spi_master_get(m); master = spi_master_get(m);
break; break;

Просмотреть файл

@ -479,7 +479,7 @@ int spi_bitbang_start(struct spi_bitbang *bitbang)
/* this task is the only thing to touch the SPI bits */ /* this task is the only thing to touch the SPI bits */
bitbang->busy = 0; bitbang->busy = 0;
bitbang->workqueue = create_singlethread_workqueue( bitbang->workqueue = create_singlethread_workqueue(
bitbang->master->cdev.dev->bus_id); bitbang->master->dev.parent->bus_id);
if (bitbang->workqueue == NULL) { if (bitbang->workqueue == NULL) {
status = -EBUSY; status = -EBUSY;
goto err1; goto err1;
@ -513,14 +513,14 @@ int spi_bitbang_stop(struct spi_bitbang *bitbang)
while (!list_empty(&bitbang->queue) && limit--) { while (!list_empty(&bitbang->queue) && limit--) {
spin_unlock_irq(&bitbang->lock); 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); msleep(10);
spin_lock_irq(&bitbang->lock); spin_lock_irq(&bitbang->lock);
} }
spin_unlock_irq(&bitbang->lock); spin_unlock_irq(&bitbang->lock);
if (!list_empty(&bitbang->queue)) { 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; return -EBUSY;
} }

Просмотреть файл

@ -246,7 +246,7 @@ static void butterfly_attach(struct parport *p)
* and no way to be selective about what it binds to. * 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 * e.g. /sys/bus/pnp0/00:0b, some PCI thing, etc
* setting up a platform device like this is an ugly kluge... * setting up a platform device like this is an ugly kluge...
*/ */
@ -386,7 +386,7 @@ static void butterfly_detach(struct parport *p)
butterfly = NULL; butterfly = NULL;
/* stop() unregisters child devices too */ /* 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); status = spi_bitbang_stop(&pp->bitbang);
/* turn off VCC */ /* 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 * usb_register_dev() to enable that functionality. This function no longer
* takes care of that. * 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; 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.probe = usb_probe_interface;
new_driver->drvwrap.driver.remove = usb_unbind_interface; new_driver->drvwrap.driver.remove = usb_unbind_interface;
new_driver->drvwrap.driver.owner = owner; new_driver->drvwrap.driver.owner = owner;
new_driver->drvwrap.driver.mod_name = mod_name;
spin_lock_init(&new_driver->dynids.lock); spin_lock_init(&new_driver->dynids.lock);
INIT_LIST_HEAD(&new_driver->dynids.list); INIT_LIST_HEAD(&new_driver->dynids.list);

Просмотреть файл

@ -32,7 +32,7 @@
#include <linux/hid.h> #include <linux/hid.h>
#include "usbhid.h" #include "usbhid.h"
struct device_type { struct dev_type {
u16 idVendor; u16 idVendor;
u16 idProduct; u16 idProduct;
const signed short *ff; const signed short *ff;
@ -48,7 +48,7 @@ static const signed short ff_joystick[] = {
-1 -1
}; };
static const struct device_type devices[] = { static const struct dev_type devices[] = {
{ 0x046d, 0xc211, ff_rumble }, { 0x046d, 0xc211, ff_rumble },
{ 0x046d, 0xc219, ff_rumble }, { 0x046d, 0xc219, ff_rumble },
{ 0x046d, 0xc283, ff_joystick }, { 0x046d, 0xc283, ff_joystick },

Просмотреть файл

@ -16,6 +16,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/semaphore.h>
#include "sysfs.h" #include "sysfs.h"
@ -146,7 +147,7 @@ static int open(struct inode * inode, struct file * file)
Error: Error:
module_put(attr->attr.owner); module_put(attr->attr.owner);
Done: Done:
if (error && kobj) if (error)
kobject_put(kobj); kobject_put(kobj);
return error; 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); struct bin_attribute * attr = to_bin_attr(file->f_path.dentry);
u8 * buffer = file->private_data; u8 * buffer = file->private_data;
if (kobj) kobject_put(kobj);
kobject_put(kobj);
module_put(attr->attr.owner); module_put(attr->attr.owner);
kfree(buffer); kfree(buffer);
return 0; return 0;

Просмотреть файл

@ -9,6 +9,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/kobject.h> #include <linux/kobject.h>
#include <linux/namei.h> #include <linux/namei.h>
#include <asm/semaphore.h>
#include "sysfs.h" #include "sysfs.h"
DECLARE_RWSEM(sysfs_rename_sem); 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 * 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, static struct sysfs_dirent * __sysfs_new_dirent(void * element)
void * element)
{ {
struct sysfs_dirent * sd; 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_count, 1);
atomic_set(&sd->s_event, 1); atomic_set(&sd->s_event, 1);
INIT_LIST_HEAD(&sd->s_children); 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; sd->s_element = element;
return sd; 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 * 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, static struct sysfs_dirent *
void * element, umode_t mode, int type) __sysfs_make_dirent(struct dentry *dentry, void *element, mode_t mode, int type)
{ {
struct sysfs_dirent * sd; struct sysfs_dirent * sd;
sd = sysfs_new_dirent(parent_sd, element); sd = __sysfs_new_dirent(element);
if (!sd) if (!sd)
return -ENOMEM; goto out;
sd->s_mode = mode; sd->s_mode = mode;
sd->s_type = type; 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; 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) 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. * sysfs_create_dir - create a directory for an object.
* @parent: parent parent object.
* @kobj: object we're creating directory for. * @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 * dentry = NULL;
struct dentry * parent; struct dentry * parent;
@ -177,7 +205,9 @@ int sysfs_create_dir(struct kobject * kobj)
BUG_ON(!kobj); BUG_ON(!kobj);
if (kobj->parent) if (shadow_parent)
parent = shadow_parent;
else if (kobj->parent)
parent = kobj->parent->dentry; parent = kobj->parent->dentry;
else if (sysfs_mount && sysfs_mount->mnt_sb) else if (sysfs_mount && sysfs_mount->mnt_sb)
parent = sysfs_mount->mnt_sb->s_root; parent = sysfs_mount->mnt_sb->s_root;
@ -298,21 +328,12 @@ void sysfs_remove_subdir(struct dentry * d)
} }
/** static void __sysfs_remove_dir(struct dentry *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)
{ {
struct dentry * dentry = dget(kobj->dentry);
struct sysfs_dirent * parent_sd; struct sysfs_dirent * parent_sd;
struct sysfs_dirent * sd, * tmp; struct sysfs_dirent * sd, * tmp;
dget(dentry);
if (!dentry) if (!dentry)
return; return;
@ -333,32 +354,60 @@ void sysfs_remove_dir(struct kobject * kobj)
* Drop reference from dget() on entrance. * Drop reference from dget() on entrance.
*/ */
dput(dentry); 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; 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; int error = 0;
struct dentry * new_dentry, * parent; struct dentry * new_dentry;
if (!strcmp(kobject_name(kobj), new_name)) if (!new_parent)
return -EINVAL; return -EFAULT;
if (!kobj->parent)
return -EINVAL;
down_write(&sysfs_rename_sem); 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, new_parent, strlen(new_name));
new_dentry = lookup_one_len(new_name, parent, strlen(new_name));
if (!IS_ERR(new_dentry)) { 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); error = kobject_set_name(kobj, "%s", new_name);
if (!error) { if (!error) {
struct sysfs_dirent *sd, *parent_sd;
d_add(new_dentry, NULL); d_add(new_dentry, NULL);
d_move(kobj->dentry, new_dentry); 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 else
d_drop(new_dentry); d_drop(new_dentry);
@ -366,7 +415,7 @@ int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
error = -EEXIST; error = -EEXIST;
dput(new_dentry); dput(new_dentry);
} }
mutex_unlock(&parent->d_inode->i_mutex); mutex_unlock(&new_parent->d_inode->i_mutex);
up_write(&sysfs_rename_sem); up_write(&sysfs_rename_sem);
return error; return error;
@ -378,12 +427,10 @@ int sysfs_move_dir(struct kobject *kobj, struct kobject *new_parent)
struct sysfs_dirent *new_parent_sd, *sd; struct sysfs_dirent *new_parent_sd, *sd;
int error; int error;
if (!new_parent)
return -EINVAL;
old_parent_dentry = kobj->parent ? old_parent_dentry = kobj->parent ?
kobj->parent->dentry : sysfs_mount->mnt_sb->s_root; 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: again:
mutex_lock(&old_parent_dentry->d_inode->i_mutex); 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; 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 = { const struct file_operations sysfs_dir_operations = {
.open = sysfs_dir_open, .open = sysfs_dir_open,
.release = sysfs_dir_close, .release = sysfs_dir_close,

Просмотреть файл

@ -7,6 +7,7 @@
#include <linux/kobject.h> #include <linux/kobject.h>
#include <linux/namei.h> #include <linux/namei.h>
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/list.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/semaphore.h> #include <asm/semaphore.h>
@ -50,17 +51,29 @@ static struct sysfs_ops subsys_sysfs_ops = {
.store = subsys_attr_store, .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 { static inline void
size_t count; add_to_collection(struct sysfs_buffer *buffer, struct inode *node)
loff_t pos; {
char * page; struct sysfs_buffer_collection *set = node->i_private;
struct sysfs_ops * ops;
struct semaphore sem;
int needs_read_fill;
int event;
};
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. * 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 * Allocate @buffer->page, if it hasn't been already, then call the
* kobject's show() method to fill the buffer with this attribute's * kobject's show() method to fill the buffer with this attribute's
* data. * 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) 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); buffer->event = atomic_read(&sd->s_event);
count = ops->show(kobj,attr,buffer->page); count = ops->show(kobj,attr,buffer->page);
buffer->needs_read_fill = 0;
BUG_ON(count > (ssize_t)PAGE_SIZE); BUG_ON(count > (ssize_t)PAGE_SIZE);
if (count >= 0) if (count >= 0) {
buffer->needs_read_fill = 0;
buffer->count = count; buffer->count = count;
else } else {
ret = count; ret = count;
}
return ret; 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; ssize_t retval = 0;
down(&buffer->sem); down(&buffer->sem);
if (buffer->orphaned) {
retval = -ENODEV;
goto out;
}
if (buffer->needs_read_fill) { if (buffer->needs_read_fill) {
if ((retval = fill_read_buffer(file->f_path.dentry,buffer))) if ((retval = fill_read_buffer(file->f_path.dentry,buffer)))
goto out; goto out;
@ -165,7 +184,6 @@ out:
return retval; return retval;
} }
/** /**
* fill_write_buffer - copy buffer from userspace. * fill_write_buffer - copy buffer from userspace.
* @buffer: data buffer for file. * @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; ssize_t len;
down(&buffer->sem); down(&buffer->sem);
if (buffer->orphaned) {
len = -ENODEV;
goto out;
}
len = fill_write_buffer(buffer, buf, count); len = fill_write_buffer(buffer, buf, count);
if (len > 0) if (len > 0)
len = flush_write_buffer(file->f_path.dentry, buffer, len); len = flush_write_buffer(file->f_path.dentry, buffer, len);
if (len > 0) if (len > 0)
*ppos += len; *ppos += len;
out:
up(&buffer->sem); up(&buffer->sem);
return len; 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 kobject *kobj = sysfs_get_kobject(file->f_path.dentry->d_parent);
struct attribute * attr = to_attr(file->f_path.dentry); struct attribute * attr = to_attr(file->f_path.dentry);
struct sysfs_buffer_collection *set;
struct sysfs_buffer * buffer; struct sysfs_buffer * buffer;
struct sysfs_ops * ops = NULL; struct sysfs_ops * ops = NULL;
int error = 0; int error = 0;
@ -285,6 +309,18 @@ static int check_perm(struct inode * inode, struct file * file)
if (!ops) if (!ops)
goto Eaccess; 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. /* File needs write support.
* The inode's perms must say it's ok, * The inode's perms must say it's ok,
* and we must have a store method. * 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); buffer = kzalloc(sizeof(struct sysfs_buffer), GFP_KERNEL);
if (buffer) { if (buffer) {
INIT_LIST_HEAD(&buffer->associates);
init_MUTEX(&buffer->sem); init_MUTEX(&buffer->sem);
buffer->needs_read_fill = 1; buffer->needs_read_fill = 1;
buffer->ops = ops; buffer->ops = ops;
add_to_collection(buffer, inode);
file->private_data = buffer; file->private_data = buffer;
} else } else
error = -ENOMEM; error = -ENOMEM;
@ -325,16 +363,11 @@ static int check_perm(struct inode * inode, struct file * file)
error = -EACCES; error = -EACCES;
module_put(attr->owner); module_put(attr->owner);
Done: Done:
if (error && kobj) if (error)
kobject_put(kobj); kobject_put(kobj);
return error; 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) static int sysfs_release(struct inode * inode, struct file * filp)
{ {
struct kobject * kobj = to_kobj(filp->f_path.dentry->d_parent); 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 module * owner = attr->owner;
struct sysfs_buffer * buffer = filp->private_data; struct sysfs_buffer * buffer = filp->private_data;
if (kobj) if (buffer)
kobject_put(kobj); remove_from_collection(buffer, inode);
kobject_put(kobj);
/* After this point, attr should not be accessed. */ /* After this point, attr should not be accessed. */
module_put(owner); module_put(owner);
@ -548,7 +582,7 @@ EXPORT_SYMBOL_GPL(sysfs_chmod_file);
void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr) 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/dcache.h>
#include <linux/namei.h> #include <linux/namei.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/fs.h>
#include <asm/semaphore.h>
#include "sysfs.h" #include "sysfs.h"

Просмотреть файл

@ -13,6 +13,7 @@
#include <linux/backing-dev.h> #include <linux/backing-dev.h>
#include <linux/capability.h> #include <linux/capability.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <asm/semaphore.h>
#include "sysfs.h" #include "sysfs.h"
extern struct super_block * sysfs_sb; extern struct super_block * sysfs_sb;
@ -32,6 +33,16 @@ static struct inode_operations sysfs_inode_operations ={
.setattr = sysfs_setattr, .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) int sysfs_setattr(struct dentry * dentry, struct iattr * iattr)
{ {
struct inode * inode = dentry->d_inode; struct inode * inode = dentry->d_inode;
@ -209,6 +220,22 @@ const unsigned char * sysfs_get_name(struct sysfs_dirent *sd)
return NULL; 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 * 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) void sysfs_drop_dentry(struct sysfs_dirent * sd, struct dentry * parent)
{ {
struct dentry * dentry = sd->s_dentry; struct dentry * dentry = sd->s_dentry;
struct inode *inode;
if (dentry) { if (dentry) {
spin_lock(&dcache_lock); spin_lock(&dcache_lock);
spin_lock(&dentry->d_lock); spin_lock(&dentry->d_lock);
if (!(d_unhashed(dentry) && dentry->d_inode)) { 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); dget_locked(dentry);
__d_drop(dentry); __d_drop(dentry);
spin_unlock(&dentry->d_lock); spin_unlock(&dentry->d_lock);
spin_unlock(&dcache_lock); spin_unlock(&dcache_lock);
simple_unlink(parent->d_inode, dentry); simple_unlink(parent->d_inode, dentry);
orphan_all_buffers(inode);
iput(inode);
} else { } else {
spin_unlock(&dentry->d_lock); spin_unlock(&dentry->d_lock);
spin_unlock(&dcache_lock); spin_unlock(&dcache_lock);
@ -248,7 +282,7 @@ int sysfs_hash_and_remove(struct dentry * dir, const char * name)
return -ENOENT; return -ENOENT;
parent_sd = dir->d_fsdata; 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) { list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
if (!sd->s_element) if (!sd->s_element)
continue; continue;

Просмотреть файл

@ -8,6 +8,7 @@
#include <linux/mount.h> #include <linux/mount.h>
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/init.h> #include <linux/init.h>
#include <asm/semaphore.h>
#include "sysfs.h" #include "sysfs.h"
@ -18,9 +19,12 @@ struct vfsmount *sysfs_mount;
struct super_block * sysfs_sb = NULL; struct super_block * sysfs_sb = NULL;
struct kmem_cache *sysfs_dir_cachep; struct kmem_cache *sysfs_dir_cachep;
static void sysfs_clear_inode(struct inode *inode);
static struct super_operations sysfs_ops = { static struct super_operations sysfs_ops = {
.statfs = simple_statfs, .statfs = simple_statfs,
.drop_inode = generic_delete_inode, .drop_inode = sysfs_delete_inode,
.clear_inode = sysfs_clear_inode,
}; };
static struct sysfs_dirent sysfs_root = { static struct sysfs_dirent sysfs_root = {
@ -31,6 +35,11 @@ static struct sysfs_dirent sysfs_root = {
.s_iattr = NULL, .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) static int sysfs_fill_super(struct super_block *sb, void *data, int silent)
{ {
struct inode *inode; struct inode *inode;

Просмотреть файл

@ -7,6 +7,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/kobject.h> #include <linux/kobject.h>
#include <linux/namei.h> #include <linux/namei.h>
#include <asm/semaphore.h>
#include "sysfs.h" #include "sysfs.h"

Просмотреть файл

@ -2,6 +2,7 @@
extern struct vfsmount * sysfs_mount; extern struct vfsmount * sysfs_mount;
extern struct kmem_cache *sysfs_dir_cachep; 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 struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent *);
extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *)); extern int sysfs_create(struct dentry *, int mode, int (*init)(struct inode *));
@ -33,6 +34,22 @@ struct sysfs_symlink {
struct kobject * target_kobj; 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) static inline struct kobject * to_kobj(struct dentry * dentry)
{ {
struct sysfs_dirent * sd = dentry->d_fsdata; struct sysfs_dirent * sd = dentry->d_fsdata;
@ -96,3 +113,7 @@ static inline void sysfs_put(struct sysfs_dirent * sd)
release_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 klist_node knode_bus;
struct module * owner; struct module * owner;
const char * mod_name; /* used for built-in modules */
int (*probe) (struct device * dev); int (*probe) (struct device * dev);
int (*remove) (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))); __attribute__((format(printf,5,6)));
extern void class_device_destroy(struct class *cls, dev_t devt); 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 */ /* interface for exporting device attributes */
struct device_attribute { struct device_attribute {
struct attribute attr; struct attribute attr;
@ -355,6 +363,7 @@ struct device {
struct kobject kobj; struct kobject kobj;
char bus_id[BUS_ID_SIZE]; /* position on parent bus */ char bus_id[BUS_ID_SIZE]; /* position on parent bus */
struct device_type *type;
unsigned is_registered:1; unsigned is_registered:1;
struct device_attribute uevent_attr; struct device_attribute uevent_attr;
struct device_attribute *devt_attr; struct device_attribute *devt_attr;
@ -390,9 +399,10 @@ struct device {
/* class_device migration path */ /* class_device migration path */
struct list_head node; struct list_head node;
struct class *class; /* optional*/ struct class *class;
dev_t devt; /* dev_t, creates the sysfs "dev" */ dev_t devt; /* dev_t, creates the sysfs "dev" */
struct attribute_group **groups; /* optional groups */ struct attribute_group **groups; /* optional groups */
int uevent_suppress;
void (*release)(struct device * dev); void (*release)(struct device * dev);
}; };

Просмотреть файл

@ -1192,8 +1192,8 @@ void ide_init_disk(struct gendisk *, ide_drive_t *);
extern int ideprobe_init(void); extern int ideprobe_init(void);
extern void ide_scan_pcibus(int scan_direction) __init; extern void ide_scan_pcibus(int scan_direction) __init;
extern int __ide_pci_register_driver(struct pci_driver *driver, struct module *owner); 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) #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 *); 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); 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 void kobject_cleanup(struct kobject *);
extern int __must_check kobject_add(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 void kobject_del(struct kobject *);
extern int __must_check kobject_rename(struct kobject *, const char *new_name); 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_move(struct kobject *, struct kobject *);
extern int __must_check kobject_register(struct kobject *); extern int __must_check kobject_register(struct kobject *);

Просмотреть файл

@ -58,6 +58,7 @@ struct module_kobject
{ {
struct kobject kobj; struct kobject kobj;
struct module *mod; struct module *mod;
struct kobject *drivers_dir;
}; };
/* These are either module local, or the kernel's dummy ones. */ /* These are either module local, or the kernel's dummy ones. */
@ -263,7 +264,7 @@ struct module
struct module_attribute *modinfo_attrs; struct module_attribute *modinfo_attrs;
const char *version; const char *version;
const char *srcversion; const char *srcversion;
struct kobject *drivers_dir; struct kobject *holders_dir;
/* Exported symbols */ /* Exported symbols */
const struct kernel_symbol *syms; const struct kernel_symbol *syms;

Просмотреть файл

@ -529,10 +529,11 @@ struct net_device
struct net_bridge_port *br_port; struct net_bridge_port *br_port;
/* class/net/name entry */ /* class/net/name entry */
struct class_device class_dev; struct device dev;
/* space for optional statistics and wireless sysfs groups */ /* space for optional statistics and wireless sysfs groups */
struct attribute_group *sysfs_groups[3]; 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 32
#define NETDEV_ALIGN_CONST (NETDEV_ALIGN - 1) #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 /* Set the sysfs physical device reference for the network logical device
* if set prior to registration will cause a symlink during initialization. * 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 { struct packet_type {
__be16 type; /* This is really htons(ether_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); void pci_enable_bridges(struct pci_bus *bus);
/* Proper probing supporting hot-pluggable devices */ /* 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) 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 *); 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_port(struct serio *serio);
void serio_unregister_child_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); int serio_register_driver(struct serio_driver *drv);
void serio_unregister_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. * message's completion function when the transaction completes.
*/ */
struct spi_master { struct spi_master {
struct class_device cdev; struct device dev;
/* other than negative (== assign one dynamically), bus_num is fully /* other than negative (== assign one dynamically), bus_num is fully
* board-specific. usually that simplifies to being SOC-specific. * 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) 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) 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) 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 NULL;
return master; 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) static inline void spi_master_put(struct spi_master *master)
{ {
if (master) if (master)
class_device_put(&master->cdev); put_device(&master->dev);
} }

Просмотреть файл

@ -11,10 +11,12 @@
#define _SYSFS_H_ #define _SYSFS_H_
#include <linux/compiler.h> #include <linux/compiler.h>
#include <linux/list.h>
#include <asm/atomic.h> #include <asm/atomic.h>
struct kobject; struct kobject;
struct module; struct module;
struct nameidata;
struct attribute { struct attribute {
const char * name; const char * name;
@ -88,13 +90,13 @@ struct sysfs_dirent {
#ifdef CONFIG_SYSFS #ifdef CONFIG_SYSFS
extern int __must_check extern int __must_check
sysfs_create_dir(struct kobject *); sysfs_create_dir(struct kobject *, struct dentry *);
extern void extern void
sysfs_remove_dir(struct kobject *); sysfs_remove_dir(struct kobject *);
extern int __must_check 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 extern int __must_check
sysfs_move_dir(struct kobject *, struct kobject *); 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_remove_group(struct kobject *, const struct attribute_group *);
void sysfs_notify(struct kobject * k, char *dir, char *attr); 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); extern int __must_check sysfs_init(void);
#else /* CONFIG_SYSFS */ #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; 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; 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) static inline int __must_check sysfs_init(void)
{ {
return 0; return 0;

Просмотреть файл

@ -868,10 +868,11 @@ struct usb_class_driver {
* use these in module_init()/module_exit() * use these in module_init()/module_exit()
* and don't forget MODULE_DEVICE_TABLE(usb, ...) * 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) 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 *); extern void usb_deregister(struct usb_driver *);

Просмотреть файл

@ -284,7 +284,7 @@ struct pcmcia_socket {
#endif #endif
/* socket device */ /* socket device */
struct class_device dev; struct device dev;
void *driver_data; /* data internal to the socket driver */ 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) static int use_module(struct module *a, struct module *b)
{ {
struct module_use *use; struct module_use *use;
int no_warn;
if (b == NULL || already_uses(a, b)) return 1; if (b == NULL || already_uses(a, b)) return 1;
if (!strong_try_module_get(b)) 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; use->module_which_uses = a;
list_add(&use->list, &b->modules_which_use_me); list_add(&use->list, &b->modules_which_use_me);
no_warn = sysfs_create_link(b->holders_dir, &a->mkobj.kobj, a->name);
return 1; return 1;
} }
@ -569,6 +572,7 @@ static void module_unload_free(struct module *mod)
module_put(i); module_put(i);
list_del(&use->list); list_del(&use->list);
kfree(use); kfree(use);
sysfs_remove_link(i->holders_dir, mod->name);
/* There can be at most one match. */ /* There can be at most one match. */
break; break;
} }
@ -1106,9 +1110,7 @@ static void module_remove_modinfo_attrs(struct module *mod)
kfree(mod->modinfo_attrs); kfree(mod->modinfo_attrs);
} }
static int mod_sysfs_setup(struct module *mod, static int mod_sysfs_init(struct module *mod)
struct kernel_param *kparam,
unsigned int num_params)
{ {
int err; int err;
@ -1125,21 +1127,30 @@ static int mod_sysfs_setup(struct module *mod,
kobj_set_kset_s(&mod->mkobj, module_subsys); kobj_set_kset_s(&mod->mkobj, module_subsys);
mod->mkobj.mod = mod; mod->mkobj.mod = mod;
/* delay uevent until full sysfs population */
kobject_init(&mod->mkobj.kobj); 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); err = kobject_add(&mod->mkobj.kobj);
if (err) if (err)
goto out; goto out;
mod->drivers_dir = kobject_add_dir(&mod->mkobj.kobj, "drivers"); mod->holders_dir = kobject_add_dir(&mod->mkobj.kobj, "holders");
if (!mod->drivers_dir) { if (!mod->holders_dir)
err = -ENOMEM;
goto out_unreg; goto out_unreg;
}
err = module_param_sysfs_setup(mod, kparam, num_params); err = module_param_sysfs_setup(mod, kparam, num_params);
if (err) if (err)
goto out_unreg_drivers; goto out_unreg_holders;
err = module_add_modinfo_attrs(mod); err = module_add_modinfo_attrs(mod);
if (err) if (err)
@ -1150,8 +1161,8 @@ static int mod_sysfs_setup(struct module *mod,
out_unreg_param: out_unreg_param:
module_param_sysfs_remove(mod); module_param_sysfs_remove(mod);
out_unreg_drivers: out_unreg_holders:
kobject_unregister(mod->drivers_dir); kobject_unregister(mod->holders_dir);
out_unreg: out_unreg:
kobject_del(&mod->mkobj.kobj); kobject_del(&mod->mkobj.kobj);
kobject_put(&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_remove_modinfo_attrs(mod);
module_param_sysfs_remove(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); 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. */ /* Now we've moved module, initialize linked lists, etc. */
module_unload_init(mod); 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 up license info based on the info section */
set_license(mod, get_modinfo(sechdrs, infoindex, "license")); set_license(mod, get_modinfo(sechdrs, infoindex, "license"));
@ -2340,19 +2358,43 @@ static char *make_driver_name(struct device_driver *drv)
return driver_name; 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) void module_add_driver(struct module *mod, struct device_driver *drv)
{ {
char *driver_name; char *driver_name;
int no_warn; 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; return;
/* Don't check return codes; these calls are idempotent */ /* 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); driver_name = make_driver_name(drv);
if (driver_name) { 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); driver_name);
kfree(driver_name); kfree(driver_name);
} }
@ -2367,10 +2409,10 @@ void module_remove_driver(struct device_driver *drv)
return; return;
sysfs_remove_link(&drv->kobj, "module"); 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); driver_name = make_driver_name(drv);
if (driver_name) { if (driver_name) {
sysfs_remove_link(drv->owner->drivers_dir, sysfs_remove_link(drv->owner->mkobj.drivers_dir,
driver_name); driver_name);
kfree(driver_name); kfree(driver_name);
} }

Просмотреть файл

@ -30,6 +30,8 @@
#define DEBUGP(fmt, a...) #define DEBUGP(fmt, a...)
#endif #endif
static struct kobj_type module_ktype;
static inline char dash2underscore(char c) static inline char dash2underscore(char c)
{ {
if (c == '-') if (c == '-')
@ -561,14 +563,11 @@ static void __init kernel_param_sysfs_setup(const char *name,
mk->mod = THIS_MODULE; mk->mod = THIS_MODULE;
kobj_set_kset_s(mk, module_subsys); kobj_set_kset_s(mk, module_subsys);
kobject_set_name(&mk->kobj, name); kobject_set_name(&mk->kobj, name);
ret = kobject_register(&mk->kobj); kobject_init(&mk->kobj);
ret = kobject_add(&mk->kobj);
BUG_ON(ret < 0); BUG_ON(ret < 0);
param_sysfs_setup(mk, kparam, num_params, name_skip);
/* no need to keep the kobject if no parameter is exported */ kobject_uevent(&mk->kobj, KOBJ_ADD);
if (!param_sysfs_setup(mk, kparam, num_params, name_skip)) {
kobject_unregister(&mk->kobj);
kfree(mk);
}
} }
/* /*
@ -674,6 +673,19 @@ static struct sysfs_ops module_sysfs_ops = {
.store = module_attr_store, .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 #else
static struct sysfs_ops module_sysfs_ops = { static struct sysfs_ops module_sysfs_ops = {
.show = NULL, .show = NULL,
@ -685,7 +697,7 @@ static struct kobj_type module_ktype = {
.sysfs_ops = &module_sysfs_ops, .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 * param_sysfs_init - wrapper for built-in params support

Просмотреть файл

@ -44,11 +44,11 @@ static int populate_dir(struct kobject * kobj)
return error; return error;
} }
static int create_dir(struct kobject * kobj) static int create_dir(struct kobject * kobj, struct dentry *shadow_parent)
{ {
int error = 0; int error = 0;
if (kobject_name(kobj)) { if (kobject_name(kobj)) {
error = sysfs_create_dir(kobj); error = sysfs_create_dir(kobj, shadow_parent);
if (!error) { if (!error) {
if ((error = populate_dir(kobj))) if ((error = populate_dir(kobj)))
sysfs_remove_dir(kobj); sysfs_remove_dir(kobj);
@ -126,6 +126,8 @@ EXPORT_SYMBOL_GPL(kobject_get_path);
*/ */
void kobject_init(struct kobject * kobj) void kobject_init(struct kobject * kobj)
{ {
if (!kobj)
return;
kref_init(&kobj->kref); kref_init(&kobj->kref);
INIT_LIST_HEAD(&kobj->entry); INIT_LIST_HEAD(&kobj->entry);
init_waitqueue_head(&kobj->poll); init_waitqueue_head(&kobj->poll);
@ -156,9 +158,10 @@ static void unlink(struct kobject * kobj)
/** /**
* kobject_add - add an object to the hierarchy. * kobject_add - add an object to the hierarchy.
* @kobj: object. * @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; int error = 0;
struct kobject * parent; struct kobject * parent;
@ -189,12 +192,11 @@ int kobject_add(struct kobject * kobj)
} }
kobj->parent = parent; kobj->parent = parent;
error = create_dir(kobj); error = create_dir(kobj, shadow_parent);
if (error) { if (error) {
/* unlink does the kobject_put() for us */ /* unlink does the kobject_put() for us */
unlink(kobj); unlink(kobj);
if (parent) kobject_put(parent);
kobject_put(parent);
/* be noisy on error issues */ /* be noisy on error issues */
if (error == -EEXIST) if (error == -EEXIST)
@ -211,6 +213,15 @@ int kobject_add(struct kobject * kobj)
return error; 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. * 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); kobj = kobject_get(kobj);
if (!kobj) if (!kobj)
return -EINVAL; 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); kobject_put(kobj);
return error; return error;
@ -312,7 +345,7 @@ int kobject_rename(struct kobject * kobj, const char *new_name)
/** /**
* kobject_move - move object to another parent * kobject_move - move object to another parent
* @kobj: object in question. * @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) 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; return -EINVAL;
new_parent = kobject_get(new_parent); new_parent = kobject_get(new_parent);
if (!new_parent) { if (!new_parent) {
error = -EINVAL; if (kobj->kset)
goto out; new_parent = kobject_get(&kobj->kset->kobj);
} }
/* old object path */ /* old object path */
devpath = kobject_get_path(kobj, GFP_KERNEL); devpath = kobject_get_path(kobj, GFP_KERNEL);
@ -366,6 +399,8 @@ out:
void kobject_del(struct kobject * kobj) void kobject_del(struct kobject * kobj)
{ {
if (!kobj)
return;
sysfs_remove_dir(kobj); sysfs_remove_dir(kobj);
unlink(kobj); unlink(kobj);
} }
@ -377,6 +412,8 @@ void kobject_del(struct kobject * kobj)
void kobject_unregister(struct kobject * kobj) void kobject_unregister(struct kobject * kobj)
{ {
if (!kobj)
return;
pr_debug("kobject %s: unregistering\n",kobject_name(kobj)); pr_debug("kobject %s: unregistering\n",kobject_name(kobj));
kobject_uevent(kobj, KOBJ_REMOVE); kobject_uevent(kobj, KOBJ_REMOVE);
kobject_del(kobj); kobject_del(kobj);
@ -414,8 +451,7 @@ void kobject_cleanup(struct kobject * kobj)
t->release(kobj); t->release(kobj);
if (s) if (s)
kset_put(s); kset_put(s);
if (parent) kobject_put(parent);
kobject_put(parent);
} }
static void kobject_release(struct kref *kref) static void kobject_release(struct kref *kref)
@ -523,6 +559,8 @@ int kset_add(struct kset * k)
int kset_register(struct kset * k) int kset_register(struct kset * k)
{ {
if (!k)
return -EINVAL;
kset_init(k); kset_init(k);
return kset_add(k); return kset_add(k);
} }
@ -535,6 +573,8 @@ int kset_register(struct kset * k)
void kset_unregister(struct kset * k) void kset_unregister(struct kset * k)
{ {
if (!k)
return;
kobject_unregister(&k->kobj); kobject_unregister(&k->kobj);
} }
@ -586,6 +626,9 @@ int subsystem_register(struct subsystem * s)
{ {
int error; int error;
if (!s)
return -EINVAL;
subsystem_init(s); subsystem_init(s);
pr_debug("subsystem %s: registering\n",s->kset.kobj.name); 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) void subsystem_unregister(struct subsystem * s)
{ {
if (!s)
return;
pr_debug("subsystem %s: unregistering\n",s->kset.kobj.name); pr_debug("subsystem %s: unregistering\n",s->kset.kobj.name);
kset_unregister(&s->kset); 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 subsys_create_file(struct subsystem * s, struct subsys_attribute * a)
{ {
int error = 0; int error = 0;
if (!s || !a)
return -EINVAL;
if (subsys_get(s)) { if (subsys_get(s)) {
error = sysfs_create_file(&s->kset.kobj,&a->attr); error = sysfs_create_file(&s->kset.kobj,&a->attr);
subsys_put(s); subsys_put(s);

Просмотреть файл

@ -286,7 +286,7 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br,
kobject_init(&p->kobj); kobject_init(&p->kobj);
kobject_set_name(&p->kobj, SYSFS_BRIDGE_PORT_ATTR); kobject_set_name(&p->kobj, SYSFS_BRIDGE_PORT_ATTR);
p->kobj.ktype = &brport_ktype; p->kobj.ktype = &brport_ktype;
p->kobj.parent = &(dev->class_dev.kobj); p->kobj.parent = &(dev->dev.kobj);
p->kobj.kset = NULL; p->kobj.kset = NULL;
return p; return p;

Просмотреть файл

@ -21,18 +21,17 @@
#include "br_private.h" #include "br_private.h"
#define to_class_dev(obj) container_of(obj,struct class_device,kobj) #define to_dev(obj) container_of(obj, struct device, kobj)
#define to_net_dev(class) container_of(class, struct net_device, class_dev)
#define to_bridge(cd) ((struct net_bridge *)(to_net_dev(cd)->priv)) #define to_bridge(cd) ((struct net_bridge *)(to_net_dev(cd)->priv))
/* /*
* Common code for storing bridge parameters. * 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, const char *buf, size_t len,
void (*set)(struct net_bridge *, unsigned long)) void (*set)(struct net_bridge *, unsigned long))
{ {
struct net_bridge *br = to_bridge(cd); struct net_bridge *br = to_bridge(d);
char *endp; char *endp;
unsigned long val; 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)); 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; br->bridge_forward_delay = delay;
} }
static ssize_t store_forward_delay(struct class_device *cd, const char *buf, static ssize_t store_forward_delay(struct device *d,
size_t len) 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, static DEVICE_ATTR(forward_delay, S_IRUGO | S_IWUSR,
show_forward_delay, store_forward_delay); 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", 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) 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; 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) 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, static ssize_t show_max_age(struct device *d, struct device_attribute *attr,
store_hello_time); char *buf)
static ssize_t show_max_age(struct class_device *cd, char *buf)
{ {
return sprintf(buf, "%lu\n", 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) 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; br->bridge_max_age = t;
} }
static ssize_t store_max_age(struct class_device *cd, const char *buf, static ssize_t store_max_age(struct device *d, struct device_attribute *attr,
size_t len) 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, static ssize_t show_ageing_time(struct device *d,
store_max_age); struct device_attribute *attr, char *buf)
static ssize_t show_ageing_time(struct class_device *cd, 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)); 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); br->ageing_time = clock_t_to_jiffies(val);
} }
static ssize_t store_ageing_time(struct class_device *cd, const char *buf, static ssize_t store_ageing_time(struct device *d,
size_t len) 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, static ssize_t show_stp_state(struct device *d,
store_ageing_time); struct device_attribute *attr, char *buf)
static ssize_t show_stp_state(struct class_device *cd, char *buf)
{ {
struct net_bridge *br = to_bridge(cd); struct net_bridge *br = to_bridge(d);
return sprintf(buf, "%d\n", br->stp_enabled); 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; br->stp_enabled = val;
} }
static ssize_t store_stp_state(struct class_device *cd, static ssize_t store_stp_state(struct device *d,
const char *buf, size_t len) 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, static ssize_t show_priority(struct device *d, struct device_attribute *attr,
store_stp_state); char *buf)
static ssize_t show_priority(struct class_device *cd, char *buf)
{ {
struct net_bridge *br = to_bridge(cd); struct net_bridge *br = to_bridge(d);
return sprintf(buf, "%d\n", return sprintf(buf, "%d\n",
(br->bridge_id.prio[0] << 8) | br->bridge_id.prio[1]); (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); 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) 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, static DEVICE_ATTR(priority, S_IRUGO | S_IWUSR, show_priority, store_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); 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)); 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)); 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)); 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)); 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", return sprintf(buf, "%x:%x:%x:%x:%x:%x\n",
br->group_addr[0], br->group_addr[1], br->group_addr[0], br->group_addr[1],
br->group_addr[2], br->group_addr[3], br->group_addr[2], br->group_addr[3],
br->group_addr[4], br->group_addr[5]); br->group_addr[4], br->group_addr[5]);
} }
static ssize_t store_group_addr(struct class_device *cd, const char *buf, static ssize_t store_group_addr(struct device *d,
size_t len) 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]; unsigned new_addr[6];
int i; int i;
@ -286,28 +306,28 @@ static ssize_t store_group_addr(struct class_device *cd, const char *buf,
return len; return len;
} }
static CLASS_DEVICE_ATTR(group_addr, S_IRUGO | S_IWUSR, static DEVICE_ATTR(group_addr, S_IRUGO | S_IWUSR,
show_group_addr, store_group_addr); show_group_addr, store_group_addr);
static struct attribute *bridge_attrs[] = { static struct attribute *bridge_attrs[] = {
&class_device_attr_forward_delay.attr, &dev_attr_forward_delay.attr,
&class_device_attr_hello_time.attr, &dev_attr_hello_time.attr,
&class_device_attr_max_age.attr, &dev_attr_max_age.attr,
&class_device_attr_ageing_time.attr, &dev_attr_ageing_time.attr,
&class_device_attr_stp_state.attr, &dev_attr_stp_state.attr,
&class_device_attr_priority.attr, &dev_attr_priority.attr,
&class_device_attr_bridge_id.attr, &dev_attr_bridge_id.attr,
&class_device_attr_root_id.attr, &dev_attr_root_id.attr,
&class_device_attr_root_path_cost.attr, &dev_attr_root_path_cost.attr,
&class_device_attr_root_port.attr, &dev_attr_root_port.attr,
&class_device_attr_topology_change.attr, &dev_attr_topology_change.attr,
&class_device_attr_topology_change_detected.attr, &dev_attr_topology_change_detected.attr,
&class_device_attr_hello_timer.attr, &dev_attr_hello_timer.attr,
&class_device_attr_tcn_timer.attr, &dev_attr_tcn_timer.attr,
&class_device_attr_topology_change_timer.attr, &dev_attr_topology_change_timer.attr,
&class_device_attr_gc_timer.attr, &dev_attr_gc_timer.attr,
&class_device_attr_group_addr.attr, &dev_attr_group_addr.attr,
NULL NULL
}; };
@ -325,8 +345,8 @@ static struct attribute_group bridge_group = {
static ssize_t brforward_read(struct kobject *kobj, char *buf, static ssize_t brforward_read(struct kobject *kobj, char *buf,
loff_t off, size_t count) loff_t off, size_t count)
{ {
struct class_device *cdev = to_class_dev(kobj); struct device *dev = to_dev(kobj);
struct net_bridge *br = to_bridge(cdev); struct net_bridge *br = to_bridge(dev);
int n; int n;
/* must read whole records */ /* must read whole records */
@ -363,7 +383,7 @@ static struct bin_attribute bridge_forward = {
*/ */
int br_sysfs_addbr(struct net_device *dev) 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); struct net_bridge *br = netdev_priv(dev);
int err; int err;
@ -395,9 +415,9 @@ int br_sysfs_addbr(struct net_device *dev)
} }
return 0; return 0;
out3: out3:
sysfs_remove_bin_file(&dev->class_dev.kobj, &bridge_forward); sysfs_remove_bin_file(&dev->dev.kobj, &bridge_forward);
out2: out2:
sysfs_remove_group(&dev->class_dev.kobj, &bridge_group); sysfs_remove_group(&dev->dev.kobj, &bridge_group);
out1: out1:
return err; return err;
@ -405,7 +425,7 @@ int br_sysfs_addbr(struct net_device *dev)
void br_sysfs_delbr(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); struct net_bridge *br = netdev_priv(dev);
kobject_unregister(&br->ifobj); kobject_unregister(&br->ifobj);

Просмотреть файл

@ -211,7 +211,7 @@ int br_sysfs_addif(struct net_bridge_port *p)
struct brport_attribute **a; struct brport_attribute **a;
int err; 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); SYSFS_BRIDGE_PORT_LINK);
if (err) if (err)
goto out2; goto out2;

Просмотреть файл

@ -751,7 +751,7 @@ int dev_change_name(struct net_device *dev, char *newname)
else else
strlcpy(dev->name, newname, IFNAMSIZ); strlcpy(dev->name, newname, IFNAMSIZ);
err = class_device_rename(&dev->class_dev, dev->name); err = device_rename(&dev->dev, dev->name);
if (!err) { if (!err) {
hlist_del(&dev->name_hlist); hlist_del(&dev->name_hlist);
hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name)); 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); BUG_ON(dev->reg_state != NETREG_UNREGISTERED);
dev->reg_state = NETREG_RELEASED; dev->reg_state = NETREG_RELEASED;
/* will free via class release */ /* will free via device release */
class_device_put(&dev->class_dev); put_device(&dev->dev);
#else #else
kfree((char *)dev - dev->padded); kfree((char *)dev - dev->padded);
#endif #endif

Просмотреть файл

@ -18,9 +18,6 @@
#include <linux/wireless.h> #include <linux/wireless.h>
#include <net/iw_handler.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_hex[] = "%#x\n";
static const char fmt_long_hex[] = "%#lx\n"; static const char fmt_long_hex[] = "%#lx\n";
static const char fmt_dec[] = "%d\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 */ /* 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 *)) 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; ssize_t ret = -EINVAL;
read_lock(&dev_base_lock); 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); \ 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 */ /* 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, const char *buf, size_t len,
int (*set)(struct net_device *, unsigned long)) 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; 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); struct net_device *net = to_net_dev(dev);
ssize_t ret = -EINVAL; ssize_t ret = -EINVAL;
@ -116,7 +116,8 @@ static ssize_t show_address(struct class_device *dev, char *buf)
return ret; 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); struct net_device *net = to_net_dev(dev);
if (dev_isalive(net)) if (dev_isalive(net))
@ -124,7 +125,8 @@ static ssize_t show_broadcast(struct class_device *dev, char *buf)
return -EINVAL; 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); struct net_device *netdev = to_net_dev(dev);
if (netif_running(netdev)) { if (netif_running(netdev)) {
@ -133,7 +135,8 @@ static ssize_t show_carrier(struct class_device *dev, char *buf)
return -EINVAL; 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); struct net_device *netdev = to_net_dev(dev);
@ -153,7 +156,8 @@ static const char *operstates[] = {
"up" "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); const struct net_device *netdev = to_net_dev(dev);
unsigned char operstate; 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); 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); 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); 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); 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; 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); NETDEVICE_SHOW(weight, fmt_dec);
@ -216,12 +224,13 @@ static int change_weight(struct net_device *net, unsigned long new_weight)
return 0; 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(addr_len, S_IRUGO, show_addr_len, NULL),
__ATTR(iflink, S_IRUGO, show_iflink, NULL), __ATTR(iflink, S_IRUGO, show_iflink, NULL),
__ATTR(ifindex, S_IRUGO, show_ifindex, 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 */ /* 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) unsigned long offset)
{ {
struct net_device *dev = to_net_dev(cd); struct net_device *dev = to_net_dev(d);
struct net_device_stats *stats; struct net_device_stats *stats;
ssize_t ret = -EINVAL; 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 */ /* generate a read-only statistics attribute */
#define NETSTAT_ENTRY(name) \ #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)); \ 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(rx_packets);
NETSTAT_ENTRY(tx_packets); NETSTAT_ENTRY(tx_packets);
@ -297,29 +308,29 @@ NETSTAT_ENTRY(rx_compressed);
NETSTAT_ENTRY(tx_compressed); NETSTAT_ENTRY(tx_compressed);
static struct attribute *netstat_attrs[] = { static struct attribute *netstat_attrs[] = {
&class_device_attr_rx_packets.attr, &dev_attr_rx_packets.attr,
&class_device_attr_tx_packets.attr, &dev_attr_tx_packets.attr,
&class_device_attr_rx_bytes.attr, &dev_attr_rx_bytes.attr,
&class_device_attr_tx_bytes.attr, &dev_attr_tx_bytes.attr,
&class_device_attr_rx_errors.attr, &dev_attr_rx_errors.attr,
&class_device_attr_tx_errors.attr, &dev_attr_tx_errors.attr,
&class_device_attr_rx_dropped.attr, &dev_attr_rx_dropped.attr,
&class_device_attr_tx_dropped.attr, &dev_attr_tx_dropped.attr,
&class_device_attr_multicast.attr, &dev_attr_multicast.attr,
&class_device_attr_collisions.attr, &dev_attr_collisions.attr,
&class_device_attr_rx_length_errors.attr, &dev_attr_rx_length_errors.attr,
&class_device_attr_rx_over_errors.attr, &dev_attr_rx_over_errors.attr,
&class_device_attr_rx_crc_errors.attr, &dev_attr_rx_crc_errors.attr,
&class_device_attr_rx_frame_errors.attr, &dev_attr_rx_frame_errors.attr,
&class_device_attr_rx_fifo_errors.attr, &dev_attr_rx_fifo_errors.attr,
&class_device_attr_rx_missed_errors.attr, &dev_attr_rx_missed_errors.attr,
&class_device_attr_tx_aborted_errors.attr, &dev_attr_tx_aborted_errors.attr,
&class_device_attr_tx_carrier_errors.attr, &dev_attr_tx_carrier_errors.attr,
&class_device_attr_tx_fifo_errors.attr, &dev_attr_tx_fifo_errors.attr,
&class_device_attr_tx_heartbeat_errors.attr, &dev_attr_tx_heartbeat_errors.attr,
&class_device_attr_tx_window_errors.attr, &dev_attr_tx_window_errors.attr,
&class_device_attr_rx_compressed.attr, &dev_attr_rx_compressed.attr,
&class_device_attr_tx_compressed.attr, &dev_attr_tx_compressed.attr,
NULL NULL
}; };
@ -331,11 +342,11 @@ static struct attribute_group netstat_group = {
#ifdef WIRELESS_EXT #ifdef WIRELESS_EXT
/* helper function that does all the locking etc for wireless stats */ /* 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 *, ssize_t (*format)(const struct iw_statistics *,
char *)) char *))
{ {
struct net_device *dev = to_net_dev(cd); struct net_device *dev = to_net_dev(d);
const struct iw_statistics *iw = NULL; const struct iw_statistics *iw = NULL;
ssize_t ret = -EINVAL; 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); \ 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(status, status, fmt_hex);
WIRELESS_SHOW(link, qual.qual, fmt_dec); 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); WIRELESS_SHOW(beacon, miss.beacon, fmt_dec);
static struct attribute *wireless_attrs[] = { static struct attribute *wireless_attrs[] = {
&class_device_attr_status.attr, &dev_attr_status.attr,
&class_device_attr_link.attr, &dev_attr_link.attr,
&class_device_attr_level.attr, &dev_attr_level.attr,
&class_device_attr_noise.attr, &dev_attr_noise.attr,
&class_device_attr_nwid.attr, &dev_attr_nwid.attr,
&class_device_attr_crypt.attr, &dev_attr_crypt.attr,
&class_device_attr_fragment.attr, &dev_attr_fragment.attr,
&class_device_attr_retries.attr, &dev_attr_retries.attr,
&class_device_attr_misc.attr, &dev_attr_misc.attr,
&class_device_attr_beacon.attr, &dev_attr_beacon.attr,
NULL NULL
}; };
@ -396,10 +408,10 @@ static struct attribute_group wireless_group = {
#endif #endif
#ifdef CONFIG_HOTPLUG #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) 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 i = 0;
int n; int n;
@ -419,12 +431,11 @@ static int netdev_uevent(struct class_device *cd, char **envp,
/* /*
* netdev_release -- destroy and free a dead device. * 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 struct net_device *dev = to_net_dev(d);
= container_of(cd, struct net_device, class_dev);
BUG_ON(dev->reg_state != NETREG_RELEASED); BUG_ON(dev->reg_state != NETREG_RELEASED);
@ -433,31 +444,31 @@ static void netdev_release(struct class_device *cd)
static struct class net_class = { static struct class net_class = {
.name = "net", .name = "net",
.release = netdev_release, .dev_release = netdev_release,
.class_dev_attrs = net_class_attributes, .dev_attrs = net_class_attributes,
#ifdef CONFIG_HOTPLUG #ifdef CONFIG_HOTPLUG
.uevent = netdev_uevent, .dev_uevent = netdev_uevent,
#endif #endif
}; };
void netdev_unregister_sysfs(struct net_device * net) void netdev_unregister_sysfs(struct net_device * net)
{ {
class_device_del(&(net->class_dev)); device_del(&(net->dev));
} }
/* Create sysfs entries for network device. */ /* Create sysfs entries for network device. */
int netdev_register_sysfs(struct net_device *net) 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; struct attribute_group **groups = net->sysfs_groups;
class_device_initialize(class_dev); device_initialize(dev);
class_dev->class = &net_class; dev->class = &net_class;
class_dev->class_data = net; dev->platform_data = net;
class_dev->groups = groups; dev->groups = groups;
BUILD_BUG_ON(BUS_ID_SIZE < IFNAMSIZ); 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) if (net->get_stats)
*groups++ = &netstat_group; *groups++ = &netstat_group;
@ -467,7 +478,7 @@ int netdev_register_sysfs(struct net_device *net)
*groups++ = &wireless_group; *groups++ = &wireless_group;
#endif #endif
return class_device_add(class_dev); return device_add(dev);
} }
int netdev_sysfs_init(void) int netdev_sysfs_init(void)

Просмотреть файл

@ -268,7 +268,7 @@ nodata:
struct sk_buff *__netdev_alloc_skb(struct net_device *dev, struct sk_buff *__netdev_alloc_skb(struct net_device *dev,
unsigned int length, gfp_t gfp_mask) 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; struct sk_buff *skb;
skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask, 0, node); skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask, 0, node);