void print_mmc_csd()

in common/recipes-lib/obmc-mmc/files/lsmmc.c [1240:1967]


void print_mmc_csd(struct config *config, char *csd)
{
	unsigned int csd_structure;
	unsigned int spec_vers;
	unsigned int taac_timevalue;
	unsigned int taac_timeunit;
	unsigned int nsac;
	unsigned int tran_speed_timevalue;
	unsigned int tran_speed_transferrateunit;
	unsigned int ccc;
	unsigned int read_bl_len;
	unsigned int read_bl_partial;
	unsigned int write_blk_misalign;
	unsigned int read_blk_misalign;
	unsigned int dsr_imp;
	unsigned int c_size;
	unsigned int vdd_r_curr_min;
	unsigned int vdd_r_curr_max;
	unsigned int vdd_w_curr_min;
	unsigned int vdd_w_curr_max;
	unsigned int c_size_mult;
	unsigned int erase_grp_size;
	unsigned int erase_grp_mult;
	unsigned int wp_grp_size;
	unsigned int wp_grp_enable;
	unsigned int default_ecc;
	unsigned int r2w_factor;
	unsigned int write_bl_len;
	unsigned int write_bl_partial;
	unsigned int content_prot_app;
	unsigned int file_format_grp;
	unsigned int copy;
	unsigned int perm_write_protect;
	unsigned int tmp_write_protect;
	unsigned int file_format;
	unsigned int ecc;
	unsigned int crc;
	unsigned int taac;
	unsigned int tran_speed;

	parse_bin(csd, "2u4u2r1r4u3u8u1r4u3u12u4u1u1u1u1u2r12u3u3u3u3u3u"
		  "5u5u5u1u2u3u4u1u4r1u1u1u1u1u2u2u7u1r",
		  &csd_structure, &spec_vers, &taac_timevalue,
		  &taac_timeunit, &nsac, &tran_speed_timevalue,
		  &tran_speed_transferrateunit, &ccc, &read_bl_len,
		  &read_bl_partial, &write_blk_misalign,
		  &read_blk_misalign, &dsr_imp, &c_size,
		  &vdd_r_curr_min, &vdd_r_curr_max,
		  &vdd_w_curr_min, &vdd_w_curr_max, &c_size_mult,
		  &erase_grp_size, &erase_grp_mult, &wp_grp_size,
		  &wp_grp_enable, &default_ecc, &r2w_factor,
		  &write_bl_len, &write_bl_partial, &content_prot_app,
		  &file_format_grp, &copy, &perm_write_protect,
		  &tmp_write_protect, &file_format, &ecc, &crc);

	taac = taac_timevalue << 3 | taac_timeunit;
	tran_speed = tran_speed_timevalue << 3 | tran_speed_transferrateunit;

	if (config->verbose) {
		float value;
		int mult;
		int blocknr;
		int block_len;
		unsigned long long blocks = 0;
		int block_size = 0;
		unsigned long long memory_capacity;

		printf("======MMC/CSD======\n");

		printf("\tCSD_STRUCTURE: 0x%01x (", csd_structure);
		switch (csd_structure) {
		case 0x0:
			printf("v1.0)\n");
			break;
		case 0x1:
			printf("v1.1)\n");
			break;
		case 0x2:
			printf("v1.2)\n");
			break;
		case 0x3:
			printf("version in ext_csd)\n");
			break;
		}

		printf("\tSPEC_VERS: 0x%01x (", spec_vers);
		switch (spec_vers) {
		case 0x0:
			printf("v1.0-v1.2)\n");
			break;
		case 0x1:
			printf("v1.4)\n");
			break;
		case 0x2:
			printf("v2.0-v2.2)\n");
			break;
		case 0x3:
			printf("v3.1-v3.31)\n");
			break;
		case 0x4:
			printf("v4.0-v4.3)\n");
			break;
		default:
			printf("reserved)\n");
			break;
		}

		printf("\tTAAC: 0x%02x (", taac);
		switch (taac_timevalue) {
		case 0x0:
			value = 0.0f;
			break;
		case 0x1:
			value = 1.0f;
			break;
		case 0x2:
			value = 1.2f;
			break;
		case 0x3:
			value = 1.3f;
			break;
		case 0x4:
			value = 1.5f;
			break;
		case 0x5:
			value = 2.0f;
			break;
		case 0x6:
			value = 2.5f;
			break;
		case 0x7:
			value = 3.0f;
			break;
		case 0x8:
			value = 3.5f;
			break;
		case 0x9:
			value = 4.0f;
			break;
		case 0xa:
			value = 4.5f;
			break;
		case 0xb:
			value = 5.0f;
			break;
		case 0xc:
			value = 5.5f;
			break;
		case 0xd:
			value = 6.0f;
			break;
		case 0xe:
			value = 7.0f;
			break;
		case 0xf:
			value = 8.0f;
			break;
		default:
			value = 0.0f;
			break;
		}

		switch (taac_timeunit) {
		case 0x0:
			printf("%.2fns)\n", value * 1.0f);
			break;
		case 0x1:
			printf("%.2fns)\n", value * 10.0f);
			break;
		case 0x2:
			printf("%.2fns)\n", value * 100.0f);
			break;
		case 0x3:
			printf("%.2fus)\n", value * 1.0f);
			break;
		case 0x4:
			printf("%.2fus)\n", value * 10.0f);
			break;
		case 0x5:
			printf("%.2fus)\n", value * 100.0f);
			break;
		case 0x6:
			printf("%.2fms)\n", value * 1.0f);
			break;
		case 0x7:
			printf("%.2fms)\n", value * 10.0f);
			break;
		}

		printf("\tNSAC: %d clocks\n", nsac);
		printf("\tTRAN_SPEED: 0x%02x (", tran_speed);
		switch (tran_speed_timevalue) {
		case 0x0:
			value = 0.0f;
			break;
		case 0x1:
			value = 1.0f;
			break;
		case 0x2:
			value = 1.2f;
			break;
		case 0x3:
			value = 1.3f;
			break;
		case 0x4:
			value = 1.5f;
			break;
		case 0x5:
			value = 2.0f;
			break;
		case 0x6:
			value = 2.6f;
			break;
		case 0x7:
			value = 3.0f;
			break;
		case 0x8:
			value = 3.5f;
			break;
		case 0x9:
			value = 4.0f;
			break;
		case 0xa:
			value = 4.5f;
			break;
		case 0xb:
			value = 5.2f;
			break;
		case 0xc:
			value = 5.5f;
			break;
		case 0xd:
			value = 6.0f;
			break;
		case 0xe:
			value = 7.0f;
			break;
		case 0xf:
			value = 8.0f;
			break;
		default:
			value = 0.0f;
			break;
		}

		switch (tran_speed_transferrateunit) {
		case 0x0:
			printf("%.2fKHz/s)\n", value * 100.0f);
			break;
		case 0x1:
			printf("%.2fMHz/s)\n", value * 1.0f);
			break;
		case 0x2:
			printf("%.2fMHz/s)\n", value * 10.0f);
			break;
		case 0x3:
			printf("%.2fMHz/s)\n", value * 100.0f);
			break;
		default:
			printf("reserved)\n");
			break;
		}

		printf("\tCCC: 0x%03x (class: ", ccc);
		if (ccc & 0x800)
			printf("11, ");
		if (ccc & 0x400)
			printf("10, ");
		if (ccc & 0x200)
			printf("9, ");
		if (ccc & 0x100)
			printf("8, ");
		if (ccc & 0x080)
			printf("7, ");
		if (ccc & 0x040)
			printf("6, ");
		if (ccc & 0x020)
			printf("5, ");
		if (ccc & 0x010)
			printf("4, ");
		if (ccc & 0x008)
			printf("3, ");
		if (ccc & 0x004)
			printf("2, ");
		if (ccc & 0x002)
			printf("1, ");
		if (ccc & 0x001)
			printf("0, ");
		printf("  )\n");

		printf("\tREAD_BL_LEN: 0x%01x (", read_bl_len);
		switch (read_bl_len) {
		case 0x0:
			printf("1 byte)\n");
			break;
		case 0x1:
			printf("2 byte)\n");
			break;
		case 0x2:
			printf("4 byte)\n");
			break;
		case 0x3:
			printf("8 byte)\n");
			break;
		case 0x4:
			printf("16 byte)\n");
			break;
		case 0x5:
			printf("32 byte)\n");
			break;
		case 0x6:
			printf("64 byte)\n");
			break;
		case 0x7:
			printf("128 byte)\n");
			break;
		case 0x8:
			printf("256 byte)\n");
			break;
		case 0x9:
			printf("512 bytes)\n");
			break;
		case 0xa:
			printf("1024 bytes)\n");
			break;
		case 0xb:
			printf("2048 bytes)\n");
			break;
		case 0xc:
			printf("4096 bytes)\n");
			break;
		case 0xd:
			printf("8192 bytes)\n");
			break;
		case 0xe:
			printf("16K bytes)\n");
			break;
		default:
			printf("reserved bytes)\n");
			break;
		}

		printf("\tREAD_BL_PARTIAL: 0x%01x (", read_bl_partial);
		switch (read_bl_partial) {
		case 0x0:
			printf("only 512 byte and READ_BL_LEN block size)\n");
			break;
		case 0x1:
			printf("less than READ_BL_LEN block size can be used)\n");
			break;
		}

		printf("\tWRITE_BLK_MISALIGN: 0x%01x (", write_blk_misalign);
		switch (write_blk_misalign) {
		case 0x0:
			printf("writes across block boundaries are invalid)\n");
			break;
		case 0x1:
			printf("writes across block boundaries are allowed)\n");
			break;
		}

		printf("\tREAD_BLK_MISALIGN: 0x%01x (", read_blk_misalign);
		switch (read_blk_misalign) {
		case 0x0:
			printf("reads across block boundaries are invalid)\n");
			break;
		case 0x1:
			printf("reads across block boundaries are allowed)\n");
			break;
		}

		printf("\tDSR_IMP: 0x%01x (", dsr_imp);
		switch (dsr_imp) {
		case 0x0:
			printf("configurable driver stage not available)\n");
			break;
		case 0x1:
			printf("configurable driver state available)\n");
			break;
		}

		printf("\tC_SIZE: 0x%03x\n", c_size);
		printf("\tVDD_R_CURR_MIN: 0x%01x (", vdd_r_curr_min);
		switch (vdd_r_curr_min) {
		case 0x0:
			printf("0.5mA)\n");
			break;
		case 0x1:
			printf("1mA)\n");
			break;
		case 0x2:
			printf("5mA)\n");
			break;
		case 0x3:
			printf("10mA)\n");
			break;
		case 0x4:
			printf("25mA)\n");
			break;
		case 0x5:
			printf("35mA)\n");
			break;
		case 0x6:
			printf("60mA)\n");
			break;
		case 0x7:
			printf("100mA)\n");
			break;
		}

		printf("\tVDD_R_CURR_MAX: 0x%01x (", vdd_r_curr_max);
		switch (vdd_r_curr_max) {
		case 0x0:
			printf("1mA)\n");
			break;
		case 0x1:
			printf("5mA)\n");
			break;
		case 0x2:
			printf("10mA)\n");
			break;
		case 0x3:
			printf("25mA)\n");
			break;
		case 0x4:
			printf("35mA)\n");
			break;
		case 0x5:
			printf("45mA)\n");
			break;
		case 0x6:
			printf("80mA)\n");
			break;
		case 0x7:
			printf("200mA)\n");
			break;
		}

		printf("\tVDD_W_CURR_MIN: 0x%01x (", vdd_w_curr_min);
		switch (vdd_w_curr_min) {
		case 0x0:
			printf("0.5mA)\n");
			break;
		case 0x1:
			printf("1mA)\n");
			break;
		case 0x2:
			printf("5mA)\n");
			break;
		case 0x3:
			printf("10mA)\n");
			break;
		case 0x4:
			printf("25mA)\n");
			break;
		case 0x5:
			printf("35mA)\n");
			break;
		case 0x6:
			printf("60mA)\n");
			break;
		case 0x7:
			printf("100mA)\n");
			break;
		}

		printf("\tVDD_W_CURR_MAX: 0x%01x (", vdd_w_curr_max);
		switch (vdd_w_curr_max) {
		case 0x0:
			printf("1mA)\n");
			break;
		case 0x1:
			printf("5mA)\n");
			break;
		case 0x2:
			printf("10mA)\n");
			break;
		case 0x3:
			printf("25mA)\n");
			break;
		case 0x4:
			printf("35mA)\n");
			break;
		case 0x5:
			printf("45mA)\n");
			break;
		case 0x6:
			printf("80mA)\n");
			break;
		case 0x7:
			printf("200mA)\n");
			break;
		}

		printf("\tC_SIZE_MULT: 0x%01x\n", c_size_mult);
		printf("\tERASE_GRP_SIZE: 0x%02x\n", erase_grp_size);
		printf("\tERASE_GRP_MULT: 0x%02x (%d write blocks/erase group)\n",
		       erase_grp_mult, (erase_grp_size + 1) *
		       (erase_grp_mult + 1));
		printf("\tWP_GRP_SIZE: 0x%02x (%d blocks/write protect group)\n",
		       wp_grp_size, wp_grp_size + 1);
		printf("\tWP_GRP_ENABLE: 0x%01x\n", wp_grp_enable);

		printf("\tDEFAULT_ECC: 0x%01x (", default_ecc);
		switch (default_ecc) {
		case 0:
			printf("none)\n");
			break;
		case 1:
			printf("BCH)\n");
			break;
		default:
			printf("reserved)\n");
			break;
		}

		printf("\tR2W_FACTOR: 0x%01x (Write %d times read)\n",
		       r2w_factor, r2w_factor);

		printf("\tWRITE_BL_LEN: 0x%01x (", write_bl_len);
		switch (write_bl_len) {
		case 0x0:
			printf("1 byte)\n");
			break;
		case 0x1:
			printf("2 byte)\n");
			break;
		case 0x2:
			printf("4 byte)\n");
			break;
		case 0x3:
			printf("8 byte)\n");
			break;
		case 0x4:
			printf("16 byte)\n");
			break;
		case 0x5:
			printf("32 byte)\n");
			break;
		case 0x6:
			printf("64 byte)\n");
			break;
		case 0x7:
			printf("128 byte)\n");
			break;
		case 0x8:
			printf("256 byte)\n");
			break;
		case 0x9:
			printf("512 bytes)\n");
			break;
		case 0xa:
			printf("1024 bytes)\n");
			break;
		case 0xb:
			printf("2048 bytes)\n");
			break;
		case 0xc:
			printf("4096 bytes)\n");
			break;
		case 0xd:
			printf("8192 bytes)\n");
			break;
		case 0xe:
			printf("16K bytes)\n");
			break;
		default:
			printf("reserved bytes)\n");
			break;
		}

		printf("\tWRITE_BL_PARTIAL: 0x%01x (", write_bl_partial);
		switch (write_bl_partial) {
		case 0x0:
			printf("only 512 byte and WRITE_BL_LEN block size)\n");
			break;
		case 0x1:
			printf("less than WRITE_BL_LEN block size can be used)\n");
			break;
		}

		printf("\tCONTENT_PROT_APP: 0x%01x\n", content_prot_app);
		printf("\tFILE_FORMAT_GRP: 0x%01x\n", file_format_grp);
		if (file_format_grp != 0)
			printf("Warn: Invalid FILE_FORMAT_GRP\n");

		printf("\tCOPY: 0x%01x\n", copy);
		printf("\tPERM_WRITE_PROTECT: 0x%01x\n", perm_write_protect);
		printf("\tTMP_WRITE_PROTECT: 0x%01x\n", tmp_write_protect);
		printf("\tFILE_FORMAT: 0x%01x (", file_format);
		if (file_format != 0)
			printf("Warn: Invalid FILE_FORMAT\n");

		if (file_format_grp == 1) {
			printf("reserved)\n");
		} else {
			switch (file_format) {
			case 0:
				printf("partition table)\n");
				break;
			case 1:
				printf("no partition table)\n");
				break;
			case 2:
				printf("Universal File Format)\n");
				break;
			case 3:
				printf("Others/unknown)\n");
				break;
			}
		}

		printf("\tECC: 0x%01x (", ecc);
		switch (ecc) {
		case 0:
			printf("none)\n");
			break;
		case 1:
			printf("BCH(542,512))\n");
			break;
		default:
			printf("reserved)\n");
			break;
		}

		printf("\tCRC: 0x%01x\n", crc);

		mult = 1 << (c_size_mult + 2);
		blocknr = (c_size + 1) * mult;
		block_len = 1 << read_bl_len;
		blocks = blocknr;
		block_size = block_len;

		memory_capacity = blocks * block_size;

		printf("\tCAPACITY: ");
		if (memory_capacity / (1024ull * 1024ull * 1024ull) > 0)
			printf("%.2fGbyte",
			       memory_capacity / (1024.0 * 1024.0 * 1024.0));
		else if (memory_capacity / (1024ull * 1024ull) > 0)
			printf("%.2fMbyte", memory_capacity / (1024.0 * 1024.0));
		else if (memory_capacity / (1024ull) > 0)
			printf("%.2fKbyte", memory_capacity / (1024.0));
		else
			printf("%.2fbyte", memory_capacity * 1.0);

		printf(" (%lld bytes, %lld sectors, %d bytes each)\n",
		       memory_capacity, blocks, block_size);
	} else {
		int mult;
		int blocknr;
		int block_len;
		unsigned long long blocks = 0;
		int block_size = 0;
		unsigned long long memory_capacity;

		printf("version: ");
		switch (spec_vers) {
		case 0x0:
			printf("MMC v1.0-v1.2\n");
			break;
		case 0x1:
			printf("MMC v1.4\n");
			break;
		case 0x2:
			printf("MMC v2.0-v2.2\n");
			break;
		case 0x3:
			printf("MMC v3.1-v3.31\n");
			break;
		case 0x4:
			printf("MMC v4.0-v4.3\n");
			break;
		default:
			printf("reserved\n");
			break;
		}

		printf("card classes: ");
		if (ccc & 0x800)
			printf("11, ");
		if (ccc & 0x400)
			printf("10, ");
		if (ccc & 0x200)
			printf("9, ");
		if (ccc & 0x100)
			printf("8, ");
		if (ccc & 0x080)
			printf("7, ");
		if (ccc & 0x040)
			printf("6, ");
		if (ccc & 0x020)
			printf("5, ");
		if (ccc & 0x010)
			printf("4, ");
		if (ccc & 0x008)
			printf("3, ");
		if (ccc & 0x004)
			printf("2, ");
		if (ccc & 0x002)
			printf("1, ");
		if (ccc & 0x001)
			printf("0, ");
		printf("\b\b\n");

		mult = 1 << (c_size_mult + 2);
		blocknr = (c_size + 1) * mult;
		block_len = 1 << read_bl_len;
		blocks = blocknr;
		block_size = block_len;

		memory_capacity = blocks * block_size;

		printf("capacity: ");
		if (memory_capacity / (1024ull * 1024ull * 1024ull) > 0)
			printf("%.2fGbyte",
			       memory_capacity / (1024.0 * 1024.0 * 1024.0));
		else if (memory_capacity / (1024ull * 1024ull) > 0)
			printf("%.2fMbyte", memory_capacity / (1024.0 * 1024.0));
		else if (memory_capacity / (1024ull) > 0)
			printf("%.2fKbyte", memory_capacity / (1024.0));
		else
			printf("%.2fbyte", memory_capacity * 1.0);
		printf(" (%lld bytes, %lld sectors, %d bytes each)\n",
		       memory_capacity, blocks, block_size);
	}
}