drivers/char/ipmi/ipmi_msghandler.c
Source file repositories/reference/linux-study-clean/drivers/char/ipmi/ipmi_msghandler.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/char/ipmi/ipmi_msghandler.c- Extension
.c- Size
- 148156 bytes
- Lines
- 5700
- Domain
- Driver Families
- Bucket
- drivers/char
- 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/module.hlinux/errno.hlinux/panic_notifier.hlinux/poll.hlinux/sched.hlinux/seq_file.hlinux/spinlock.hlinux/mutex.hlinux/slab.hlinux/ipmi.hlinux/ipmi_smi.hlinux/notifier.hlinux/init.hlinux/rcupdate.hlinux/interrupt.hlinux/moduleparam.hlinux/workqueue.hlinux/uuid.hlinux/nospec.hlinux/vmalloc.hlinux/delay.h
Detected Declarations
struct ipmi_userstruct cmd_rcvrstruct seq_tablestruct ipmi_channelstruct ipmi_channel_setstruct ipmi_my_addrinfostruct bmc_devicestruct ipmi_smistruct prod_dev_idenum ipmi_panic_event_openum ipmi_stat_indexesfunction panic_op_write_handlerfunction panic_op_read_handlerfunction ipmi_lock_xmit_msgsfunction ipmi_unlock_xmit_msgsfunction free_ipmi_userfunction release_ipmi_userfunction is_lan_addrfunction is_ipmb_addrfunction is_ipmb_bcast_addrfunction is_ipmb_direct_addrfunction free_recv_msg_listfunction list_for_each_entry_safefunction free_smi_msg_listfunction list_for_each_entry_safefunction intf_freefunction ipmi_smi_watcher_registerfunction list_for_each_entryfunction ipmi_smi_watcher_unregisterfunction call_smi_watchersfunction list_for_each_entryfunction ipmi_addr_equalfunction ipmi_validate_addrfunction ipmi_addr_lengthfunction deliver_responsefunction deliver_local_responsefunction deliver_err_responsefunction smi_add_watchfunction smi_remove_watchfunction intf_next_seqfunction correctlyfunction intf_start_seq_timerfunction intf_err_seqfunction ipmi_create_userfunction ipmi_get_smi_infofunction _ipmi_destroy_userfunction lockdep_is_heldfunction ipmi_destroy_user
Annotated Snippet
static struct bmc_device *ipmi_find_bmc_guid(struct device_driver *drv,
guid_t *guid)
{
struct device *dev;
struct bmc_device *bmc = NULL;
dev = driver_find_device(drv, NULL, guid, __find_bmc_guid);
if (dev) {
bmc = to_bmc_device(dev);
put_device(dev);
}
return bmc;
}
struct prod_dev_id {
unsigned int product_id;
unsigned char device_id;
};
static int __find_bmc_prod_dev_id(struct device *dev, const void *data)
{
const struct prod_dev_id *cid = data;
struct bmc_device *bmc;
int rv;
if (dev->type != &bmc_device_type)
return 0;
bmc = to_bmc_device(dev);
rv = (bmc->id.product_id == cid->product_id
&& bmc->id.device_id == cid->device_id);
if (rv)
rv = kref_get_unless_zero(&bmc->usecount);
return rv;
}
/*
* Returns with the bmc's usecount incremented, if it is non-NULL.
*/
static struct bmc_device *ipmi_find_bmc_prod_dev_id(
struct device_driver *drv,
unsigned int product_id, unsigned char device_id)
{
struct prod_dev_id id = {
.product_id = product_id,
.device_id = device_id,
};
struct device *dev;
struct bmc_device *bmc = NULL;
dev = driver_find_device(drv, NULL, &id, __find_bmc_prod_dev_id);
if (dev) {
bmc = to_bmc_device(dev);
put_device(dev);
}
return bmc;
}
static DEFINE_IDA(ipmi_bmc_ida);
static void
release_bmc_device(struct device *dev)
{
kfree(to_bmc_device(dev));
}
static void cleanup_bmc_work(struct work_struct *work)
{
struct bmc_device *bmc = container_of(work, struct bmc_device,
remove_work);
int id = bmc->pdev.id; /* Unregister overwrites id */
platform_device_unregister(&bmc->pdev);
ida_free(&ipmi_bmc_ida, id);
}
static void
cleanup_bmc_device(struct kref *ref)
{
struct bmc_device *bmc = container_of(ref, struct bmc_device, usecount);
/*
* Remove the platform device in a work queue to avoid issues
* with removing the device attributes while reading a device
* attribute.
*/
queue_work(bmc_remove_work_wq, &bmc->remove_work);
}
/*
Annotation
- Immediate include surface: `linux/module.h`, `linux/errno.h`, `linux/panic_notifier.h`, `linux/poll.h`, `linux/sched.h`, `linux/seq_file.h`, `linux/spinlock.h`, `linux/mutex.h`.
- Detected declarations: `struct ipmi_user`, `struct cmd_rcvr`, `struct seq_table`, `struct ipmi_channel`, `struct ipmi_channel_set`, `struct ipmi_my_addrinfo`, `struct bmc_device`, `struct ipmi_smi`, `struct prod_dev_id`, `enum ipmi_panic_event_op`.
- Atlas domain: Driver Families / drivers/char.
- 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.