commit mmc-utils for openSUSE:Factory
Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package mmc-utils for openSUSE:Factory checked in at 2021-04-29 01:38:13 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/mmc-utils (Old) and /work/SRC/openSUSE:Factory/.mmc-utils.new.12324 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "mmc-utils" Thu Apr 29 01:38:13 2021 rev:14 rq:888951 version:0.1+git.20210330 Changes: -------- --- /work/SRC/openSUSE:Factory/mmc-utils/mmc-utils.changes 2020-02-05 19:41:40.187266775 +0100 +++ /work/SRC/openSUSE:Factory/.mmc-utils.new.12324/mmc-utils.changes 2021-04-29 01:39:12.522647180 +0200 @@ -1,0 +2,14 @@ +Wed Apr 28 07:43:21 UTC 2021 - Martin Pluskal <mpluskal@suse.com> + +- Update to version 0.1+git.20210330: + * Various fixes + * Add various SD/eMMC vendors to table + * Fix parsing of Product Revision and Serial Number + * mmc_cmds.c: fix build with gcc 4.9 + * mmc-utils: Add AUTO_EN support in the BKOPS_EN + * mmc-utils: Expand 'writeprotect boot' + * mmc-utils: Fix scaling of cache size + * rpmb: Zero-init MMC_IOC_MULTI_CMD structures + * mmc-utils: let FFU mode use CMD23 and CMD25 + +------------------------------------------------------------------- Old: ---- mmc-utils-0.1+git.20191004.obscpio New: ---- mmc-utils-0.1+git.20210330.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ mmc-utils.spec ++++++ --- /var/tmp/diff_new_pack.vN3KdQ/_old 2021-04-29 01:39:13.014647877 +0200 +++ /var/tmp/diff_new_pack.vN3KdQ/_new 2021-04-29 01:39:13.018647883 +0200 @@ -1,7 +1,7 @@ # # spec file for package mmc-utils # -# Copyright (c) 2020 SUSE LLC +# Copyright (c) 2021 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,12 +17,12 @@ Name: mmc-utils -Version: 0.1+git.20191004 +Version: 0.1+git.20210330 Release: 0 Summary: Tools for MMC/SD devices License: GPL-2.0-only Group: Hardware/Other -URL: http://git.kernel.org/cgit/linux/kernel/git/cjb/mmc-utils.git/ +URL: https://git.kernel.org/cgit/linux/kernel/git/cjb/mmc-utils.git/ Source0: %{name}-%{version}.tar.gz Source1: https://www.gnu.org/licenses/gpl-2.0.txt ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.vN3KdQ/_old 2021-04-29 01:39:13.054647934 +0200 +++ /var/tmp/diff_new_pack.vN3KdQ/_new 2021-04-29 01:39:13.058647940 +0200 @@ -1,4 +1,4 @@ <servicedata> <service name="tar_scm"> <param name="url">git://git.kernel.org/pub/scm/linux/kernel/git/cjb/mmc-utils.git</param> - <param name="changesrevision">73d6c59af8d1bcedf5de4aa1f5d5b7f765f545f5</param></service></servicedata> \ No newline at end of file + <param name="changesrevision">e9654ebc4a6a48642848822c4a1355a9de4958d1</param></service></servicedata> \ No newline at end of file ++++++ mmc-utils-0.1+git.20191004.obscpio -> mmc-utils-0.1+git.20210330.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mmc-utils-0.1+git.20191004/lsmmc.c new/mmc-utils-0.1+git.20210330/lsmmc.c --- old/mmc-utils-0.1+git.20191004/lsmmc.c 2019-10-05 02:47:33.000000000 +0200 +++ new/mmc-utils-0.1+git.20210330/lsmmc.c 2021-03-30 15:28:34.000000000 +0200 @@ -112,7 +112,7 @@ { .type = "sd", .id = 0x1b, - .manufacturer = "Transcend", + .manufacturer = "Transcend/Samsung", }, { .type = "sd", @@ -122,7 +122,7 @@ { .type = "sd", .id = 0x1d, - .manufacturer = "Corsair", + .manufacturer = "Corsair/AData", }, { .type = "sd", @@ -136,6 +136,11 @@ }, { .type = "sd", + .id = 0x27, + .manufacturer = "Delkin/Phison", + }, + { + .type = "sd", .id = 0x28, .manufacturer = "Lexar", }, @@ -146,6 +151,11 @@ }, { .type = "sd", + .id = 0x31, + .manufacturer = "Silicon Power", + }, + { + .type = "sd", .id = 0x33, .manufacturer = "STMicroelectronics", }, @@ -161,6 +171,21 @@ }, { .type = "sd", + .id = 0x74, + .manufacturer = "Transcend", + }, + { + .type = "sd", + .id = 0x76, + .manufacturer = "Patriot", + }, + { + .type = "sd", + .id = 0x82, + .manufacturer = "Gobe/Sony", + }, + { + .type = "sd", .id = 0x89, .manufacturer = "Unknown", }, @@ -224,6 +249,11 @@ .id = 0x70, .manufacturer = "Kingston", }, + { + .type = "mmc", + .id = 0xfe, + .manufacturer = "Micron", + }, }; /* Command line parsing functions */ @@ -524,9 +554,9 @@ printf("\tOID: %s\n", oid); printf("\tPNM: %s\n", pnm); printf("\tPRV: 0x%01x%01x ", prv_major, prv_minor); - printf("(%d.%d)\n", prv_major, prv_minor); + printf("(%u.%u)\n", prv_major, prv_minor); printf("\tPSN: 0x%08x\n", psn); - printf("\tMDT: 0x%02x%01x %d %s\n", mdt_year, mdt_month, + printf("\tMDT: 0x%02x%01x %u %s\n", mdt_year, mdt_month, 2000 + mdt_year, months[mdt_month]); printf("\tCRC: 0x%02x\n", crc); } else { @@ -536,9 +566,9 @@ else printf("manufacturer: 'Unlisted' '%s'\n", oid); - printf("product: '%s' %d.%d\n", pnm, prv_major, prv_minor); + printf("product: '%s' %u.%u\n", pnm, prv_major, prv_minor); printf("serial: 0x%08x\n", psn); - printf("manfacturing date: %d %s\n", 2000 + mdt_year, + printf("manufacturing date: %u %s\n", 2000 + mdt_year, months[mdt_month]); } } @@ -562,7 +592,7 @@ unsigned int crc; parse_bin(cid, "8u6r2u8u48a4u4u32u4u4u7u1r", - &mid, &cbx, &oid, &pnm[0], &psn, &prv_major, &prv_minor, + &mid, &cbx, &oid, &pnm[0], &prv_major, &prv_minor, &psn, &mdt_year, &mdt_month, &crc); pnm[6] = '\0'; @@ -595,9 +625,9 @@ printf("\tOID: 0x%01x\n", oid); printf("\tPNM: %s\n", pnm); printf("\tPRV: 0x%01x%01x ", prv_major, prv_minor); - printf("(%d.%d)\n", prv_major, prv_minor); + printf("(%u.%u)\n", prv_major, prv_minor); printf("\tPSN: 0x%08x\n", psn); - printf("\tMDT: 0x%01x%01x %d %s\n", mdt_month, mdt_year, + printf("\tMDT: 0x%01x%01x %u %s\n", mdt_month, mdt_year, 1997 + mdt_year, months[mdt_month]); printf("\tCRC: 0x%02x\n", crc); } else { @@ -607,9 +637,9 @@ else printf("manufacturer: 'Unlisted' '%c'\n", oid); - printf("product: '%s' %d.%d\n", pnm, prv_major, prv_minor); + printf("product: '%s' %u.%u\n", pnm, prv_major, prv_minor); printf("serial: 0x%08x\n", psn); - printf("manfacturing date: %d %s\n", 1997 + mdt_year, + printf("manufacturing date: %u %s\n", 1997 + mdt_year, months[mdt_month]); } } @@ -699,7 +729,7 @@ printf("======SD/CSD======\n"); - printf("\tCSD_STRUCTURE: %d\n", csd_structure); + printf("\tCSD_STRUCTURE: %u\n", csd_structure); printf("\tTAAC: 0x%02x (", taac); switch (taac_timevalue) { @@ -786,7 +816,7 @@ if (csd_structure == 1 && taac != 0x0e) printf("Warn: Invalid TAAC (should be 0x0e)\n"); - printf("\tNSAC: %d clocks\n", nsac); + printf("\tNSAC: %u clocks\n", nsac); if (csd_structure == 1 && nsac != 0x00) printf("Warn: Invalid NSAC (should be 0x00)\n"); @@ -1073,12 +1103,12 @@ if (erase_blk_en != 0x01) printf("Warn: Invalid ERASE_BLK_EN (should be 0x01)\n"); - printf("\tSECTOR_SIZE: 0x%02x (Erasable sector: %d blocks)\n", + printf("\tSECTOR_SIZE: 0x%02x (Erasable sector: %u blocks)\n", sector_size, sector_size + 1); if (sector_size != 0x7f) printf("Warn: Invalid SECTOR_SIZE (should be 0x7f)\n"); - printf("\tWP_GRP_SIZE: 0x%02x (Write protect group: %d blocks)\n", + printf("\tWP_GRP_SIZE: 0x%02x (Write protect group: %u blocks)\n", wp_grp_size, wp_grp_size + 1); if (wp_grp_size != 0x00) printf("Warn: Invalid WP_GRP_SIZE (should be 0x00)\n"); @@ -1087,7 +1117,7 @@ if (wp_grp_enable != 0x00) printf("Warn: Invalid WP_GRP_ENABLE (should be 0x00)\n"); - printf("\tR2W_FACTOR: 0x%01x (Write %d times read)\n", + printf("\tR2W_FACTOR: 0x%01x (Write %u times read)\n", r2w_factor, r2w_factor); if (r2w_factor != 0x02) printf("Warn: Invalid R2W_FACTOR (should be 0x02)\n"); @@ -1169,7 +1199,7 @@ else printf("%.2fbyte", memory_capacity * 1.0); - printf(" (%lld bytes, %lld sectors, %d bytes each)\n", + printf(" (%llu bytes, %llu sectors, %d bytes each)\n", memory_capacity, blocks, block_size); } else { unsigned long long blocks = 0; @@ -1232,7 +1262,7 @@ else printf("%.2fbyte", memory_capacity * 1.0); - printf(" (%lld bytes, %lld sectors, %d bytes each)\n", + printf(" (%llu bytes, %llu sectors, %d bytes each)\n", memory_capacity, blocks, block_size); } } @@ -1426,7 +1456,7 @@ break; } - printf("\tNSAC: %d clocks\n", nsac); + printf("\tNSAC: %u clocks\n", nsac); printf("\tTRAN_SPEED: 0x%02x (", tran_speed); switch (tran_speed_timevalue) { case 0x0: @@ -1734,10 +1764,10 @@ printf("\tC_SIZE_MULT: 0x%01x\n", c_size_mult); printf("\tERASE_GRP_SIZE: 0x%02x\n", erase_grp_size); - printf("\tERASE_GRP_MULT: 0x%02x (%d write blocks/erase group)\n", + printf("\tERASE_GRP_MULT: 0x%02x (%u write blocks/erase group)\n", erase_grp_mult, (erase_grp_size + 1) * (erase_grp_mult + 1)); - printf("\tWP_GRP_SIZE: 0x%02x (%d blocks/write protect group)\n", + printf("\tWP_GRP_SIZE: 0x%02x (%u blocks/write protect group)\n", wp_grp_size, wp_grp_size + 1); printf("\tWP_GRP_ENABLE: 0x%01x\n", wp_grp_enable); @@ -1754,7 +1784,7 @@ break; } - printf("\tR2W_FACTOR: 0x%01x (Write %d times read)\n", + printf("\tR2W_FACTOR: 0x%01x (Write %u times read)\n", r2w_factor, r2w_factor); printf("\tWRITE_BL_LEN: 0x%01x (", write_bl_len); @@ -1884,7 +1914,7 @@ else printf("%.2fbyte", memory_capacity * 1.0); - printf(" (%lld bytes, %lld sectors, %d bytes each)\n", + printf(" (%llu bytes, %llu sectors, %d bytes each)\n", memory_capacity, blocks, block_size); } else { int mult; @@ -1961,7 +1991,7 @@ printf("%.2fKbyte", memory_capacity / (1024.0)); else printf("%.2fbyte", memory_capacity * 1.0); - printf(" (%lld bytes, %lld sectors, %d bytes each)\n", + printf(" (%llu bytes, %llu sectors, %d bytes each)\n", memory_capacity, blocks, block_size); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mmc-utils-0.1+git.20191004/mmc.c new/mmc-utils-0.1+git.20210330/mmc.c --- old/mmc-utils-0.1+git.20191004/mmc.c 2019-10-05 02:47:33.000000000 +0200 +++ new/mmc-utils-0.1+git.20210330/mmc.c 2021-03-30 15:28:34.000000000 +0200 @@ -64,9 +64,20 @@ NULL }, { do_writeprotect_boot_set, -1, - "writeprotect boot set", "<device>\n" - "Set the boot partitions write protect status for <device>.\nThis sets the eMMC boot partitions to be write-protected until\nthe next boot.", - NULL + "writeprotect boot set", +#ifdef DANGEROUS_COMMANDS_ENABLED + "[-p] " +#endif /* DANGEROUS_COMMANDS_ENABLED */ + "<device> [<number>]\n" + "Set the boot partition write protect status for <device>.\n" + "If <number> is passed (0 or 1), only protect that particular\n" + "eMMC boot partition, otherwise protect both. It will be\n" + "write-protected until the next boot.\n" +#ifdef DANGEROUS_COMMANDS_ENABLED + " -p Protect partition permanently instead.\n" + " NOTE! -p is a one-time programmable (unreversible) change.\n" +#endif /* DANGEROUS_COMMANDS_ENABLED */ + , NULL }, { do_writeprotect_user_set, -4, "writeprotect user set", "<type>" "<start block>" "<blocks>" "<device>\n" @@ -120,9 +131,12 @@ "<boot_bus_width> must be \"x1|x4|x8\"", NULL }, - { do_write_bkops_en, -1, - "bkops enable", "<device>\n" - "Enable the eMMC BKOPS feature on <device>.\nNOTE! This is a one-time programmable (unreversible) change.", + { do_write_bkops_en, -2, + "bkops_en", "<auto|manual> <device>\n" + "Enable the eMMC BKOPS feature on <device>.\n" + "The auto (AUTO_EN) setting is only supported on eMMC 5.0 or newer.\n" + "Setting auto won't have any effect if manual is set.\n" + "NOTE! Setting manual (MANUAL_EN) is one-time programmable (unreversible) change.", NULL }, { do_hwreset_en, -1, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mmc-utils-0.1+git.20191004/mmc.h new/mmc-utils-0.1+git.20210330/mmc.h --- old/mmc-utils-0.1+git.20191004/mmc.h 2019-10-05 02:47:33.000000000 +0200 +++ new/mmc-utils-0.1+git.20210330/mmc.h 2021-03-30 15:28:34.000000000 +0200 @@ -29,6 +29,7 @@ #define R1_SWITCH_ERROR (1 << 7) /* sx, c */ #define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */ #define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */ +#define MMC_SET_BLOCK_COUNT 23 /* adtc [31:0] data addr R1 */ #define MMC_WRITE_BLOCK 24 /* adtc [31:0] data addr R1 */ #define MMC_WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */ #define MMC_SET_WRITE_PROT 28 /* ac [31:0] data addr R1b */ @@ -74,6 +75,7 @@ #define EXT_CSD_PART_CONFIG 179 #define EXT_CSD_BOOT_BUS_CONDITIONS 177 #define EXT_CSD_ERASE_GROUP_DEF 175 +#define EXT_CSD_BOOT_WP_STATUS 174 #define EXT_CSD_BOOT_WP 173 #define EXT_CSD_USER_WP 171 #define EXT_CSD_FW_CONFIG 169 /* R/W */ @@ -126,9 +128,10 @@ #define EN_REL_WR (1<<2) /* - * BKOPS_EN field definition + * BKOPS_EN field definitions */ -#define BKOPS_ENABLE (1<<0) +#define BKOPS_MAN_ENABLE (1<<0) +#define BKOPS_AUTO_ENABLE (1<<1) /* * EXT_CSD field definitions @@ -143,9 +146,19 @@ #define EXT_CSD_HPI_SUPP (1<<0) #define EXT_CSD_HPI_IMPL (1<<1) #define EXT_CSD_CMD_SET_NORMAL (1<<0) +/* NOTE: The eMMC spec calls the partitions "Area 1" and "Area 2", but Linux + * calls them mmcblk0boot0 and mmcblk0boot1. To avoid confustion between the two + * numbering schemes, this tool uses 0 and 1 throughout. */ +#define EXT_CSD_BOOT_WP_S_AREA_1_PERM (0x08) +#define EXT_CSD_BOOT_WP_S_AREA_1_PWR (0x04) +#define EXT_CSD_BOOT_WP_S_AREA_0_PERM (0x02) +#define EXT_CSD_BOOT_WP_S_AREA_0_PWR (0x01) +#define EXT_CSD_BOOT_WP_B_SEC_WP_SEL (0x80) #define EXT_CSD_BOOT_WP_B_PWR_WP_DIS (0x40) #define EXT_CSD_BOOT_WP_B_PERM_WP_DIS (0x10) +#define EXT_CSD_BOOT_WP_B_PERM_WP_SEC_SEL (0x08) #define EXT_CSD_BOOT_WP_B_PERM_WP_EN (0x04) +#define EXT_CSD_BOOT_WP_B_PWR_WP_SEC_SEL (0x02) #define EXT_CSD_BOOT_WP_B_PWR_WP_EN (0x01) #define EXT_CSD_BOOT_INFO_HS_MODE (1<<2) #define EXT_CSD_BOOT_INFO_DDR_DDR (1<<1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mmc-utils-0.1+git.20191004/mmc_cmds.c new/mmc-utils-0.1+git.20210330/mmc_cmds.c --- old/mmc-utils-0.1+git.20191004/mmc_cmds.c 2019-10-05 02:47:33.000000000 +0200 +++ new/mmc-utils-0.1+git.20210330/mmc_cmds.c 2021-03-30 15:28:34.000000000 +0200 @@ -202,11 +202,19 @@ else printf("possible\n"); - printf(" ro lock status: "); - if (reg & EXT_CSD_BOOT_WP_B_PWR_WP_EN) + reg = ext_csd[EXT_CSD_BOOT_WP_STATUS]; + printf(" partition 0 ro lock status: "); + if (reg & EXT_CSD_BOOT_WP_S_AREA_0_PERM) + printf("locked permanently\n"); + else if (reg & EXT_CSD_BOOT_WP_S_AREA_0_PWR) printf("locked until next power on\n"); - else if (reg & EXT_CSD_BOOT_WP_B_PERM_WP_EN) + else + printf("not locked\n"); + printf(" partition 1 ro lock status: "); + if (reg & EXT_CSD_BOOT_WP_S_AREA_1_PERM) printf("locked permanently\n"); + else if (reg & EXT_CSD_BOOT_WP_S_AREA_1_PWR) + printf("locked until next power on\n"); else printf("not locked\n"); } @@ -252,6 +260,7 @@ print_writeprotect_boot_status(ext_csd); + close(fd); return ret; } @@ -260,13 +269,28 @@ __u8 ext_csd[512], value; int fd, ret; char *device; + char *end; + int argi = 1; + int permanent = 0; + int partition = -1; - if (nargs != 2) { - fprintf(stderr, "Usage: mmc writeprotect boot set </path/to/mmcblkX>\n"); +#ifdef DANGEROUS_COMMANDS_ENABLED + if (!strcmp(argv[argi], "-p")){ + permanent = 1; + argi++; + } +#endif + + if (nargs < 1 + argi || nargs > 2 + argi) { + fprintf(stderr, "Usage: mmc writeprotect boot set " +#ifdef DANGEROUS_COMMANDS_ENABLED + "[-p] " +#endif + "</path/to/mmcblkX> [0|1]\n"); exit(1); } - device = argv[1]; + device = argv[argi++]; fd = open(device, O_RDWR); if (fd < 0) { @@ -274,14 +298,49 @@ exit(1); } + if (nargs == 1 + argi) { + partition = strtoul(argv[argi], &end, 0); + if (*end != '\0' || !(partition == 0 || partition == 1)) { + fprintf(stderr, "Invalid partition number (must be 0 or 1): %s\n", + argv[argi]); + exit(1); + } + } + ret = read_extcsd(fd, ext_csd); if (ret) { fprintf(stderr, "Could not read EXT_CSD from %s\n", device); exit(1); } - value = ext_csd[EXT_CSD_BOOT_WP] | - EXT_CSD_BOOT_WP_B_PWR_WP_EN; + value = ext_csd[EXT_CSD_BOOT_WP]; + /* + * If permanent protection is already on for one partition and we're + * trying to enable power-reset protection for the other we need to make + * sure the selection bit for permanent protection still points to the + * former or we'll accidentally permanently protect the latter. + */ + if ((value & EXT_CSD_BOOT_WP_B_PERM_WP_EN) && !permanent) { + if (ext_csd[EXT_CSD_BOOT_WP_STATUS] & + EXT_CSD_BOOT_WP_S_AREA_1_PERM) { + value |= EXT_CSD_BOOT_WP_B_PERM_WP_SEC_SEL; + if (partition != 1) + partition = 0; + } else { + /* PERM_WP_SEC_SEL cleared -> pointing to partition 0 */ + if (partition != 0) + partition = 1; + } + } + if (partition != -1) { + value |= EXT_CSD_BOOT_WP_B_SEC_WP_SEL; + if (partition == 1) + value |= permanent ? EXT_CSD_BOOT_WP_B_PERM_WP_SEC_SEL + : EXT_CSD_BOOT_WP_B_PWR_WP_SEC_SEL; + } + value |= permanent ? EXT_CSD_BOOT_WP_B_PERM_WP_EN + : EXT_CSD_BOOT_WP_B_PWR_WP_EN; + ret = write_extcsd_value(fd, EXT_CSD_BOOT_WP, value); if (ret) { fprintf(stderr, "Could not write 0x%02x to " @@ -290,6 +349,7 @@ exit(1); } + close(fd); return ret; } @@ -378,6 +438,7 @@ if (last_wpblk != (x + y - 1)) print_wp_status(wp_sizeblks, last_wpblk, cnt - 1, last_prot); + close(fd); return ret; } @@ -524,6 +585,7 @@ printf("MMC does not support disabling 512B emulation mode.\n"); } + close(fd); return ret; } @@ -595,6 +657,7 @@ value, EXT_CSD_PART_CONFIG, device); exit(1); } + close(fd); return ret; } @@ -716,6 +779,7 @@ exit(1); } + close(fd); return ret; } @@ -734,13 +798,15 @@ __u8 ext_csd[512], value = 0; int fd, ret; char *device; + char *en_type; - if (nargs != 2) { - fprintf(stderr, "Usage: mmc bkops enable </path/to/mmcblkX>\n"); - exit(1); + if (nargs != 3) { + fprintf(stderr, "Usage: mmc bkops_en <auto|manual> </path/to/mmcblkX>\n"); + exit(1); } - device = argv[1]; + en_type = argv[1]; + device = argv[2]; fd = open(device, O_RDWR); if (fd < 0) { @@ -754,18 +820,26 @@ exit(1); } - if (!(ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1)) { - fprintf(stderr, "%s doesn't support BKOPS\n", device); + if (strcmp(en_type, "auto") == 0) { + if (ext_csd[EXT_CSD_REV] < EXT_CSD_REV_V5_0) { + fprintf(stderr, "%s doesn't support AUTO_EN in the BKOPS_EN register\n", device); + exit(1); + } + ret = write_extcsd_value(fd, EXT_CSD_BKOPS_EN, BKOPS_AUTO_ENABLE); + } else if (strcmp(en_type, "manual") == 0) { + ret = write_extcsd_value(fd, EXT_CSD_BKOPS_EN, BKOPS_MAN_ENABLE); + } else { + fprintf(stderr, "%s invalid mode for BKOPS_EN requested: %s. Valid options: auto or manual\n", en_type, device); exit(1); } - ret = write_extcsd_value(fd, EXT_CSD_BKOPS_EN, BKOPS_ENABLE); if (ret) { fprintf(stderr, "Could not write 0x%02x to EXT_CSD[%d] in %s\n", value, EXT_CSD_BKOPS_EN, device); exit(1); } + close(fd); return ret; } @@ -796,6 +870,7 @@ printf("SEND_STATUS response: 0x%08x\n", response); + close(fd); return ret; } @@ -1419,8 +1494,8 @@ printf("Power off notification [POWER_OFF_LONG_TIME: 0x%02x]\n", ext_csd[247]); printf("Cache Size [CACHE_SIZE] is %d KiB\n", - ext_csd[249] << 0 | (ext_csd[250] << 8) | - (ext_csd[251] << 16) | (ext_csd[252] << 24)); + (ext_csd[249] << 0 | (ext_csd[250] << 8) | + (ext_csd[251] << 16) | (ext_csd[252] << 24)) / 8); } /* A441: Reserved [501:247] @@ -1615,11 +1690,11 @@ printf("Write reliability setting register" " [WR_REL_SET]: 0x%02x\n", reg); - printf(" user area: %s\n", reg & (1<<0) ? reliable : fast); + printf(" user area: %s\n", (reg & (1<<0)) ? reliable : fast); int i; for (i = 1; i <= 4; i++) { printf(" partition %d: %s\n", i, - reg & (1<<i) ? reliable : fast); + (reg & (1<<i)) ? reliable : fast); } reg = ext_csd[EXT_CSD_WR_REL_PARAM]; @@ -1837,6 +1912,7 @@ exit(1); } + close(fd); return ret; } @@ -1915,14 +1991,16 @@ u_int16_t rpmb_type; struct mmc_ioc_multi_cmd *mioc; struct mmc_ioc_cmd *ioc; - struct rpmb_frame frame_status = {0}; + struct rpmb_frame frame_status; + + memset(&frame_status, 0, sizeof(frame_status)); if (!frame_in || !frame_out || !out_cnt) return -EINVAL; /* prepare arguments for MMC_IOC_MULTI_CMD ioctl */ mioc = (struct mmc_ioc_multi_cmd *) - malloc(sizeof (struct mmc_ioc_multi_cmd) + + calloc(1, sizeof (struct mmc_ioc_multi_cmd) + RPMB_MULTI_CMD_MAX_CMDS * sizeof (struct mmc_ioc_cmd)); if (!mioc) { return -ENOMEM; @@ -2422,6 +2500,7 @@ exit(1); } + close(fd); return ret; } @@ -2446,12 +2525,13 @@ int sect_done = 0, retry = 3, ret = -EINVAL; unsigned int sect_size; __u8 ext_csd[512]; - __u8 *buf; + __u8 *buf = NULL; __u32 arg; off_t fw_size; ssize_t chunk_size; char *device; - struct mmc_ioc_multi_cmd *multi_cmd; + struct mmc_ioc_multi_cmd *multi_cmd = NULL; + __u32 blocks = 1; if (nargs != 3) { fprintf(stderr, "Usage: ffu <image name> </path/to/mmcblkX> \n"); @@ -2471,14 +2551,6 @@ exit(1); } - buf = malloc(512); - multi_cmd = calloc(1, sizeof(struct mmc_ioc_multi_cmd) + - 3 * sizeof(struct mmc_ioc_cmd)); - if (!buf || !multi_cmd) { - perror("failed to allocate memory"); - goto out; - } - ret = read_extcsd(dev_fd, ext_csd); if (ret) { fprintf(stderr, "Could not read EXT_CSD from %s\n", device); @@ -2503,9 +2575,17 @@ } fw_size = lseek(img_fd, 0, SEEK_END); + if (fw_size > MMC_IOC_MAX_BYTES || fw_size == 0) { + fprintf(stderr, "Wrong firmware size"); + goto out; + } - if (fw_size == 0) { - fprintf(stderr, "Firmware image is empty"); + /* allocate maximum required */ + buf = malloc(fw_size); + multi_cmd = calloc(1, sizeof(struct mmc_ioc_multi_cmd) + + 4 * sizeof(struct mmc_ioc_cmd)); + if (!buf || !multi_cmd) { + perror("failed to allocate memory"); goto out; } @@ -2515,14 +2595,19 @@ goto out; } + /* calculate required fw blocks for CMD25 */ + blocks = fw_size / sect_size; + /* set CMD ARG */ arg = ext_csd[EXT_CSD_FFU_ARG_0] | ext_csd[EXT_CSD_FFU_ARG_1] << 8 | ext_csd[EXT_CSD_FFU_ARG_2] << 16 | ext_csd[EXT_CSD_FFU_ARG_3] << 24; + /* prepare multi_cmd for FFU based on cmd to be used */ + /* prepare multi_cmd to be sent */ - multi_cmd->num_of_cmds = 3; + multi_cmd->num_of_cmds = 4; /* put device into ffu mode */ multi_cmd->cmds[0].opcode = MMC_SWITCH; @@ -2533,37 +2618,42 @@ multi_cmd->cmds[0].flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; multi_cmd->cmds[0].write_flag = 1; + /* send block count */ + multi_cmd->cmds[1].opcode = MMC_SET_BLOCK_COUNT; + multi_cmd->cmds[1].arg = blocks; + multi_cmd->cmds[1].flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; + /* send image chunk */ - multi_cmd->cmds[1].opcode = MMC_WRITE_BLOCK; - multi_cmd->cmds[1].blksz = sect_size; - multi_cmd->cmds[1].blocks = 1; - multi_cmd->cmds[1].arg = arg; - multi_cmd->cmds[1].flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; - multi_cmd->cmds[1].write_flag = 1; - mmc_ioc_cmd_set_data(multi_cmd->cmds[1], buf); + multi_cmd->cmds[2].opcode = MMC_WRITE_MULTIPLE_BLOCK; + multi_cmd->cmds[2].blksz = sect_size; + multi_cmd->cmds[2].blocks = blocks; + multi_cmd->cmds[2].arg = arg; + multi_cmd->cmds[2].flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; + multi_cmd->cmds[2].write_flag = 1; + mmc_ioc_cmd_set_data(multi_cmd->cmds[2], buf); /* return device into normal mode */ - multi_cmd->cmds[2].opcode = MMC_SWITCH; - multi_cmd->cmds[2].arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | + multi_cmd->cmds[3].opcode = MMC_SWITCH; + multi_cmd->cmds[3].arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) | (EXT_CSD_MODE_CONFIG << 16) | (EXT_CSD_NORMAL_MODE << 8) | EXT_CSD_CMD_SET_NORMAL; - multi_cmd->cmds[2].flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; - multi_cmd->cmds[2].write_flag = 1; + multi_cmd->cmds[3].flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; + multi_cmd->cmds[3].write_flag = 1; do_retry: /* read firmware chunk */ lseek(img_fd, 0, SEEK_SET); - chunk_size = read(img_fd, buf, 512); + chunk_size = read(img_fd, buf, fw_size); - while (chunk_size > 0) { + if (chunk_size > 0) { /* send ioctl with multi-cmd */ ret = ioctl(dev_fd, MMC_IOC_MULTI_CMD, multi_cmd); if (ret) { perror("Multi-cmd ioctl"); /* In case multi-cmd ioctl failed before exiting from ffu mode */ - ioctl(dev_fd, MMC_IOC_CMD, &multi_cmd->cmds[2]); + ioctl(dev_fd, MMC_IOC_CMD, &multi_cmd->cmds[3]); goto out; } @@ -2590,9 +2680,6 @@ } else { fprintf(stderr, "Programmed %d/%jd bytes\r", sect_done * sect_size, (intmax_t)fw_size); } - - /* read the next firmware chunk (if any) */ - chunk_size = read(img_fd, buf, 512); } if ((sect_done * sect_size) == fw_size) { @@ -2629,7 +2716,7 @@ if (ret) { perror("Multi-cmd ioctl failed setting install mode"); /* In case multi-cmd ioctl failed before exiting from ffu mode */ - ioctl(dev_fd, MMC_IOC_CMD, &multi_cmd->cmds[2]); + ioctl(dev_fd, MMC_IOC_CMD, &multi_cmd->cmds[3]); goto out; } ++++++ mmc-utils.obsinfo ++++++ --- /var/tmp/diff_new_pack.vN3KdQ/_old 2021-04-29 01:39:13.178648110 +0200 +++ /var/tmp/diff_new_pack.vN3KdQ/_new 2021-04-29 01:39:13.178648110 +0200 @@ -1,5 +1,5 @@ name: mmc-utils -version: 0.1+git.20191004 -mtime: 1570236453 -commit: 73d6c59af8d1bcedf5de4aa1f5d5b7f765f545f5 +version: 0.1+git.20210330 +mtime: 1617110914 +commit: e9654ebc4a6a48642848822c4a1355a9de4958d1
participants (1)
-
Source-Sync