drivers/i2c/i2c-core-smbus.c
Source file repositories/reference/linux-study-clean/drivers/i2c/i2c-core-smbus.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/i2c/i2c-core-smbus.c- Extension
.c- Size
- 21232 bytes
- Lines
- 741
- Domain
- Driver Families
- Bucket
- drivers/i2c
- 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/device.hlinux/err.hlinux/i2c.hlinux/i2c-smbus.hlinux/property.hlinux/slab.hlinux/string_choices.hi2c-core.htrace/events/smbus.h
Detected Declarations
function crc8function i2c_smbus_pecfunction i2c_smbus_msg_pecfunction i2c_smbus_add_pecfunction readfunction i2c_smbus_read_bytefunction i2c_smbus_write_bytefunction i2c_smbus_read_byte_datafunction i2c_smbus_write_byte_datafunction i2c_smbus_read_word_datafunction i2c_smbus_write_word_datafunction mechanismfunction i2c_smbus_write_block_datafunction i2c_smbus_read_i2c_block_datafunction i2c_smbus_write_i2c_block_datafunction i2c_smbus_try_get_dmabuffunction i2c_smbus_xfer_emulatedfunction i2c_smbus_xferfunction __i2c_smbus_xferfunction i2c_smbus_read_i2c_block_data_or_emulatedfunction i2c_setup_smbus_alertexport i2c_smbus_pecexport i2c_smbus_read_byteexport i2c_smbus_write_byteexport i2c_smbus_read_byte_dataexport i2c_smbus_write_byte_dataexport i2c_smbus_read_word_dataexport i2c_smbus_write_word_dataexport i2c_smbus_read_block_dataexport i2c_smbus_write_block_dataexport i2c_smbus_read_i2c_block_dataexport i2c_smbus_write_i2c_block_dataexport i2c_smbus_xferexport __i2c_smbus_xferexport i2c_smbus_read_i2c_block_data_or_emulatedexport i2c_new_smbus_alert_device
Annotated Snippet
if (read_write == I2C_SMBUS_READ) {
/* Special case: only a read! */
msg[0].flags = I2C_M_RD | flags;
nmsgs = 1;
}
break;
case I2C_SMBUS_BYTE_DATA:
if (read_write == I2C_SMBUS_READ)
msg[1].len = 1;
else {
msg[0].len = 2;
msgbuf0[1] = data->byte;
}
break;
case I2C_SMBUS_WORD_DATA:
if (read_write == I2C_SMBUS_READ)
msg[1].len = 2;
else {
msg[0].len = 3;
msgbuf0[1] = data->word & 0xff;
msgbuf0[2] = data->word >> 8;
}
break;
case I2C_SMBUS_PROC_CALL:
nmsgs = 2; /* Special case */
read_write = I2C_SMBUS_READ;
msg[0].len = 3;
msg[1].len = 2;
msgbuf0[1] = data->word & 0xff;
msgbuf0[2] = data->word >> 8;
break;
case I2C_SMBUS_BLOCK_DATA:
if (read_write == I2C_SMBUS_READ) {
msg[1].flags |= I2C_M_RECV_LEN;
msg[1].len = 1; /* block length will be added by
the underlying bus driver */
i2c_smbus_try_get_dmabuf(&msg[1], 0);
} else {
msg[0].len = data->block[0] + 2;
if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 2) {
dev_err(&adapter->dev,
"Invalid block write size %d\n",
data->block[0]);
return -EINVAL;
}
i2c_smbus_try_get_dmabuf(&msg[0], command);
memcpy(msg[0].buf + 1, data->block, msg[0].len - 1);
}
break;
case I2C_SMBUS_BLOCK_PROC_CALL:
nmsgs = 2; /* Another special case */
read_write = I2C_SMBUS_READ;
if (data->block[0] > I2C_SMBUS_BLOCK_MAX) {
dev_err(&adapter->dev,
"Invalid block write size %d\n",
data->block[0]);
return -EINVAL;
}
msg[0].len = data->block[0] + 2;
i2c_smbus_try_get_dmabuf(&msg[0], command);
memcpy(msg[0].buf + 1, data->block, msg[0].len - 1);
msg[1].flags |= I2C_M_RECV_LEN;
msg[1].len = 1; /* block length will be added by
the underlying bus driver */
i2c_smbus_try_get_dmabuf(&msg[1], 0);
break;
case I2C_SMBUS_I2C_BLOCK_DATA:
if (data->block[0] > I2C_SMBUS_BLOCK_MAX) {
dev_err(&adapter->dev, "Invalid block %s size %d\n",
str_read_write(read_write == I2C_SMBUS_READ),
data->block[0]);
return -EINVAL;
}
if (read_write == I2C_SMBUS_READ) {
msg[1].len = data->block[0];
i2c_smbus_try_get_dmabuf(&msg[1], 0);
} else {
msg[0].len = data->block[0] + 1;
i2c_smbus_try_get_dmabuf(&msg[0], command);
memcpy(msg[0].buf + 1, data->block + 1, data->block[0]);
}
break;
default:
dev_err(&adapter->dev, "Unsupported transaction %d\n", size);
return -EOPNOTSUPP;
Annotation
- Immediate include surface: `linux/device.h`, `linux/err.h`, `linux/i2c.h`, `linux/i2c-smbus.h`, `linux/property.h`, `linux/slab.h`, `linux/string_choices.h`, `i2c-core.h`.
- Detected declarations: `function crc8`, `function i2c_smbus_pec`, `function i2c_smbus_msg_pec`, `function i2c_smbus_add_pec`, `function read`, `function i2c_smbus_read_byte`, `function i2c_smbus_write_byte`, `function i2c_smbus_read_byte_data`, `function i2c_smbus_write_byte_data`, `function i2c_smbus_read_word_data`.
- Atlas domain: Driver Families / drivers/i2c.
- 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.