diff --git a/fs/fat/fat.c b/fs/fat/fat.c
index 1542194a1a66a983df14fb41bbe22f26fdc1c091..2bb7adfcf156424e48b9df634473c6fb6d6bca54 100644
--- a/fs/fat/fat.c
+++ b/fs/fat/fat.c
@@ -43,50 +43,30 @@ static void downcase (char *str)
 	}
 }
 
-static block_dev_desc_t *cur_dev = NULL;
+static block_dev_desc_t *cur_dev;
+static unsigned int cur_part_nr;
+static disk_partition_t cur_part_info;
 
-static unsigned long part_offset = 0;
-
-static int cur_part = 1;
-
-#define DOS_PART_TBL_OFFSET	0x1be
-#define DOS_PART_MAGIC_OFFSET	0x1fe
+#define DOS_BOOT_MAGIC_OFFSET	0x1fe
 #define DOS_FS_TYPE_OFFSET	0x36
 #define DOS_FS32_TYPE_OFFSET	0x52
 
-static int disk_read (__u32 startblock, __u32 getsize, __u8 * bufptr)
+static int disk_read(__u32 block, __u32 nr_blocks, void *buf)
 {
-	if (cur_dev == NULL)
+	if (!cur_dev || !cur_dev->block_read)
 		return -1;
 
-	startblock += part_offset;
-
-	if (cur_dev->block_read) {
-		return cur_dev->block_read(cur_dev->dev, startblock, getsize,
-					   (unsigned long *) bufptr);
-	}
-	return -1;
+	return cur_dev->block_read(cur_dev->dev,
+			cur_part_info.start + block, nr_blocks, buf);
 }
 
 int fat_register_device (block_dev_desc_t * dev_desc, int part_no)
 {
 	unsigned char buffer[dev_desc->blksz];
 
-	if (!dev_desc->block_read)
-		return -1;
+	/* First close any currently found FAT filesystem */
+	cur_dev = NULL;
 
-	cur_dev = dev_desc;
-	/* check if we have a MBR (on floppies we have only a PBR) */
-	if (dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *)buffer) != 1) {
-		printf("** Can't read from device %d **\n",
-			dev_desc->dev);
-		return -1;
-	}
-	if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 ||
-	    buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) {
-		/* no signature found */
-		return -1;
-	}
 #if (defined(CONFIG_CMD_IDE) || \
      defined(CONFIG_CMD_MG_DISK) || \
      defined(CONFIG_CMD_SATA) || \
@@ -94,45 +74,54 @@ int fat_register_device (block_dev_desc_t * dev_desc, int part_no)
      defined(CONFIG_CMD_USB) || \
      defined(CONFIG_MMC) || \
      defined(CONFIG_SYSTEMACE) )
-	{
-		disk_partition_t info;
-
-		/* First we assume there is a MBR */
-		if (!get_partition_info(dev_desc, part_no, &info)) {
-			part_offset = info.start;
-			cur_part = part_no;
-		} else if ((strncmp((char *)&buffer[DOS_FS_TYPE_OFFSET],
-				    "FAT", 3) == 0) ||
-			   (strncmp((char *)&buffer[DOS_FS32_TYPE_OFFSET],
-				    "FAT32", 5) == 0)) {
-			/* ok, we assume we are on a PBR only */
-			cur_part = 1;
-			part_offset = 0;
-		} else {
+
+	/* Read the partition table, if present */
+	if (!get_partition_info(dev_desc, part_no, &cur_part_info)) {
+		cur_dev = dev_desc;
+		cur_part_nr = part_no;
+	}
+#endif
+
+	/* Otherwise it might be a superfloppy (whole-disk FAT filesystem) */
+	if (!cur_dev) {
+		if (part_no != 1) {
 			printf("** Partition %d not valid on device %d **\n",
-				part_no, dev_desc->dev);
+					part_no, dev_desc->dev);
 			return -1;
 		}
+
+		cur_dev = dev_desc;
+		cur_part_nr = 1;
+		cur_part_info.start = 0;
+		cur_part_info.size = dev_desc->lba;
+		cur_part_info.blksz = dev_desc->blksz;
+		memset(cur_part_info.name, 0, sizeof(cur_part_info.name));
+		memset(cur_part_info.type, 0, sizeof(cur_part_info.type));
 	}
-#else
-	if ((strncmp((char *)&buffer[DOS_FS_TYPE_OFFSET], "FAT", 3) == 0) ||
-	    (strncmp((char *)&buffer[DOS_FS32_TYPE_OFFSET], "FAT32", 5) == 0)) {
-		/* ok, we assume we are on a PBR only */
-		cur_part = 1;
-		part_offset = 0;
-	} else {
-		/* FIXME we need to determine the start block of the
-		 * partition where the DOS FS resides. This can be done
-		 * by using the get_partition_info routine. For this
-		 * purpose the libpart must be included.
-		 */
-		part_offset = 32;
-		cur_part = 1;
+
+	/* Make sure it has a valid FAT header */
+	if (disk_read(0, 1, buffer) != 1) {
+		cur_dev = NULL;
+		return -1;
 	}
-#endif
-	return 0;
+
+	/* Check if it's actually a DOS volume */
+	if (memcmp(buffer + DOS_BOOT_MAGIC_OFFSET, "\x55\xAA", 2)) {
+		cur_dev = NULL;
+		return -1;
+	}
+
+	/* Check for FAT12/FAT16/FAT32 filesystem */
+	if (!memcmp(buffer + DOS_FS_TYPE_OFFSET, "FAT", 3))
+		return 0;
+	if (!memcmp(buffer + DOS_FS32_TYPE_OFFSET, "FAT32", 5))
+		return 0;
+
+	cur_dev = NULL;
+	return -1;
 }
 
+
 /*
  * Get the first occurence of a directory delimiter ('/' or '\') in a string.
  * Return index into string if found, -1 otherwise.
@@ -1172,7 +1161,7 @@ int file_fat_detectfs (void)
 	vol_label[11] = '\0';
 	volinfo.fs_type[5] = '\0';
 
-	printf("Partition %d: Filesystem: %s \"%s\"\n", cur_part,
+	printf("Partition %d: Filesystem: %s \"%s\"\n", cur_part_nr,
 		volinfo.fs_type, vol_label);
 
 	return 0;