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