1
0
Fork 0

FAT: get_cluster: Add buffer bouncing

Add a buffer bouncing mechanism to get_cluster.  This can be useful
for misaligned applicative buffers passed through get_contents.
This is required for the following patches in the case of data
aligned differently relatively to buffers and clusters.

Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
Cc: Wolfgang Denk <wd@denx.de>
utp
Benoît Thébaudeau 2012-07-20 15:21:08 +02:00 committed by Wolfgang Denk
parent cd1b042c5c
commit cc63b25efb
1 changed files with 30 additions and 12 deletions

View File

@ -273,7 +273,6 @@ get_cluster(fsdata *mydata, __u32 clustnum, __u8 *buffer, unsigned long size)
{
__u32 idx = 0;
__u32 startsect;
__u32 nr_sect;
int ret;
if (clustnum > 0) {
@ -285,25 +284,44 @@ get_cluster(fsdata *mydata, __u32 clustnum, __u8 *buffer, unsigned long size)
debug("gc - clustnum: %d, startsect: %d\n", clustnum, startsect);
nr_sect = size / mydata->sect_size;
ret = disk_read(startsect, nr_sect, buffer);
if (ret != nr_sect) {
debug("Error reading data (got %d)\n", ret);
return -1;
}
if (size % mydata->sect_size) {
if ((unsigned long)buffer & (ARCH_DMA_MINALIGN - 1)) {
ALLOC_CACHE_ALIGN_BUFFER(__u8, tmpbuf, mydata->sect_size);
printf("FAT: Misaligned buffer address (%p)\n", buffer);
while (size >= mydata->sect_size) {
ret = disk_read(startsect++, 1, tmpbuf);
if (ret != 1) {
debug("Error reading data (got %d)\n", ret);
return -1;
}
memcpy(buffer, tmpbuf, mydata->sect_size);
buffer += mydata->sect_size;
size -= mydata->sect_size;
}
} else {
idx = size / mydata->sect_size;
ret = disk_read(startsect + idx, 1, tmpbuf);
ret = disk_read(startsect, idx, buffer);
if (ret != idx) {
debug("Error reading data (got %d)\n", ret);
return -1;
}
startsect += idx;
idx *= mydata->sect_size;
buffer += idx;
size -= idx;
}
if (size) {
ALLOC_CACHE_ALIGN_BUFFER(__u8, tmpbuf, mydata->sect_size);
ret = disk_read(startsect, 1, tmpbuf);
if (ret != 1) {
debug("Error reading data (got %d)\n", ret);
return -1;
}
buffer += idx * mydata->sect_size;
memcpy(buffer, tmpbuf, size % mydata->sect_size);
return 0;
memcpy(buffer, tmpbuf, size);
}
return 0;