Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2eb645e7 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6:
  driver core: numa: fix BUILD_BUG_ON for node_read_distance
  driver-core: document ERR_PTR() return values
  kobject: documentation: Update to refer to kset-example.c.
  sysdev: the cpu probe/release attributes should be sysdev_class_attributes
  kobject: documentation: Fix erroneous example in kobject doc.
  driver-core: fix missing kernel-doc in firmware_class
  Driver core: Early platform kernel-doc update
  sysfs: fix sysfs lockdep warning in mlx4 code
  sysfs: fix sysfs lockdep warning in infiniband code
  sysfs: fix sysfs lockdep warning in ipmi code
  sysfs: Initialised pci bus legacy_mem field before use
  sysfs: use sysfs_bin_attr_init in firmware class driver
parents 8fdb7e9f 12ee3c0a
Loading
Loading
Loading
Loading
+40 −20
Original line number Original line Diff line number Diff line
@@ -59,18 +59,20 @@ nice to have in other objects. The C language does not allow for the
direct expression of inheritance, so other techniques - such as structure
direct expression of inheritance, so other techniques - such as structure
embedding - must be used.
embedding - must be used.


So, for example, the UIO code has a structure that defines the memory
(As an aside, for those familiar with the kernel linked list implementation,
region associated with a uio device:
this is analogous as to how "list_head" structs are rarely useful on
their own, but are invariably found embedded in the larger objects of
interest.)


struct uio_mem {
So, for example, the UIO code in drivers/uio/uio.c has a structure that
defines the memory region associated with a uio device:

    struct uio_map {
	struct kobject kobj;
	struct kobject kobj;
	unsigned long addr;
	struct uio_mem *mem;
	unsigned long size;
	int memtype;
	void __iomem *internal_addr;
    };
    };


If you have a struct uio_mem structure, finding its embedded kobject is
If you have a struct uio_map structure, finding its embedded kobject is
just a matter of using the kobj member.  Code that works with kobjects will
just a matter of using the kobj member.  Code that works with kobjects will
often have the opposite problem, however: given a struct kobject pointer,
often have the opposite problem, however: given a struct kobject pointer,
what is the pointer to the containing structure?  You must avoid tricks
what is the pointer to the containing structure?  You must avoid tricks
@@ -79,17 +81,34 @@ and, instead, use the container_of() macro, found in <linux/kernel.h>:


    container_of(pointer, type, member)
    container_of(pointer, type, member)


where pointer is the pointer to the embedded kobject, type is the type of
where:
the containing structure, and member is the name of the structure field to

which pointer points.  The return value from container_of() is a pointer to
  * "pointer" is the pointer to the embedded kobject,
the given type. So, for example, a pointer "kp" to a struct kobject
  * "type" is the type of the containing structure, and
embedded within a struct uio_mem could be converted to a pointer to the
  * "member" is the name of the structure field to which "pointer" points.
containing uio_mem structure with:

The return value from container_of() is a pointer to the corresponding
container type. So, for example, a pointer "kp" to a struct kobject
embedded *within* a struct uio_map could be converted to a pointer to the
*containing* uio_map structure with:

    struct uio_map *u_map = container_of(kp, struct uio_map, kobj);

For convenience, programmers often define a simple macro for "back-casting"
kobject pointers to the containing type.  Exactly this happens in the
earlier drivers/uio/uio.c, as you can see here:

    struct uio_map {
        struct kobject kobj;
        struct uio_mem *mem;
    };

    #define to_map(map) container_of(map, struct uio_map, kobj)


    struct uio_mem *u_mem = container_of(kp, struct uio_mem, kobj);
where the macro argument "map" is a pointer to the struct kobject in
question.  That macro is subsequently invoked with:


Programmers often define a simple macro for "back-casting" kobject pointers
    struct uio_map *map = to_map(kobj);
to the containing type.




Initialization of kobjects
Initialization of kobjects
@@ -387,4 +406,5 @@ called, and the objects in the former circle release each other.
Example code to copy from
Example code to copy from


For a more complete example of using ksets and kobjects properly, see the
For a more complete example of using ksets and kobjects properly, see the
sample/kobject/kset-example.c code.
example programs samples/kobject/{kobject-example.c,kset-example.c},
which will be built as loadable modules if you select CONFIG_SAMPLE_KOBJECT.
+2 −0
Original line number Original line Diff line number Diff line
@@ -219,6 +219,8 @@ static void class_create_release(struct class *cls)
 * This is used to create a struct class pointer that can then be used
 * This is used to create a struct class pointer that can then be used
 * in calls to device_create().
 * in calls to device_create().
 *
 *
 * Returns &struct class pointer on success, or ERR_PTR() on error.
 *
 * Note, the pointer created here is to be destroyed when finished by
 * Note, the pointer created here is to be destroyed when finished by
 * making a call to class_destroy().
 * making a call to class_destroy().
 */
 */
