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) || \
+#if defined(CONFIG_IDE) || \
+ defined(CONFIG_SATA) || \
defined(CONFIG_SCSI) || \
defined(CONFIG_CMD_USB) || \
defined(CONFIG_MMC)