From mboxrd@z Thu Jan  1 00:00:00 1970
Received: from eggs.gnu.org ([140.186.70.92]:40326)
	by lists.gnu.org with esmtp (Exim 4.71)
	(envelope-from <david.gilbert@linaro.org>) id 1QlKAD-0004ZC-9I
	for qemu-devel@nongnu.org; Mon, 25 Jul 2011 08:21:38 -0400
Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71)
	(envelope-from <david.gilbert@linaro.org>) id 1QlKAC-000702-4j
	for qemu-devel@nongnu.org; Mon, 25 Jul 2011 08:21:37 -0400
Received: from mtagate2.uk.ibm.com ([194.196.100.162]:32818)
	by eggs.gnu.org with esmtp (Exim 4.71)
	(envelope-from <david.gilbert@linaro.org>) id 1QlKAB-0006zU-Pt
	for qemu-devel@nongnu.org; Mon, 25 Jul 2011 08:21:36 -0400
Received: from d06nrmr1507.portsmouth.uk.ibm.com
	(d06nrmr1507.portsmouth.uk.ibm.com [9.149.38.233])
	by mtagate2.uk.ibm.com (8.13.1/8.13.1) with ESMTP id p6PCLXe9020638
	for <qemu-devel@nongnu.org>; Mon, 25 Jul 2011 12:21:33 GMT
Received: from d06av12.portsmouth.uk.ibm.com (d06av12.portsmouth.uk.ibm.com
	[9.149.37.247])
	by d06nrmr1507.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with
	ESMTP id p6PCLX4P2654306
	for <qemu-devel@nongnu.org>; Mon, 25 Jul 2011 13:21:33 +0100
Received: from d06av12.portsmouth.uk.ibm.com (loopback [127.0.0.1])
	by d06av12.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with
	ESMTP id p6PCLWew000987
	for <qemu-devel@nongnu.org>; Mon, 25 Jul 2011 06:21:33 -0600
Date: Mon, 25 Jul 2011 13:21:30 +0100
From: "Dr. David Alan Gilbert" <david.gilbert@linaro.org>
Message-ID: <20110725122130.GA5297@davesworkthinkpad>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Subject: [Qemu-devel] [PATCH] Fix last sector write on sd card
List-Id: <qemu-devel.nongnu.org>
List-Unsubscribe: <https://lists.nongnu.org/mailman/options/qemu-devel>,
	<mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>
List-Archive: <http://lists.nongnu.org/archive/html/qemu-devel>
List-Post: <mailto:qemu-devel@nongnu.org>
List-Help: <mailto:qemu-devel-request@nongnu.org?subject=help>
List-Subscribe: <https://lists.nongnu.org/mailman/listinfo/qemu-devel>,
	<mailto:qemu-devel-request@nongnu.org?subject=subscribe>
To: qemu-devel@nongnu.org
Cc: patches@linaro.org

    When writing the last sector of an SD card using WRITE_MULTIPLE_BLOCK
QEmu throws an error saying that we've run off the end, and leaves
itself in the wrong state.

    Tested on ARM Vexpress model.

Signed-off-by: Dr. David Alan Gilbert <david.gilbert@linaro.org>

---
Don't throw address error on last block, and leave in correct state.

diff --git a/hw/sd.c b/hw/sd.c
index cedfb20..219a0dd 100644
--- a/hw/sd.c
+++ b/hw/sd.c
@@ -1450,14 +1450,8 @@ void sd_write_data(SDState *sd, uint8_t value)
         break;
 
     case 25:	/* CMD25:  WRITE_MULTIPLE_BLOCK */
