[U-Boot-Users] [PATCH] Fix use of "void *" for block dev read/write buffer pointers

Greg Lopp lopp at pobox.com
Thu Apr 12 17:28:44 CEST 2007


A couple months ago, a patch was submitted which changed the
prototypes for block_write and block_read in the block_dev_desc_t
structure (include/part.h).  For both, the buffer parameter was
changed from a ulong* to a void*.  Seven functions were changed as a
result of this. Four of those functions take that parameter and pass
it to a local variable of a different type, thereby insulating them
from this change.  The other three were not so lucky.....
Using the 2006-06-16 version of common/cmd_ide.c as the reference,
lets look at ide_read().  The function begins on line 1230 and a while
loop begins on line 1279. At the bottom of this loop, we see
1339                 ++blknr;
1340                 buffer += ATA_SECTORWORDS;
1341         }
Back when buffer was a ulong*, this pointer addition would result in
the pointer moving 0x200 bytes or 0x80 ulongs (ATA_SECTORWORDS is
defined as 512/sizeof(unsigned long) in include/ata.h).  Now that
buffer is a void*, this pointer addition results in the pointer moving
by only 0x80 bytes.
In my debugging, I used the diskboot command to read an image into
address 0x200000 and tftp to place the same image at 0x400000.  When I
compared these two locations, I discovered that the data was different
starting at address 0x200280.  The data at that location was the same
as that found at 0x400400.  Then 0x200300-0x200380 ==
0x400600-0x400680, 0x200380-0x200400 == 0x400800-0x400880 and so on
and so on.
The first 0x200 is correct because that is done in a separate call to
ide_read that only requests a single block. The second read copied
0x200 bytes to 0x200200, the third read is copied 0x200 bytes to
0x200280, etc.
The following patch fixes the pointer manipulation in ide_read(),
ide_write() and atapi_read().

diff -up a/common/cmd_ide.c b/common/cmd_ide.c
--- a/common/cmd_ide.c      2007-04-12 09:12:49.000000000 -0500
+++ b/common/cmd_ide.c    2007-04-12 09:14:40.843750000 -0500
@@ -1344,7 +1344,7 @@ ulong ide_read (int device, lbaint_t blk

                ++n;
                ++blknr;
-               buffer += ATA_SECTORWORDS;
+               buffer += ATA_BLOCKSIZE;
        }
 IDE_READ_E:
        ide_led (DEVICE_LED(device), 0);        /* LED off      */
@@ -1428,7 +1428,7 @@ ulong ide_write (int device, lbaint_t bl
                c = ide_inb (device, ATA_STATUS);       /* clear IRQ */
                ++n;
                ++blknr;
-               buffer += ATA_SECTORWORDS;
+               buffer += ATA_BLOCKSIZE;
        }
 WR_OUT:
        ide_led (DEVICE_LED(device), 0);        /* LED off      */
@@ -2052,7 +2052,7 @@ ulong atapi_read (int device, lbaint_t b
                n+=cnt;
                blkcnt-=cnt;
                blknr+=cnt;
-               buffer+=cnt*(ATAPI_READ_BLOCK_SIZE/4); /* ulong
blocksize in ulong */
+               buffer+=(cnt*ATAPI_READ_BLOCK_SIZE); /* ulong
blocksize in ulong */
        } while (blkcnt > 0);
        return (n);
 }




More information about the U-Boot mailing list