drivers/base/bus.c
Source file repositories/reference/linux-study-clean/drivers/base/bus.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/base/bus.c- Extension
.c- Size
- 37501 bytes
- Lines
- 1490
- Domain
- Driver Families
- Bucket
- drivers/base
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- 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/async.hlinux/device/bus.hlinux/device.hlinux/module.hlinux/errno.hlinux/slab.hlinux/init.hlinux/string.hlinux/mutex.hlinux/sysfs.hbase.hpower/power.h
Detected Declarations
struct subsys_dev_iterfunction list_for_each_entryfunction bus_putfunction drv_attr_showfunction drv_attr_storefunction driver_releasefunction bus_attr_showfunction bus_attr_storefunction bus_create_filefunction bus_remove_filefunction bus_releasefunction bus_uevent_filterfunction unbind_storefunction bind_storefunction drivers_autoprobe_showfunction drivers_autoprobe_storefunction drivers_probe_storefunction bus_for_each_devfunction bus_for_each_devfunction bus_for_each_drvfunction driver_override_storefunction driver_override_showfunction bus_add_devicefunction bus_probe_devicefunction bus_remove_devicefunction add_bind_filesfunction remove_bind_filesfunction add_probe_filesfunction remove_probe_filesfunction uevent_storefunction bus_add_driverfunction bus_add_driverfunction bus_rescan_devices_helperfunction device_attachfunction driverfunction klist_devices_getfunction klist_devices_putfunction bus_uevent_storefunction bus_registerfunction bus_unregisterfunction bus_register_notifierfunction bus_unregister_notifierfunction bus_notifyfunction device_insertion_sort_klistfunction list_for_each_entryfunction bus_sort_breadthfirstfunction subsys_dev_iter_initfunction subsys_dev_iter_exit
Annotated Snippet
* bus_to_subsys - Turn a struct bus_type into a struct subsys_private
*
* @bus: pointer to the struct bus_type to look up
*
* The driver core internals needs to work on the subsys_private structure, not
* the external struct bus_type pointer. This function walks the list of
* registered busses in the system and finds the matching one and returns the
* internal struct subsys_private that relates to that bus.
*
* Note, the reference count of the return value is INCREMENTED if it is not
* NULL. A call to subsys_put() must be done when finished with the pointer in
* order for it to be properly freed.
*/
struct subsys_private *bus_to_subsys(const struct bus_type *bus)
{
struct subsys_private *sp = NULL;
struct kobject *kobj;
if (!bus || !bus_kset)
return NULL;
spin_lock(&bus_kset->list_lock);
if (list_empty(&bus_kset->list))
goto done;
list_for_each_entry(kobj, &bus_kset->list, entry) {
struct kset *kset = container_of(kobj, struct kset, kobj);
sp = container_of_const(kset, struct subsys_private, subsys);
if (sp->bus == bus)
goto done;
}
sp = NULL;
done:
sp = subsys_get(sp);
spin_unlock(&bus_kset->list_lock);
return sp;
}
static const struct bus_type *bus_get(const struct bus_type *bus)
{
struct subsys_private *sp = bus_to_subsys(bus);
if (sp)
return bus;
return NULL;
}
static void bus_put(const struct bus_type *bus)
{
struct subsys_private *sp = bus_to_subsys(bus);
/* two puts are required as the call to bus_to_subsys incremented it again */
subsys_put(sp);
subsys_put(sp);
}
static ssize_t drv_attr_show(struct kobject *kobj, struct attribute *attr,
char *buf)
{
struct driver_attribute *drv_attr = to_drv_attr(attr);
struct driver_private *drv_priv = to_driver(kobj);
ssize_t ret = -EIO;
if (drv_attr->show)
ret = drv_attr->show(drv_priv->driver, buf);
return ret;
}
static ssize_t drv_attr_store(struct kobject *kobj, struct attribute *attr,
const char *buf, size_t count)
{
struct driver_attribute *drv_attr = to_drv_attr(attr);
struct driver_private *drv_priv = to_driver(kobj);
ssize_t ret = -EIO;
if (drv_attr->store)
ret = drv_attr->store(drv_priv->driver, buf, count);
return ret;
}
static const struct sysfs_ops driver_sysfs_ops = {
.show = drv_attr_show,
.store = drv_attr_store,
};
static void driver_release(struct kobject *kobj)
{
struct driver_private *drv_priv = to_driver(kobj);
Annotation
- Immediate include surface: `linux/async.h`, `linux/device/bus.h`, `linux/device.h`, `linux/module.h`, `linux/errno.h`, `linux/slab.h`, `linux/init.h`, `linux/string.h`.
- Detected declarations: `struct subsys_dev_iter`, `function list_for_each_entry`, `function bus_put`, `function drv_attr_show`, `function drv_attr_store`, `function driver_release`, `function bus_attr_show`, `function bus_attr_store`, `function bus_create_file`, `function bus_remove_file`.
- Atlas domain: Driver Families / drivers/base.
- Implementation status: pattern 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.