Root/
1 | /* |
2 | * fs/partitions/amiga.c |
3 | * |
4 | * Code extracted from drivers/block/genhd.c |
5 | * |
6 | * Copyright (C) 1991-1998 Linus Torvalds |
7 | * Re-organised Feb 1998 Russell King |
8 | */ |
9 | |
10 | #include <linux/types.h> |
11 | #include <linux/affs_hardblocks.h> |
12 | |
13 | #include "check.h" |
14 | #include "amiga.h" |
15 | |
16 | static __inline__ u32 |
17 | checksum_block(__be32 *m, int size) |
18 | { |
19 | u32 sum = 0; |
20 | |
21 | while (size--) |
22 | sum += be32_to_cpu(*m++); |
23 | return sum; |
24 | } |
25 | |
26 | int amiga_partition(struct parsed_partitions *state) |
27 | { |
28 | Sector sect; |
29 | unsigned char *data; |
30 | struct RigidDiskBlock *rdb; |
31 | struct PartitionBlock *pb; |
32 | int start_sect, nr_sects, blk, part, res = 0; |
33 | int blksize = 1; /* Multiplier for disk block size */ |
34 | int slot = 1; |
35 | char b[BDEVNAME_SIZE]; |
36 | |
37 | for (blk = 0; ; blk++, put_dev_sector(sect)) { |
38 | if (blk == RDB_ALLOCATION_LIMIT) |
39 | goto rdb_done; |
40 | data = read_part_sector(state, blk, §); |
41 | if (!data) { |
42 | if (warn_no_part) |
43 | printk("Dev %s: unable to read RDB block %d\n", |
44 | bdevname(state->bdev, b), blk); |
45 | res = -1; |
46 | goto rdb_done; |
47 | } |
48 | if (*(__be32 *)data != cpu_to_be32(IDNAME_RIGIDDISK)) |
49 | continue; |
50 | |
51 | rdb = (struct RigidDiskBlock *)data; |
52 | if (checksum_block((__be32 *)data, be32_to_cpu(rdb->rdb_SummedLongs) & 0x7F) == 0) |
53 | break; |
54 | /* Try again with 0xdc..0xdf zeroed, Windows might have |
55 | * trashed it. |
56 | */ |
57 | *(__be32 *)(data+0xdc) = 0; |
58 | if (checksum_block((__be32 *)data, |
59 | be32_to_cpu(rdb->rdb_SummedLongs) & 0x7F)==0) { |
60 | printk("Warning: Trashed word at 0xd0 in block %d " |
61 | "ignored in checksum calculation\n",blk); |
62 | break; |
63 | } |
64 | |
65 | printk("Dev %s: RDB in block %d has bad checksum\n", |
66 | bdevname(state->bdev, b), blk); |
67 | } |
68 | |
69 | /* blksize is blocks per 512 byte standard block */ |
70 | blksize = be32_to_cpu( rdb->rdb_BlockBytes ) / 512; |
71 | |
72 | { |
73 | char tmp[7 + 10 + 1 + 1]; |
74 | |
75 | /* Be more informative */ |
76 | snprintf(tmp, sizeof(tmp), " RDSK (%d)", blksize * 512); |
77 | strlcat(state->pp_buf, tmp, PAGE_SIZE); |
78 | } |
79 | blk = be32_to_cpu(rdb->rdb_PartitionList); |
80 | put_dev_sector(sect); |
81 | for (part = 1; blk>0 && part<=16; part++, put_dev_sector(sect)) { |
82 | blk *= blksize; /* Read in terms partition table understands */ |
83 | data = read_part_sector(state, blk, §); |
84 | if (!data) { |
85 | if (warn_no_part) |
86 | printk("Dev %s: unable to read partition block %d\n", |
87 | bdevname(state->bdev, b), blk); |
88 | res = -1; |
89 | goto rdb_done; |
90 | } |
91 | pb = (struct PartitionBlock *)data; |
92 | blk = be32_to_cpu(pb->pb_Next); |
93 | if (pb->pb_ID != cpu_to_be32(IDNAME_PARTITION)) |
94 | continue; |
95 | if (checksum_block((__be32 *)pb, be32_to_cpu(pb->pb_SummedLongs) & 0x7F) != 0 ) |
96 | continue; |
97 | |
98 | /* Tell Kernel about it */ |
99 | |
100 | nr_sects = (be32_to_cpu(pb->pb_Environment[10]) + 1 - |
101 | be32_to_cpu(pb->pb_Environment[9])) * |
102 | be32_to_cpu(pb->pb_Environment[3]) * |
103 | be32_to_cpu(pb->pb_Environment[5]) * |
104 | blksize; |
105 | if (!nr_sects) |
106 | continue; |
107 | start_sect = be32_to_cpu(pb->pb_Environment[9]) * |
108 | be32_to_cpu(pb->pb_Environment[3]) * |
109 | be32_to_cpu(pb->pb_Environment[5]) * |
110 | blksize; |
111 | put_partition(state,slot++,start_sect,nr_sects); |
112 | { |
113 | /* Be even more informative to aid mounting */ |
114 | char dostype[4]; |
115 | char tmp[42]; |
116 | |
117 | __be32 *dt = (__be32 *)dostype; |
118 | *dt = pb->pb_Environment[16]; |
119 | if (dostype[3] < ' ') |
120 | snprintf(tmp, sizeof(tmp), " (%c%c%c^%c)", |
121 | dostype[0], dostype[1], |
122 | dostype[2], dostype[3] + '@' ); |
123 | else |
124 | snprintf(tmp, sizeof(tmp), " (%c%c%c%c)", |
125 | dostype[0], dostype[1], |
126 | dostype[2], dostype[3]); |
127 | strlcat(state->pp_buf, tmp, PAGE_SIZE); |
128 | snprintf(tmp, sizeof(tmp), "(res %d spb %d)", |
129 | be32_to_cpu(pb->pb_Environment[6]), |
130 | be32_to_cpu(pb->pb_Environment[4])); |
131 | strlcat(state->pp_buf, tmp, PAGE_SIZE); |
132 | } |
133 | res = 1; |
134 | } |
135 | strlcat(state->pp_buf, "\n", PAGE_SIZE); |
136 | |
137 | rdb_done: |
138 | return res; |
139 | } |
140 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9