|
@@ -0,0 +1,122 @@
|
|
|
|
+/*
|
|
|
|
+ * linux/fs/partitions/acorn.c
|
|
|
|
+ *
|
|
|
|
+ * Copyright (c) 1996-2000 Russell King.
|
|
|
|
+ *
|
|
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
|
|
+ * it under the terms of the GNU General Public License version 2 as
|
|
|
|
+ * published by the Free Software Foundation.
|
|
|
|
+ *
|
|
|
|
+ * Scan ADFS partitions on hard disk drives. Unfortunately, there
|
|
|
|
+ * isn't a standard for partitioning drives on Acorn machines, so
|
|
|
|
+ * every single manufacturer of SCSI and IDE cards created their own
|
|
|
|
+ * method.
|
|
|
|
+ */
|
|
|
|
+#include <linux/buffer_head.h>
|
|
|
|
+#include <linux/adfs_fs.h>
|
|
|
|
+
|
|
|
|
+#include "check.h"
|
|
|
|
+#include "acorn.h"
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * Partition types. (Oh for reusability)
|
|
|
|
+ */
|
|
|
|
+#define PARTITION_RISCIX_MFM 1
|
|
|
|
+#define PARTITION_RISCIX_SCSI 2
|
|
|
|
+#define PARTITION_LINUX 9
|
|
|
|
+
|
|
|
|
+#if defined(CONFIG_ACORN_PARTITION_CUMANA) || \
|
|
|
|
+ defined(CONFIG_ACORN_PARTITION_ADFS)
|
|
|
|
+static struct adfs_discrecord *
|
|
|
|
+adfs_partition(struct parsed_partitions *state, char *name, char *data,
|
|
|
|
+ unsigned long first_sector, int slot)
|
|
|
|
+{
|
|
|
|
+ struct adfs_discrecord *dr;
|
|
|
|
+ unsigned int nr_sects;
|
|
|
|
+
|
|
|
|
+ if (adfs_checkbblk(data))
|
|
|
|
+ return NULL;
|
|
|
|
+
|
|
|
|
+ dr = (struct adfs_discrecord *)(data + 0x1c0);
|
|
|
|
+
|
|
|
|
+ if (dr->disc_size == 0 && dr->disc_size_high == 0)
|
|
|
|
+ return NULL;
|
|
|
|
+
|
|
|
|
+ nr_sects = (le32_to_cpu(dr->disc_size_high) << 23) |
|
|
|
|
+ (le32_to_cpu(dr->disc_size) >> 9);
|
|
|
|
+
|
|
|
|
+ if (name) {
|
|
|
|
+ strlcat(state->pp_buf, " [", PAGE_SIZE);
|
|
|
|
+ strlcat(state->pp_buf, name, PAGE_SIZE);
|
|
|
|
+ strlcat(state->pp_buf, "]", PAGE_SIZE);
|
|
|
|
+ }
|
|
|
|
+ put_partition(state, slot, first_sector, nr_sects);
|
|
|
|
+ return dr;
|
|
|
|
+}
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+#ifdef CONFIG_ACORN_PARTITION_RISCIX
|
|
|
|
+
|
|
|
|
+struct riscix_part {
|
|
|
|
+ __le32 start;
|
|
|
|
+ __le32 length;
|
|
|
|
+ __le32 one;
|
|
|
|
+ char name[16];
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+struct riscix_record {
|
|
|
|
+ __le32 magic;
|
|
|
|
+#define RISCIX_MAGIC cpu_to_le32(0x4a657320)
|
|
|
|
+ __le32 date;
|
|
|
|
+ struct riscix_part part[8];
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+#if defined(CONFIG_ACORN_PARTITION_CUMANA) || \
|
|
|
|
+ defined(CONFIG_ACORN_PARTITION_ADFS)
|
|
|
|
+static int riscix_partition(struct parsed_partitions *state,
|
|
|
|
+ unsigned long first_sect, int slot,
|
|
|
|
+ unsigned long nr_sects)
|
|
|
|
+{
|
|
|
|
+ Sector sect;
|
|
|
|
+ struct riscix_record *rr;
|
|
|
|
+
|
|
|
|
+ rr = read_part_sector(state, first_sect, §);
|
|
|
|
+ if (!rr)
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ strlcat(state->pp_buf, " [RISCiX]", PAGE_SIZE);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ if (rr->magic == RISCIX_MAGIC) {
|
|
|
|
+ unsigned long size = nr_sects > 2 ? 2 : nr_sects;
|
|
|
|
+ int part;
|
|
|
|
+
|
|
|
|
+ strlcat(state->pp_buf, " <", PAGE_SIZE);
|
|
|
|
+
|
|
|
|
+ put_partition(state, slot++, first_sect, size);
|
|
|
|
+ for (part = 0; part < 8; part++) {
|
|
|
|
+ if (rr->part[part].one &&
|
|
|
|
+ memcmp(rr->part[part].name, "All\0", 4)) {
|
|
|
|
+ put_partition(state, slot++,
|
|
|
|
+ le32_to_cpu(rr->part[part].start),
|
|
|
|
+ le32_to_cpu(rr->part[part].length));
|
|
|
|
+ strlcat(state->pp_buf, "(", PAGE_SIZE);
|
|
|
|
+ strlcat(state->pp_buf, rr->part[part].name, PAGE_SIZE);
|
|
|
|
+ strlcat(state->pp_buf, ")", PAGE_SIZE);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ strlcat(state->pp_buf, " >\n", PAGE_SIZE);
|
|
|
|
+ } else {
|
|
|
|
+ put_partition(state, slot++, first_sect, nr_sects);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ put_dev_sector(sect);
|
|
|
|
+ return slot;
|
|
|
|
+}
|
|
|
|
+#endif
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+#define LINUX_NATIVE_MAGIC 0xdeafa1de
|
|
|
|
+#define LINUX_SWAP_MAGIC 0xdeafab1e
|
|
|
|
+
|