diff mbox series

[v2] mmc: core: Return correct emmc response in case of ioctl error

Message ID 20210808172448.4641-1-nishadkamdar@gmail.com
State New
Headers show
Series [v2] mmc: core: Return correct emmc response in case of ioctl error | expand

Commit Message

Nishad Kamdar Aug. 8, 2021, 5:24 p.m. UTC
When a read/write command is sent via ioctl to the kernel,
and the command fails, the actual error response of the emmc
is not sent to the user.

Following are the tests carried out using commands
17 (Single BLock Read),
24 (Single Block Write),
18 (Multi Block Read),
25 (Multi Block Write)

The tests are carried out on a 64Gb emmc device. All of these
tests try to access an "out of range" sector address (0x09B2FFFF).

It is seen that without the patch the response received by the user
is not OUT_OF_RANGE error (R1 response 31st bit is not set) as per
JEDEC specification. After applying the patch proper response is seen.

The user level ioctl testcode for the above commands and their
respective outputs without and with the patch are shown below:

CMD17 (Test Code Snippet):

Comments

Avri Altman Aug. 9, 2021, 8:41 a.m. UTC | #1
> When a read/write command is sent via ioctl to the kernel,

> and the command fails, the actual error response of the emmc

> is not sent to the user.

> 

> Following are the tests carried out using commands

> 17 (Single BLock Read),

> 24 (Single Block Write),

> 18 (Multi Block Read),

> 25 (Multi Block Write)

> 

> The tests are carried out on a 64Gb emmc device. All of these

> tests try to access an "out of range" sector address (0x09B2FFFF).

> 

> It is seen that without the patch the response received by the user

> is not OUT_OF_RANGE error (R1 response 31st bit is not set) as per

> JEDEC specification. After applying the patch proper response is seen.

> 

> The user level ioctl testcode for the above commands and their

> respective outputs without and with the patch are shown below:

> 

> CMD17 (Test Code Snippet):

> ==========================

>         printf("Forming CMD%d\n", opt_idx);

>         /*  single block read */

>         cmd.blksz = 512;

>         cmd.blocks = 1;

>         cmd.write_flag = 0;

>         cmd.opcode = 17;

>         //cmd.arg = atoi(argv[3]);

>         cmd.arg = 0x09B2FFFF;

>         /* Expecting response R1B */

>         cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;

> 

>         memset(data, 0, sizeof(__u8) * 512);

>         mmc_ioc_cmd_set_data(cmd, data);

> 

>         printf("Sending CMD%d: ARG[0x%08x]\n", opt_idx, cmd.arg);

>         if(ioctl(fd, MMC_IOC_CMD, &cmd))

>                 perror("Error");

> 

>         printf("\nResponse: %08x\n", cmd.response[0]);

> 

> CMD17 (Output without patch):

> =============================

> test@test-LIVA-Z:~$ sudo ./mmc cmd_test /dev/mmcblk0 17 09B2FFFF

No need for arg 3 - you are hardcoded overriding it.

> Entering the do_mmc_commands:Device: /dev/mmcblk0 nargs:4

> Entering the do_mmc_commands:Device: /dev/mmcblk0 options[17,

> 0x09B2FFF]

> Forming CMD17

> Sending CMD17: ARG[0x09b2ffff]

> Error: Connection timed out

> 

> Response: 00000000  (Wrong response)

> 

> CMD17 (Output with patch):

> ==========================

> test@test-LIVA-Z:~$ sudo ./mmc cmd_test /dev/mmcblk0 17 09B2FFFF

> [sudo] password for test:

> Entering the do_mmc_commands:Device: /dev/mmcblk0 nargs:4

> Entering the do_mmc_commands:Device: /dev/mmcblk0 options[17, 09B2FFFF]

> Forming CMD17

> Sending CMD17: ARG[0x09b2ffff]

> Error: Connection timed out

> 

> Response: 80000900

> (Correct OUT_OF_ERROR response as per JEDEC specification)



> 

> CMD24 (Test Code Snippet):

> ==========================

>         printf("Forming CMD%d\n", opt_idx);

>         cmd.opcode = 24;

>         //cmd.arg = atoi(argv[3]);

>         cmd.arg = 0x09B2FFFF;

>         cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;

>         cmd.blksz = 512;

>         cmd.blocks = 1;

>         cmd.write_flag = 1;

> 

