patch-2.3.14 linux/fs/partitions/amiga.c
Next file: linux/fs/partitions/amiga.h
Previous file: linux/fs/partitions/acorn.h
Back to the patch index
Back to the overall index
- Lines: 121
- Date:
Sun Aug 15 11:44:29 1999
- Orig file:
v2.3.13/linux/fs/partitions/amiga.c
- Orig date:
Wed Dec 31 16:00:00 1969
diff -u --recursive --new-file v2.3.13/linux/fs/partitions/amiga.c linux/fs/partitions/amiga.c
@@ -0,0 +1,120 @@
+/*
+ * fs/partitions/amiga.c
+ *
+ * Code extracted from drivers/block/genhd.c
+ *
+ * Copyright (C) 1991-1998 Linus Torvalds
+ * Re-organised Feb 1998 Russell King
+ */
+
+#include <linux/fs.h>
+#include <linux/genhd.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/blk.h>
+
+#include <asm/byteorder.h>
+#include <linux/affs_hardblocks.h>
+
+#include "check.h"
+#include "amiga.h"
+
+static __inline__ u32
+checksum_block(u32 *m, int size)
+{
+ u32 sum = 0;
+
+ while (size--)
+ sum += be32_to_cpu(*m++);
+ return sum;
+}
+
+int
+amiga_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector, int first_part_minor)
+{
+ struct buffer_head *bh;
+ struct RigidDiskBlock *rdb;
+ struct PartitionBlock *pb;
+ int start_sect;
+ int nr_sects;
+ int blk;
+ int part, res;
+ int old_blocksize;
+ int blocksize;
+
+ old_blocksize = get_ptable_blocksize(dev);
+ blocksize = get_hardsect_size(dev);
+
+ if (blocksize < 512)
+ blocksize = 512;
+
+ set_blocksize(dev,blocksize);
+ res = 0;
+
+ for (blk = 0; blk < RDB_ALLOCATION_LIMIT; blk++) {
+ if(!(bh = bread(dev,blk,blocksize))) {
+ printk("Dev %s: unable to read RDB block %d\n",
+ kdevname(dev),blk);
+ goto rdb_done;
+ }
+ if (*(u32 *)bh->b_data == cpu_to_be32(IDNAME_RIGIDDISK)) {
+ rdb = (struct RigidDiskBlock *)bh->b_data;
+ if (checksum_block((u32 *)bh->b_data,be32_to_cpu(rdb->rdb_SummedLongs) & 0x7F)) {
+ /* Try again with 0xdc..0xdf zeroed, Windows might have
+ * trashed it.
+ */
+ *(u32 *)(&bh->b_data[0xdc]) = 0;
+ if (checksum_block((u32 *)bh->b_data,
+ be32_to_cpu(rdb->rdb_SummedLongs) & 0x7F)) {
+ brelse(bh);
+ printk("Dev %s: RDB in block %d has bad checksum\n",
+ kdevname(dev),blk);
+ continue;
+ }
+ printk("Warning: Trashed word at 0xd0 in block %d "
+ "ignored in checksum calculation\n",blk);
+ }
+ printk(" RDSK");
+ blk = be32_to_cpu(rdb->rdb_PartitionList);
+ brelse(bh);
+ for (part = 1; blk > 0 && part <= 16; part++) {
+ if (!(bh = bread(dev,blk,blocksize))) {
+ printk("Dev %s: unable to read partition block %d\n",
+ kdevname(dev),blk);
+ goto rdb_done;
+ }
+ pb = (struct PartitionBlock *)bh->b_data;
+ blk = be32_to_cpu(pb->pb_Next);
+ if (pb->pb_ID == cpu_to_be32(IDNAME_PARTITION) && checksum_block(
+ (u32 *)pb,be32_to_cpu(pb->pb_SummedLongs) & 0x7F) == 0 ) {
+
+ /* Tell Kernel about it */
+
+ if (!(nr_sects = (be32_to_cpu(pb->pb_Environment[10]) + 1 -
+ be32_to_cpu(pb->pb_Environment[9])) *
+ be32_to_cpu(pb->pb_Environment[3]) *
+ be32_to_cpu(pb->pb_Environment[5]))) {
+ brelse(bh);
+ continue;
+ }
+ start_sect = be32_to_cpu(pb->pb_Environment[9]) *
+ be32_to_cpu(pb->pb_Environment[3]) *
+ be32_to_cpu(pb->pb_Environment[5]);
+ add_gd_partition(hd,first_part_minor,start_sect,nr_sects);
+ first_part_minor++;
+ res = 1;
+ }
+ brelse(bh);
+ }
+ printk("\n");
+ break;
+ }
+ else
+ brelse(bh);
+ }
+
+rdb_done:
+ set_blocksize(dev,old_blocksize);
+ return res;
+}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)