drivers/base/attribute_container.c
Source file repositories/reference/linux-study-clean/drivers/base/attribute_container.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/base/attribute_container.c- Extension
.c- Size
- 13323 bytes
- Lines
- 501
- Domain
- Driver Families
- Bucket
- drivers/base
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/attribute_container.hlinux/device.hlinux/kernel.hlinux/slab.hlinux/list.hlinux/module.hlinux/mutex.hbase.h
Detected Declarations
struct internal_containerfunction internal_container_klist_getfunction internal_container_klist_putfunction attribute_container_classdev_to_containerfunction attribute_container_registerfunction attribute_container_unregisterfunction attribute_container_releasefunction devicefunction device_unregisterfunction klist_for_each_entryfunction do_attribute_container_device_trigger_safefunction klist_for_each_entryfunction attribute_container_device_trigger_safefunction list_for_each_entryfunction attribute_container_device_triggerfunction klist_for_each_entryfunction attribute_container_add_attrsfunction attribute_container_add_class_devicefunction attribute_container_remove_attrsfunction attribute_container_class_device_delfunction attribute_container_find_class_devicefunction klist_for_each_entryexport attribute_container_classdev_to_containerexport attribute_container_registerexport attribute_container_unregisterexport attribute_container_find_class_device
Annotated Snippet
* device_add. If a function is provided, it is expected to add
* the class device at the appropriate time. One of the things that
* might be necessary is to allocate and initialise the classdev and
* then add it a later time. To do this, call this routine for
* allocation and initialisation and then use
* attribute_container_device_trigger() to call device_add() on
* it. Note: after this, the class device contains a reference to dev
* which is not relinquished until the release of the classdev.
*/
void
attribute_container_add_device(struct device *dev,
int (*fn)(struct attribute_container *,
struct device *,
struct device *))
{
struct attribute_container *cont;
mutex_lock(&attribute_container_mutex);
list_for_each_entry(cont, &attribute_container_list, node) {
struct internal_container *ic;
if (attribute_container_no_classdevs(cont))
continue;
if (!cont->match(cont, dev))
continue;
ic = kzalloc_obj(*ic);
if (!ic) {
dev_err(dev, "failed to allocate class container\n");
continue;
}
ic->cont = cont;
device_initialize(&ic->classdev);
ic->classdev.parent = get_device(dev);
ic->classdev.class = cont->class;
cont->class->dev_release = attribute_container_release;
dev_set_name(&ic->classdev, "%s", dev_name(dev));
if (fn)
fn(cont, dev, &ic->classdev);
else
attribute_container_add_class_device(&ic->classdev);
klist_add_tail(&ic->node, &cont->containers);
}
mutex_unlock(&attribute_container_mutex);
}
/* FIXME: can't break out of this unless klist_iter_exit is also
* called before doing the break
*/
#define klist_for_each_entry(pos, head, member, iter) \
for (klist_iter_init(head, iter); (pos = ({ \
struct klist_node *n = klist_next(iter); \
n ? container_of(n, typeof(*pos), member) : \
({ klist_iter_exit(iter) ; NULL; }); \
})) != NULL;)
/**
* attribute_container_remove_device - make device eligible for removal.
*
* @dev: The generic device
* @fn: A function to call to remove the device
*
* This routine triggers device removal. If fn is NULL, then it is
* simply done via device_unregister (note that if something
* still has a reference to the classdev, then the memory occupied
* will not be freed until the classdev is released). If you want a
* two phase release: remove from visibility and then delete the
* device, then you should use this routine with a fn that calls
* device_del() and then use attribute_container_device_trigger()
* to do the final put on the classdev.
*/
void
attribute_container_remove_device(struct device *dev,
void (*fn)(struct attribute_container *,
struct device *,
struct device *))
{
struct attribute_container *cont;
mutex_lock(&attribute_container_mutex);
list_for_each_entry(cont, &attribute_container_list, node) {
struct internal_container *ic;
struct klist_iter iter;
if (attribute_container_no_classdevs(cont))
continue;
Annotation
- Immediate include surface: `linux/attribute_container.h`, `linux/device.h`, `linux/kernel.h`, `linux/slab.h`, `linux/list.h`, `linux/module.h`, `linux/mutex.h`, `base.h`.
- Detected declarations: `struct internal_container`, `function internal_container_klist_get`, `function internal_container_klist_put`, `function attribute_container_classdev_to_container`, `function attribute_container_register`, `function attribute_container_unregister`, `function attribute_container_release`, `function device`, `function device_unregister`, `function klist_for_each_entry`.
- Atlas domain: Driver Families / drivers/base.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.