>         memset(data, 0xA5, sizeof(__u8) * 512);

>         mmc_ioc_cmd_set_data(cmd, data);

> 

>         printf("Sending CMD%d: ARG[0x%08x]\n", opt_idx, cmd.arg);

>         if(ioctl(fd, MMC_IOC_CMD, &cmd))

>                 perror("Error");

> 

>         printf("\nResponse: %08x\n", cmd.response[0]);

> 

> CMD24 (Output without patch):

> =============================

> test@test-LIVA-Z:~$ sudo ./mmc cmd_test /dev/mmcblk0 24 0x09B2FFF

> [sudo] password for test:

> Entering the do_mmc_commands:Device: /dev/mmcblk0 nargs:4

> Entering the do_mmc_commands:Device: /dev/mmcblk0 options[24,

> 0x09B2FFF]

> Forming CMD24

> Sending CMD24: ARG[0x09b2ffff]

> Error: Connection timed out

> 

> Response: 00000000 (Incorrect response)

> 

> CMD24 (Output with patch):

> ==========================

> test@test-LIVA-Z:~$ sudo ./mmc cmd_test /dev/mmcblk0 24 09B2FFFF

> Entering the do_mmc_commands:Device: /dev/mmcblk0 nargs:4

> Entering the do_mmc_commands:Device: /dev/mmcblk0 options[24, 09B2FFFF]

> Forming CMD24

> Sending CMD24: ARG[0x09b2ffff]

> Error: Connection timed out

> 

> Response: 80000900

> (Correct OUT_OF_RANGE response as per JEDEC specification)

> 

> CMD18 (Test Code Snippet):

> ==========================

>         printf("Forming CMD%d\n", opt_idx);

> 

>         cmd.blksz = 512;

>         cmd.blocks = 1;

>         cmd.write_flag = 0;

>         cmd.opcode = 18;

>         //cmd.arg = atoi(argv[3]);

>         cmd.arg = 0x09B2FFFF;

> 

>         cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;

> 

>         memset(data, 0, sizeof(__u8) * 512);

>         mmc_ioc_cmd_set_data(cmd, data);

> 

>         printf("Sending CMD%d: ARG[0x%08x]\n", opt_idx, cmd.arg);

>         if(ioctl(fd, MMC_IOC_CMD, &cmd)) {

>                 printf(" error ioctl \n");

>                 perror("Error");

>         }

> 

>         printf("\nResponse: %08x\n", cmd.response[0]);

> 

> CMD18 (Output without patch):

> =============================

> test@test-LIVA-Z:~$ sudo ./mmc cmd_test /dev/mmcblk0 18 0x09B2FFF

> Entering the do_mmc_commands:Device: /dev/mmcblk0 nargs:4

> Entering the do_mmc_commands:Device: /dev/mmcblk0 options[18,

> 0x09B2FFF]

> Forming CMD18

> Sending CMD18: ARG[0x09b2ffff]

>  error ioctl

> Error: Connection timed out

> 

> Response: 00000000 (Incorrect response)

> 

> CMD18 (Output with patch):

> ==========================

> test@test-LIVA-Z:~$ sudo ./mmc cmd_test /dev/mmcblk0 18 09B2FFFF

> Entering the do_mmc_commands:Device: /dev/mmcblk0 nargs:4

> Entering the do_mmc_commands:Device: /dev/mmcblk0 options[18, 09B2FFFF]

> Forming CMD18

> Sending CMD18: ARG[0x09b2ffff]

>  error ioctl

> Error: Connection timed out

> 

> Response: 80000900

> (Correct OUT_OF_RANGE response as per JEDEC specification)

> 

> CMD25 (Test Code Snippet):

> ==========================

>         printf("Forming CMD%d\n", opt_idx);

>         cmd.opcode = 25;

>         //cmd.arg = atoi(argv[3]);

>         cmd.arg = 0x09B2FFFF;

>         cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;

> 

>         cmd.blksz = 512;

>         cmd.blocks = 1;

>         cmd.write_flag = 1;

> 

>         memset(data, 0xA5, sizeof(__u8) * 512);

>         mmc_ioc_cmd_set_data(cmd, data);

> 

>         printf("Sending CMD%d: ARG[0x%08x]\n", opt_idx, cmd.arg);

>         if(ioctl(fd, MMC_IOC_CMD, &cmd)) {

>                 printf("\nerror ioctl\n");

>                 perror("Error");

>         }

