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 2023-03-24 15:21:37
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/mmc-utils (Old)
 and      /work/SRC/openSUSE:Factory/.mmc-utils.new.31432 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "mmc-utils"

Fri Mar 24 15:21:37 2023 rev:20 rq:1074096 version:0.1+git.20230209

Changes:
--------
--- /work/SRC/openSUSE:Factory/mmc-utils/mmc-utils.changes      2022-02-17 
23:41:45.735700300 +0100
+++ /work/SRC/openSUSE:Factory/.mmc-utils.new.31432/mmc-utils.changes   
2023-03-24 15:21:51.111335553 +0100
@@ -1,0 +2,19 @@
+Fri Mar 24 08:08:30 UTC 2023 - Martin Pluskal <[email protected]>
+
+- Update to version 0.1+git.20230209:
+  * mmc-utils: Add basic erase error check
+  * mmc-utils: Add a command to write extcsd registers
+  * mmc-utils: Implement alternative boot operation
+  * mmc-utils: Add CMD0 softreset and preidle command
+  * mmc-utils: Allow for custom sanitize timeout
+  * mmc-utils: Refactor switch to allow custom timeout
+  * mmc-utils: Fix a typo for ATP mid
+  * mmc-utils: Fix ffu in case of unsupported MODE_OPERATION_CODES
+  * mmc-utils: fix warning on uninitialized 'cnt'
+  * mmc-utils: correct and clean up the file handling
+  * mmc-utils: Fix 4k sector size block count in FFU
+  * mmc-utils: Add General command CMD56 read support
+  * mmc-utils: Fix build error MMC_BLOCK_MAJOR undeclared
+  * Enhancement to do_status_get() function for detailed Response info
+
+-------------------------------------------------------------------

Old:
----
  mmc-utils-0.1+git.20220208.obscpio

New:
----
  mmc-utils-0.1+git.20230209.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ mmc-utils.spec ++++++
--- /var/tmp/diff_new_pack.UbayAV/_old  2023-03-24 15:21:51.615338181 +0100
+++ /var/tmp/diff_new_pack.UbayAV/_new  2023-03-24 15:21:51.627338244 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package mmc-utils
 #
-# Copyright (c) 2022 SUSE LLC
+# Copyright (c) 2023 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
 
 
 Name:           mmc-utils
-Version:        0.1+git.20220208
+Version:        0.1+git.20230209
 Release:        0
 Summary:        Tools for MMC/SD devices
 License:        GPL-2.0-only

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.UbayAV/_old  2023-03-24 15:21:51.679338514 +0100
+++ /var/tmp/diff_new_pack.UbayAV/_new  2023-03-24 15:21:51.687338557 +0100
@@ -1,6 +1,6 @@
 <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">4637a7c0df49ba349f9f0e4ab0828133fc06cc81</param></service></servicedata>
+              <param 
name="changesrevision">d4c2910981ff99b983734426dfa99632fb81ac6b</param></service></servicedata>
 (No newline at EOF)
 

++++++ mmc-utils-0.1+git.20220208.obscpio -> mmc-utils-0.1+git.20230209.obscpio 
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mmc-utils-0.1+git.20220208/lsmmc.c 
new/mmc-utils-0.1+git.20230209/lsmmc.c
--- old/mmc-utils-0.1+git.20220208/lsmmc.c      2022-02-08 16:15:35.000000000 
+0100
+++ new/mmc-utils-0.1+git.20230209/lsmmc.c      2023-02-09 15:16:51.000000000 
+0100
@@ -237,7 +237,7 @@
        {
                .type = "mmc",
                .id = 0x44,
-               .manufacturer = "SanDisk",
+               .manufacturer = "ATP",
        },
        {
                .type = "mmc",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mmc-utils-0.1+git.20220208/mmc.c 
new/mmc-utils-0.1+git.20230209/mmc.c
--- old/mmc-utils-0.1+git.20220208/mmc.c        2022-02-08 16:15:35.000000000 
+0100
+++ new/mmc-utils-0.1+git.20230209/mmc.c        2023-02-09 15:16:51.000000000 
+0100
@@ -58,6 +58,11 @@
                "Print extcsd data from <device>.",
          NULL
        },
+       { do_write_extcsd, 3,
+         "extcsd write", "<offset> <value> <device>\n"
+                 "Write <value> at offset <offset> to <device>'s extcsd.",
+         NULL
+       },
        { do_writeprotect_boot_get, -1,
          "writeprotect boot get", "<device>\n"
                "Print the boot partitions write protect status for <device>.",
@@ -150,7 +155,7 @@
          NULL
        },
        { do_sanitize, -1,
-         "sanitize", "<device>\n"
+         "sanitize", "<device> [timeout_ms]\n"
                "Send Sanitize command to the <device>.\nThis will delete the 
unmapped memory region of the device.",
          NULL
        },
@@ -237,6 +242,36 @@
                "secure-trim1 | secure-trim2 | trim \n",
        NULL
        },
+       { do_general_cmd_read, -1,
+       "gen_cmd read", "<device> [arg]\n"
+               "Send GEN_CMD (CMD56) to read vendor-specific format/meaning 
data from <device>\n\n"
+               "NOTE!: [arg] is optional and defaults to 0x1. If [arg] is 
specified, then [arg]\n"
+               "must be a 32-bit hexadecimal number, prefixed with 0x/0X. And 
bit0 in [arg] must\n"
+               "be 1.",
+       NULL
+       },
+       { do_softreset, -1,
+         "softreset", "<device>\n"
+         "Issues a CMD0 softreset, e.g. for testing if hardware reset for UHS 
works",
+         NULL
+       },
+       { do_preidle, -1,
+         "preidle", "<device>\n"
+         "Issues a CMD0 GO_PRE_IDLE",
+         NULL
+       },
+       { do_alt_boot_op, -1,
+         "boot_operation", "<boot_data_file> <device>\n"
+         "Does the alternative boot operation and writes the specified 
starting blocks of boot data into the requested file.\n\n"
+         "Note some limitations\n:"
+         "1. The boot operation must be configured, e.g. for legacy speed:\n"
+         "mmc-utils bootbus set single_backward retain x8 /dev/mmcblk2\n"
+         "mmc-utils bootpart enable 1 0 /dev/mmcblk2\n"
+         "2. The MMC must currently be running at the bus mode that is 
configured for the boot operation (HS200 and HS400 not supported at all).\n"
+         "3. Only up to 512K bytes of boot data will be transferred.\n"
+         "4. The MMC will perform a soft reset, if your system cannot handle 
that do not use the boot operation from mmc-utils.\n",
+         NULL
+       },
        { 0, 0, 0, 0 }
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mmc-utils-0.1+git.20220208/mmc.h 
new/mmc-utils-0.1+git.20230209/mmc.h
--- old/mmc-utils-0.1+git.20220208/mmc.h        2022-02-08 16:15:35.000000000 
+0100
+++ new/mmc-utils-0.1+git.20230209/mmc.h        2023-02-09 15:16:51.000000000 
+0100
@@ -17,9 +17,14 @@
  * those modifications are Copyright (c) 2016 SanDisk Corp.
  */
 
