*/
#include <common.h>
+#include <blk.h>
#include <config.h>
#include <exports.h>
#include <fat.h>
}
}
-static block_dev_desc_t *cur_dev;
+static struct blk_desc *cur_dev;
static disk_partition_t cur_part_info;
#define DOS_BOOT_MAGIC_OFFSET 0x1fe
{
ulong ret;
- if (!cur_dev || !cur_dev->block_read)
+ if (!cur_dev)
return -1;
- ret = cur_dev->block_read(cur_dev->dev,
- cur_part_info.start + block, nr_blocks, buf);
+ ret = blk_dread(cur_dev, cur_part_info.start + block, nr_blocks, buf);
if (nr_blocks && ret == 0)
return -1;
return ret;
}
-int fat_set_blk_dev(block_dev_desc_t *dev_desc, disk_partition_t *info)
+int fat_set_blk_dev(struct blk_desc *dev_desc, disk_partition_t *info)
{
ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz);
return -1;
}
-int fat_register_device(block_dev_desc_t *dev_desc, int part_no)
+int fat_register_device(struct blk_desc *dev_desc, int part_no)
{
disk_partition_t info;
cur_dev = NULL;
/* Read the partition table, if present */
- if (get_partition_info(dev_desc, part_no, &info)) {
+ if (part_get_info(dev_desc, part_no, &info)) {
if (part_no != 0) {
printf("** Partition %d not valid on device %d **\n",
- part_no, dev_desc->dev);
+ part_no, dev_desc->devnum);
return -1;
}
info.name[0] = 0;
info.type[0] = 0;
info.bootable = 0;
-#ifdef CONFIG_PARTITION_UUIDS
+#if CONFIG_IS_ENABLED(PARTITION_UUIDS)
info.uuid[0] = 0;
#endif
}
downcase(s_name);
}
+static int flush_dirty_fat_buffer(fsdata *mydata);
+#if !defined(CONFIG_FAT_WRITE)
+/* Stub for read only operation */
+int flush_dirty_fat_buffer(fsdata *mydata)
+{
+ (void)(mydata);
+ return 0;
+}
+#endif
+
/*
* Get the entry at index 'entry' in a FAT (12/16/32) table.
* On failure 0x00 is returned.
static __u32 get_fatent(fsdata *mydata, __u32 entry)
{
__u32 bufnum;
- __u32 off16, offset;
+ __u32 offset, off8;
__u32 ret = 0x00;
- __u16 val1, val2;
+
+ if (CHECK_CLUST(entry, mydata->fatsize)) {
+ printf("Error: Invalid FAT entry: 0x%08x\n", entry);
+ return ret;
+ }
switch (mydata->fatsize) {
case 32:
return ret;
}
- debug("FAT%d: entry: 0x%04x = %d, offset: 0x%04x = %d\n",
+ debug("FAT%d: entry: 0x%08x = %d, offset: 0x%04x = %d\n",
mydata->fatsize, entry, entry, offset, offset);
/* Read a new block of FAT entries into the cache. */
__u32 fatlength = mydata->fatlength;
__u32 startblock = bufnum * FATBUFBLOCKS;
+ /* Cap length if fatlength is not a multiple of FATBUFBLOCKS */
if (startblock + getsize > fatlength)
getsize = fatlength - startblock;
startblock += mydata->fat_sect; /* Offset from start of disk */
+ /* Write back the fatbuf to the disk */
+ if (flush_dirty_fat_buffer(mydata) < 0)
+ return -1;
+
if (disk_read(startblock, getsize, bufptr) < 0) {
debug("Error reading FAT blocks\n");
return ret;
ret = FAT2CPU16(((__u16 *) mydata->fatbuf)[offset]);
break;
case 12:
- off16 = (offset * 3) / 4;
+ off8 = (offset * 3) / 2;
+ /* fatbut + off8 may be unaligned, read in byte granularity */
+ ret = mydata->fatbuf[off8] + (mydata->fatbuf[off8 + 1] << 8);
- switch (offset & 0x3) {
- case 0:
- ret = FAT2CPU16(((__u16 *) mydata->fatbuf)[off16]);
- ret &= 0xfff;
- break;
- case 1:
- val1 = FAT2CPU16(((__u16 *)mydata->fatbuf)[off16]);
- val1 &= 0xf000;
- val2 = FAT2CPU16(((__u16 *)mydata->fatbuf)[off16 + 1]);
- val2 &= 0x00ff;
- ret = (val2 << 4) | (val1 >> 12);
- break;
- case 2:
- val1 = FAT2CPU16(((__u16 *)mydata->fatbuf)[off16]);
- val1 &= 0xff00;
- val2 = FAT2CPU16(((__u16 *)mydata->fatbuf)[off16 + 1]);
- val2 &= 0x000f;
- ret = (val2 << 8) | (val1 >> 8);
- break;
- case 3:
- ret = FAT2CPU16(((__u16 *)mydata->fatbuf)[off16]);
- ret = (ret & 0xfff0) >> 4;
- break;
- default:
- break;
- }
- break;
+ if (offset & 0x1)
+ ret >>= 4;
+ ret &= 0xfff;
}
- debug("FAT%d: ret: %08x, offset: %04x\n",
- mydata->fatsize, ret, offset);
+ debug("FAT%d: ret: 0x%08x, entry: 0x%08x, offset: 0x%04x\n",
+ mydata->fatsize, ret, entry, offset);
return ret;
}
}
mydata->fatbufnum = -1;
+ mydata->fat_dirty = 0;
mydata->fatbuf = memalign(ARCH_DMA_MINALIGN, FATBUFSIZE);
if (mydata->fatbuf == NULL) {
debug("Error: allocating memory\n");
return 1;
}
-#if defined(CONFIG_CMD_IDE) || \
- defined(CONFIG_CMD_SATA) || \
- defined(CONFIG_CMD_SCSI) || \
+#if defined(CONFIG_IDE) || \
+ defined(CONFIG_SATA) || \
+ defined(CONFIG_SCSI) || \
defined(CONFIG_CMD_USB) || \
defined(CONFIG_MMC)
printf("Interface: ");
printf("Unknown");
}
- printf("\n Device %d: ", cur_dev->dev);
+ printf("\n Device %d: ", cur_dev->devnum);
dev_print(cur_dev);
#endif