> 

>         printf("\nResponse: %08x\n", cmd.response[0]);

> 

> CMD25 (Output without patch):

> =============================

> test@test-LIVA-Z:~$ sudo ./mmc cmd_test /dev/mmcblk0 25 0x09B2FFF

> Entering the do_mmc_commands:Device: /dev/mmcblk0 nargs:4

> Entering the do_mmc_commands:Device: /dev/mmcblk0 options[25,

> 0x09B2FFF]

> Forming CMD25

> Sending CMD25: ARG[0x09b2ffff]

> 

> error ioctl

> Error: Connection timed out

> 

> Response: 00000000 (Incorrect response)

> 

> CMD25 (Output with patch):

> ==========================

> test@test-LIVA-Z:~$ sudo ./mmc cmd_test /dev/mmcblk0 25 09B2FFFF

> Entering the do_mmc_commands:Device: /dev/mmcblk0 nargs:4

> Entering the do_mmc_commands:Device: /dev/mmcblk0 options[25, 09B2FFFF]

> Forming CMD25

> Sending CMD25: ARG[0x09b2ffff]

> 

> error ioctl

> Error: Connection timed out

> 

> Response: 80000900

> (Correct OUT_OF_RANGE response as per JEDEC specification)

> 

> Signed-off-by: Nishad Kamdar <nishadkamdar@gmail.com>

Reviewed-by: Avri Altman <avri.altman@wdc.com>


> ---

> Changes in v2:

>   - Make commit message clearer by adding test cases as outputs

A little overwhelming IMO

> 

>  drivers/mmc/core/block.c | 2 ++

>  1 file changed, 2 insertions(+)

> 

> diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c

> index a9ad9f5fa9491..efa92aa7e2368 100644

> --- a/drivers/mmc/core/block.c

> +++ b/drivers/mmc/core/block.c

> @@ -522,11 +522,13 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card

> *card, struct mmc_blk_data *md,

>         if (cmd.error) {

>                 dev_err(mmc_dev(card->host), "%s: cmd error %d\n",

>                                                 __func__, cmd.error);

> +               memcpy(&idata->ic.response, cmd.resp, sizeof(cmd.resp));

>                 return cmd.error;

>         }

>         if (data.error) {

>                 dev_err(mmc_dev(card->host), "%s: data error %d\n",

>                                                 __func__, data.error);

> +               memcpy(&idata->ic.response, cmd.resp, sizeof(cmd.resp));

>                 return data.error;

>         }

> 

> --

> 2.17.1
Nishad Kamdar Aug. 25, 2021, 5:36 a.m. UTC | #2
On Mon, Aug 09, 2021 at 08:41:19AM +0000, Avri Altman wrote:
> > When a read/write command is sent via ioctl to the kernel,

> > and the command fails, the actual error response of the emmc

> > is not sent to the user.

> > 

> > Following are the tests carried out using commands

> > 17 (Single BLock Read),

> > 24 (Single Block Write),

> > 18 (Multi Block Read),

> > 25 (Multi Block Write)

> > 

> > The tests are carried out on a 64Gb emmc device. All of these

> > tests try to access an "out of range" sector address (0x09B2FFFF).

> > 

> > It is seen that without the patch the response received by the user

> > is not OUT_OF_RANGE error (R1 response 31st bit is not set) as per

> > JEDEC specification. After applying the patch proper response is seen.

> > 

> > The user level ioctl testcode for the above commands and their

> > respective outputs without and with the patch are shown below:

> > 

> > CMD17 (Test Code Snippet):

> > ==========================

> >         printf("Forming CMD%d\n", opt_idx);

> >         /*  single block read */

> >         cmd.blksz = 512;

> >         cmd.blocks = 1;

> >         cmd.write_flag = 0;

> >         cmd.opcode = 17;

> >         //cmd.arg = atoi(argv[3]);

> >         cmd.arg = 0x09B2FFFF;

> >         /* Expecting response R1B */

> >         cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;

> > 

> >         memset(data, 0, sizeof(__u8) * 512);

> >         mmc_ioc_cmd_set_data(cmd, data);

> > 

> >         printf("Sending CMD%d: ARG[0x%08x]\n", opt_idx, cmd.arg);

> >         if(ioctl(fd, MMC_IOC_CMD, &cmd))

