mmc_cmds.c revision f74dfe23cd00894aa9f235374468e05acb793e17
1a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM/*
2a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM * This program is free software; you can redistribute it and/or
3a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM * modify it under the terms of the GNU General Public
4a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM * License v2 as published by the Free Software Foundation.
5a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM *
6a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM * This program is distributed in the hope that it will be useful,
7a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM * but WITHOUT ANY WARRANTY; without even the implied warranty of
8a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
9a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM * General Public License for more details.
10a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM *
11a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM * You should have received a copy of the GNU General Public
12a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM * License along with this program; if not, write to the
13a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
14a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM * Boston, MA 021110-1307, USA.
15a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM */
16a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM
17a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM#include <stdio.h>
18a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM#include <stdlib.h>
19a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM#include <string.h>
20a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM#include <sys/ioctl.h>
21a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM#include <sys/types.h>
22a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM#include <dirent.h>
23a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM#include <sys/stat.h>
24a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM#include <unistd.h>
25a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM#include <fcntl.h>
26a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM#include <libgen.h>
27a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM#include <limits.h>
28a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM#include <ctype.h>
29a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM
30a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM#include "mmc.h"
31a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM#include "mmc_cmds.h"
32a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM
33a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLMint read_extcsd(int fd, __u8 *ext_csd)
34a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM{
35a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	int ret = 0;
36a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	struct mmc_ioc_cmd idata;
37a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	memset(&idata, 0, sizeof(idata));
38a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	memset(ext_csd, 0, sizeof(__u8) * 512);
39a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	idata.write_flag = 0;
40a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	idata.opcode = MMC_SEND_EXT_CSD;
41a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	idata.arg = 0;
42a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	idata.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
43a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	idata.blksz = 512;
44a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	idata.blocks = 1;
45a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	mmc_ioc_cmd_set_data(idata, ext_csd);
46a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM
47a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	ret = ioctl(fd, MMC_IOC_CMD, &idata);
48a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	if (ret)
49a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM		perror("ioctl");
50a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM
51a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	return ret;
52a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM}
53a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM
54a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLMint write_extcsd_value(int fd, __u8 index, __u8 value)
55a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM{
56a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	int ret = 0;
57a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	struct mmc_ioc_cmd idata;
58a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM
59a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	memset(&idata, 0, sizeof(idata));
60a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	idata.write_flag = 1;
61a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	idata.opcode = MMC_SWITCH;
62a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	idata.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
63a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM			(index << 16) |
64a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM			(value << 8) |
65a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM			EXT_CSD_CMD_SET_NORMAL;
66a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	idata.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
67a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM
68a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	ret = ioctl(fd, MMC_IOC_CMD, &idata);
69a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	if (ret)
70a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM		perror("ioctl");
71a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM
72a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	return ret;
73a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM}
74a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM
75b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ballvoid print_writeprotect_status(__u8 *ext_csd)
76b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball{
77b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	__u8 reg;
78b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	__u8 ext_csd_rev = ext_csd[192];
79b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball
80b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	/* A43: reserved [174:0] */
81b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	if (ext_csd_rev >= 5) {
82b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball		printf("Boot write protection status registers"
83b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball			" [BOOT_WP_STATUS]: 0x%02x\n", ext_csd[174]);
84b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball
85b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball		reg = ext_csd[EXT_CSD_BOOT_WP];
86b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball		printf("Boot Area Write protection [BOOT_WP]: 0x%02x\n", reg);
87b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball		printf(" Power ro locking: ");
88b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball		if (reg & EXT_CSD_BOOT_WP_B_PWR_WP_DIS)
89b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball			printf("not possible\n");
90b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball		else
91b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball			printf("possible\n");
92b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball
93b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball		printf(" Permanent ro locking: ");
94b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball		if (reg & EXT_CSD_BOOT_WP_B_PERM_WP_DIS)
95b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball			printf("not possible\n");
96b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball		else
97b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball			printf("possible\n");
98b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball
99b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball		printf(" ro lock status: ");
100b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball		if (reg & EXT_CSD_BOOT_WP_B_PWR_WP_EN)
101b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball			printf("locked until next power on\n");
102b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball		else if (reg & EXT_CSD_BOOT_WP_B_PERM_WP_EN)
103b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball			printf("locked permanently\n");
104b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball		else
105b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball			printf("not locked\n");
106b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	}
107b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball}
108b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball
109b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ballint do_writeprotect_get(int nargs, char **argv)
110b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball{
111b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	__u8 ext_csd[512];
112b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	int fd, ret;
113b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	char *device;
114b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball
1158ba4466a4ad458618282f8bdcc2706025856a9f2Chris Ball	CHECK(nargs != 2, "Usage: mmc writeprotect get </path/to/mmcblkX>\n",
1168ba4466a4ad458618282f8bdcc2706025856a9f2Chris Ball			  exit(1));
117b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball
118b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	device = argv[1];
119b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball
120b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	fd = open(device, O_RDWR);
121b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	if (fd < 0) {
122b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball		perror("open");
123b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball		exit(1);
124b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	}
125b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball
126b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	ret = read_extcsd(fd, ext_csd);
127b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	if (ret) {
128b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball		fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
129b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball		exit(1);
130b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	}
131b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball
132b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	print_writeprotect_status(ext_csd);
133b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball
134b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	return ret;
135b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball}
136b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball
137b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ballint do_writeprotect_set(int nargs, char **argv)
138b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball{
139b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	__u8 ext_csd[512], value;
140b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	int fd, ret;
141b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	char *device;
142b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball
1438ba4466a4ad458618282f8bdcc2706025856a9f2Chris Ball	CHECK(nargs != 2, "Usage: mmc writeprotect set </path/to/mmcblkX>\n",
1448ba4466a4ad458618282f8bdcc2706025856a9f2Chris Ball			  exit(1));
145b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball
146b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	device = argv[1];
147b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball
148b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	fd = open(device, O_RDWR);
149b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	if (fd < 0) {
150b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball		perror("open");
151b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball		exit(1);
152b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	}
153b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball
154b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	ret = read_extcsd(fd, ext_csd);
155b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	if (ret) {
156b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball		fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
157b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball		exit(1);
158b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	}
159b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball
160b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	value = ext_csd[EXT_CSD_BOOT_WP] |
161b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball		EXT_CSD_BOOT_WP_B_PWR_WP_EN;
162b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	ret = write_extcsd_value(fd, EXT_CSD_BOOT_WP, value);
163b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	if (ret) {
164b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball		fprintf(stderr, "Could not write 0x%02x to "
165b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball			"EXT_CSD[%d] in %s\n",
166b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball			value, EXT_CSD_BOOT_WP, device);
167b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball		exit(1);
168b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	}
169b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball
170b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	return ret;
171b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball}
172b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball
173b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Dasint do_disable_512B_emulation(int nargs, char **argv)
174b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das{
175b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das	__u8 ext_csd[512], native_sector_size, data_sector_size, wr_rel_param;
176b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das	int fd, ret;
177b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das	char *device;
178b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das
179b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das	CHECK(nargs != 2, "Usage: mmc disable 512B emulation </path/to/mmcblkX>\n", exit(1));
180b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das	device = argv[1];
181b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das
182b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das	fd = open(device, O_RDWR);
183b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das	if (fd < 0) {
184b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das		perror("open");
185b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das		exit(1);
186b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das	}
187b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das
188b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das	ret = read_extcsd(fd, ext_csd);
189b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das	if (ret) {
190b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das		fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
191b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das		exit(1);
192b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das	}
193b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das
194b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das	wr_rel_param = ext_csd[EXT_CSD_WR_REL_PARAM];
195b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das	native_sector_size = ext_csd[EXT_CSD_NATIVE_SECTOR_SIZE];
196b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das	data_sector_size = ext_csd[EXT_CSD_DATA_SECTOR_SIZE];
197b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das
198b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das	if (native_sector_size && !data_sector_size &&
199b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das	   (wr_rel_param & EN_REL_WR)) {
200b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das		ret = write_extcsd_value(fd, EXT_CSD_USE_NATIVE_SECTOR, 1);
201b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das
202b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das		if (ret) {
203b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das			fprintf(stderr, "Could not write 0x%02x to EXT_CSD[%d] in %s\n",
204b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das					1, EXT_CSD_BOOT_WP, device);
205b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das			exit(1);
206b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das		}
207b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das		printf("MMC disable 512B emulation successful.  Now reset the device to switch to 4KB native sector mode.\n");
208b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das	} else if (native_sector_size && data_sector_size) {
209b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das		printf("MMC 512B emulation mode is already disabled; doing nothing.\n");
210b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das	} else {
211b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das		printf("MMC does not support disabling 512B emulation mode.\n");
212b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das	}
213b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das
214b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das	return ret;
215b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das}
216b7e2599c67408c38e57e91d2426c077a4541dc8cSaugata Das
2177bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLAROint do_write_boot_en(int nargs, char **argv)
2187bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO{
2197bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	__u8 ext_csd[512];
2207bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	__u8 value = 0;
2217bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	int fd, ret;
2227bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	char *device;
2237bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	int boot_area, send_ack;
2247bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO
2257bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	CHECK(nargs != 4, "Usage: mmc bootpart enable <partition_number> "
2267bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO			  "<send_ack> </path/to/mmcblkX>\n", exit(1));
2277bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO
2287bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	/*
2297bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	 * If <send_ack> is 1, the device will send acknowledgment
2307bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	 * pattern "010" to the host when boot operation begins.
2317bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	 * If <send_ack> is 0, it won't.
2327bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	 */
2337bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	boot_area = strtol(argv[1], NULL, 10);
2347bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	send_ack = strtol(argv[2], NULL, 10);
2357bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	device = argv[3];
2367bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO
2377bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	fd = open(device, O_RDWR);
2387bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	if (fd < 0) {
2397bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO		perror("open");
2407bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO		exit(1);
2417bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	}
2427bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO
2437bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	ret = read_extcsd(fd, ext_csd);
2447bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	if (ret) {
2457bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO		fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
2467bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO		exit(1);
2477bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	}
2487bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO
2497bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	value = ext_csd[EXT_CSD_PART_CONFIG];
2507bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO
2517bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	switch (boot_area) {
2527bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	case EXT_CSD_PART_CONFIG_ACC_BOOT0:
2537bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO		value |= (1 << 3);
2547bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO		value &= ~(3 << 4);
2557bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO		break;
2567bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	case EXT_CSD_PART_CONFIG_ACC_BOOT1:
2577bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO		value |= (1 << 4);
2587bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO		value &= ~(1 << 3);
2597bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO		value &= ~(1 << 5);
2607bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO		break;
2617bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	case EXT_CSD_PART_CONFIG_ACC_USER_AREA:
2627bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO		value |= (boot_area << 3);
2637bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO		break;
2647bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	default:
2657bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO		fprintf(stderr, "Cannot enable the boot area\n");
2667bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO		exit(1);
2677bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	}
2687bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	if (send_ack)
2697bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO		value |= EXT_CSD_PART_CONFIG_ACC_ACK;
2707bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	else
2717bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO		value &= ~EXT_CSD_PART_CONFIG_ACC_ACK;
2727bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO
2737bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	ret = write_extcsd_value(fd, EXT_CSD_PART_CONFIG, value);
2747bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	if (ret) {
2757bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO		fprintf(stderr, "Could not write 0x%02x to "
2767bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO			"EXT_CSD[%d] in %s\n",
2777bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO			value, EXT_CSD_PART_CONFIG, device);
2787bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO		exit(1);
2797bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	}
2807bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO	return ret;
2817bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO}
2827bd1320b2cb38f040ab5cf017d17e283496690bfGiuseppe CAVALLARO
283f74dfe23cd00894aa9f235374468e05acb793e17Chris Ballint do_hwreset(int value, int nargs, char **argv)
284f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball{
285f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball	__u8 ext_csd[512];
286f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball	int fd, ret;
287f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball	char *device;
288f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball
289f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball	CHECK(nargs != 2, "Usage: mmc hwreset enable </path/to/mmcblkX>\n",
290f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball			  exit(1));
291f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball
292f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball	device = argv[1];
293f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball
294f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball	fd = open(device, O_RDWR);
295f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball	if (fd < 0) {
296f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball		perror("open");
297f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball		exit(1);
298f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball	}
299f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball
300f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball	ret = read_extcsd(fd, ext_csd);
301f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball	if (ret) {
302f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball		fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
303f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball		exit(1);
304f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball	}
305f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball
306f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball	if ((ext_csd[EXT_CSD_RST_N_FUNCTION] & EXT_CSD_RST_N_EN_MASK) ==
307f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball	    EXT_CSD_HW_RESET_EN) {
308f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball		fprintf(stderr,
309f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball			"H/W Reset is already permanently enabled on %s\n",
310f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball			device);
311f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball		exit(1);
312f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball	}
313f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball	if ((ext_csd[EXT_CSD_RST_N_FUNCTION] & EXT_CSD_RST_N_EN_MASK) ==
314f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball	    EXT_CSD_HW_RESET_DIS) {
315f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball		fprintf(stderr,
316f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball			"H/W Reset is already permanently disabled on %s\n",
317f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball			device);
318f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball		exit(1);
319f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball	}
320f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball
321f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball	ret = write_extcsd_value(fd, EXT_CSD_RST_N_FUNCTION, value);
322f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball	if (ret) {
323f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball		fprintf(stderr,
324f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball			"Could not write 0x%02x to EXT_CSD[%d] in %s\n",
325f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball			value, EXT_CSD_RST_N_FUNCTION, device);
326f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball		exit(1);
327f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball	}
328f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball
329f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball	return ret;
330f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball}
331f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball
332f74dfe23cd00894aa9f235374468e05acb793e17Chris Ballint do_hwreset_en(int nargs, char **argv)
333f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball{
334f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball	return do_hwreset(EXT_CSD_HW_RESET_EN, nargs, argv);
335f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball}
336f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball
337f74dfe23cd00894aa9f235374468e05acb793e17Chris Ballint do_hwreset_dis(int nargs, char **argv)
338f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball{
339f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball	return do_hwreset(EXT_CSD_HW_RESET_DIS, nargs, argv);
340f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball}
341f74dfe23cd00894aa9f235374468e05acb793e17Chris Ball
3428649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chungint do_write_bkops_en(int nargs, char **argv)
3438649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung{
3448649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung	__u8 ext_csd[512], value = 0;
3458649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung	int fd, ret;
3468649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung	char *device;
3478649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung
3488649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung	CHECK(nargs != 2, "Usage: mmc bkops enable </path/to/mmcblkX>\n",
3498649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung			exit(1));
3508649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung
3518649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung	device = argv[1];
3528649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung
3538649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung	fd = open(device, O_RDWR);
3548649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung	if (fd < 0) {
3558649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung		perror("open");
3568649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung		exit(1);
3578649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung	}
3588649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung
3598649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung	ret = read_extcsd(fd, ext_csd);
3608649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung	if (ret) {
3618649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung		fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
3628649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung		exit(1);
3638649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung	}
3648649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung
3658649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung	if (!(ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1)) {
3668649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung		fprintf(stderr, "%s doesn't support BKOPS\n", device);
3678649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung		exit(1);
3688649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung	}
3698649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung
3708649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung	ret = write_extcsd_value(fd, EXT_CSD_BKOPS_EN, BKOPS_ENABLE);
3718649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung	if (ret) {
3728649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung		fprintf(stderr, "Could not write 0x%02x to EXT_CSD[%d] in %s\n",
3738649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung			value, EXT_CSD_BKOPS_EN, device);
3748649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung		exit(1);
3758649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung	}
3768649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung
3778649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung	return ret;
3788649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung}
3798649651b743a5d7c290ea0f8058794f8d127736eJaehoon Chung
380a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLMint do_read_extcsd(int nargs, char **argv)
381a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM{
382a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	__u8 ext_csd[512], ext_csd_rev, reg;
383a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	int fd, ret;
384a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	char *device;
385a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	const char *str;
386a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM
3878ba4466a4ad458618282f8bdcc2706025856a9f2Chris Ball	CHECK(nargs != 2, "Usage: mmc extcsd read </path/to/mmcblkX>\n",
3888ba4466a4ad458618282f8bdcc2706025856a9f2Chris Ball			  exit(1));
389a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM
390a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	device = argv[1];
391a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM
392a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	fd = open(device, O_RDWR);
393a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	if (fd < 0) {
394a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM		perror("open");
395a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM		exit(1);
396a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	}
397a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM
398a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	ret = read_extcsd(fd, ext_csd);
399a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	if (ret) {
400a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM		fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
401a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM		exit(1);
402a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	}
403a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM
404a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	ext_csd_rev = ext_csd[192];
405a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO
406a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	switch (ext_csd_rev) {
407a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	case 6:
408a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		str = "4.5";
409a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		break;
410a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	case 5:
411a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		str = "4.41";
412a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		break;
413a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	case 3:
414a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		str = "4.3";
415a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		break;
416a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	case 2:
417a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		str = "4.2";
418a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		break;
419a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	case 1:
420a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		str = "4.1";
421a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		break;
422a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	case 0:
423a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		str = "4.0";
424a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		break;
425a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	default:
426a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		goto out_free;
427a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	}
428a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf("=============================================\n");
429a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf("  Extended CSD rev 1.%d (MMC %s)\n", ext_csd_rev, str);
430a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf("=============================================\n\n");
431a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO
432a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	if (ext_csd_rev < 3)
433a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		goto out_free; /* No ext_csd */
434a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO
435a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	/* Parse the Extended CSD registers.
436a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	 * Reserved bit should be read as "0" in case of spec older
437a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	 * than A441.
438a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	 */
439a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	reg = ext_csd[EXT_CSD_S_CMD_SET];
440a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf("Card Supported Command sets [S_CMD_SET: 0x%02x]\n", reg);
441a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	if (!reg)
442b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball		printf(" - Standard MMC command sets\n");
443a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO
444a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	reg = ext_csd[EXT_CSD_HPI_FEATURE];
445a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf("HPI Features [HPI_FEATURE: 0x%02x]: ", reg);
446a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	if (reg & EXT_CSD_HPI_SUPP) {
447a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		if (reg & EXT_CSD_HPI_IMPL)
448b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball			printf("implementation based on CMD12\n");
449a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		else
450a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			printf("implementation based on CMD13\n");
451a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	}
452a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO
453a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf("Background operations support [BKOPS_SUPPORT: 0x%02x]\n",
454a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		ext_csd[502]);
455a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO
456a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	if (ext_csd_rev >= 6) {
457a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Max Packet Read Cmd [MAX_PACKED_READS: 0x%02x]\n",
458a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			ext_csd[501]);
459a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Max Packet Write Cmd [MAX_PACKED_WRITES: 0x%02x]\n",
460a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			ext_csd[500]);
461a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Data TAG support [DATA_TAG_SUPPORT: 0x%02x]\n",
462a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			ext_csd[499]);
463a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO
464a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Data TAG Unit Size [TAG_UNIT_SIZE: 0x%02x]\n",
465a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			ext_csd[498]);
466a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Tag Resources Size [TAG_RES_SIZE: 0x%02x]\n",
467a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			ext_csd[497]);
468a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Context Management Capabilities"
469a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			" [CONTEXT_CAPABILITIES: 0x%02x]\n", ext_csd[496]);
470a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Large Unit Size [LARGE_UNIT_SIZE_M1: 0x%02x]\n",
471a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			ext_csd[495]);
472a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Extended partition attribute support"
473a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			" [EXT_SUPPORT: 0x%02x]\n", ext_csd[494]);
474a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Generic CMD6 Timer [GENERIC_CMD6_TIME: 0x%02x]\n",
475a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			ext_csd[248]);
476a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Power off notification [POWER_OFF_LONG_TIME: 0x%02x]\n",
477a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			ext_csd[247]);
478a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Cache Size [CACHE_SIZE] is %d KiB\n",
479a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			ext_csd[249] << 0 | (ext_csd[250] << 8) |
480a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			(ext_csd[251] << 16) | (ext_csd[252] << 24));
481a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	}
482a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO
483a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	/* A441: Reserved [501:247]
484a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	    A43: reserved [246:229] */
485a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	if (ext_csd_rev >= 5) {
486a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Background operations status"
487b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball			" [BKOPS_STATUS: 0x%02x]\n", ext_csd[246]);
488a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO
489a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		/* CORRECTLY_PRG_SECTORS_NUM [245:242] TODO */
490a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO
491a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("1st Initialisation Time after programmed sector"
492a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			" [INI_TIMEOUT_AP: 0x%02x]\n", ext_csd[241]);
493a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO
494a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		/* A441: reserved [240] */
495a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Power class for 52MHz, DDR at 3.6V"
496a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			" [PWR_CL_DDR_52_360: 0x%02x]\n", ext_csd[239]);
497a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Power class for 52MHz, DDR at 1.95V"
498a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			" [PWR_CL_DDR_52_195: 0x%02x]\n", ext_csd[238]);
499a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO
500a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		/* A441: reserved [237-236] */
501a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO
502a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		if (ext_csd_rev >= 6) {
503a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			printf("Power class for 200MHz at 3.6V"
504a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO				" [PWR_CL_200_360: 0x%02x]\n", ext_csd[237]);
505a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			printf("Power class for 200MHz, at 1.95V"
506a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO				" [PWR_CL_200_195: 0x%02x]\n", ext_csd[236]);
507a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		}
508b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball		printf("Minimum Performance for 8bit at 52MHz in DDR mode:\n");
509a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf(" [MIN_PERF_DDR_W_8_52: 0x%02x]\n", ext_csd[235]);
510a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf(" [MIN_PERF_DDR_R_8_52: 0x%02x]\n", ext_csd[234]);
511a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		/* A441: reserved [233] */
512a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("TRIM Multiplier [TRIM_MULT: 0x%02x]\n", ext_csd[232]);
513a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Secure Feature support [SEC_FEATURE_SUPPORT: 0x%02x]\n",
514a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			ext_csd[231]);
515a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	}
516a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	if (ext_csd_rev == 5) { /* Obsolete in 4.5 */
517a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Secure Erase Multiplier [SEC_ERASE_MULT: 0x%02x]\n",
518a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			ext_csd[230]);
519a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Secure TRIM Multiplier [SEC_TRIM_MULT: 0x%02x]\n",
520a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			ext_csd[229]);
521a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	}
522a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	reg = ext_csd[EXT_CSD_BOOT_INFO];
523a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf("Boot Information [BOOT_INFO: 0x%02x]\n", reg);
524a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	if (reg & EXT_CSD_BOOT_INFO_ALT)
525a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf(" Device supports alternative boot method\n");
526a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	if (reg & EXT_CSD_BOOT_INFO_DDR_DDR)
527a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf(" Device supports dual data rate during boot\n");
528a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	if (reg & EXT_CSD_BOOT_INFO_HS_MODE)
529a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf(" Device supports high speed timing during boot\n");
530a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO
531a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	/* A441/A43: reserved [227] */
532a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf("Boot partition size [BOOT_SIZE_MULTI: 0x%02x]\n", ext_csd[226]);
533a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf("Access size [ACC_SIZE: 0x%02x]\n", ext_csd[225]);
534a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf("High-capacity erase unit size [HC_ERASE_GRP_SIZE: 0x%02x]\n",
535a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		ext_csd[224]);
536a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf("High-capacity erase timeout [ERASE_TIMEOUT_MULT: 0x%02x]\n",
537a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		ext_csd[223]);
538a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf("Reliable write sector count [REL_WR_SEC_C: 0x%02x]\n",
539a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		ext_csd[222]);
540a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf("High-capacity W protect group size [HC_WP_GRP_SIZE: 0x%02x]\n",
541a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		ext_csd[221]);
542a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf("Sleep current (VCC) [S_C_VCC: 0x%02x]\n", ext_csd[220]);
543a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf("Sleep current (VCCQ) [S_C_VCCQ: 0x%02x]\n", ext_csd[219]);
544a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	/* A441/A43: reserved [218] */
545a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf("Sleep/awake timeout [S_A_TIMEOUT: 0x%02x]\n", ext_csd[217]);
546a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	/* A441/A43: reserved [216] */
547a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf("Sector Count [SEC_COUNT: 0x%08x]\n", (ext_csd[215] << 24) |
548a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		      (ext_csd[214] << 16) | (ext_csd[213] << 8)  |
549a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		      ext_csd[212]);
550a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	/* A441/A43: reserved [211] */
551a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf("Minimum Write Performance for 8bit:\n");
552a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf(" [MIN_PERF_W_8_52: 0x%02x]\n", ext_csd[210]);
553a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf(" [MIN_PERF_R_8_52: 0x%02x]\n", ext_csd[209]);
554a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf(" [MIN_PERF_W_8_26_4_52: 0x%02x]\n", ext_csd[208]);
555a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf(" [MIN_PERF_R_8_26_4_52: 0x%02x]\n", ext_csd[207]);
556a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf("Minimum Write Performance for 4bit:\n");
557a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf(" [MIN_PERF_W_4_26: 0x%02x]\n", ext_csd[206]);
558a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf(" [MIN_PERF_R_4_26: 0x%02x]\n", ext_csd[205]);
559a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	/* A441/A43: reserved [204] */
560a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf("Power classes registers:\n");
561a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf(" [PWR_CL_26_360: 0x%02x]\n", ext_csd[203]);
562a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf(" [PWR_CL_52_360: 0x%02x]\n", ext_csd[202]);
563a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf(" [PWR_CL_26_195: 0x%02x]\n", ext_csd[201]);
564a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf(" [PWR_CL_52_195: 0x%02x]\n", ext_csd[200]);
565a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO
566a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	/* A43: reserved [199:198] */
567a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	if (ext_csd_rev >= 5) {
568a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Partition switching timing "
569a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			"[PARTITION_SWITCH_TIME: 0x%02x]\n", ext_csd[199]);
570a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Out-of-interrupt busy timing"
571a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			" [OUT_OF_INTERRUPT_TIME: 0x%02x]\n", ext_csd[198]);
572a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	}
573a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO
574a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	/* A441/A43: reserved	[197] [195] [193] [190] [188]
575a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	 * [186] [184] [182] [180] [176] */
576a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO
577a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	if (ext_csd_rev >= 6)
578a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("I/O Driver Strength [DRIVER_STRENGTH: 0x%02x]\n",
579a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			ext_csd[197]);
580a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO
581a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf("Card Type [CARD_TYPE: 0x%02x]\n", ext_csd[196]);
582a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	/* DEVICE_TYPE in A45 */
583a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	switch (reg) {
584a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	case 5:
585a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("HS200 Single Data Rate eMMC @200MHz 1.2VI/O\n");
586a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		break;
587a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	case 4:
588a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("HS200 Single Data Rate eMMC @200MHz 1.8VI/O\n");
589a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		break;
590a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	case 3:
591a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("HS Dual Data Rate eMMC @52MHz 1.2VI/O\n");
592a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO
593a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		break;
594a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	case 2:
595a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("HS Dual Data Rate eMMC @52MHz 1.8V or 3VI/O\n");
596a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		break;
597a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	case 1:
598a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("HS eMMC @52MHz - at rated device voltage(s)\n");
599a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		break;
600a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	case 0:
601a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("HS eMMC @26MHz - at rated device voltage(s)\n");
602a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		break;
603a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	}
604a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf("CSD structure version [CSD_STRUCTURE: 0x%02x]\n", ext_csd[194]);
605a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	/* ext_csd_rev = ext_csd[192] (already done!!!) */
606a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf("Command set [CMD_SET: 0x%02x]\n", ext_csd[191]);
607a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf("Command set revision [CMD_SET_REV: 0x%02x]\n", ext_csd[189]);
608a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf("Power class [POWER_CLASS: 0x%02x]\n", ext_csd[187]);
609a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf("High-speed interface timing [HS_TIMING: 0x%02x]\n",
610a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		ext_csd[185]);
611a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	/* bus_width: ext_csd[183] not readable */
612a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf("Erased memory content [ERASED_MEM_CONT: 0x%02x]\n",
613a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		ext_csd[181]);
614a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	reg = ext_csd[EXT_CSD_BOOT_CFG];
615a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf("Boot configuration bytes [PARTITION_CONFIG: 0x%02x]\n", reg);
616a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	switch (reg & EXT_CSD_BOOT_CFG_EN) {
617a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	case 0x0:
618a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf(" Not boot enable\n");
619a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		break;
620a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	case 0x1:
621a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf(" Boot Partition 1 enabled\n");
622a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		break;
623a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	case 0x2:
624a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf(" Boot Partition 2 enabled\n");
625a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		break;
626a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	case 0x7:
627a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf(" User Area Enabled for boot\n");
628a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		break;
629a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	}
630a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	switch (reg & EXT_CSD_BOOT_CFG_ACC) {
631a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	case 0x0:
632a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf(" No access to boot partition\n");
633a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		break;
634a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	case 0x1:
635a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf(" R/W Boot Partition 1\n");
636a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		break;
637a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	case 0x2:
638a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf(" R/W Boot Partition 2\n");
639a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		break;
640a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	default:
641a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf(" Access to General Purpuse partition %d\n",
642a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			(reg & EXT_CSD_BOOT_CFG_ACC) - 3);
643a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		break;
644a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	}
645a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO
646a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf("Boot config protection [BOOT_CONFIG_PROT: 0x%02x]\n",
647a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		ext_csd[178]);
648a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf("Boot bus Conditions [BOOT_BUS_CONDITIONS: 0x%02x]\n",
649a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		ext_csd[177]);
650a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	printf("High-density erase group definition"
651a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		" [ERASE_GROUP_DEF: 0x%02x]\n", ext_csd[175]);
652a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO
653b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	print_writeprotect_status(ext_csd);
654a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO
655b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball	if (ext_csd_rev >= 5) {
656a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		/* A441]: reserved [172] */
657a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("User area write protection register"
658a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			" [USER_WP]: 0x%02x\n", ext_csd[171]);
659a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		/* A441]: reserved [170] */
660a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("FW configuration [FW_CONFIG]: 0x%02x\n", ext_csd[169]);
661a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("RPMB Size [RPMB_SIZE_MULT]: 0x%02x\n", ext_csd[168]);
662a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Write reliability setting register"
663a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			" [WR_REL_SET]: 0x%02x\n", ext_csd[167]);
664a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Write reliability parameter register"
665a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			" [WR_REL_PARAM]: 0x%02x\n", ext_csd[166]);
666a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		/* sanitize_start ext_csd[165]]: not readable
667a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		 * bkops_start ext_csd[164]]: only writable */
668a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Enable background operations handshake"
669a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			" [BKOPS_EN]: 0x%02x\n", ext_csd[163]);
670a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("H/W reset function"
671a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			" [RST_N_FUNCTION]: 0x%02x\n", ext_csd[162]);
672a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("HPI management [HPI_MGMT]: 0x%02x\n", ext_csd[161]);
673a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		reg = ext_csd[160];
674a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Partitioning Support [PARTITIONING_SUPPORT]: 0x%02x\n",
675a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			reg);
676a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		if (reg & 0x1)
677a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			printf(" Device support partitioning feature\n");
678a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		else
679a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			printf(" Device NOT support partitioning feature\n");
680a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		if (reg & 0x2)
681a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			printf(" Device can have enhanced tech.\n");
682a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		else
683a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			printf(" Device cannot have enhanced tech.\n");
684a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO
685a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Max Enhanced Area Size [MAX_ENH_SIZE_MULT]: 0x%06x\n",
686a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			   (ext_csd[159] << 16) | (ext_csd[158] << 8) |
687a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			    ext_csd[157]);
688a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Partitions attribute [PARTITIONS_ATTRIBUTE]: 0x%02x\n",
689a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			ext_csd[156]);
690a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Partitioning Setting"
691a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			" [PARTITION_SETTING_COMPLETED]: 0x%02x\n",
692a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			ext_csd[155]);
693a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("General Purpose Partition Size\n"
694a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			" [GP_SIZE_MULT_4]: 0x%06x\n", (ext_csd[154] << 16) |
695a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			(ext_csd[153] << 8) | ext_csd[152]);
696a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf(" [GP_SIZE_MULT_3]: 0x%06x\n", (ext_csd[151] << 16) |
697a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			   (ext_csd[150] << 8) | ext_csd[149]);
698a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf(" [GP_SIZE_MULT_2]: 0x%06x\n", (ext_csd[148] << 16) |
699a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			   (ext_csd[147] << 8) | ext_csd[146]);
700a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf(" [GP_SIZE_MULT_1]: 0x%06x\n", (ext_csd[145] << 16) |
701a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			   (ext_csd[144] << 8) | ext_csd[143]);
702a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO
703a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Enhanced User Data Area Size"
704a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			" [ENH_SIZE_MULT]: 0x%06x\n", (ext_csd[142] << 16) |
705a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			(ext_csd[141] << 8) | ext_csd[140]);
706a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Enhanced User Data Start Address"
707a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			" [ENH_START_ADDR]: 0x%06x\n", (ext_csd[139] << 16) |
708a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			   (ext_csd[138] << 8) | ext_csd[137]);
709a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO
710a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		/* A441]: reserved [135] */
711a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Bad Block Management mode"
712a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			" [SEC_BAD_BLK_MGMNT]: 0x%02x\n", ext_csd[134]);
713a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		/* A441: reserved [133:0] */
714a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	}
715a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	/* B45 */
716a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	if (ext_csd_rev >= 6) {
717a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		int j;
718a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		/* tcase_support ext_csd[132] not readable */
719a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Periodic Wake-up [PERIODIC_WAKEUP]: 0x%02x\n",
720a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			ext_csd[131]);
721a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Program CID/CSD in DDR mode support"
722a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			" [PROGRAM_CID_CSD_DDR_SUPPORT]: 0x%02x\n",
723a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			   ext_csd[130]);
724a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO
725a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		for (j = 127; j >= 64; j--)
726a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			printf("Vendor Specific Fields"
727a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO				" [VENDOR_SPECIFIC_FIELD[%d]]: 0x%02x\n",
728a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO				j, ext_csd[j]);
729a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO
730a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Native sector size [NATIVE_SECTOR_SIZE]: 0x%02x\n",
731a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			ext_csd[63]);
732a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Sector size emulation [USE_NATIVE_SECTOR]: 0x%02x\n",
733a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			ext_csd[62]);
734a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Sector size [DATA_SECTOR_SIZE]: 0x%02x\n", ext_csd[61]);
735a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("1st initialization after disabling sector"
736a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			" size emulation [INI_TIMEOUT_EMU]: 0x%02x\n",
737a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			ext_csd[60]);
738a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Class 6 commands control [CLASS_6_CTRL]: 0x%02x\n",
739a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			ext_csd[59]);
740a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Number of addressed group to be Released"
741a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			"[DYNCAP_NEEDED]: 0x%02x\n", ext_csd[58]);
742a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Exception events control"
743a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			" [EXCEPTION_EVENTS_CTRL]: 0x%04x\n",
744a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			(ext_csd[57] << 8) | ext_csd[56]);
745a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Exception events status"
746a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			"[EXCEPTION_EVENTS_STATUS]: 0x%04x\n",
747a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			(ext_csd[55] << 8) | ext_csd[54]);
748a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Extended Partitions Attribute"
749a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			" [EXT_PARTITIONS_ATTRIBUTE]: 0x%04x\n",
750a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			(ext_csd[53] << 8) | ext_csd[52]);
751a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO
752a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		for (j = 51; j >= 37; j--)
753a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			printf("Context configuration"
754a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO				" [CONTEXT_CONF[%d]]: 0x%02x\n", j, ext_csd[j]);
755a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO
756a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Packed command status"
757a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			" [PACKED_COMMAND_STATUS]: 0x%02x\n", ext_csd[36]);
758a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Packed command failure index"
759a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			" [PACKED_FAILURE_INDEX]: 0x%02x\n", ext_csd[35]);
760a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		printf("Power Off Notification"
761a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO			" [POWER_OFF_NOTIFICATION]: 0x%02x\n", ext_csd[34]);
762b9c7a17fce190f085bb4eb6e6535a22e2c69de68Chris Ball		printf("Control to turn the Cache ON/OFF"			" [CACHE_CTRL]: 0x%02x\n", ext_csd[33]);
763a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		/* flush_cache ext_csd[32] not readable */
764a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO		/*Reserved [31:0] */
765a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO	}
766a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLARO
767a5bf4a2030a9dcfbcebf1b647e65c1e936a56e14Giuseppe CAVALLAROout_free:
768a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM	return ret;
769a8bfde77e0e275070791138d60b75d1cc293daf0Johan RUDHOLM}
770