drivers/edac/edac_mc.c

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

File Facts

System
Linux kernel
Corpus path
drivers/edac/edac_mc.c
Extension
.c
Size
26430 bytes
Lines
1088
Domain
Driver Families
Bucket
drivers/edac
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

if (csr->channels) {
				for (chn = 0; chn < mci->num_cschannel; chn++)
					kfree(csr->channels[chn]);
				kfree(csr->channels);
			}
			kfree(csr);
		}
		kfree(mci->csrows);
	}
	kfree(mci->pvt_info);
	kfree(mci);
}

static int edac_mc_alloc_csrows(struct mem_ctl_info *mci)
{
	unsigned int tot_channels = mci->num_cschannel;
	unsigned int tot_csrows = mci->nr_csrows;
	unsigned int row, chn;

	/*
	 * Allocate and fill the csrow/channels structs
	 */
	mci->csrows = kzalloc_objs(*mci->csrows, tot_csrows);
	if (!mci->csrows)
		return -ENOMEM;

	for (row = 0; row < tot_csrows; row++) {
		struct csrow_info *csr;

		csr = kzalloc_obj(**mci->csrows);
		if (!csr)
			return -ENOMEM;

		mci->csrows[row] = csr;
		csr->csrow_idx = row;
		csr->mci = mci;
		csr->nr_channels = tot_channels;
		csr->channels = kzalloc_objs(*csr->channels, tot_channels);
		if (!csr->channels)
			return -ENOMEM;

		for (chn = 0; chn < tot_channels; chn++) {
			struct rank_info *chan;

			chan = kzalloc_obj(**csr->channels);
			if (!chan)
				return -ENOMEM;

			csr->channels[chn] = chan;
			chan->chan_idx = chn;
			chan->csrow = csr;
		}
	}

	return 0;
}

static int edac_mc_alloc_dimms(struct mem_ctl_info *mci)
{
	unsigned int pos[EDAC_MAX_LAYERS];
	unsigned int row, chn, idx;
	int layer;
	void *p;

	/*
	 * Allocate and fill the dimm structs
	 */
	mci->dimms  = kzalloc_objs(*mci->dimms, mci->tot_dimms);
	if (!mci->dimms)
		return -ENOMEM;

	memset(&pos, 0, sizeof(pos));
	row = 0;
	chn = 0;
	for (idx = 0; idx < mci->tot_dimms; idx++) {
		struct dimm_info *dimm;
		struct rank_info *chan;
		int n, len;

		chan = mci->csrows[row]->channels[chn];

		dimm = kzalloc_obj(**mci->dimms);
		if (!dimm)
			return -ENOMEM;
		mci->dimms[idx] = dimm;
		dimm->mci = mci;
		dimm->idx = idx;

		/*
		 * Copy DIMM location and initialize it.

Annotation

Implementation Notes