> >                 perror("Error");

> > 

> >         printf("\nResponse: %08x\n", cmd.response[0]);

> > 

> > CMD17 (Output without patch):

> > =============================

> > test@test-LIVA-Z:~$ sudo ./mmc cmd_test /dev/mmcblk0 17 09B2FFFF

> No need for arg 3 - you are hardcoded overriding it.

> 

> > Entering the do_mmc_commands:Device: /dev/mmcblk0 nargs:4

> > Entering the do_mmc_commands:Device: /dev/mmcblk0 options[17,

> > 0x09B2FFF]

> > Forming CMD17

> > Sending CMD17: ARG[0x09b2ffff]

> > Error: Connection timed out

> > 

> > Response: 00000000  (Wrong response)

> > 

> > CMD17 (Output with patch):

> > ==========================

> > test@test-LIVA-Z:~$ sudo ./mmc cmd_test /dev/mmcblk0 17 09B2FFFF

> > [sudo] password for test:

> > Entering the do_mmc_commands:Device: /dev/mmcblk0 nargs:4

> > Entering the do_mmc_commands:Device: /dev/mmcblk0 options[17, 09B2FFFF]

> > Forming CMD17

> > Sending CMD17: ARG[0x09b2ffff]

> > Error: Connection timed out

> > 

> > Response: 80000900

> > (Correct OUT_OF_ERROR response as per JEDEC specification)

> 

> 

> > 

> > CMD24 (Test Code Snippet):

> > ==========================

> >         printf("Forming CMD%d\n", opt_idx);

> >         cmd.opcode = 24;

> >         //cmd.arg = atoi(argv[3]);

> >         cmd.arg = 0x09B2FFFF;

> >         cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;

> >         cmd.blksz = 512;

> >         cmd.blocks = 1;

> >         cmd.write_flag = 1;

> > 

> >         memset(data, 0xA5, sizeof(__u8) * 512);

> >         mmc_ioc_cmd_set_data(cmd, data);

> > 

> >         printf("Sending CMD%d: ARG[0x%08x]\n", opt_idx, cmd.arg);

> >         if(ioctl(fd, MMC_IOC_CMD, &cmd))

> >                 perror("Error");

> > 

> >         printf("\nResponse: %08x\n", cmd.response[0]);

> > 

> > CMD24 (Output without patch):

> > =============================

> > test@test-LIVA-Z:~$ sudo ./mmc cmd_test /dev/mmcblk0 24 0x09B2FFF

> > [sudo] password for test:

> > Entering the do_mmc_commands:Device: /dev/mmcblk0 nargs:4

> > Entering the do_mmc_commands:Device: /dev/mmcblk0 options[24,

> > 0x09B2FFF]

> > Forming CMD24

> > Sending CMD24: ARG[0x09b2ffff]

> > Error: Connection timed out

> > 

> > Response: 00000000 (Incorrect response)

> > 

> > CMD24 (Output with patch):

> > ==========================

> > test@test-LIVA-Z:~$ sudo ./mmc cmd_test /dev/mmcblk0 24 09B2FFFF

> > Entering the do_mmc_commands:Device: /dev/mmcblk0 nargs:4

> > Entering the do_mmc_commands:Device: /dev/mmcblk0 options[24, 09B2FFFF]

> > Forming CMD24

> > Sending CMD24: ARG[0x09b2ffff]

> > Error: Connection timed out

> > 

> > Response: 80000900

> > (Correct OUT_OF_RANGE response as per JEDEC specification)

> > 

> > CMD18 (Test Code Snippet):

> > ==========================

> >         printf("Forming CMD%d\n", opt_idx);

> > 

> >         cmd.blksz = 512;

> >         cmd.blocks = 1;

> >         cmd.write_flag = 0;

> >         cmd.opcode = 18;

> >         //cmd.arg = atoi(argv[3]);

> >         cmd.arg = 0x09B2FFFF;

> > 

> >         cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;

> > 

> >         memset(data, 0, sizeof(__u8) * 512);

> >         mmc_ioc_cmd_set_data(cmd, data);

> > 

> >         printf("Sending CMD%d: ARG[0x%08x]\n", opt_idx, cmd.arg);

> >         if(ioctl(fd, MMC_IOC_CMD, &cmd)) {

> >                 printf(" error ioctl \n");

> >                 perror("Error");

> >         }

> > 