+#include <linux/major.h>
 #include <linux/mmc/ioctl.h>
 
 /* From kernel linux/mmc/mmc.h */
+#define MMC_GO_IDLE_STATE         0   /* bc                          */
+#define MMC_GO_IDLE_STATE_ARG          0x0
+#define MMC_GO_PRE_IDLE_STATE_ARG      0xF0F0F0F0
+#define MMC_BOOT_INITIATION_ARG                0xFFFFFFFA
 #define MMC_SWITCH             6       /* ac   [31:0] See below        R1b */
 #define MMC_SEND_EXT_CSD       8       /* adtc                         R1  */
 #define MMC_SEND_STATUS                13      /* ac   [31:16] RCA        R1  
*/
@@ -41,6 +46,30 @@
                                              [1] Discard Enable
                                              [0] Identify Write Blocks for
                                              Erase (or TRIM Enable)  R1b */
+#define MMC_GEN_CMD            56   /* adtc  [31:1] stuff bits.
+                                             [0]: RD/WR1 R1 */
+
+#define R1_OUT_OF_RANGE         (1 << 31)       /* er, c */
+#define R1_ADDRESS_ERROR        (1 << 30)       /* erx, c */
+#define R1_BLOCK_LEN_ERROR      (1 << 29)       /* er, c */
+#define R1_ERASE_SEQ_ERROR      (1 << 28)       /* er, c */
+#define R1_ERASE_PARAM          (1 << 27)       /* ex, c */
+#define R1_WP_VIOLATION         (1 << 26)       /* erx, c */
+#define R1_CARD_IS_LOCKED       (1 << 25)       /* sx, a */
+#define R1_LOCK_UNLOCK_FAILED   (1 << 24)       /* erx, c */
+#define R1_COM_CRC_ERROR        (1 << 23)       /* er, b */
+#define R1_ILLEGAL_COMMAND      (1 << 22)       /* er, b */
+#define R1_CARD_ECC_FAILED      (1 << 21)       /* ex, c */
+#define R1_CC_ERROR             (1 << 20)       /* erx, c */
+#define R1_ERROR                (1 << 19)       /* erx, c */
+#define R1_CID_CSD_OVERWRITE    (1 << 16)       /* erx, c, CID/CSD overwrite */
+#define R1_WP_ERASE_SKIP        (1 << 15)       /* sx, c */
+#define R1_CARD_ECC_DISABLED    (1 << 14)       /* sx, a */
+#define R1_ERASE_RESET          (1 << 13)       /* sr, c */
+#define R1_READY_FOR_DATA       (1 << 8)        /* sx, a */
+#define R1_EXCEPTION_EVENT      (1 << 6)        /* sr, a */
+#define R1_APP_CMD              (1 << 5)        /* sr, c */
+
 /*
  * EXT_CSD fields
  */
@@ -69,6 +98,7 @@
 #define EXT_CSD_CACHE_SIZE_0           249
 #define EXT_CSD_SEC_FEATURE_SUPPORT    231
 #define EXT_CSD_BOOT_INFO              228     /* R/W */
+#define EXT_CSD_BOOT_MULT              226     /* RO */
 #define EXT_CSD_HC_ERASE_GRP_SIZE      224
 #define EXT_CSD_HC_WP_GRP_SIZE         221
 #define EXT_CSD_SEC_COUNT_3            215
@@ -201,6 +231,7 @@
 
 
 /* From kernel linux/mmc/core.h */
+#define MMC_RSP_NONE   0                       /* no response */
 #define MMC_RSP_PRESENT        (1 << 0)
 #define MMC_RSP_136    (1 << 1)                /* 136 bit response */
 #define MMC_RSP_CRC    (1 << 2)                /* expect valid crc */
@@ -209,6 +240,7 @@
 
 #define MMC_CMD_AC     (0 << 5)
 #define MMC_CMD_ADTC   (1 << 5)
+#define MMC_CMD_BC     (2 << 5)
 
 #define MMC_RSP_SPI_S1 (1 << 7)                /* one status byte */
 #define MMC_RSP_SPI_BUSY (1 << 10)             /* card may send busy */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mmc-utils-0.1+git.20220208/mmc_cmds.c 
new/mmc-utils-0.1+git.20230209/mmc_cmds.c
--- old/mmc-utils-0.1+git.20220208/mmc_cmds.c   2022-02-08 16:15:35.000000000 
+0100
+++ new/mmc-utils-0.1+git.20230209/mmc_cmds.c   2023-02-09 15:16:51.000000000 
+0100
@@ -54,7 +54,6 @@
 #define WPTYPE_PWRON 2
 #define WPTYPE_PERM 3
 
-
 int read_extcsd(int fd, __u8 *ext_csd)
 {
        int ret = 0;
@@ -76,7 +75,7 @@
        return ret;
 }
 
-int write_extcsd_value(int fd, __u8 index, __u8 value)
+int write_extcsd_value(int fd, __u8 index, __u8 value, unsigned int timeout_ms)
 {
        int ret = 0;
        struct mmc_ioc_cmd idata;
@@ -89,6 +88,8 @@
                        (value << 8) |
                        EXT_CSD_CMD_SET_NORMAL;
        idata.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
+       /* Kernel will set cmd_timeout_ms if 0 is set */
+       idata.cmd_timeout_ms = timeout_ms;
 
        ret = ioctl(fd, MMC_IOC_CMD, &idata);
        if (ret)
@@ -341,7 +342,7 @@
        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);
