|
@@ -390,3 +390,167 @@ int adfspart_check_ICS(struct parsed_partitions *state)
|
|
size = -size;
|
|
size = -size;
|
|
|
|
|
|
/*
|
|
/*
|
|
|
|
+ * Our own extension - We use the first sector
|
|
|
|
+ * of the partition to identify what type this
|
|
|
|
+ * partition is. We must not make this visible
|
|
|
|
+ * to the filesystem.
|
|
|
|
+ */
|
|
|
|
+ if (size > 1 && adfspart_check_ICSLinux(state, start)) {
|
|
|
|
+ start += 1;
|
|
|
|
+ size -= 1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (size)
|
|
|
|
+ put_partition(state, slot++, start, size);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ put_dev_sector(sect);
|
|
|
|
+ strlcat(state->pp_buf, "\n", PAGE_SIZE);
|
|
|
|
+ return 1;
|
|
|
|
+}
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+#ifdef CONFIG_ACORN_PARTITION_POWERTEC
|
|
|
|
+struct ptec_part {
|
|
|
|
+ __le32 unused1;
|
|
|
|
+ __le32 unused2;
|
|
|
|
+ __le32 start;
|
|
|
|
+ __le32 size;
|
|
|
|
+ __le32 unused5;
|
|
|
|
+ char type[8];
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static inline int valid_ptec_sector(const unsigned char *data)
|
|
|
|
+{
|
|
|
|
+ unsigned char checksum = 0x2a;
|
|
|
|
+ int i;
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * If it looks like a PC/BIOS partition, then it
|
|
|
|
+ * probably isn't PowerTec.
|
|
|
|
+ */
|
|
|
|
+ if (data[510] == 0x55 && data[511] == 0xaa)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < 511; i++)
|
|
|
|
+ checksum += data[i];
|
|
|
|
+
|
|
|
|
+ return checksum == data[511];
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * Purpose: allocate ICS partitions.
|
|
|
|
+ * Params : hd - pointer to gendisk structure to store partition info.
|
|
|
|
+ * dev - device number to access.
|
|
|
|
+ * Returns: -1 on error, 0 for no ICS table, 1 for partitions ok.
|
|
|
|
+ * Alloc : hda = whole drive
|
|
|
|
+ * hda1 = ADFS partition 0 on first drive.
|
|
|
|
+ * hda2 = ADFS partition 1 on first drive.
|
|
|
|
+ * ..etc..
|
|
|
|
+ */
|
|
|
|
+int adfspart_check_POWERTEC(struct parsed_partitions *state)
|
|
|
|
+{
|
|
|
|
+ Sector sect;
|
|
|
|
+ const unsigned char *data;
|
|
|
|
+ const struct ptec_part *p;
|
|
|
|
+ int slot = 1;
|
|
|
|
+ int i;
|
|
|
|
+
|
|
|
|
+ data = read_part_sector(state, 0, §);
|
|
|
|
+ if (!data)
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ if (!valid_ptec_sector(data)) {
|
|
|
|
+ put_dev_sector(sect);
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ strlcat(state->pp_buf, " [POWERTEC]", PAGE_SIZE);
|
|
|
|
+
|
|
|
|
+ for (i = 0, p = (const struct ptec_part *)data; i < 12; i++, p++) {
|
|
|
|
+ u32 start = le32_to_cpu(p->start);
|
|
|
|
+ u32 size = le32_to_cpu(p->size);
|
|
|
|
+
|
|
|
|
+ if (size)
|
|
|
|
+ put_partition(state, slot++, start, size);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ put_dev_sector(sect);
|
|
|
|
+ strlcat(state->pp_buf, "\n", PAGE_SIZE);
|
|
|
|
+ return 1;
|
|
|
|
+}
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+#ifdef CONFIG_ACORN_PARTITION_EESOX
|
|
|
|
+struct eesox_part {
|
|
|
|
+ char magic[6];
|
|
|
|
+ char name[10];
|
|
|
|
+ __le32 start;
|
|
|
|
+ __le32 unused6;
|
|
|
|
+ __le32 unused7;
|
|
|
|
+ __le32 unused8;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * Guess who created this format?
|
|
|
|
+ */
|
|
|
|
+static const char eesox_name[] = {
|
|
|
|
+ 'N', 'e', 'i', 'l', ' ',
|
|
|
|
+ 'C', 'r', 'i', 't', 'c', 'h', 'e', 'l', 'l', ' ', ' '
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * EESOX SCSI partition format.
|
|
|
|
+ *
|
|
|
|
+ * This is a goddamned awful partition format. We don't seem to store
|
|
|
|
+ * the size of the partition in this table, only the start addresses.
|
|
|
|
+ *
|
|
|
|
+ * There are two possibilities where the size comes from:
|
|
|
|
+ * 1. The individual ADFS boot block entries that are placed on the disk.
|
|
|
|
+ * 2. The start address of the next entry.
|
|
|
|
+ */
|
|
|
|
+int adfspart_check_EESOX(struct parsed_partitions *state)
|
|
|
|
+{
|
|
|
|
+ Sector sect;
|
|
|
|
+ const unsigned char *data;
|
|
|
|
+ unsigned char buffer[256];
|
|
|
|
+ struct eesox_part *p;
|
|
|
|
+ sector_t start = 0;
|
|
|
|
+ int i, slot = 1;
|
|
|
|
+
|
|
|
|
+ data = read_part_sector(state, 7, §);
|
|
|
|
+ if (!data)
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * "Decrypt" the partition table. God knows why...
|
|
|
|
+ */
|
|
|
|
+ for (i = 0; i < 256; i++)
|
|
|
|
+ buffer[i] = data[i] ^ eesox_name[i & 15];
|
|
|
|
+
|
|
|
|
+ put_dev_sector(sect);
|
|
|
|
+
|
|
|
|
+ for (i = 0, p = (struct eesox_part *)buffer; i < 8; i++, p++) {
|
|
|
|
+ sector_t next;
|
|
|
|
+
|
|
|
|
+ if (memcmp(p->magic, "Eesox", 6))
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ next = le32_to_cpu(p->start);
|
|
|
|
+ if (i)
|
|
|
|
+ put_partition(state, slot++, start, next - start);
|
|
|
|
+ start = next;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (i != 0) {
|
|
|
|
+ sector_t size;
|
|
|
|
+
|
|
|
|
+ size = get_capacity(state->bdev->bd_disk);
|
|
|
|
+ put_partition(state, slot++, start, size - start);
|
|
|
|
+ strlcat(state->pp_buf, "\n", PAGE_SIZE);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return i ? 1 : 0;
|
|
|
|
+}
|
|
|
|
+#endif
|