> >         printf("\nResponse: %08x\n", cmd.response[0]);

> > 

> > CMD18 (Output without patch):

> > =============================

> > test@test-LIVA-Z:~$ sudo ./mmc cmd_test /dev/mmcblk0 18 0x09B2FFF

> > Entering the do_mmc_commands:Device: /dev/mmcblk0 nargs:4

> > Entering the do_mmc_commands:Device: /dev/mmcblk0 options[18,

> > 0x09B2FFF]

> > Forming CMD18

> > Sending CMD18: ARG[0x09b2ffff]

> >  error ioctl

> > Error: Connection timed out

> > 

> > Response: 00000000 (Incorrect response)

> > 

> > CMD18 (Output with patch):

> > ==========================

> > test@test-LIVA-Z:~$ sudo ./mmc cmd_test /dev/mmcblk0 18 09B2FFFF

> > Entering the do_mmc_commands:Device: /dev/mmcblk0 nargs:4

> > Entering the do_mmc_commands:Device: /dev/mmcblk0 options[18, 09B2FFFF]

> > Forming CMD18

> > Sending CMD18: ARG[0x09b2ffff]

> >  error ioctl

> > Error: Connection timed out

> > 

> > Response: 80000900

> > (Correct OUT_OF_RANGE response as per JEDEC specification)

> > 

> > CMD25 (Test Code Snippet):

> > ==========================

> >         printf("Forming CMD%d\n", opt_idx);

> >         cmd.opcode = 25;

> >         //cmd.arg = atoi(argv[3]);

> >         cmd.arg = 0x09B2FFFF;

> >         cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;

> > 

> >         cmd.blksz = 512;

> >         cmd.blocks = 1;

> >         cmd.write_flag = 1;

> > 

> >         memset(data, 0xA5, sizeof(__u8) * 512);

> >         mmc_ioc_cmd_set_data(cmd, data);

> > 

> >         printf("Sending CMD%d: ARG[0x%08x]\n", opt_idx, cmd.arg);

> >         if(ioctl(fd, MMC_IOC_CMD, &cmd)) {

> >                 printf("\nerror ioctl\n");

> >                 perror("Error");

> >         }

> > 

> >         printf("\nResponse: %08x\n", cmd.response[0]);

> > 

> > CMD25 (Output without patch):

> > =============================

> > test@test-LIVA-Z:~$ sudo ./mmc cmd_test /dev/mmcblk0 25 0x09B2FFF

> > Entering the do_mmc_commands:Device: /dev/mmcblk0 nargs:4

> > Entering the do_mmc_commands:Device: /dev/mmcblk0 options[25,

> > 0x09B2FFF]

> > Forming CMD25

> > Sending CMD25: ARG[0x09b2ffff]

> > 

> > error ioctl

> > Error: Connection timed out

> > 

> > Response: 00000000 (Incorrect response)

> > 

> > CMD25 (Output with patch):

> > ==========================

> > test@test-LIVA-Z:~$ sudo ./mmc cmd_test /dev/mmcblk0 25 09B2FFFF

> > Entering the do_mmc_commands:Device: /dev/mmcblk0 nargs:4

> > Entering the do_mmc_commands:Device: /dev/mmcblk0 options[25, 09B2FFFF]

> > Forming CMD25

> > Sending CMD25: ARG[0x09b2ffff]

> > 

> > error ioctl

> > Error: Connection timed out

> > 

> > Response: 80000900

> > (Correct OUT_OF_RANGE response as per JEDEC specification)

> > 

> > Signed-off-by: Nishad Kamdar <nishadkamdar@gmail.com>

> Reviewed-by: Avri Altman <avri.altman@wdc.com>

> 

> > ---

> > Changes in v2:

> >   - Make commit message clearer by adding test cases as outputs

> A little overwhelming IMO

> 

Ok, Thanks for the review and comments.

Regards,
Nishad
> > 

> >  drivers/mmc/core/block.c | 2 ++

> >  1 file changed, 2 insertions(+)

> > 

> > diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c

> > index a9ad9f5fa9491..efa92aa7e2368 100644

> > --- a/drivers/mmc/core/block.c

> > +++ b/drivers/mmc/core/block.c

> > @@ -522,11 +522,13 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card

> > *card, struct mmc_blk_data *md,