-        sd->data[sd->data_offset ++] = value;
-        if (sd->data_offset >= sd->blk_len) {
-            /* TODO: Check CRC before committing */
-            sd->state = sd_programming_state;
-            BLK_WRITE_BLOCK(sd->data_start, sd->data_offset);
-            sd->blk_written ++;
-            sd->data_start += sd->blk_len;
-            sd->data_offset = 0;
+        if (sd->data_offset == 0) {
+            /* Start of the block - lets check the address is valid */
             if (sd->data_start + sd->blk_len > sd->size) {
                 sd->card_status |= ADDRESS_ERROR;
                 break;
@@ -1466,6 +1460,15 @@ void sd_write_data(SDState *sd, uint8_t value)
                 sd->card_status |= WP_VIOLATION;
                 break;
             }
+        }
+        sd->data[sd->data_offset++] = value;
+        if (sd->data_offset >= sd->blk_len) {
+            /* TODO: Check CRC before committing */
+            sd->state = sd_programming_state;
+            BLK_WRITE_BLOCK(sd->data_start, sd->data_offset);
+            sd->blk_written++;
+            sd->data_start += sd->blk_len;
+            sd->data_offset = 0;
             sd->csd[14] |= 0x40;
 
             /* Bzzzzzzztt .... Operation complete.  */

From mboxrd@z Thu Jan  1 00:00:00 1970
Received: from eggs.gnu.org ([140.186.70.92]:47158)
	by lists.gnu.org with esmtp (Exim 4.71)
	(envelope-from <anthony@codemonkey.ws>) id 1QmoB7-0002SS-6X
	for qemu-devel@nongnu.org; Fri, 29 Jul 2011 10:36:41 -0400
Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71)
	(envelope-from <anthony@codemonkey.ws>) id 1QmoB6-0006Qg-0y
	for qemu-devel@nongnu.org; Fri, 29 Jul 2011 10:36:41 -0400
Received: from mail-gx0-f173.google.com ([209.85.161.173]:42103)
	by eggs.gnu.org with esmtp (Exim 4.71)
	(envelope-from <anthony@codemonkey.ws>) id 1QmoB5-0006QO-U4
	for qemu-devel@nongnu.org; Fri, 29 Jul 2011 10:36:39 -0400
Received: by gxk26 with SMTP id 26so3068255gxk.4
	for <qemu-devel@nongnu.org>; Fri, 29 Jul 2011 07:36:39 -0700 (PDT)
Message-ID: <4E32C574.10802@codemonkey.ws>
Date: Fri, 29 Jul 2011 09:36:36 -0500
From: Anthony Liguori <anthony@codemonkey.ws>
MIME-Version: 1.0
References: <20110725122130.GA5297@davesworkthinkpad>
In-Reply-To: <20110725122130.GA5297@davesworkthinkpad>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Subject: Re: [Qemu-devel] [PATCH] Fix last sector write on sd card
List-Id: <qemu-devel.nongnu.org>
List-Unsubscribe: <https://lists.nongnu.org/mailman/options/qemu-devel>,
	<mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>
List-Archive: <http://lists.nongnu.org/archive/html/qemu-devel>
List-Post: <mailto:qemu-devel@nongnu.org>
List-Help: <mailto:qemu-devel-request@nongnu.org?subject=help>
List-Subscribe: <https://lists.nongnu.org/mailman/listinfo/qemu-devel>,
	<mailto:qemu-devel-request@nongnu.org?subject=subscribe>
To: "Dr. David Alan Gilbert" <david.gilbert@linaro.org>
Cc: qemu-devel@nongnu.org, patches@linaro.org

On 07/25/2011 07:21 AM, Dr. David Alan Gilbert wrote:
>      When writing the last sector of an SD card using WRITE_MULTIPLE_BLOCK
> QEmu throws an error saying that we've run off the end, and leaves
> itself in the wrong state.
>
>      Tested on ARM Vexpress model.
>
> Signed-off-by: Dr. David Alan Gilbert<david.gilbert@linaro.org>

Applied.  Thanks.

Regards,

Anthony Liguori

>
> ---
> Don't throw address error on last block, and leave in correct state.
>
> diff --git a/hw/sd.c b/hw/sd.c
> index cedfb20..219a0dd 100644
> --- a/hw/sd.c
> +++ b/hw/sd.c
> @@ -1450,14 +1450,8 @@ void sd_write_data(SDState *sd, uint8_t value)
>           break;
>
>       case 25:	/* CMD25:  WRITE_MULTIPLE_BLOCK */
> -        sd->data[sd->data_offset ++] = value;
> -        if (sd->data_offset>= sd->blk_len) {
> -            /* TODO: Check CRC before committing */
> -            sd->state = sd_programming_state;
> -            BLK_WRITE_BLOCK(sd->data_start, sd->data_offset);
> -            sd->blk_written ++;
> -            sd->data_start += sd->blk_len;
> -            sd->data_offset = 0;
> +        if (sd->data_offset == 0) {
> +            /* Start of the block - lets check the address is valid */
>               if (sd->data_start + sd->blk_len>  sd->size) {
>                   sd->card_status |= ADDRESS_ERROR;
>                   break;
> @@ -1466,6 +1460,15 @@ void sd_write_data(SDState *sd, uint8_t value)
>                   sd->card_status |= WP_VIOLATION;
>                   break;
>               }
> +        }
> +        sd->data[sd->data_offset++] = value;
> +        if (sd->data_offset>= sd->blk_len) {
> +            /* TODO: Check CRC before committing */
> +            sd->state = sd_programming_state;
> +            BLK_WRITE_BLOCK(sd->data_start, sd->data_offset);
> +            sd->blk_written++;
> +            sd->data_start += sd->blk_len;
> +            sd->data_offset = 0;
>               sd->csd[14] |= 0x40;
>
>               /* Bzzzzzzztt .... Operation complete.  */
>
>

