[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