> >         if (cmd.error) {

> >                 dev_err(mmc_dev(card->host), "%s: cmd error %d\n",

> >                                                 __func__, cmd.error);

> > +               memcpy(&idata->ic.response, cmd.resp, sizeof(cmd.resp));

> >                 return cmd.error;

> >         }

> >         if (data.error) {

> >                 dev_err(mmc_dev(card->host), "%s: data error %d\n",

> >                                                 __func__, data.error);

> > +               memcpy(&idata->ic.response, cmd.resp, sizeof(cmd.resp));

> >                 return data.error;

> >         }

> > 

> > --

> > 2.17.1

>
diff mbox series

Patch

==========================
        printf("Forming CMD%d\n", opt_idx);
        /*  single block read */
        cmd.blksz = 512;
        cmd.blocks = 1;
        cmd.write_flag = 0;
        cmd.opcode = 17;
        //cmd.arg = atoi(argv[3]);
        cmd.arg = 0x09B2FFFF;
        /* Expecting response R1B */
        cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;

        memset(data, 0, sizeof(__u8) * 512);
        mmc_ioc_cmd_set_data(cmd, data);

        printf("Sending CMD%d: ARG[0x%08x]\n", opt_idx, cmd.arg);
        if(ioctl(fd, MMC_IOC_CMD, &cmd))
                perror("Error");

        printf("\nResponse: %08x\n", cmd.response[0]);

CMD17 (Output without patch):
=============================
test@test-LIVA-Z:~$ sudo ./mmc cmd_test /dev/mmcblk0 17 09B2FFFF
Entering the do_mmc_commands:Device: /dev/mmcblk0 nargs:4
Entering the do_mmc_commands:Device: /dev/mmcblk0 options[17, 0x09B2FFF]
Forming CMD17
Sending CMD17: ARG[0x09b2ffff]
Error: Connection timed out

Response: 00000000  (Wrong response)

CMD17 (Output with patch):
==========================
test@test-LIVA-Z:~$ sudo ./mmc cmd_test /dev/mmcblk0 17 09B2FFFF
[sudo] password for test:
Entering the do_mmc_commands:Device: /dev/mmcblk0 nargs:4
Entering the do_mmc_commands:Device: /dev/mmcblk0 options[17, 09B2FFFF]
Forming CMD17
Sending CMD17: ARG[0x09b2ffff]
Error: Connection timed out

Response: 80000900
(Correct OUT_OF_ERROR response as per JEDEC specification)

CMD24 (Test Code Snippet):
==========================
        printf("Forming CMD%d\n", opt_idx);
        cmd.opcode = 24;
        //cmd.arg = atoi(argv[3]);
        cmd.arg = 0x09B2FFFF;
        cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
        cmd.blksz = 512;
        cmd.blocks = 1;
        cmd.write_flag = 1;

        memset(data, 0xA5, sizeof(__u8) * 512);
        mmc_ioc_cmd_set_data(cmd, data);

        printf("Sending CMD%d: ARG[0x%08x]\n", opt_idx, cmd.arg);
        if(ioctl(fd, MMC_IOC_CMD, &cmd))
                perror("Error");

        printf("\nResponse: %08x\n", cmd.response[0]);

CMD24 (Output without patch):
=============================
test@test-LIVA-Z:~$ sudo ./mmc cmd_test /dev/mmcblk0 24 0x09B2FFF
[sudo] password for test:
Entering the do_mmc_commands:Device: /dev/mmcblk0 nargs:4
Entering the do_mmc_commands:Device: /dev/mmcblk0 options[24, 0x09B2FFF]
Forming CMD24
Sending CMD24: ARG[0x09b2ffff]
Error: Connection timed out

Response: 00000000 (Incorrect response)

CMD24 (Output with patch):
==========================
test@test-LIVA-Z:~$ sudo ./mmc cmd_test /dev/mmcblk0 24 09B2FFFF
Entering the do_mmc_commands:Device: /dev/mmcblk0 nargs:4
Entering the do_mmc_commands:Device: /dev/mmcblk0 options[24, 09B2FFFF]
Forming CMD24
Sending CMD24: ARG[0x09b2ffff]
Error: Connection timed out

Response: 80000900
(Correct OUT_OF_RANGE response as per JEDEC specification)

