drivers/mmc/core/sd.c

Source file repositories/reference/linux-study-clean/drivers/mmc/core/sd.c

File Facts

System
Linux kernel
Corpus path
drivers/mmc/core/sd.c
Extension
.c
Size
46083 bytes
Lines
1923
Domain
Driver Families
Bucket
drivers/mmc
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct sd_busy_data {
	struct mmc_card *card;
	u8 *reg_buf;
};

/*
 * Given the decoded CSD structure, decode the raw CID to our CID structure.
 */
void mmc_decode_cid(struct mmc_card *card)
{
	u32 *resp = card->raw_cid;

	/*
	 * Add the raw card ID (cid) data to the entropy pool. It doesn't
	 * matter that not all of it is unique, it's just bonus entropy.
	 */
	add_device_randomness(&card->raw_cid, sizeof(card->raw_cid));

	/*
	 * SD doesn't currently have a version field so we will
	 * have to assume we can parse this.
	 */
	card->cid.manfid		= unstuff_bits(resp, 120, 8);
	card->cid.oemid			= unstuff_bits(resp, 104, 16);
	card->cid.prod_name[0]		= unstuff_bits(resp, 96, 8);
	card->cid.prod_name[1]		= unstuff_bits(resp, 88, 8);
	card->cid.prod_name[2]		= unstuff_bits(resp, 80, 8);
	card->cid.prod_name[3]		= unstuff_bits(resp, 72, 8);
	card->cid.prod_name[4]		= unstuff_bits(resp, 64, 8);
	card->cid.hwrev			= unstuff_bits(resp, 60, 4);
	card->cid.fwrev			= unstuff_bits(resp, 56, 4);
	card->cid.serial		= unstuff_bits(resp, 24, 32);
	card->cid.year			= unstuff_bits(resp, 12, 8);
	card->cid.month			= unstuff_bits(resp, 8, 4);

	card->cid.year += 2000; /* SD cards year offset */

	/* some product names may include trailing whitespace */
	strim(card->cid.prod_name);
}

/*
 * Given a 128-bit response, decode to our card CSD structure.
 */
static int mmc_decode_csd(struct mmc_card *card, bool is_sduc)
{
	struct mmc_csd *csd = &card->csd;
	unsigned int e, m, csd_struct;
	u32 *resp = card->raw_csd;

	csd_struct = unstuff_bits(resp, 126, 2);

	switch (csd_struct) {
	case 0:
		m = unstuff_bits(resp, 115, 4);
		e = unstuff_bits(resp, 112, 3);
		csd->taac_ns	 = (taac_exp[e] * taac_mant[m] + 9) / 10;
		csd->taac_clks	 = unstuff_bits(resp, 104, 8) * 100;

		m = unstuff_bits(resp, 99, 4);
		e = unstuff_bits(resp, 96, 3);
		csd->max_dtr	  = tran_exp[e] * tran_mant[m];
		csd->cmdclass	  = unstuff_bits(resp, 84, 12);

		e = unstuff_bits(resp, 47, 3);
		m = unstuff_bits(resp, 62, 12);
		csd->capacity	  = (1 + m) << (e + 2);

		csd->read_blkbits = unstuff_bits(resp, 80, 4);
		csd->read_partial = unstuff_bits(resp, 79, 1);
		csd->write_misalign = unstuff_bits(resp, 78, 1);
		csd->read_misalign = unstuff_bits(resp, 77, 1);
		csd->dsr_imp = unstuff_bits(resp, 76, 1);
		csd->r2w_factor = unstuff_bits(resp, 26, 3);
		csd->write_blkbits = unstuff_bits(resp, 22, 4);
		csd->write_partial = unstuff_bits(resp, 21, 1);

		if (unstuff_bits(resp, 46, 1)) {
			csd->erase_size = 1;
		} else if (csd->write_blkbits >= 9) {
			csd->erase_size = unstuff_bits(resp, 39, 7) + 1;
			csd->erase_size <<= csd->write_blkbits - 9;
		}

		if (unstuff_bits(resp, 13, 1))
			mmc_card_set_readonly(card);
		break;
	case 1:
	case 2:
		/*

Annotation

Implementation Notes