* added 0.99 linux version
[mascara-docs.git] / i386 / linux / linux-2.3.21 / fs / partitions / amiga.c
blobaa86053155083f86e8dd8ba163164505196bc6c9
1 /*
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
8 */
10 #include <linux/fs.h>
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>
20 #include "check.h"
21 #include "amiga.h"
23 static __inline__ u32
24 checksum_block(u32 *m, int size)
26 u32 sum = 0;
28 while (size--)
29 sum += be32_to_cpu(*m++);
30 return sum;
33 int
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;
39 int start_sect;
40 int nr_sects;
41 int blk;
42 int part, res;
43 int old_blocksize;
44 int blocksize;
46 old_blocksize = get_ptable_blocksize(dev);
47 blocksize = get_hardsect_size(dev);
49 if (blocksize < 512)
50 blocksize = 512;
52 set_blocksize(dev,blocksize);
53 res = 0;
55 for (blk = 0; blk < RDB_ALLOCATION_LIMIT; blk++) {
56 if(!(bh = bread(dev,blk,blocksize))) {
57 printk("Dev %s: unable to read RDB block %d\n",
58 kdevname(dev),blk);
59 goto rdb_done;
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
65 * trashed it.
67 *(u32 *)(&bh->b_data[0xdc]) = 0;
68 if (checksum_block((u32 *)bh->b_data,
69 be32_to_cpu(rdb->rdb_SummedLongs) & 0x7F)) {
70 brelse(bh);
71 printk("Dev %s: RDB in block %d has bad checksum\n",
72 kdevname(dev),blk);
73 continue;
75 printk("Warning: Trashed word at 0xd0 in block %d "
76 "ignored in checksum calculation\n",blk);
78 printk(" RDSK");
79 blk = be32_to_cpu(rdb->rdb_PartitionList);
80 brelse(bh);
81 for (part = 1; blk > 0 && part <= 16; part++) {
82 if (!(bh = bread(dev,blk,blocksize))) {
83 printk("Dev %s: unable to read partition block %d\n",
84 kdevname(dev),blk);
85 goto rdb_done;
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]))) {
98 brelse(bh);
99 continue;
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);
105 first_part_minor++;
106 res = 1;
108 brelse(bh);
110 printk("\n");
111 break;
113 else
114 brelse(bh);
117 rdb_done:
118 set_blocksize(dev,old_blocksize);
119 return res;