drivers/char/ipmi/ipmi_si_intf.c
Source file repositories/reference/linux-study-clean/drivers/char/ipmi/ipmi_si_intf.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/char/ipmi/ipmi_si_intf.c- Extension
.c- Size
- 63578 bytes
- Lines
- 2426
- Domain
- Driver Families
- Bucket
- drivers/char
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- 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/moduleparam.hlinux/sched.hlinux/seq_file.hlinux/timer.hlinux/errno.hlinux/spinlock.hlinux/slab.hlinux/delay.hlinux/list.hlinux/notifier.hlinux/mutex.hlinux/kthread.hasm/irq.hlinux/interrupt.hlinux/rcupdate.hlinux/ipmi.hlinux/ipmi_smi.hipmi_si.hipmi_si_sm.hlinux/string.hlinux/ctype.h
Detected Declarations
struct smi_infoenum si_intf_stateenum si_stat_indexesfunction debug_timestampfunction register_xaction_notifierfunction deliver_recv_msgfunction return_hosed_msgfunction start_next_msgfunction smi_mod_timerfunction andfunction start_check_enablesfunction start_clear_flagsfunction start_get_flagsfunction start_getting_msg_queuefunction start_getting_eventsfunction disable_irqfunction enable_si_irqfunction handle_flagsfunction current_global_enablesfunction check_bt_irqfunction handle_transaction_donefunction smi_event_handlerfunction check_start_timer_threadfunction flush_messagesfunction senderfunction set_run_to_completionfunction ipmi_thread_busy_waitfunction ipmi_threadfunction pollfunction request_eventsfunction set_need_watchfunction smi_timeoutfunction ipmi_si_irq_handlerfunction smi_start_processingfunction get_smi_infofunction set_maintenance_modefunction ipmi_irq_finish_setupfunction ipmi_irq_start_cleanupfunction std_irq_cleanupfunction ipmi_std_irq_setupfunction wait_for_msg_donefunction try_get_dev_idfunction get_global_enablesfunction set_global_enablesfunction enablesfunction check_set_rcv_irqfunction try_enable_event_bufferfunction DEVICE_ATTR_RO
Annotated Snippet
module_init(init_ipmi_si);
static void wait_msg_processed(struct smi_info *smi_info)
{
unsigned long jiffies_now;
long time_diff;
while (smi_info->si_state != SI_HOSED &&
(smi_info->curr_msg || (smi_info->si_state != SI_NORMAL))) {
jiffies_now = jiffies;
time_diff = (((long)jiffies_now - (long)smi_info->last_timeout_jiffies)
* SI_USEC_PER_JIFFY);
smi_event_handler(smi_info, time_diff);
schedule_timeout_uninterruptible(1);
}
}
static void shutdown_smi(void *send_info)
{
struct smi_info *smi_info = send_info;
if (smi_info->dev_group_added) {
device_remove_group(smi_info->io.dev, &ipmi_si_dev_attr_group);
smi_info->dev_group_added = false;
}
if (smi_info->io.dev)
dev_set_drvdata(smi_info->io.dev, NULL);
/*
* Make sure that interrupts, the timer and the thread are
* stopped and will not run again.
*/
smi_info->interrupt_disabled = true;
if (smi_info->io.irq_cleanup) {
smi_info->io.irq_cleanup(&smi_info->io);
smi_info->io.irq_cleanup = NULL;
}
stop_timer_and_thread(smi_info);
/*
* Wait until we know that we are out of any interrupt
* handlers might have been running before we freed the
* interrupt.
*/
synchronize_rcu();
/*
* Timeouts are stopped, now make sure the interrupts are off
* in the BMC. Note that timers and CPU interrupts are off,
* so no need for locks.
*/
wait_msg_processed(smi_info);
if (smi_info->handlers)
disable_si_irq(smi_info);
wait_msg_processed(smi_info);
if (smi_info->handlers)
smi_info->handlers->cleanup(smi_info->si_sm);
if (smi_info->io.io_cleanup) {
smi_info->io.io_cleanup(&smi_info->io);
smi_info->io.io_cleanup = NULL;
}
kfree(smi_info->si_sm);
smi_info->si_sm = NULL;
smi_info->intf = NULL;
}
/*
* Must be called with smi_infos_lock held, to serialize the
* smi_info->intf check.
*/
static void cleanup_one_si(struct smi_info *smi_info)
{
if (!smi_info)
return;
list_del(&smi_info->link);
ipmi_unregister_smi(smi_info->intf);
kfree(smi_info);
}
void ipmi_si_remove_by_dev(struct device *dev)
{
struct smi_info *e;
Annotation
- Immediate include surface: `linux/module.h`, `linux/moduleparam.h`, `linux/sched.h`, `linux/seq_file.h`, `linux/timer.h`, `linux/errno.h`, `linux/spinlock.h`, `linux/slab.h`.
- Detected declarations: `struct smi_info`, `enum si_intf_state`, `enum si_stat_indexes`, `function debug_timestamp`, `function register_xaction_notifier`, `function deliver_recv_msg`, `function return_hosed_msg`, `function start_next_msg`, `function smi_mod_timer`, `function and`.
- Atlas domain: Driver Families / drivers/char.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.