2 * Copyright 2003-2009, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
10 #include <KernelExport.h>
11 #include <disk_device_manager/ddm_modules.h>
12 #include <disk_device_types.h>
14 # include <boot/partitions.h>
16 # include <DiskDeviceTypes.h>
18 #include <util/kernel_cpp.h>
24 //#define TRACE_AMIGA_RDB
25 #ifdef TRACE_AMIGA_RDB
26 # define TRACE(x) dprintf x
32 #define AMIGA_PARTITION_MODULE_NAME "partitioning_systems/amiga_rdb/v1"
35 template<typename Type
> bool
36 validate_check_sum(Type
*type
)
38 if (type
->SummedLongs() != sizeof(*type
) / sizeof(uint32
))
42 uint32
*longs
= (uint32
*)type
;
44 for (uint32 i
= 0; i
< type
->SummedLongs(); i
++)
45 sum
+= B_BENDIAN_TO_HOST_INT32(longs
[i
]);
47 #ifdef TRACE_AMIGA_RDB
49 TRACE(("search_rdb: check sum is incorrect!\n"));
56 #ifdef TRACE_AMIGA_RDB
60 static unsigned char tupel
[5];
62 tupel
[0] = 0xff & (id
>> 24);
63 tupel
[1] = 0xff & (id
>> 16);
64 tupel
[2] = 0xff & (id
>> 8);
65 tupel
[3] = 0xff & (id
);
67 for (int16 i
= 0;i
< 4;i
++) {
68 if (tupel
[i
] < ' ' || tupel
[i
] > 128)
78 get_next_partition(int fd
, rigid_disk_block
&rdb
, uint32
&cookie
,
79 partition_block
&partition
)
83 cookie
= rdb
.FirstPartition();
84 } else if (cookie
== 0xffffffff) {
86 return B_ENTRY_NOT_FOUND
;
89 ssize_t bytesRead
= read_pos(fd
, (off_t
)cookie
* rdb
.BlockSize(),
90 (void *)&partition
, sizeof(partition_block
));
91 if (bytesRead
< (ssize_t
)sizeof(partition_block
))
94 // TODO: Should we retry with the next block if the following test fails, as
95 // long as this we find partition_blocks within a reasonable range?
97 if (partition
.ID() != RDB_PARTITION_ID
98 || !validate_check_sum
<partition_block
>(&partition
))
101 cookie
= partition
.Next();
107 search_rdb(int fd
, rigid_disk_block
**_rdb
)
109 for (int32 sector
= 0; sector
< RDB_LOCATION_LIMIT
; sector
++) {
111 ssize_t bytesRead
= read_pos(fd
, sector
* 512, buffer
, sizeof(buffer
));
112 if (bytesRead
< (ssize_t
)sizeof(buffer
)) {
113 TRACE(("search_rdb: read error: %ld\n", bytesRead
));
117 rigid_disk_block
*rdb
= (rigid_disk_block
*)buffer
;
118 if (rdb
->ID() == RDB_DISK_ID
119 && validate_check_sum
<rigid_disk_block
>(rdb
)) {
120 // copy the RDB to a new piece of memory
121 rdb
= new rigid_disk_block();
122 memcpy(rdb
, buffer
, sizeof(rigid_disk_block
));
133 // #pragma mark - public module interface
137 amiga_rdb_std_ops(int32 op
, ...)
141 case B_MODULE_UNINIT
:
150 amiga_rdb_identify_partition(int fd
, partition_data
*partition
, void **_cookie
)
152 rigid_disk_block
*rdb
;
153 if (!search_rdb(fd
, &rdb
))
156 *_cookie
= (void *)rdb
;
162 amiga_rdb_scan_partition(int fd
, partition_data
*partition
, void *_cookie
)
164 TRACE(("amiga_rdb_scan_partition(cookie = %p)\n", _cookie
));
166 rigid_disk_block
&rdb
= *(rigid_disk_block
*)_cookie
;
168 partition
->status
= B_PARTITION_VALID
;
169 partition
->flags
|= B_PARTITION_PARTITIONING_SYSTEM
170 | B_PARTITION_READ_ONLY
;
171 partition
->content_size
= partition
->size
;
175 partition_block partitionBlock
;
176 uint32 index
= 0, cookie
= 0;
179 while ((status
= get_next_partition(fd
, rdb
, cookie
, partitionBlock
))
181 disk_environment
&environment
182 = *(disk_environment
*)&partitionBlock
.environment
[0];
183 TRACE(("amiga_rdb: file system: %s\n",
184 get_tupel(B_BENDIAN_TO_HOST_INT32(environment
.dos_type
))));
186 if (environment
.Start() + environment
.Size()
187 > (uint64
)partition
->size
) {
188 TRACE(("amiga_rdb: child partition exceeds existing space (%Ld "
189 "bytes)\n", environment
.Size()));
193 partition_data
*child
= create_child_partition(partition
->id
, index
++,
194 partition
->offset
+ environment
.Start(), environment
.Size(), -1);
196 TRACE(("amiga_rdb: Creating child at index %ld failed\n",
201 child
->block_size
= environment
.BlockSize();
204 if (status
== B_ENTRY_NOT_FOUND
)
212 amiga_rdb_free_identify_partition_cookie(partition_data
*partition
,
215 delete (rigid_disk_block
*)_cookie
;
220 static partition_module_info sAmigaPartitionModule
= {
222 partition_module_info gAmigaPartitionModule
= {
225 AMIGA_PARTITION_MODULE_NAME
,
229 "amiga", // short_name
230 AMIGA_PARTITION_NAME
, // pretty_name
234 amiga_rdb_identify_partition
,
235 amiga_rdb_scan_partition
,
236 amiga_rdb_free_identify_partition_cookie
,
241 partition_module_info
*modules
[] = {
242 &sAmigaPartitionModule
,