drivers/cxl/core/edac.c

Source file repositories/reference/linux-study-clean/drivers/cxl/core/edac.c

File Facts

System
Linux kernel
Corpus path
drivers/cxl/core/edac.c
Extension
.c
Size
57128 bytes
Lines
2119
Domain
Driver Families
Bucket
drivers/cxl
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct cxl_patrol_scrub_context {
	u8 instance;
	u16 get_feat_size;
	u16 set_feat_size;
	u8 get_version;
	u8 set_version;
	u16 effects;
	struct cxl_memdev *cxlmd;
	struct cxl_region *cxlr;
};

/*
 * See CXL spec rev 3.2 @8.2.10.9.11.1 Table 8-222 Device Patrol Scrub Control
 * Feature Readable Attributes.
 */
struct cxl_scrub_rd_attrbs {
	u8 scrub_cycle_cap;
	__le16 scrub_cycle_hours;
	u8 scrub_flags;
} __packed;

/*
 * See CXL spec rev 3.2 @8.2.10.9.11.1 Table 8-223 Device Patrol Scrub Control
 * Feature Writable Attributes.
 */
struct cxl_scrub_wr_attrbs {
	u8 scrub_cycle_hours;
	u8 scrub_flags;
} __packed;

#define CXL_SCRUB_CONTROL_CHANGEABLE BIT(0)
#define CXL_SCRUB_CONTROL_REALTIME BIT(1)
#define CXL_SCRUB_CONTROL_CYCLE_MASK GENMASK(7, 0)
#define CXL_SCRUB_CONTROL_MIN_CYCLE_MASK GENMASK(15, 8)
#define CXL_SCRUB_CONTROL_ENABLE BIT(0)

#define CXL_GET_SCRUB_CYCLE_CHANGEABLE(cap) \
	FIELD_GET(CXL_SCRUB_CONTROL_CHANGEABLE, cap)
#define CXL_GET_SCRUB_CYCLE(cycle) \
	FIELD_GET(CXL_SCRUB_CONTROL_CYCLE_MASK, cycle)
#define CXL_GET_SCRUB_MIN_CYCLE(cycle) \
	FIELD_GET(CXL_SCRUB_CONTROL_MIN_CYCLE_MASK, cycle)
#define CXL_GET_SCRUB_EN_STS(flags) FIELD_GET(CXL_SCRUB_CONTROL_ENABLE, flags)

#define CXL_SET_SCRUB_CYCLE(cycle) \
	FIELD_PREP(CXL_SCRUB_CONTROL_CYCLE_MASK, cycle)
#define CXL_SET_SCRUB_EN(en) FIELD_PREP(CXL_SCRUB_CONTROL_ENABLE, en)

static int cxl_mem_scrub_get_attrbs(struct cxl_mailbox *cxl_mbox, u8 *cap,
				    u16 *cycle, u8 *flags, u8 *min_cycle)
{
	size_t rd_data_size = sizeof(struct cxl_scrub_rd_attrbs);
	size_t data_size;
	struct cxl_scrub_rd_attrbs *rd_attrbs __free(kfree) =
		kzalloc(rd_data_size, GFP_KERNEL);
	if (!rd_attrbs)
		return -ENOMEM;

	data_size = cxl_get_feature(cxl_mbox, &CXL_FEAT_PATROL_SCRUB_UUID,
				    CXL_GET_FEAT_SEL_CURRENT_VALUE, rd_attrbs,
				    rd_data_size, 0, NULL);
	if (!data_size)
		return -EIO;

	*cap = rd_attrbs->scrub_cycle_cap;
	*cycle = le16_to_cpu(rd_attrbs->scrub_cycle_hours);
	*flags = rd_attrbs->scrub_flags;
	if (min_cycle)
		*min_cycle = CXL_GET_SCRUB_MIN_CYCLE(*cycle);

	return 0;
}

static int cxl_scrub_get_attrbs(struct cxl_patrol_scrub_context *cxl_ps_ctx,
				u8 *cap, u16 *cycle, u8 *flags, u8 *min_cycle)
{
	struct cxl_mailbox *cxl_mbox;
	struct cxl_region_params *p;
	struct cxl_memdev *cxlmd;
	struct cxl_region *cxlr;
	u8 min_scrub_cycle = 0;
	int i, ret;

	if (!cxl_ps_ctx->cxlr) {
		cxl_mbox = &cxl_ps_ctx->cxlmd->cxlds->cxl_mbox;
		return cxl_mem_scrub_get_attrbs(cxl_mbox, cap, cycle,
						flags, min_cycle);
	}

	ACQUIRE(rwsem_read_intr, rwsem)(&cxl_rwsem.region);

Annotation

Implementation Notes