summaryrefslogtreecommitdiff
path: root/nuttx/fs/fat
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-11-15 16:44:45 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-11-15 16:44:45 +0000
commit4bf2eeec797de1c158143d33c572ef38e6ccc015 (patch)
tree7984e3dd5ddc7d8d474bbbc53f5031863834d50f /nuttx/fs/fat
parentc5c3f5ad84cce90b89cff4d88334789c2bc2e2f9 (diff)
downloadpx4-nuttx-4bf2eeec797de1c158143d33c572ef38e6ccc015.tar.gz
px4-nuttx-4bf2eeec797de1c158143d33c572ef38e6ccc015.tar.bz2
px4-nuttx-4bf2eeec797de1c158143d33c572ef38e6ccc015.zip
Add support for more FAT partitions; support for SD cards greater than 4Gb; TSC2007 touchscreen driver improvements
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4092 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/fs/fat')
-rw-r--r--nuttx/fs/fat/fs_fat32.h44
-rw-r--r--nuttx/fs/fat/fs_fat32util.c95
2 files changed, 112 insertions, 27 deletions
diff --git a/nuttx/fs/fat/fs_fat32.h b/nuttx/fs/fat/fs_fat32.h
index 026d87a6d..536e8fd7e 100644
--- a/nuttx/fs/fat/fs_fat32.h
+++ b/nuttx/fs/fat/fs_fat32.h
@@ -129,10 +129,12 @@
*/
/* 446@0: Generally unused and zero; but may
* include IDM Boot Manager menu entry at 8@394 */
+#define PART_ENTRY(n) (446+((n) << 4)) /* n = 0,1,2,3 */
#define PART_ENTRY1 446 /* 16@446: Partition table, first entry */
#define PART_ENTRY2 462 /* 16@462: Partition table, second entry */
- /* 32@478: Unused, should be zero */
-#define PART_SIGNATURE /* 2@510: Valid partitions have 0x55aa here */
+#define PART_ENTRY3 478 /* 16@478: Partition table, third entry */
+#define PART_ENTRY4 494 /* 16@494: Partition table, fourth entry */
+#define PART_SIGNATURE 510 /* 2@510: Valid partitions have 0x55aa here */
/****************************************************************************
* These offsets describes one partition table entry. NOTE that ent entries
@@ -148,6 +150,26 @@
#define PART_SIZE 12 /* 4@12: Partition size (in sectors) */
/****************************************************************************
+ * Partition table types.
+ */
+
+#define PART_TYPE_NONE 0 /* No partition */
+#define PART_TYPE_FAT12 1 /* FAT12 */
+#define PART_TYPE_FAT16A 4 /* FAT16 (Partition smaller than 32MB) */
+#define PART_TYPE_EXT 5 /* Extended MS-DOS Partition */
+#define PART_TYPE_FAT16B 6 /* FAT16 (Partition larger than 32MB) */
+#define PART_TYPE_FAT32 11 /* FAT32 (Partition up to 2048Gb) */
+#define PART_TYPE_FAT32X 12 /* Same as 11, but uses LBA1 0x13 extensions */
+#define PART_TYPE_FAT16X 14 /* Same as 6, but uses LBA1 0x13 extensions */
+#define PART_TYPE_EXTX 15 /* Same as 5, but uses LBA1 0x13 extensions */
+
+/****************************************************************************
+ * Each FAT "short" 8.3 file name directory entry is 32-bytes long.
+ *
+ * Sizes and limits
+ */
+
+/****************************************************************************
* Each FAT "short" 8.3 file name directory entry is 32-bytes long.
*
* Sizes and limits
@@ -329,8 +351,11 @@
#define MBR_GETBOOTSIG16(p) UBYTE_VAL(p,BS16_BOOTSIG)
#define MBR_GETBOOTSIG32(p) UBYTE_VAL(p,BS32_BOOTSIG)
+#define PART_GETTYPE(n,p) UBYTE_VAL(p,PART_ENTRY(n)+PART_TYPE)
#define PART1_GETTYPE(p) UBYTE_VAL(p,PART_ENTRY1+PART_TYPE)
#define PART2_GETTYPE(p) UBYTE_VAL(p,PART_ENTRY2+PART_TYPE)
+#define PART3_GETTYPE(p) UBYTE_VAL(p,PART_ENTRY3+PART_TYPE)
+#define PART4_GETTYPE(p) UBYTE_VAL(p,PART_ENTRY4+PART_TYPE)
#define DIR_GETATTRIBUTES(p) UBYTE_VAL(p,DIR_ATTRIBUTES)
#define DIR_GETNTRES(p) UBYTE_VAL(p,DIR_NTRES)
@@ -351,8 +376,11 @@
#define MBR_PUTBOOTSIG16(p,v) UBYTE_PUT(p,BS16_BOOTSIG,v)
#define MBR_PUTBOOTSIG32(p,v) UBYTE_PUT(p,BS32_BOOTSIG,v)
+#define PART_PUTTYPE(n,p,v) UBYTE_PUT(p,PART_ENTRY(n)+PART_TYPE,v)
#define PART1_PUTTYPE(p,v) UBYTE_PUT(p,PART_ENTRY1+PART_TYPE,v)
#define PART2_PUTTYPE(p,v) UBYTE_PUT(p,PART_ENTRY2+PART_TYPE,v)
+#define PART3_PUTTYPE(p,v) UBYTE_PUT(p,PART_ENTRY3+PART_TYPE,v)
+#define PART4_PUTTYPE(p,v) UBYTE_PUT(p,PART_ENTRY4+PART_TYPE,v)
#define DIR_PUTATTRIBUTES(p,v) UBYTE_PUT(p,DIR_ATTRIBUTES,v)
#define DIR_PUTNTRES(p,v) UBYTE_PUT(p,DIR_NTRES,v)
@@ -378,10 +406,16 @@
#define MBR_GETVOLID16(p) fat_getuint32(UBYTE_PTR(p,BS16_VOLID))
#define MBR_GETVOLID32(p) fat_getuint32(UBYTE_PTR(p,BS32_VOLID))
+#define PART_GETSTARTSECTOR(n,p) fat_getuint32(UBYTE_PTR(p,PART_ENTRY(n)+PART_STARTSECTOR))
+#define PART_GETSIZE(n,p) fat_getuint32(UBYTE_PTR(p,PART_ENTRY(n)+PART_SIZE))
#define PART1_GETSTARTSECTOR(p) fat_getuint32(UBYTE_PTR(p,PART_ENTRY1+PART_STARTSECTOR))
#define PART1_GETSIZE(p) fat_getuint32(UBYTE_PTR(p,PART_ENTRY1+PART_SIZE))
#define PART2_GETSTARTSECTOR(p) fat_getuint32(UBYTE_PTR(p,PART_ENTRY2+PART_STARTSECTOR))
#define PART2_GETSIZE(p) fat_getuint32(UBYTE_PTR(p,PART_ENTRY2+PART_SIZE))
+#define PART3_GETSTARTSECTOR(p) fat_getuint32(UBYTE_PTR(p,PART_ENTRY3+PART_STARTSECTOR))
+#define PART3_GETSIZE(p) fat_getuint32(UBYTE_PTR(p,PART_ENTRY3+PART_SIZE))
+#define PART4_GETSTARTSECTOR(p) fat_getuint32(UBYTE_PTR(p,PART_ENTRY4+PART_STARTSECTOR))
+#define PART4_GETSIZE(p) fat_getuint32(UBYTE_PTR(p,PART_ENTRY4+PART_SIZE))
#define MBR_PUTBYTESPERSEC(p,v) fat_putuint16(UBYTE_PTR(p,BS_BYTESPERSEC),v)
#define MBR_PUTROOTENTCNT(p,v) fat_putuint16(UBYTE_PTR(p,BS_ROOTENTCNT),v)
@@ -389,10 +423,16 @@
#define MBR_PUTVOLID16(p,v) fat_putuint32(UBYTE_PTR(p,BS16_VOLID),v)
#define MBR_PUTVOLID32(p,v) fat_putuint32(UBYTE_PTR(p,BS32_VOLID),v)
+#define PART_PUTSTARTSECTOR(n,p,v) fat_putuint32(UBYTE_PTR(p,PART_ENTRY(n)+PART_STARTSECTOR),v)
+#define PART_PUTSIZE(n,p,v) fat_putuint32(UBYTE_PTR(p,PART_ENTRY(n)+PART_SIZE),v)
#define PART1_PUTSTARTSECTOR(p,v) fat_putuint32(UBYTE_PTR(p,PART_ENTRY1+PART_STARTSECTOR),v)
#define PART1_PUTSIZE(p,v) fat_putuint32(UBYTE_PTR(p,PART_ENTRY1+PART_SIZE),v)
#define PART2_PUTSTARTSECTOR(p,v) fat_putuint32(UBYTE_PTR(p,PART_ENTRY2+PART_STARTSECTOR),v)
#define PART2_PUTSIZE(p,v) fat_putuint32(UBYTE_PTR(p,PART_ENTRY2+PART_SIZE),v)
+#define PART3_PUTSTARTSECTOR(p,v) fat_putuint32(UBYTE_PTR(p,PART_ENTRY3+PART_STARTSECTOR),v)
+#define PART3_PUTSIZE(p,v) fat_putuint32(UBYTE_PTR(p,PART_ENTRY3+PART_SIZE),v)
+#define PART4_PUTSTARTSECTOR(p,v) fat_putuint32(UBYTE_PTR(p,PART_ENTRY4+PART_STARTSECTOR),v)
+#define PART4_PUTSIZE(p,v) fat_putuint32(UBYTE_PTR(p,PART_ENTRY4+PART_SIZE),v)
#ifdef CONFIG_FAT_LFN
# define LDIR_PTRWCHAR1_5(p) UBYTE_PTR(p,LDIR_WCHAR1_5)
diff --git a/nuttx/fs/fat/fs_fat32util.c b/nuttx/fs/fat/fs_fat32util.c
index 5c402b468..12c2394f0 100644
--- a/nuttx/fs/fat/fs_fat32util.c
+++ b/nuttx/fs/fat/fs_fat32util.c
@@ -138,6 +138,10 @@ static int fat_checkbootrecord(struct fat_mountpt_s *fs)
if (MBR_GETSIGNATURE(fs->fs_buffer) != BOOT_SIGNATURE16 ||
MBR_GETBYTESPERSEC(fs->fs_buffer) != fs->fs_hwsectorsize)
{
+ fdbg("ERROR: Signature: %04x FS sectorsize: %d HW sectorsize: %d\n",
+ MBR_GETSIGNATURE(fs->fs_buffer), MBR_GETBYTESPERSEC(fs->fs_buffer),
+ fs->fs_hwsectorsize);
+
return -ENODEV;
}
@@ -172,6 +176,9 @@ static int fat_checkbootrecord(struct fat_mountpt_s *fs)
if (!fs->fs_nfatsects || fs->fs_nfatsects >= fs->fs_hwnsectors)
{
+ fdbg("ERROR: fs_nfatsects %d fs_hwnsectors: %d\n",
+ fs->fs_nfatsects, fs->fs_hwnsectors);
+
return -ENODEV;
}
@@ -189,6 +196,9 @@ static int fat_checkbootrecord(struct fat_mountpt_s *fs)
if (!fs->fs_fattotsec || fs->fs_fattotsec > fs->fs_hwnsectors)
{
+ fdbg("ERROR: fs_fattotsec %d fs_hwnsectors: %d\n",
+ fs->fs_fattotsec, fs->fs_hwnsectors);
+
return -ENODEV;
}
@@ -197,6 +207,9 @@ static int fat_checkbootrecord(struct fat_mountpt_s *fs)
fs->fs_fatresvdseccount = MBR_GETRESVDSECCOUNT(fs->fs_buffer);
if (fs->fs_fatresvdseccount > fs->fs_hwnsectors)
{
+ fdbg("ERROR: fs_fatresvdseccount %d fs_hwnsectors: %d\n",
+ fs->fs_fatresvdseccount, fs->fs_hwnsectors);
+
return -ENODEV;
}
@@ -210,6 +223,9 @@ static int fat_checkbootrecord(struct fat_mountpt_s *fs)
ndatasectors = fs->fs_fattotsec - fs->fs_fatresvdseccount - ntotalfatsects - rootdirsectors;
if (ndatasectors > fs->fs_hwnsectors)
{
+ fdbg("ERROR: ndatasectors %d fs_hwnsectors: %d\n",
+ ndatasectors, fs->fs_hwnsectors);
+
return -ENODEV;
}
@@ -235,11 +251,14 @@ static int fat_checkbootrecord(struct fat_mountpt_s *fs)
}
else if (!notfat32)
{
- fs->fs_fsinfo = fs->fs_fatbase + MBR_GETFSINFO(fs->fs_buffer);
- fs->fs_type = FSTYPE_FAT32;
+ fs->fs_fsinfo = fs->fs_fatbase + MBR_GETFSINFO(fs->fs_buffer);
+ fs->fs_type = FSTYPE_FAT32;
}
else
{
+ fdbg("ERROR: notfat32: %d fs_nclusters: %d\n",
+ notfat32, fs->fs_nclusters);
+
return -ENODEV;
}
@@ -550,37 +569,63 @@ int fat_mount(struct fat_mountpt_s *fs, bool writeable)
/* The contents of sector 0 is not a boot record. It could be a
* partition, however. Assume it is a partition and get the offset
* into the partition table. This table is at offset MBR_TABLE and is
- * indexed by 16x the partition number. Here we support only
- * partition 0.
- *
- * Check if the partition exists and, if so, get the bootsector for that
- * partition and see if we can find the boot record there.
+ * indexed by 16x the partition number.
*/
+
+ int i;
+ for (i = 0; i < 4; i++)
+ {
+ /* Check if the partition exists and, if so, get the bootsector for that
+ * partition and see if we can find the boot record there.
+ */
- if (PART1_GETTYPE(fs->fs_buffer) == 0)
- {
- fdbg("No MBR or partition\n");
- goto errout_with_buffer;
- }
+ uint8_t part = PART_GETTYPE(i, fs->fs_buffer);
+ fvdbg("Partition %d, offset %d, type %d\n", i, PART_ENTRY(i), part);
- /* There appears to be a partition, get the sector number of the
- * partition (LBA)
- */
+ if (part == 0)
+ {
+ fvdbg("No partition %d\n", i);
+ continue;
+ }
- fs->fs_fatbase = PART1_GETSTARTSECTOR(fs->fs_buffer);
+ /* There appears to be a partition, get the sector number of the
+ * partition (LBA)
+ */
- /* Read the new candidate boot sector */
+ fs->fs_fatbase = PART_GETSTARTSECTOR(i, fs->fs_buffer);
- ret = fat_hwread(fs, fs->fs_buffer, fs->fs_fatbase, 1);
- if (ret < 0)
- {
- goto errout_with_buffer;
- }
+ /* Read the new candidate boot sector */
- /* Check if this is a boot record */
+ ret = fat_hwread(fs, fs->fs_buffer, fs->fs_fatbase, 1);
+ if (ret < 0)
+ {
+ /* Failed to read the sector */
- ret = fat_checkbootrecord(fs);
- if (ret != OK)
+ goto errout_with_buffer;
+ }
+
+ /* Check if this is a boot record */
+
+ ret = fat_checkbootrecord(fs);
+ if (ret == OK)
+ {
+ /* Break out of the loop if a valid boot record is found */
+
+ fvdbg("MBR found in partition %d\n", i);
+ break;
+ }
+
+ /* Re-read sector 0 so that we can check the next partition */
+
+ fvdbg("Partition %d is not an MBR\n", i);
+ ret = fat_hwread(fs, fs->fs_buffer, 0, 1);
+ if (ret < 0)
+ {
+ goto errout_with_buffer;
+ }
+ }
+
+ if (i > 3)
{
fdbg("No valid MBR\n");
goto errout_with_buffer;