drivers/hwmon/occ/p9_sbe.c
Source file repositories/reference/linux-study-clean/drivers/hwmon/occ/p9_sbe.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/hwmon/occ/p9_sbe.c- Extension
.c- Size
- 4556 bytes
- Lines
- 204
- Domain
- Driver Families
- Bucket
- drivers/hwmon
- Inferred role
- Driver Families: implementation source
- Status
- source 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.
- 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/errno.hlinux/slab.hlinux/fsi-occ.hlinux/mm.hlinux/module.hlinux/mod_devicetable.hlinux/mutex.hlinux/platform_device.hlinux/string.hlinux/sysfs.hcommon.h
Detected Declarations
struct p9_sbe_occfunction ffdc_readfunction p9_sbe_occ_save_ffdcfunction p9_sbe_occ_send_cmdfunction p9_sbe_occ_probefunction p9_sbe_occ_remove
Annotated Snippet
struct p9_sbe_occ {
struct occ occ;
bool sbe_error;
void *ffdc;
size_t ffdc_len;
size_t ffdc_size;
struct mutex sbe_error_lock; /* lock access to ffdc data */
struct device *sbe;
};
#define to_p9_sbe_occ(x) container_of((x), struct p9_sbe_occ, occ)
static ssize_t ffdc_read(struct file *filp, struct kobject *kobj,
const struct bin_attribute *battr, char *buf, loff_t pos,
size_t count)
{
ssize_t rc = 0;
struct occ *occ = dev_get_drvdata(kobj_to_dev(kobj));
struct p9_sbe_occ *ctx = to_p9_sbe_occ(occ);
mutex_lock(&ctx->sbe_error_lock);
if (ctx->sbe_error) {
rc = memory_read_from_buffer(buf, count, &pos, ctx->ffdc,
ctx->ffdc_len);
if (pos >= ctx->ffdc_len)
ctx->sbe_error = false;
}
mutex_unlock(&ctx->sbe_error_lock);
return rc;
}
static const BIN_ATTR_RO(ffdc, OCC_MAX_RESP_WORDS * 4);
static bool p9_sbe_occ_save_ffdc(struct p9_sbe_occ *ctx, const void *resp,
size_t resp_len)
{
bool notify = false;
mutex_lock(&ctx->sbe_error_lock);
if (!ctx->sbe_error) {
if (resp_len > ctx->ffdc_size) {
kvfree(ctx->ffdc);
ctx->ffdc = kvmalloc(resp_len, GFP_KERNEL);
if (!ctx->ffdc) {
ctx->ffdc_len = 0;
ctx->ffdc_size = 0;
goto done;
}
ctx->ffdc_size = resp_len;
}
notify = true;
ctx->sbe_error = true;
ctx->ffdc_len = resp_len;
memcpy(ctx->ffdc, resp, resp_len);
}
done:
mutex_unlock(&ctx->sbe_error_lock);
return notify;
}
static int p9_sbe_occ_send_cmd(struct occ *occ, u8 *cmd, size_t len,
void *resp, size_t resp_len)
{
size_t original_resp_len = resp_len;
struct p9_sbe_occ *ctx = to_p9_sbe_occ(occ);
int rc, i;
for (i = 0; i < OCC_CHECKSUM_RETRIES; ++i) {
rc = fsi_occ_submit(ctx->sbe, cmd, len, resp, &resp_len);
if (rc >= 0)
break;
if (resp_len) {
if (p9_sbe_occ_save_ffdc(ctx, resp, resp_len))
sysfs_notify(&occ->bus_dev->kobj, NULL,
bin_attr_ffdc.attr.name);
return rc;
}
if (rc != -EBADE)
return rc;
resp_len = original_resp_len;
}
switch (((struct occ_response *)resp)->return_status) {
case OCC_RESP_CMD_IN_PRG:
rc = -ETIMEDOUT;
break;
case OCC_RESP_SUCCESS:
Annotation
- Immediate include surface: `linux/device.h`, `linux/errno.h`, `linux/slab.h`, `linux/fsi-occ.h`, `linux/mm.h`, `linux/module.h`, `linux/mod_devicetable.h`, `linux/mutex.h`.
- Detected declarations: `struct p9_sbe_occ`, `function ffdc_read`, `function p9_sbe_occ_save_ffdc`, `function p9_sbe_occ_send_cmd`, `function p9_sbe_occ_probe`, `function p9_sbe_occ_remove`.
- Atlas domain: Driver Families / drivers/hwmon.
- Implementation status: source 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.