2 * fs/partitions/amiga.c
4 * Code extracted from drivers/block/genhd.c
6 * Copyright (C) 1991-1998 Linus Torvalds
7 * Re-organised Feb 1998 Russell King
11 #include <linux/genhd.h>
12 #include <linux/kernel.h>
13 #include <linux/major.h>
14 #include <linux/string.h>
15 #include <linux/blk.h>
17 #include <asm/byteorder.h>
18 #include <linux/affs_hardblocks.h>
24 checksum_block(u32 *m, int size)
29 sum += be32_to_cpu(*m++);
34 amiga_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector, int first_part_minor)
36 struct buffer_head *bh;
37 struct RigidDiskBlock *rdb;
38 struct PartitionBlock *pb;
46 old_blocksize = get_ptable_blocksize(dev);
47 blocksize = get_hardsect_size(dev);
52 set_blocksize(dev,blocksize);
55 for (blk = 0; blk < RDB_ALLOCATION_LIMIT; blk++) {
56 if(!(bh = bread(dev,blk,blocksize))) {
57 if (warn_no_part) printk("Dev %s: unable to read RDB block %d\n",
61 if (*(u32 *)bh->b_data == cpu_to_be32(IDNAME_RIGIDDISK)) {
62 rdb = (struct RigidDiskBlock *)bh->b_data;
63 if (checksum_block((u32 *)bh->b_data,be32_to_cpu(rdb->rdb_SummedLongs) & 0x7F)) {
64 /* Try again with 0xdc..0xdf zeroed, Windows might have
67 *(u32 *)(&bh->b_data[0xdc]) = 0;
68 if (checksum_block((u32 *)bh->b_data,
69 be32_to_cpu(rdb->rdb_SummedLongs) & 0x7F)) {
71 printk("Dev %s: RDB in block %d has bad checksum\n",
75 printk("Warning: Trashed word at 0xd0 in block %d "
76 "ignored in checksum calculation\n",blk);
79 blk = be32_to_cpu(rdb->rdb_PartitionList);
81 for (part = 1; blk > 0 && part <= 16; part++) {
82 if (!(bh = bread(dev,blk,blocksize))) {
83 if (warn_no_part) printk("Dev %s: unable to read partition block %d\n",
87 pb = (struct PartitionBlock *)bh->b_data;
88 blk = be32_to_cpu(pb->pb_Next);
89 if (pb->pb_ID == cpu_to_be32(IDNAME_PARTITION) && checksum_block(
90 (u32 *)pb,be32_to_cpu(pb->pb_SummedLongs) & 0x7F) == 0 ) {
92 /* Tell Kernel about it */
94 if (!(nr_sects = (be32_to_cpu(pb->pb_Environment[10]) + 1 -
95 be32_to_cpu(pb->pb_Environment[9])) *
96 be32_to_cpu(pb->pb_Environment[3]) *
97 be32_to_cpu(pb->pb_Environment[5]))) {
101 start_sect = be32_to_cpu(pb->pb_Environment[9]) *
102 be32_to_cpu(pb->pb_Environment[3]) *
103 be32_to_cpu(pb->pb_Environment[5]);
104 add_gd_partition(hd,first_part_minor,start_sect,nr_sects);
118 set_blocksize(dev,old_blocksize);