CMD18 (Test Code Snippet):
==========================
        printf("Forming CMD%d\n", opt_idx);

        cmd.blksz = 512;
        cmd.blocks = 1;
        cmd.write_flag = 0;
        cmd.opcode = 18;
        //cmd.arg = atoi(argv[3]);
        cmd.arg = 0x09B2FFFF;

        cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;

        memset(data, 0, sizeof(__u8) * 512);
        mmc_ioc_cmd_set_data(cmd, data);

        printf("Sending CMD%d: ARG[0x%08x]\n", opt_idx, cmd.arg);
        if(ioctl(fd, MMC_IOC_CMD, &cmd)) {
                printf(" error ioctl \n");
                perror("Error");
        }

        printf("\nResponse: %08x\n", cmd.response[0]);

CMD18 (Output without patch):
=============================
test@test-LIVA-Z:~$ sudo ./mmc cmd_test /dev/mmcblk0 18 0x09B2FFF
Entering the do_mmc_commands:Device: /dev/mmcblk0 nargs:4
Entering the do_mmc_commands:Device: /dev/mmcblk0 options[18, 0x09B2FFF]
Forming CMD18
Sending CMD18: ARG[0x09b2ffff]
 error ioctl
Error: Connection timed out

Response: 00000000 (Incorrect response)

CMD18 (Output with patch):
==========================
test@test-LIVA-Z:~$ sudo ./mmc cmd_test /dev/mmcblk0 18 09B2FFFF
Entering the do_mmc_commands:Device: /dev/mmcblk0 nargs:4
Entering the do_mmc_commands:Device: /dev/mmcblk0 options[18, 09B2FFFF]
Forming CMD18
Sending CMD18: ARG[0x09b2ffff]
 error ioctl
Error: Connection timed out

Response: 80000900
(Correct OUT_OF_RANGE response as per JEDEC specification)

CMD25 (Test Code Snippet):
==========================
        printf("Forming CMD%d\n", opt_idx);
        cmd.opcode = 25;
        //cmd.arg = atoi(argv[3]);
        cmd.arg = 0x09B2FFFF;
        cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;

        cmd.blksz = 512;
        cmd.blocks = 1;
        cmd.write_flag = 1;

        memset(data, 0xA5, sizeof(__u8) * 512);
        mmc_ioc_cmd_set_data(cmd, data);

        printf("Sending CMD%d: ARG[0x%08x]\n", opt_idx, cmd.arg);
        if(ioctl(fd, MMC_IOC_CMD, &cmd)) {
                printf("\nerror ioctl\n");
                perror("Error");
        }

        printf("\nResponse: %08x\n", cmd.response[0]);

CMD25 (Output without patch):
=============================
test@test-LIVA-Z:~$ sudo ./mmc cmd_test /dev/mmcblk0 25 0x09B2FFF
Entering the do_mmc_commands:Device: /dev/mmcblk0 nargs:4
Entering the do_mmc_commands:Device: /dev/mmcblk0 options[25, 0x09B2FFF]
Forming CMD25
Sending CMD25: ARG[0x09b2ffff]

error ioctl
Error: Connection timed out

Response: 00000000 (Incorrect response)

CMD25 (Output with patch):
==========================
test@test-LIVA-Z:~$ sudo ./mmc cmd_test /dev/mmcblk0 25 09B2FFFF
Entering the do_mmc_commands:Device: /dev/mmcblk0 nargs:4
Entering the do_mmc_commands:Device: /dev/mmcblk0 options[25, 09B2FFFF]
Forming CMD25
Sending CMD25: ARG[0x09b2ffff]

error ioctl
Error: Connection timed out

Response: 80000900
(Correct OUT_OF_RANGE response as per JEDEC specification)

Signed-off-by: Nishad Kamdar <nishadkamdar@gmail.com>
---
Changes in v2:
  - Make commit message clearer by adding test cases as outputs

 drivers/mmc/core/block.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index a9ad9f5fa9491..efa92aa7e2368 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -522,11 +522,13 @@  static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
 	if (cmd.error) {
 		dev_err(mmc_dev(card->host), "%s: cmd error %d\n",
 						__func__, cmd.error);
+		memcpy(&idata->ic.response, cmd.resp, sizeof(cmd.resp));
 		return cmd.error;
 	}
 	if (data.error) {
 		dev_err(mmc_dev(card->host), "%s: data error %d\n",
 						__func__, data.error);
+		memcpy(&idata->ic.response, cmd.resp, sizeof(cmd.resp));
 		return data.error;
 	}