+6 −0
Original line number Original line Diff line number Diff line
@@ -1345,6 +1345,8 @@ static void root_device_release(struct device *dev)
 * 'module' symlink which points to the @owner directory
 * 'module' symlink which points to the @owner directory
 * in sysfs.
 * in sysfs.
 *
 *
 * Returns &struct device pointer on success, or ERR_PTR() on error.
 *
 * Note: You probably want to use root_device_register().
 * Note: You probably want to use root_device_register().
 */
 */
struct device *__root_device_register(const char *name, struct module *owner)
struct device *__root_device_register(const char *name, struct module *owner)
@@ -1432,6 +1434,8 @@ static void device_create_release(struct device *dev)
 * Any further sysfs files that might be required can be created using this
 * Any further sysfs files that might be required can be created using this
 * pointer.
 * pointer.
 *
 *
 * Returns &struct device pointer on success, or ERR_PTR() on error.
 *
 * Note: the struct class passed to this function must have previously
 * Note: the struct class passed to this function must have previously
 * been created with a call to class_create().
 * been created with a call to class_create().
 */
 */
@@ -1492,6 +1496,8 @@ EXPORT_SYMBOL_GPL(device_create_vargs);
 * Any further sysfs files that might be required can be created using this
 * Any further sysfs files that might be required can be created using this
 * pointer.
 * pointer.
 *
 *
 * Returns &struct device pointer on success, or ERR_PTR() on error.
 *
 * Note: the struct class passed to this function must have previously
 * Note: the struct class passed to this function must have previously
 * been created with a call to class_create().
 * been created with a call to class_create().
 */
 */
+8 −8
Original line number Original line Diff line number Diff line
@@ -79,24 +79,24 @@ void unregister_cpu(struct cpu *cpu)
}
}


#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
static ssize_t cpu_probe_store(struct sys_device *dev,
static ssize_t cpu_probe_store(struct sysdev_class *class,
				struct sysdev_attribute *attr,
			       struct sysdev_class_attribute *attr,
			       const char *buf,
			       const char *buf,
			       size_t count)
			       size_t count)
{
{
	return arch_cpu_probe(buf, count);
	return arch_cpu_probe(buf, count);
}
}


static ssize_t cpu_release_store(struct sys_device *dev,
static ssize_t cpu_release_store(struct sysdev_class *class,
				struct sysdev_attribute *attr,
				 struct sysdev_class_attribute *attr,
				 const char *buf,
				 const char *buf,
				 size_t count)
				 size_t count)
{
{
	return arch_cpu_release(buf, count);
	return arch_cpu_release(buf, count);
}
}


static SYSDEV_ATTR(probe, S_IWUSR, NULL, cpu_probe_store);
static SYSDEV_CLASS_ATTR(probe, S_IWUSR, NULL, cpu_probe_store);
static SYSDEV_ATTR(release, S_IWUSR, NULL, cpu_release_store);
static SYSDEV_CLASS_ATTR(release, S_IWUSR, NULL, cpu_release_store);
#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */


#else /* ... !CONFIG_HOTPLUG_CPU */
#else /* ... !CONFIG_HOTPLUG_CPU */
+2 −0
Original line number Original line Diff line number Diff line
@@ -78,6 +78,7 @@ firmware_timeout_show(struct class *class,
/**
/**
 * firmware_timeout_store - set number of seconds to wait for firmware
 * firmware_timeout_store - set number of seconds to wait for firmware
 * @class: device class pointer
 * @class: device class pointer
 * @attr: device attribute pointer
 * @buf: buffer to scan for timeout value
 * @buf: buffer to scan for timeout value
 * @count: number of bytes in @buf
 * @count: number of bytes in @buf
 *
 *
@@ -442,6 +443,7 @@ static int fw_setup_device(struct firmware *fw, struct device **dev_p,
	fw_priv = dev_get_drvdata(f_dev);
	fw_priv = dev_get_drvdata(f_dev);


	fw_priv->fw = fw;
	fw_priv->fw = fw;
	sysfs_bin_attr_init(&fw_priv->attr_data);
	retval = sysfs_create_bin_file(&f_dev->kobj, &fw_priv->attr_data);
	retval = sysfs_create_bin_file(&f_dev->kobj, &fw_priv->attr_data);
	if (retval) {
	if (retval) {
		dev_err(device, "%s: sysfs_create_bin_file failed\n", __func__);
		dev_err(device, "%s: sysfs_create_bin_file failed\n", __func__);
Loading