Commit 2eb645e7 authored by Linus Torvalds's avatar Linus Torvalds

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

* 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
...@@ -59,18 +59,20 @@ nice to have in other objects. The C language does not allow for the ...@@ -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>: ...@@ -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. ...@@ -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.
...@@ -219,6 +219,8 @@ static void class_create_release(struct class *cls) ...@@ -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().
*/ */
......
...@@ -1345,6 +1345,8 @@ static void root_device_release(struct device *dev) ...@@ -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) ...@@ -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); ...@@ -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().
*/ */
......
...@@ -79,24 +79,24 @@ void unregister_cpu(struct cpu *cpu) ...@@ -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 */
......
...@@ -78,6 +78,7 @@ firmware_timeout_show(struct class *class, ...@@ -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, ...@@ -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__);
......
...@@ -165,8 +165,11 @@ static ssize_t node_read_distance(struct sys_device * dev, ...@@ -165,8 +165,11 @@ static ssize_t node_read_distance(struct sys_device * dev,
int len = 0; int len = 0;
int i; int i;
/* buf currently PAGE_SIZE, need ~4 chars per node */ /*
BUILD_BUG_ON(MAX_NUMNODES*4 > PAGE_SIZE/2); * buf is currently PAGE_SIZE in length and each node needs 4 chars
* at the most (distance + space or newline).
*/
BUILD_BUG_ON(MAX_NUMNODES * 4 > PAGE_SIZE);
for_each_online_node(i) for_each_online_node(i)
len += sprintf(buf + len, "%s%d", i ? " " : "", node_distance(nid, i)); len += sprintf(buf + len, "%s%d", i ? " " : "", node_distance(nid, i));
......
...@@ -362,6 +362,8 @@ EXPORT_SYMBOL_GPL(platform_device_unregister); ...@@ -362,6 +362,8 @@ EXPORT_SYMBOL_GPL(platform_device_unregister);
* enumeration tasks, they don't fully conform to the Linux driver model. * enumeration tasks, they don't fully conform to the Linux driver model.
* In particular, when such drivers are built as modules, they can't be * In particular, when such drivers are built as modules, they can't be
* "hotplugged". * "hotplugged".
*
* Returns &struct platform_device pointer on success, or ERR_PTR() on error.
*/ */
struct platform_device *platform_device_register_simple(const char *name, struct platform_device *platform_device_register_simple(const char *name,
int id, int id,
...@@ -408,6 +410,8 @@ EXPORT_SYMBOL_GPL(platform_device_register_simple); ...@@ -408,6 +410,8 @@ EXPORT_SYMBOL_GPL(platform_device_register_simple);
* allocated for the device allows drivers using such devices to be * allocated for the device allows drivers using such devices to be
* unloaded without waiting for the last reference to the device to be * unloaded without waiting for the last reference to the device to be
* dropped. * dropped.
*
* Returns &struct platform_device pointer on success, or ERR_PTR() on error.
*/ */
struct platform_device *platform_device_register_data( struct platform_device *platform_device_register_data(
struct device *parent, struct device *parent,
...@@ -559,6 +563,8 @@ EXPORT_SYMBOL_GPL(platform_driver_probe); ...@@ -559,6 +563,8 @@ EXPORT_SYMBOL_GPL(platform_driver_probe);
* *
* Use this in legacy-style modules that probe hardware directly and * Use this in legacy-style modules that probe hardware directly and
* register a single platform device and corresponding platform driver. * register a single platform device and corresponding platform driver.
*
* Returns &struct platform_device pointer on success, or ERR_PTR() on error.
*/ */
struct platform_device * __init_or_module platform_create_bundle( struct platform_device * __init_or_module platform_create_bundle(
struct platform_driver *driver, struct platform_driver *driver,
...@@ -1052,9 +1058,11 @@ static __initdata LIST_HEAD(early_platform_driver_list); ...@@ -1052,9 +1058,11 @@ static __initdata LIST_HEAD(early_platform_driver_list);
static __initdata LIST_HEAD(early_platform_device_list); static __initdata LIST_HEAD(early_platform_device_list);
/** /**
* early_platform_driver_register * early_platform_driver_register - register early platform driver
* @epdrv: early_platform driver structure * @epdrv: early_platform driver structure
* @buf: string passed from early_param() * @buf: string passed from early_param()
*
* Helper function for early_platform_init() / early_platform_init_buffer()
*/ */
int __init early_platform_driver_register(struct early_platform_driver *epdrv, int __init early_platform_driver_register(struct early_platform_driver *epdrv,
char *buf) char *buf)
...@@ -1106,9 +1114,12 @@ int __init early_platform_driver_register(struct early_platform_driver *epdrv, ...@@ -1106,9 +1114,12 @@ int __init early_platform_driver_register(struct early_platform_driver *epdrv,
} }
/** /**
* early_platform_add_devices - add a numbers of early platform devices * early_platform_add_devices - adds a number of early platform devices
* @devs: array of early platform devices to add * @devs: array of early platform devices to add
* @num: number of early platform devices in array * @num: number of early platform devices in array
*
* Used by early architecture code to register early platform devices and
* their platform data.
*/ */
void __init early_platform_add_devices(struct platform_device **devs, int num) void __init early_platform_add_devices(struct platform_device **devs, int num)
{ {
...@@ -1128,8 +1139,12 @@ void __init early_platform_add_devices(struct platform_device **devs, int num) ...@@ -1128,8 +1139,12 @@ void __init early_platform_add_devices(struct platform_device **devs, int num)
} }
/** /**
* early_platform_driver_register_all * early_platform_driver_register_all - register early platform drivers
* @class_str: string to identify early platform driver class * @class_str: string to identify early platform driver class
*
* Used by architecture code to register all early platform drivers
* for a certain class. If omitted then only early platform drivers
* with matching kernel command line class parameters will be registered.
*/ */
void __init early_platform_driver_register_all(char *class_str) void __init early_platform_driver_register_all(char *class_str)
{ {
...@@ -1151,7 +1166,7 @@ void __init early_platform_driver_register_all(char *class_str) ...@@ -1151,7 +1166,7 @@ void __init early_platform_driver_register_all(char *class_str)
} }
/** /**
* early_platform_match * early_platform_match - find early platform device matching driver
* @epdrv: early platform driver structure * @epdrv: early platform driver structure
* @id: id to match against * @id: id to match against
*/ */
...@@ -1169,7 +1184,7 @@ early_platform_match(struct early_platform_driver *epdrv, int id) ...@@ -1169,7 +1184,7 @@ early_platform_match(struct early_platform_driver *epdrv, int id)
} }
/** /**
* early_platform_left * early_platform_left - check if early platform driver has matching devices
* @epdrv: early platform driver structure * @epdrv: early platform driver structure
* @id: return true if id or above exists * @id: return true if id or above exists
*/ */
...@@ -1187,7 +1202,7 @@ static __init int early_platform_left(struct early_platform_driver *epdrv, ...@@ -1187,7 +1202,7 @@ static __init int early_platform_left(struct early_platform_driver *epdrv,
} }
/** /**
* early_platform_driver_probe_id * early_platform_driver_probe_id - probe drivers matching class_str and id
* @class_str: string to identify early platform driver class * @class_str: string to identify early platform driver class
* @id: id to match against * @id: id to match against
* @nr_probe: number of platform devices to successfully probe before exiting * @nr_probe: number of platform devices to successfully probe before exiting
...@@ -1257,10 +1272,14 @@ static int __init early_platform_driver_probe_id(char *class_str, ...@@ -1257,10 +1272,14 @@ static int __init early_platform_driver_probe_id(char *class_str,
} }
/** /**
* early_platform_driver_probe * early_platform_driver_probe - probe a class of registered drivers
* @class_str: string to identify early platform driver class * @class_str: string to identify early platform driver class
* @nr_probe: number of platform devices to successfully probe before exiting * @nr_probe: number of platform devices to successfully probe before exiting
* @user_only: only probe user specified early platform devices * @user_only: only probe user specified early platform devices
*
* Used by architecture code to probe registered early platform drivers
* within a certain class. For probe to happen a registered early platform
* device matching a registered early platform driver is needed.
*/ */
int __init early_platform_driver_probe(char *class_str, int __init early_platform_driver_probe(char *class_str,
int nr_probe, int nr_probe,
......
...@@ -2272,42 +2272,52 @@ static int create_files(struct bmc_device *bmc) ...@@ -2272,42 +2272,52 @@ static int create_files(struct bmc_device *bmc)
bmc->device_id_attr.attr.name = "device_id"; bmc->device_id_attr.attr.name = "device_id";
bmc->device_id_attr.attr.mode = S_IRUGO; bmc->device_id_attr.attr.mode = S_IRUGO;
bmc->device_id_attr.show = device_id_show; bmc->device_id_attr.show = device_id_show;
sysfs_attr_init(&bmc->device_id_attr.attr);
bmc->provides_dev_sdrs_attr.attr.name = "provides_device_sdrs"; bmc->provides_dev_sdrs_attr.attr.name = "provides_device_sdrs";
bmc->provides_dev_sdrs_attr.attr.mode = S_IRUGO; bmc->provides_dev_sdrs_attr.attr.mode = S_IRUGO;
bmc->provides_dev_sdrs_attr.show = provides_dev_sdrs_show; bmc->provides_dev_sdrs_attr.show = provides_dev_sdrs_show;
sysfs_attr_init(&bmc->provides_dev_sdrs_attr.attr);
bmc->revision_attr.attr.name = "revision"; bmc->revision_attr.attr.name = "revision";
bmc->revision_attr.attr.mode = S_IRUGO; bmc->revision_attr.attr.mode = S_IRUGO;
bmc->revision_attr.show = revision_show; bmc->revision_attr.show = revision_show;
sysfs_attr_init(&bmc->revision_attr.attr);
bmc->firmware_rev_attr.attr.name = "firmware_revision"; bmc->firmware_rev_attr.attr.name = "firmware_revision";
bmc->firmware_rev_attr.attr.mode = S_IRUGO; bmc->firmware_rev_attr.attr.mode = S_IRUGO;
bmc->firmware_rev_attr.show = firmware_rev_show; bmc->firmware_rev_attr.show = firmware_rev_show;
sysfs_attr_init(&bmc->firmware_rev_attr.attr);
bmc->version_attr.attr.name = "ipmi_version"; bmc->version_attr.attr.name = "ipmi_version";
bmc->version_attr.attr.mode = S_IRUGO; bmc->version_attr.attr.mode = S_IRUGO;
bmc->version_attr.show = ipmi_version_show; bmc->version_attr.show = ipmi_version_show;
sysfs_attr_init(&bmc->version_attr.attr);
bmc->add_dev_support_attr.attr.name = "additional_device_support"; bmc->add_dev_support_attr.attr.name = "additional_device_support";
bmc->add_dev_support_attr.attr.mode = S_IRUGO; bmc->add_dev_support_attr.attr.mode = S_IRUGO;
bmc->add_dev_support_attr.show = add_dev_support_show; bmc->add_dev_support_attr.show = add_dev_support_show;
sysfs_attr_init(&bmc->add_dev_support_attr.attr);
bmc->manufacturer_id_attr.attr.name = "manufacturer_id"; bmc->manufacturer_id_attr.attr.name = "manufacturer_id";
bmc->manufacturer_id_attr.attr.mode = S_IRUGO; bmc->manufacturer_id_attr.attr.mode = S_IRUGO;
bmc->manufacturer_id_attr.show = manufacturer_id_show; bmc->manufacturer_id_attr.show = manufacturer_id_show;
sysfs_attr_init(&bmc->manufacturer_id_attr.attr);
bmc->product_id_attr.attr.name = "product_id"; bmc->product_id_attr.attr.name = "product_id";
bmc->product_id_attr.attr.mode = S_IRUGO; bmc->product_id_attr.attr.mode = S_IRUGO;
bmc->product_id_attr.show = product_id_show; bmc->product_id_attr.show = product_id_show;
sysfs_attr_init(&bmc->product_id_attr.attr);
bmc->guid_attr.attr.name = "guid"; bmc->guid_attr.attr.name = "guid";
bmc->guid_attr.attr.mode = S_IRUGO; bmc->guid_attr.attr.mode = S_IRUGO;
bmc->guid_attr.show = guid_show; bmc->guid_attr.show = guid_show;
sysfs_attr_init(&bmc->guid_attr.attr);
bmc->aux_firmware_rev_attr.attr.name = "aux_firmware_revision"; bmc->aux_firmware_rev_attr.attr.name = "aux_firmware_revision";
bmc->aux_firmware_rev_attr.attr.mode = S_IRUGO; bmc->aux_firmware_rev_attr.attr.mode = S_IRUGO;
bmc->aux_firmware_rev_attr.show = aux_firmware_rev_show; bmc->aux_firmware_rev_attr.show = aux_firmware_rev_show;
sysfs_attr_init(&bmc->aux_firmware_rev_attr.attr);
err = device_create_file(&bmc->dev->dev, err = device_create_file(&bmc->dev->dev,
&bmc->device_id_attr); &bmc->device_id_attr);
......
...@@ -461,6 +461,7 @@ alloc_group_attrs(ssize_t (*show)(struct ib_port *, ...@@ -461,6 +461,7 @@ alloc_group_attrs(ssize_t (*show)(struct ib_port *,
element->attr.attr.mode = S_IRUGO; element->attr.attr.mode = S_IRUGO;
element->attr.show = show; element->attr.show = show;
element->index = i; element->index = i;
sysfs_attr_init(&element->attr.attr);
tab_attr[i] = &element->attr.attr; tab_attr[i] = &element->attr.attr;
} }
......
...@@ -1023,6 +1023,7 @@ static int mlx4_init_port_info(struct mlx4_dev *dev, int port) ...@@ -1023,6 +1023,7 @@ static int mlx4_init_port_info(struct mlx4_dev *dev, int port)
info->port_attr.attr.mode = S_IRUGO | S_IWUSR; info->port_attr.attr.mode = S_IRUGO | S_IWUSR;
info->port_attr.show = show_port_type; info->port_attr.show = show_port_type;
info->port_attr.store = set_port_type; info->port_attr.store = set_port_type;
sysfs_attr_init(&info->port_attr.attr);
err = device_create_file(&dev->pdev->dev, &info->port_attr); err = device_create_file(&dev->pdev->dev, &info->port_attr);
if (err) { if (err) {
......
...@@ -655,8 +655,8 @@ void pci_create_legacy_files(struct pci_bus *b) ...@@ -655,8 +655,8 @@ void pci_create_legacy_files(struct pci_bus *b)
goto legacy_io_err; goto legacy_io_err;
/* Allocated above after the legacy_io struct */ /* Allocated above after the legacy_io struct */
sysfs_bin_attr_init(b->legacy_mem);
b->legacy_mem = b->legacy_io + 1; b->legacy_mem = b->legacy_io + 1;
sysfs_bin_attr_init(b->legacy_mem);
b->legacy_mem->attr.name = "legacy_mem"; b->legacy_mem->attr.name = "legacy_mem";
b->legacy_mem->size = 1024*1024; b->legacy_mem->size = 1024*1024;
b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR; b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment