drivers/char/ipmi/ssif_bmc.c
Source file repositories/reference/linux-study-clean/drivers/char/ipmi/ssif_bmc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/char/ipmi/ssif_bmc.c- Extension
.c- Size
- 38027 bytes
- Lines
- 1265
- 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.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- 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/i2c.hlinux/miscdevice.hlinux/module.hlinux/of.hlinux/platform_device.hlinux/poll.hlinux/sched.hlinux/mutex.hlinux/spinlock.hlinux/timer.hlinux/jiffies.hlinux/ipmi_ssif_bmc.hkunit/test.h
Detected Declarations
struct ssif_part_bufferstruct ssif_bmc_ctxstruct ssif_bmc_test_ctxenum ssif_statefunction ssif_bmc_readfunction ssif_bmc_writefunction ssif_bmc_openfunction ssif_bmc_pollfunction ssif_bmc_releasefunction complete_responsefunction response_timeoutfunction handle_requestfunction calculate_response_part_pecfunction set_singlepart_response_bufferfunction set_multipart_response_bufferfunction supported_read_cmdfunction supported_write_cmdfunction supported_write_start_cmdfunction handle_read_processedfunction handle_write_receivedfunction validate_request_partfunction process_request_partfunction process_smbus_cmdfunction on_read_requested_eventfunction on_read_processed_eventfunction on_write_requested_eventfunction on_write_received_eventfunction on_stop_eventfunction ssif_bmc_cbfunction ssif_bmc_probefunction ssif_bmc_removefunction ssif_bmc_test_initfunction ssif_bmc_test_exitfunction ssif_bmc_test_run_event_valfunction ssif_bmc_test_run_eventfunction ssif_bmc_test_singlepart_reqfunction ssif_bmc_test_restart_write_without_stopfunction ssif_bmc_test_restart_after_invalid_commandfunction ssif_bmc_test_singlepart_read_response_completionfunction ssif_bmc_test_stop_during_start_discards_partial_requestfunction ssif_bmc_test_read_interrupts_partial_writefunction ssif_bmc_test_write_interrupts_response_sendfunction ssif_bmc_test_write_interrupts_response_sendingfunction ssif_bmc_test_timeout_interrupt_allows_retry
Annotated Snippet
static const struct file_operations ssif_bmc_fops = {
.owner = THIS_MODULE,
.open = ssif_bmc_open,
.read = ssif_bmc_read,
.write = ssif_bmc_write,
.release = ssif_bmc_release,
.poll = ssif_bmc_poll,
};
/* Called with ssif_bmc->lock held. */
static void complete_response(struct ssif_bmc_ctx *ssif_bmc)
{
/* Invalidate response in buffer to denote it having been sent. */
ssif_bmc->response.len = 0;
ssif_bmc->response_in_progress = false;
ssif_bmc->nbytes_processed = 0;
ssif_bmc->remain_len = 0;
ssif_bmc->busy = false;
wake_up_all(&ssif_bmc->wait_queue);
}
static void response_timeout(struct timer_list *t)
{
struct ssif_bmc_ctx *ssif_bmc = timer_container_of(ssif_bmc, t,
response_timer);
unsigned long flags;
spin_lock_irqsave(&ssif_bmc->lock, flags);
/* Do nothing if the response is in progress */
if (!ssif_bmc->response_in_progress) {
/* Recover ssif_bmc from busy */
ssif_bmc->busy = false;
ssif_bmc->response_timer_inited = false;
/* Set aborting flag */
ssif_bmc->aborting = true;
}
spin_unlock_irqrestore(&ssif_bmc->lock, flags);
}
/* Called with ssif_bmc->lock held. */
static void handle_request(struct ssif_bmc_ctx *ssif_bmc)
{
/* set ssif_bmc to busy waiting for response */
ssif_bmc->busy = true;
/* Request message is available to process */
ssif_bmc->request_available = true;
/* Clean old response buffer */
memset(&ssif_bmc->response, 0, sizeof(struct ipmi_ssif_msg));
/* This is the new READ request.*/
wake_up_all(&ssif_bmc->wait_queue);
/* Armed timer to recover slave from busy state in case of no response */
if (!ssif_bmc->response_timer_inited) {
timer_setup(&ssif_bmc->response_timer, response_timeout, 0);
ssif_bmc->response_timer_inited = true;
}
mod_timer(&ssif_bmc->response_timer, jiffies + msecs_to_jiffies(RESPONSE_TIMEOUT));
}
static void calculate_response_part_pec(struct ssif_part_buffer *part)
{
u8 addr = part->address;
/* PEC - Start Read Address */
part->pec = i2c_smbus_pec(0, &addr, 1);
/* PEC - SSIF Command */
part->pec = i2c_smbus_pec(part->pec, &part->smbus_cmd, 1);
/* PEC - Restart Write Address */
addr = addr | 0x01;
part->pec = i2c_smbus_pec(part->pec, &addr, 1);
part->pec = i2c_smbus_pec(part->pec, &part->length, 1);
if (part->length)
part->pec = i2c_smbus_pec(part->pec, part->payload, part->length);
}
static void set_singlepart_response_buffer(struct ssif_bmc_ctx *ssif_bmc)
{
struct ssif_part_buffer *part = &ssif_bmc->part_buf;
part->address = GET_8BIT_ADDR(ssif_bmc->client->addr);
part->length = (u8)ssif_bmc->response.len;
/* Clear the rest to 0 */
memset(part->payload + part->length, 0, MAX_PAYLOAD_PER_TRANSACTION - part->length);
memcpy(&part->payload[0], &ssif_bmc->response.payload[0], part->length);
}
static void set_multipart_response_buffer(struct ssif_bmc_ctx *ssif_bmc)
Annotation
- Immediate include surface: `linux/i2c.h`, `linux/miscdevice.h`, `linux/module.h`, `linux/of.h`, `linux/platform_device.h`, `linux/poll.h`, `linux/sched.h`, `linux/mutex.h`.
- Detected declarations: `struct ssif_part_buffer`, `struct ssif_bmc_ctx`, `struct ssif_bmc_test_ctx`, `enum ssif_state`, `function ssif_bmc_read`, `function ssif_bmc_write`, `function ssif_bmc_open`, `function ssif_bmc_poll`, `function ssif_bmc_release`, `function complete_response`.
- Atlas domain: Driver Families / drivers/char.
- Implementation status: pattern implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- 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.