+       ret = write_extcsd_value(fd, EXT_CSD_BOOT_WP, value, 0);
        if (ret) {
                fprintf(stderr, "Could not write 0x%02x to "
                        "EXT_CSD[%d] in %s\n",
@@ -508,7 +509,7 @@
                        break;
                }
                if (user_wp != ext_csd[EXT_CSD_USER_WP]) {
-                       ret = write_extcsd_value(fd, EXT_CSD_USER_WP, user_wp);
+                       ret = write_extcsd_value(fd, EXT_CSD_USER_WP, user_wp, 
0);
                        if (ret) {
                                fprintf(stderr, "Error setting EXT_CSD\n");
                                exit(1);
@@ -526,7 +527,7 @@
        }
        if (wptype != WPTYPE_NONE) {
                ret = write_extcsd_value(fd, EXT_CSD_USER_WP,
-                                       ext_csd[EXT_CSD_USER_WP]);
+                               ext_csd[EXT_CSD_USER_WP], 0);
                if (ret) {
                        fprintf(stderr, "Error restoring EXT_CSD\n");
                        exit(1);
@@ -571,7 +572,7 @@
 
        if (native_sector_size && !data_sector_size &&
           (wr_rel_param & EN_REL_WR)) {
-               ret = write_extcsd_value(fd, EXT_CSD_USE_NATIVE_SECTOR, 1);
+               ret = write_extcsd_value(fd, EXT_CSD_USE_NATIVE_SECTOR, 1, 0);
 
                if (ret) {
                        fprintf(stderr, "Could not write 0x%02x to EXT_CSD[%d] 
in %s\n",
@@ -650,7 +651,7 @@
        else
                value &= ~EXT_CSD_PART_CONFIG_ACC_ACK;
 
-       ret = write_extcsd_value(fd, EXT_CSD_PART_CONFIG, value);
+       ret = write_extcsd_value(fd, EXT_CSD_PART_CONFIG, value, 0);
        if (ret) {
                fprintf(stderr, "Could not write 0x%02x to "
                        "EXT_CSD[%d] in %s\n",
@@ -720,7 +721,7 @@
        printf("Changing ext_csd[BOOT_BUS_CONDITIONS] from 0x%02x to 0x%02x\n",
                ext_csd[EXT_CSD_BOOT_BUS_CONDITIONS], value);
 
-       ret = write_extcsd_value(fd, EXT_CSD_BOOT_BUS_CONDITIONS, value);
+       ret = write_extcsd_value(fd, EXT_CSD_BOOT_BUS_CONDITIONS, value, 0);
        if (ret) {
                fprintf(stderr, "Could not write 0x%02x to "
                        "EXT_CSD[%d] in %s\n",
@@ -771,7 +772,7 @@
                exit(1);
        }
 
-       ret = write_extcsd_value(fd, EXT_CSD_RST_N_FUNCTION, value);
+       ret = write_extcsd_value(fd, EXT_CSD_RST_N_FUNCTION, value, 0);
        if (ret) {
                fprintf(stderr,
                        "Could not write 0x%02x to EXT_CSD[%d] in %s\n",
@@ -825,9 +826,9 @@
                        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);
+               ret = write_extcsd_value(fd, EXT_CSD_BKOPS_EN, 
BKOPS_AUTO_ENABLE, 0);
        } else if (strcmp(en_type, "manual") == 0) {
-               ret = write_extcsd_value(fd, EXT_CSD_BKOPS_EN, 
BKOPS_MAN_ENABLE);
+               ret = write_extcsd_value(fd, EXT_CSD_BKOPS_EN, 
BKOPS_MAN_ENABLE, 0);
        } else {
                fprintf(stderr, "%s invalid mode for BKOPS_EN requested: %s. 
Valid options: auto or manual\n", en_type, device);
                exit(1);
@@ -848,6 +849,8 @@
        __u32 response;
        int fd, ret;
        char *device;
+       const char *str;
+       __u8 state;
 
        if (nargs != 2) {
                fprintf(stderr, "Usage: mmc status get </path/to/mmcblkX>\n");
@@ -870,6 +873,89 @@
 
        printf("SEND_STATUS response: 0x%08x\n", response);
 
+       if (response & R1_OUT_OF_RANGE)
+               printf("ERROR: ADDRESS_OUT_OF_RANGE\n");
+       if (response & R1_ADDRESS_ERROR)
+               printf("ERROR: ADDRESS_MISALIGN\n");
+       if (response & R1_BLOCK_LEN_ERROR)
+               printf("ERROR: BLOCK_LEN_ERROR\n");
+       if (response & R1_ERASE_SEQ_ERROR)
+               printf("ERROR: ERASE_SEQ_ERROR\n");
+       if (response & R1_ERASE_PARAM)
+               printf("ERROR: ERASE_PARAM_ERROR\n");
+       if (response & R1_WP_VIOLATION)
+               printf("ERROR: WP_VOILATION\n");
+       if (response & R1_CARD_IS_LOCKED)
+               printf("STATUS: DEVICE_IS_LOCKED\n");
+       if (response & R1_LOCK_UNLOCK_FAILED)
+               printf("ERROR: LOCK_UNLOCK_IS_FAILED\n");
+       if (response & R1_COM_CRC_ERROR)
+               printf("ERROR: COM_CRC_ERROR\n");
+       if (response & R1_ILLEGAL_COMMAND)
+               printf("ERROR: ILLEGAL_COMMAND\n");
+       if (response & R1_CARD_ECC_FAILED)
+               printf("ERROR: DEVICE_ECC_FAILED\n");
+       if (response & R1_CC_ERROR)
+               printf("ERROR: CC_ERROR\n");
+       if (response & R1_ERROR)
+               printf("ERROR: ERROR\n");
+       if (response & R1_CID_CSD_OVERWRITE)
+               printf("ERROR: CID/CSD OVERWRITE\n");
+       if (response & R1_WP_ERASE_SKIP)
+               printf("ERROR: WP_ERASE_SKIP\n");
+       if (response & R1_ERASE_RESET)
+               printf("ERROR: ERASE_RESET\n");
+
+       state = (response >> 9) & 0xF;
+       switch (state) {
+       case 0:
+               str = "IDLE";
+               break;
+       case 1:
+               str = "READY";
+               break;
+       case 2:
+               str = "IDENT";
+               break;
+       case 3:
+               str = "STDBY";
+               break;
+       case 4:
+               str = "TRANS";
+               break;
+       case 5:
+               str = "DATA";
+               break;
+       case 6:
+               str = "RCV";
+               break;
+       case 7:
+               str = "PRG";
+               break;
+       case 8:
+               str = "DIS";
+               break;
+       case 9:
+               str = "BTST";
+               break;
+       case 10:
+               str = "SLP";
+               break;
+       default:
+               printf("Attention : Device state is INVALID: Kindly check the 
Response\n");
+               goto out_free;
+       }
+
+       printf("DEVICE STATE: %s\n", str);
+       if (response & R1_READY_FOR_DATA)
+               printf("STATUS: READY_FOR_DATA\n");
+       if (response & R1_SWITCH_ERROR)
+               printf("ERROR: SWITCH_ERROR\n");
+       if (response & R1_EXCEPTION_EVENT)
+               printf("STATUS: EXCEPTION_EVENT\n");  /* Check 
EXCEPTION_EVENTS_STATUS fields for further actions */
+       if (response & R1_APP_CMD)
+               printf("STATUS: APP_CMD\n");
+out_free:
        close(fd);
        return ret;
 }
@@ -917,7 +1003,7 @@
        }
 
        fprintf(stderr, "setting OTP PARTITION_SETTING_COMPLETED!\n");
-       ret = write_extcsd_value(fd, EXT_CSD_PARTITION_SETTING_COMPLETED, 0x1);
+       ret = write_extcsd_value(fd, EXT_CSD_PARTITION_SETTING_COMPLETED, 0x1, 
0);
        if (ret) {
                fprintf(stderr, "Could not write 0x1 to "
                        "EXT_CSD[%d] in %s\n",
@@ -1103,7 +1189,7 @@
        gp_size_mult = (length_kib + align/2l) / align;
 
        /* set EXT_CSD_ERASE_GROUP_DEF bit 0 */
-       ret = write_extcsd_value(fd, EXT_CSD_ERASE_GROUP_DEF, 0x1);
+       ret = write_extcsd_value(fd, EXT_CSD_ERASE_GROUP_DEF, 0x1, 0);
        if (ret) {
                fprintf(stderr, "Could not write 0x1 to EXT_CSD[%d] in %s\n",
                        EXT_CSD_ERASE_GROUP_DEF, device);
@@ -1112,7 +1198,7 @@
 
        value = (gp_size_mult >> 16) & 0xff;
        address = EXT_CSD_GP_SIZE_MULT_1_2 + (partition - 1) * 3;
-       ret = write_extcsd_value(fd, address, value);
+       ret = write_extcsd_value(fd, address, value, 0);
        if (ret) {
                fprintf(stderr, "Could not write 0x%02x to EXT_CSD[%d] in %s\n",
                        value, address, device);
@@ -1120,7 +1206,7 @@
        }
        value = (gp_size_mult >> 8) & 0xff;
        address = EXT_CSD_GP_SIZE_MULT_1_1 + (partition - 1) * 3;
-       ret = write_extcsd_value(fd, address, value);
+       ret = write_extcsd_value(fd, address, value, 0);
        if (ret) {
                fprintf(stderr, "Could not write 0x%02x to EXT_CSD[%d] in %s\n",
                        value, address, device);
@@ -1128,7 +1214,7 @@
        }
        value = gp_size_mult & 0xff;
        address = EXT_CSD_GP_SIZE_MULT_1_0 + (partition - 1) * 3;
-       ret = write_extcsd_value(fd, address, value);
+       ret = write_extcsd_value(fd, address, value, 0);
        if (ret) {
                fprintf(stderr, "Could not write 0x%02x to EXT_CSD[%d] in %s\n",
                        value, address, device);
@@ -1141,7 +1227,7 @@
        else
                value &= ~(1 << partition);
 
-       ret = write_extcsd_value(fd, EXT_CSD_PARTITIONS_ATTRIBUTE, value);
+       ret = write_extcsd_value(fd, EXT_CSD_PARTITIONS_ATTRIBUTE, value, 0);
        if (ret) {
                fprintf(stderr, "Could not write EXT_CSD_ENH_%x to EXT_CSD[%d] 
in %s\n",
                        partition, EXT_CSD_PARTITIONS_ATTRIBUTE, device);
@@ -1155,7 +1241,7 @@
        else
                value &= (0xF << (4 * ((partition % 2))));
 
-       ret = write_extcsd_value(fd, address, value);
+       ret = write_extcsd_value(fd, address, value, 0);
        if (ret) {
                fprintf(stderr, "Could not write 0x%x to EXT_CSD[%d] in %s\n",
                        value, address, device);
@@ -1232,7 +1318,7 @@
        enh_start_addr *= align;
 
        /* set EXT_CSD_ERASE_GROUP_DEF bit 0 */
-       ret = write_extcsd_value(fd, EXT_CSD_ERASE_GROUP_DEF, 0x1);
+       ret = write_extcsd_value(fd, EXT_CSD_ERASE_GROUP_DEF, 0x1, 0);
        if (ret) {
                fprintf(stderr, "Could not write 0x1 to "
                        "EXT_CSD[%d] in %s\n",
@@ -1242,7 +1328,7 @@
 
        /* write to ENH_START_ADDR and ENH_SIZE_MULT and PARTITIONS_ATTRIBUTE's 
ENH_USR bit */
        value = (enh_start_addr >> 24) & 0xff;
-       ret = write_extcsd_value(fd, EXT_CSD_ENH_START_ADDR_3, value);
+       ret = write_extcsd_value(fd, EXT_CSD_ENH_START_ADDR_3, value, 0);
        if (ret) {
                fprintf(stderr, "Could not write 0x%02x to "
                        "EXT_CSD[%d] in %s\n", value,
@@ -1250,7 +1336,7 @@
                exit(1);
        }
        value = (enh_start_addr >> 16) & 0xff;
-       ret = write_extcsd_value(fd, EXT_CSD_ENH_START_ADDR_2, value);
+       ret = write_extcsd_value(fd, EXT_CSD_ENH_START_ADDR_2, value, 0);
        if (ret) {
                fprintf(stderr, "Could not write 0x%02x to "
                        "EXT_CSD[%d] in %s\n", value,
@@ -1258,7 +1344,7 @@
                exit(1);
        }
        value = (enh_start_addr >> 8) & 0xff;
-       ret = write_extcsd_value(fd, EXT_CSD_ENH_START_ADDR_1, value);
+       ret = write_extcsd_value(fd, EXT_CSD_ENH_START_ADDR_1, value, 0);
        if (ret) {
                fprintf(stderr, "Could not write 0x%02x to "
                        "EXT_CSD[%d] in %s\n", value,
@@ -1266,7 +1352,7 @@
                exit(1);
        }
        value = enh_start_addr & 0xff;
-       ret = write_extcsd_value(fd, EXT_CSD_ENH_START_ADDR_0, value);
+       ret = write_extcsd_value(fd, EXT_CSD_ENH_START_ADDR_0, value, 0);
        if (ret) {
                fprintf(stderr, "Could not write 0x%02x to "
                        "EXT_CSD[%d] in %s\n", value,
@@ -1275,7 +1361,7 @@
        }
 
        value = (enh_size_mult >> 16) & 0xff;
-       ret = write_extcsd_value(fd, EXT_CSD_ENH_SIZE_MULT_2, value);
+       ret = write_extcsd_value(fd, EXT_CSD_ENH_SIZE_MULT_2, value, 0);
        if (ret) {
                fprintf(stderr, "Could not write 0x%02x to "
                        "EXT_CSD[%d] in %s\n", value,
@@ -1283,7 +1369,7 @@
                exit(1);
        }
        value = (enh_size_mult >> 8) & 0xff;
-       ret = write_extcsd_value(fd, EXT_CSD_ENH_SIZE_MULT_1, value);
+       ret = write_extcsd_value(fd, EXT_CSD_ENH_SIZE_MULT_1, value, 0);
        if (ret) {
                fprintf(stderr, "Could not write 0x%02x to "
                        "EXT_CSD[%d] in %s\n", value,
@@ -1291,7 +1377,7 @@
                exit(1);
        }
        value = enh_size_mult & 0xff;
-       ret = write_extcsd_value(fd, EXT_CSD_ENH_SIZE_MULT_0, value);
+       ret = write_extcsd_value(fd, EXT_CSD_ENH_SIZE_MULT_0, value, 0);
        if (ret) {
                fprintf(stderr, "Could not write 0x%02x to "
                        "EXT_CSD[%d] in %s\n", value,
@@ -1299,7 +1385,7 @@
                exit(1);
        }
        value = ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] | EXT_CSD_ENH_USR;
-       ret = write_extcsd_value(fd, EXT_CSD_PARTITIONS_ATTRIBUTE, value);
+       ret = write_extcsd_value(fd, EXT_CSD_PARTITIONS_ATTRIBUTE, value, 0);
        if (ret) {
                fprintf(stderr, "Could not write EXT_CSD_ENH_USR to "
                        "EXT_CSD[%d] in %s\n",
@@ -1370,7 +1456,7 @@
        }
 
        value = ext_csd[EXT_CSD_WR_REL_SET] | (1<<partition);
-       ret = write_extcsd_value(fd, EXT_CSD_WR_REL_SET, value);
+       ret = write_extcsd_value(fd, EXT_CSD_WR_REL_SET, value, 0);
        if (ret) {
                fprintf(stderr, "Could not write 0x%02x to EXT_CSD[%d] in %s\n",
                                value, EXT_CSD_WR_REL_SET, device);
@@ -1895,16 +1981,52 @@
        return ret;
 }
 
+int do_write_extcsd(int nargs, char **argv)
+{
+       int fd, ret;
+       int offset, value;
+       char *device;
+
+       if (nargs != 4) {
+               fprintf(stderr, "Usage: mmc extcsd write <offset> <value> 
</path/to/mmcblkX>\n");
+               exit(1);
+       }
+
+       offset = strtol(argv[1], NULL, 0);
+       value  = strtol(argv[2], NULL, 0);
+       device = argv[3];
+
+       fd = open(device, O_RDWR);
+       if (fd < 0) {
+               perror("open");
+               exit(1);
+       }
+
+       ret = write_extcsd_value(fd, offset, value, 0);
+       if (ret) {
+               fprintf(stderr,
+                       "Could not write 0x%02x to EXT_CSD[%d] in %s\n",
+                       value, offset, device);
+               exit(1);
+       }
+
+       return ret;
+}
+
 int do_sanitize(int nargs, char **argv)
 {
        int fd, ret;
        char *device;
+       unsigned int timeout = 0;
 
-       if (nargs != 2) {
-               fprintf(stderr, "Usage: mmc sanitize </path/to/mmcblkX>\n");
+       if (nargs != 2 && nargs != 3) {
+               fprintf(stderr, "Usage: mmc sanitize </path/to/mmcblkX> 
[timeout_in_ms]\n");
                exit(1);
        }
 
+       if (nargs == 3)
+               timeout = strtol(argv[2], NULL, 10);
+
        device = argv[1];
 
        fd = open(device, O_RDWR);
@@ -1913,7 +2035,7 @@
                exit(1);
        }
 
-       ret = write_extcsd_value(fd, EXT_CSD_SANITIZE_START, 1);
+       ret = write_extcsd_value(fd, EXT_CSD_SANITIZE_START, 1, timeout);
        if (ret) {
                fprintf(stderr, "Could not write 0x%02x to EXT_CSD[%d] in %s\n",
                        1, EXT_CSD_SANITIZE_START, device);
@@ -2153,8 +2275,10 @@
        }
 
        /* Check RPMB response */
-       if (frame_out.result != 0)
+       if (frame_out.result != 0) {
+               *cnt = 0;
                return be16toh(frame_out.result);
+       }
 
        *cnt = be32toh(frame_out.write_counter);
 
@@ -2500,7 +2624,7 @@
                        device);
                exit(1);
        }
-       ret = write_extcsd_value(fd, EXT_CSD_CACHE_CTRL, value);
+       ret = write_extcsd_value(fd, EXT_CSD_CACHE_CTRL, value, 0);
        if (ret) {
                fprintf(stderr,
                        "Could not write 0x%02x to EXT_CSD[%d] in %s\n",
@@ -2575,6 +2699,18 @@
        if (ret)
                perror("Erase multi-cmd ioctl");
 
+       /* Does not work for SPI cards */
+       if (multi_cmd->cmds[1].response[0] & R1_ERASE_PARAM) {
+               fprintf(stderr, "Erase start response: 0x%08x\n",
+                               multi_cmd->cmds[0].response[0]);
+               ret = -EIO;
+       }
+       if (multi_cmd->cmds[2].response[0] & R1_ERASE_SEQ_ERROR) {
+               fprintf(stderr, "Erase response: 0x%08x\n",
+                               multi_cmd->cmds[2].response[0]);
+               ret = -EIO;
+       }
+
        free(multi_cmd);
        return ret;
 }
@@ -2680,10 +2816,8 @@
        __u8 *buf = NULL;
        __u32 arg;
        off_t fw_size;
-       ssize_t chunk_size;
        char *device;
        struct mmc_ioc_multi_cmd *multi_cmd = NULL;
-       __u32 blocks = 1;
 
        if (nargs != 3) {
                fprintf(stderr, "Usage: ffu <image name> </path/to/mmcblkX> 
\n");
@@ -2741,15 +2875,13 @@
                goto out;
        }
 
+       /* ensure fw is multiple of native sector size */
        sect_size = (ext_csd[EXT_CSD_DATA_SECTOR_SIZE] == 0) ? 512 : 4096;
        if (fw_size % sect_size) {
                fprintf(stderr, "Firmware data size (%jd) is not aligned!\n", 
(intmax_t)fw_size);
                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 |
@@ -2772,13 +2904,17 @@
 
        /* send block count */
        multi_cmd->cmds[1].opcode = MMC_SET_BLOCK_COUNT;
-       multi_cmd->cmds[1].arg = blocks;
+       multi_cmd->cmds[1].arg = fw_size / 512;
        multi_cmd->cmds[1].flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
 
        /* send image chunk */
        multi_cmd->cmds[2].opcode = MMC_WRITE_MULTIPLE_BLOCK;
-       multi_cmd->cmds[2].blksz = sect_size;
-       multi_cmd->cmds[2].blocks = blocks;
+       /*
+        * blksz and blocks essentially do not matter, as long as the product
+        * is fw_size, but some hosts don't handle larger blksz well.
+        */
+       multi_cmd->cmds[2].blksz = 512;
+       multi_cmd->cmds[2].blocks = fw_size / 512;
        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;
@@ -2793,45 +2929,54 @@
        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 */
+       /* read firmware */
        lseek(img_fd, 0, SEEK_SET);
-       chunk_size = read(img_fd, buf, fw_size);
+       if (read(img_fd, buf, fw_size) != fw_size) {
+               perror("Could not read the firmware file: ");
+               ret = -ENOSPC;
+               goto out;
+       }
 
-       if (chunk_size > 0) {
-               /* send ioctl with multi-cmd */
-               ret = ioctl(dev_fd, MMC_IOC_MULTI_CMD, multi_cmd);
+do_retry:
+       /* 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[3]);
-                       goto out;
-               }
+       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[3]);
+               goto out;
+       }
 
-               ret = read_extcsd(dev_fd, ext_csd);
-               if (ret) {
-                       fprintf(stderr, "Could not read EXT_CSD from %s\n", 
device);
-                       goto out;
-               }
+       /*
+        * By spec - check if mode operation codes are supported in ffu 
features,
+        * if not then skip checking number of sectors programmed after install
+        */
+       if (!ext_csd[EXT_CSD_FFU_FEATURES]) {
+               fprintf(stderr, "Please reboot to complete firmware 
installation on %s\n", device);
+               ret = 0;
+               goto out;
+       }
 
-               /* Test if we need to restart the download */
-               sect_done = ext_csd[EXT_CSD_NUM_OF_FW_SEC_PROG_0] |
-                               ext_csd[EXT_CSD_NUM_OF_FW_SEC_PROG_1] << 8 |
-                               ext_csd[EXT_CSD_NUM_OF_FW_SEC_PROG_2] << 16 |
-                               ext_csd[EXT_CSD_NUM_OF_FW_SEC_PROG_3] << 24;
-               /* By spec, host should re-start download from the first sector 
if sect_done is 0 */
-               if (sect_done == 0) {
-                       if (retry > 0) {
-                               retry--;
-                               fprintf(stderr, "Programming failed. 
Retrying... (%d)\n", retry);
-                               goto do_retry;
-                       }
-                       fprintf(stderr, "Programming failed! Aborting...\n");
-                       goto out;
-               } else {
-                       fprintf(stderr, "Programmed %d/%jd bytes\r", sect_done 
* sect_size, (intmax_t)fw_size);
+       ret = read_extcsd(dev_fd, ext_csd);
+       if (ret) {
+               fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
+               goto out;
+       }
+
+       /* Test if we need to restart the download */
+       sect_done = ext_csd[EXT_CSD_NUM_OF_FW_SEC_PROG_0] |
+                       ext_csd[EXT_CSD_NUM_OF_FW_SEC_PROG_1] << 8 |
+                       ext_csd[EXT_CSD_NUM_OF_FW_SEC_PROG_2] << 16 |
+                       ext_csd[EXT_CSD_NUM_OF_FW_SEC_PROG_3] << 24;
+       /* By spec, host should re-start download from the first sector if 
sect_done is 0 */
+       if (sect_done == 0) {
+               if (retry--) {
+                       fprintf(stderr, "Programming failed. Retrying... 
(%d)\n", retry);
+                       goto do_retry;
                }
+               fprintf(stderr, "Programming failed! Aborting...\n");
+               goto out;
        }
 
        if ((sect_done * sect_size) == fw_size) {
@@ -2843,49 +2988,44 @@
                goto out;
        }
 
-       /* check mode operation for ffu install*/
-       if (!ext_csd[EXT_CSD_FFU_FEATURES]) {
-               fprintf(stderr, "Please reboot to complete firmware 
installation on %s\n", device);
-       } else {
-               fprintf(stderr, "Installing firmware on %s...\n", device);
-               /* Re-enter ffu mode and install the firmware */
-               multi_cmd->num_of_cmds = 2;
-
-               /* set ext_csd to install mode */
-               multi_cmd->cmds[1].opcode = MMC_SWITCH;
-               multi_cmd->cmds[1].blksz = 0;
-               multi_cmd->cmds[1].blocks = 0;
-               multi_cmd->cmds[1].arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
-                               (EXT_CSD_MODE_OPERATION_CODES << 16) |
-                               (EXT_CSD_FFU_INSTALL << 8) |
-                               EXT_CSD_CMD_SET_NORMAL;
-               multi_cmd->cmds[1].flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | 
MMC_CMD_AC;
-               multi_cmd->cmds[1].write_flag = 1;
+       fprintf(stderr, "Installing firmware on %s...\n", device);
+       /* Re-enter ffu mode and install the firmware */
+       multi_cmd->num_of_cmds = 2;
+
+       /* set ext_csd to install mode */
+       multi_cmd->cmds[1].opcode = MMC_SWITCH;
+       multi_cmd->cmds[1].blksz = 0;
+       multi_cmd->cmds[1].blocks = 0;
+       multi_cmd->cmds[1].arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
+                       (EXT_CSD_MODE_OPERATION_CODES << 16) |
+                       (EXT_CSD_FFU_INSTALL << 8) |
+                       EXT_CSD_CMD_SET_NORMAL;
+       multi_cmd->cmds[1].flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
+       multi_cmd->cmds[1].write_flag = 1;
 
-               /* send ioctl with multi-cmd */
-               ret = ioctl(dev_fd, MMC_IOC_MULTI_CMD, multi_cmd);
+       /* send ioctl with multi-cmd */
+       ret = ioctl(dev_fd, MMC_IOC_MULTI_CMD, multi_cmd);
 
-               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[3]);
-                       goto out;
-               }
+       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[3]);
+               goto out;
+       }
 
-               ret = read_extcsd(dev_fd, ext_csd);
-               if (ret) {
-                       fprintf(stderr, "Could not read EXT_CSD from %s\n", 
device);
-                       goto out;
-               }
+       ret = read_extcsd(dev_fd, ext_csd);
+       if (ret) {
+               fprintf(stderr, "Could not read EXT_CSD from %s\n", device);
+               goto out;
+       }
 
-               /* return status */
-               ret = ext_csd[EXT_CSD_FFU_STATUS];
-               if (ret) {
-                       fprintf(stderr, "%s: error %d during FFU install:\n", 
device, ret);
-                       goto out;
-               } else {
-                       fprintf(stderr, "FFU finished successfully\n");
-               }
+       /* return status */
+       ret = ext_csd[EXT_CSD_FFU_STATUS];
+       if (ret) {
+               fprintf(stderr, "%s: error %d during FFU install:\n", device, 
ret);
+               goto out;
+       } else {
+               fprintf(stderr, "FFU finished successfully\n");
        }
 
 out:
@@ -2896,3 +3036,214 @@
        return ret;
 #endif
 }
+
+int do_general_cmd_read(int nargs, char **argv)
+{
+       int dev_fd;
+       char *device;
+       char *endptr;
+       __u8 buf[512];
+       __u32 arg = 0x01;
+       int ret = -EINVAL, i;
+       struct mmc_ioc_cmd idata;
+
+       if (nargs != 2 && nargs != 3) {
+               fprintf(stderr, "Usage: gen_cmd read </path/to/mmcblkX> 
[arg]\n");
+               exit(1);
+       }
+
+       device = argv[1];
+       dev_fd = open(device, O_RDWR);
+       if (dev_fd < 0) {
+               perror("device open failed");
+               exit(1);
+       }
+
+       /* arg is specified */
+       if (nargs == 3) {
+               arg = strtol(argv[2], &endptr, 16);
+               if (errno != 0 || *endptr != '\0' || !(arg & 0x1)) {
+                       fprintf(stderr, "Wrong ARG, it should be Hex number and 
bit0 must be 1\n");
+                       goto out;
+               }
+       }
+
+       memset(&idata, 0, sizeof(idata));
+       idata.write_flag = 0;
+       idata.opcode = MMC_GEN_CMD;
+       idata.arg = arg;
+       idata.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
+       idata.blksz = 512;
+       idata.blocks = 1;
+       mmc_ioc_cmd_set_data(idata, buf);
+
+       ret = ioctl(dev_fd, MMC_IOC_CMD, &idata);
+       if (ret) {
+               perror("ioctl");
+               goto out;
+       }
+
+       printf("Data:\n");
+       for (i = 0; i < 512; i++) {
+               printf("%2x ", buf[i]);
+               if ((i + 1) % 16 == 0)
+                       printf("\n");
+       }
+out:
+       close(dev_fd);
+       return ret;
+}
+
+static void issue_cmd0(char *device, __u32 arg)
+{
+       struct mmc_ioc_cmd idata;
+       int fd;
+
+       fd = open(device, O_RDWR);
+       if (fd < 0) {
+               perror("open");
+               exit(1);
+       }
+
+       memset(&idata, 0, sizeof(idata));
+       idata.opcode = MMC_GO_IDLE_STATE;
+       idata.arg = arg;
+       idata.flags = MMC_RSP_NONE | MMC_CMD_BC;
+
+       /* No need to check for error, it is expected */
+       ioctl(fd, MMC_IOC_CMD, &idata);
+       close(fd);
+}
+
+int do_softreset(int nargs, char **argv)
+{
+       char *device;
+
+       if (nargs != 2) {
+               fprintf(stderr, "Usage: mmc softreset </path/to/mmcblkX>\n");
+               exit(1);
+       }
+
+       device = argv[1];
+       issue_cmd0(device, MMC_GO_IDLE_STATE_ARG);
+
+       return 0;
+}
+
+int do_preidle(int nargs, char **argv)
+{
+       char *device;
+
+       if (nargs != 2) {
+               fprintf(stderr, "Usage: mmc preidle </path/to/mmcblkX>\n");
+               exit(1);
+       }
+
+       device = argv[1];
+       issue_cmd0(device, MMC_GO_PRE_IDLE_STATE_ARG);
+
+       return 0;
+}
+
+int do_alt_boot_op(int nargs, char **argv)
+{
+       int fd, ret, boot_data_fd;
+       char *device, *boot_data_file;
+       struct mmc_ioc_multi_cmd *mioc;
+       __u8 ext_csd[512];
+       __u8 *boot_buf;
+       unsigned int boot_blocks, ext_csd_boot_size;
+
+       if (nargs != 3) {
+               fprintf(stderr, "Usage: mmc boot_op <boot_data_file> 
</path/to/mmcblkX>\n");
+               exit(1);
+       }
+       boot_data_file = argv[1];
+       device = argv[2];
+
+       fd = open(device, O_RDWR);
+       if (fd < 0) {
+               perror("open device");
+               exit(1);
+       }
+
+       ret = read_extcsd(fd, ext_csd);
+       if (ret) {
+               perror("read extcsd");
+               goto dev_fd_close;
+       }
+       if (!(ext_csd[EXT_CSD_BOOT_INFO] & EXT_CSD_BOOT_INFO_ALT)) {
+               ret = -EINVAL;
+               perror("Card does not support alternative boot mode");
+               goto dev_fd_close;
+       }
+       if (ext_csd[EXT_CSD_PART_CONFIG] & EXT_CSD_PART_CONFIG_ACC_ACK) {
+               ret = -EINVAL;
+               perror("Boot Ack must not be enabled");
+               goto dev_fd_close;
+       }
+       ext_csd_boot_size = ext_csd[EXT_CSD_BOOT_MULT] * 128 * 1024;
+       boot_blocks = ext_csd_boot_size / 512;
+       if (ext_csd_boot_size > MMC_IOC_MAX_BYTES) {
+               printf("Boot partition size is bigger than IOCTL limit, 
limiting to 512K\n");
+               boot_blocks = MMC_IOC_MAX_BYTES / 512;
+       }
+
+       boot_data_fd = open(boot_data_file, O_WRONLY | O_CREAT, 0644);
+       if (boot_data_fd < 0) {
+               perror("open boot data file");
+               ret = 1;
+               goto boot_data_close;
+       }
+
+       boot_buf = calloc(1, sizeof(__u8) * boot_blocks * 512);
+       mioc = calloc(1, sizeof(struct mmc_ioc_multi_cmd) +
+                          2 * sizeof(struct mmc_ioc_cmd));
+       if (!mioc || !boot_buf) {
+               perror("Failed to allocate memory");
+               ret = -ENOMEM;
+               goto alloced_error;
+       }
+
+       mioc->num_of_cmds = 2;
+       mioc->cmds[0].opcode = MMC_GO_IDLE_STATE;
+       mioc->cmds[0].arg = MMC_GO_PRE_IDLE_STATE_ARG;
+       mioc->cmds[0].flags = MMC_RSP_NONE | MMC_CMD_AC;
+       mioc->cmds[0].write_flag = 0;
+
+       mioc->cmds[1].opcode = MMC_GO_IDLE_STATE;
+       mioc->cmds[1].arg = MMC_BOOT_INITIATION_ARG;
+       mioc->cmds[1].flags = MMC_RSP_NONE | MMC_CMD_ADTC;
+       mioc->cmds[1].write_flag = 0;
+       mioc->cmds[1].blksz = 512;
+       mioc->cmds[1].blocks = boot_blocks;
+       /* Access time of boot part differs wildly, spec mandates 1s */
+       mioc->cmds[1].data_timeout_ns = 2 * 1000 * 1000 * 1000;
+       mmc_ioc_cmd_set_data(mioc->cmds[1], boot_buf);
+
+       ret = ioctl(fd, MMC_IOC_MULTI_CMD, mioc);
+       if (ret) {
+               perror("multi-cmd ioctl error\n");
+               goto alloced_error;
+       }
+
+       ret = DO_IO(write, boot_data_fd, boot_buf, boot_blocks * 512);
+       if (ret < 0) {
+               perror("Write error\n");
+               goto alloced_error;
+       }
+       ret = 0;
+
+alloced_error:
+       if (mioc)
+               free(mioc);
+       if (boot_buf)
+               free(boot_buf);
+boot_data_close:
+       close(boot_data_fd);
+dev_fd_close:
+       close(fd);
+       if (ret)
+               exit(1);
+       return 0;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mmc-utils-0.1+git.20220208/mmc_cmds.h 
new/mmc-utils-0.1+git.20230209/mmc_cmds.h
--- old/mmc-utils-0.1+git.20220208/mmc_cmds.h   2022-02-08 16:15:35.000000000 
+0100
+++ new/mmc-utils-0.1+git.20230209/mmc_cmds.h   2023-02-09 15:16:51.000000000 
+0100
@@ -46,3 +46,7 @@
 int do_read_cid(int argc, char **argv);
 int do_read_csd(int argc, char **argv);
 int do_erase(int nargs, char **argv);
+int do_general_cmd_read(int nargs, char **argv);
+int do_softreset(int nargs, char **argv);
+int do_preidle(int nargs, char **argv);
+int do_alt_boot_op(int nargs, char **argv);

++++++ mmc-utils.obsinfo ++++++
--- /var/tmp/diff_new_pack.UbayAV/_old  2023-03-24 15:21:51.835339328 +0100
+++ /var/tmp/diff_new_pack.UbayAV/_new  2023-03-24 15:21:51.839339349 +0100
@@ -1,5 +1,5 @@
 name: mmc-utils
-version: 0.1+git.20220208
-mtime: 1644333335
-commit: 4637a7c0df49ba349f9f0e4ab0828133fc06cc81
+version: 0.1+git.20230209
+mtime: 1675952211
+commit: d4c2910981ff99b983734426dfa99632fb81ac6b
 

Reply via email to