2 * Copyright 2003-2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3 * Distributed under the terms of the MIT License.
10 #include <KernelExport.h>
11 #include <ddm_modules.h>
13 # include <boot/partitions.h>
15 # include <DiskDeviceTypes.h>
17 #include <util/kernel_cpp.h>
25 //#define TRACE_ATARI_PARTITION
26 #ifdef TRACE_ATARI_PARTITION
27 # define TRACE(x) dprintf x
33 #define ATARI_PARTITION_MODULE_NAME "partitioning_systems/atari/v1"
34 #define ATARI_PARTITION_NAME "Atari Partition Map"
38 template<typename Type
> bool
39 validate_check_sum(Type
*type
)
41 if (type
->SummedLongs() != sizeof(*type
) / sizeof(uint32
))
45 uint32
*longs
= (uint32
*)type
;
47 for (uint32 i
= 0; i
< type
->SummedLongs(); i
++)
48 sum
+= B_BENDIAN_TO_HOST_INT32(longs
[i
]);
50 #ifdef TRACE_ATARI_PARTITION
52 TRACE(("search_rdb: check sum is incorrect!\n"));
61 // Atari Root Block public module interface
65 atari_std_ops(int32 op
, ...)
78 atari_identify_partition(int fd
, partition_data
*partition
, void **_cookie
)
81 atari_root_block
*arb
= (atari_root_block
*)buffer
;
84 ssize_t bytesRead
= read_pos(fd
, 0, buffer
, sizeof(buffer
));
85 if (bytesRead
< (ssize_t
)sizeof(buffer
)) {
86 TRACE(("%s: read error: %ld\n", __FUNCTION__
, bytesRead
));
89 if (partition
->offset
)
92 if (arb
->Checksum() == 0x55aa)
93 weight
-= 0.1; /* possible but likely a PC sector */
94 if (arb
->_reserved_1
[1] != 0x00)
97 if (arb
->MaxPartitionSize() < 10)
100 if ((arb
->BadSectorsStart()+arb
->BadSectorsCount())*(off_t
)SECTSZ
> partition
->size
)
103 /* check each partition */
104 for (i
= 0; i
< 4; i
++) {
105 struct atari_partition_entry
*p
= &arb
->partitions
[i
];
106 if (p
->Flags() & ATARI_PART_EXISTS
) {
107 /* check for unknown flags */
108 if (p
->Flags() & ~ (ATARI_PART_EXISTS
|ATARI_PART_BOOTABLE
))
110 /* id should be readable */
111 if (!isalnum(p
->id
[0]))
113 if (!isalnum(p
->id
[1]))
115 if (!isalnum(p
->id
[2]))
117 /* make sure partition doesn't overlap bad sector list */
118 if ((arb
->BadSectorsStart() < p
->Start()) &&
119 ((arb
->BadSectorsStart() + arb
->BadSectorsCount()) > p
->Start()))
121 if ((p
->Start()+p
->Size())*(off_t
)SECTSZ
> partition
->size
)
123 /* should check partitions don't overlap each other... */
125 /* empty partition entry, then it must be all null */
126 if (p
->Flags() || p
->id
[0] || p
->id
[1] || p
->id
[2] ||
127 p
->Start() || p
->Size())
133 /* not exactly sure */
134 if (arb
->Checksum() != ATARI_BOOTABLE_MAGIC
)
141 // copy the root block to a new piece of memory
142 arb
= new atari_root_block();
143 memcpy(arb
, buffer
, sizeof(atari_root_block
));
145 *_cookie
= (void *)arb
;
154 atari_scan_partition(int fd
, partition_data
*partition
, void *_cookie
)
156 TRACE(("atari_scan_partition(cookie = %p)\n", _cookie
));
158 atari_root_block
&arb
= *(atari_root_block
*)_cookie
;
160 partition
->status
= B_PARTITION_VALID
;
161 partition
->flags
|= B_PARTITION_PARTITIONING_SYSTEM
162 | B_PARTITION_READ_ONLY
;
163 partition
->content_size
= partition
->size
;
168 status_t status
= B_ENTRY_NOT_FOUND
;
170 for (index
= 0; index
< 4; index
++) {
171 struct atari_partition_entry
*p
= &arb
.partitions
[index
];
172 if (!(p
->Flags() & ATARI_PART_EXISTS
))
174 TRACE(("atari: file system: %.3s\n", p
->id
));
175 if ((p
->Start() + p
->Size())*(uint64
)SECTSZ
> (uint64
)partition
->size
) {
176 TRACE(("atari: child partition exceeds existing space (%Ld bytes)\n", p
->Size()*SECTSZ
));
179 if (!isalnum(p
->id
[0]))
181 if (!isalnum(p
->id
[1]))
183 if (!isalnum(p
->id
[2]))
186 partition_data
*child
= create_child_partition(partition
->id
, index
,
187 partition
->offset
+ p
->Start() * (uint64
)SECTSZ
,
188 p
->Size() * (uint64
)SECTSZ
, -1);
190 TRACE(("atari: Creating child at index %ld failed\n", index
- 1));
193 #warning M68K: use a lookup table ?
194 char type
[] = "??? Partition";
195 memcpy(type
, p
->id
, 3);
196 child
->type
= strdup(type
);
197 child
->block_size
= SECTSZ
;
201 if (status
== B_ENTRY_NOT_FOUND
)
209 atari_free_identify_partition_cookie(partition_data
*partition
, void *_cookie
)
211 delete (atari_root_block
*)_cookie
;
216 static partition_module_info sAtariPartitionModule
= {
218 partition_module_info gAtariPartitionModule
= {
221 ATARI_PARTITION_MODULE_NAME
,
225 "atari", // short_name
226 ATARI_PARTITION_NAME
, // pretty_name
230 atari_identify_partition
, // identify_partition
231 atari_scan_partition
, // scan_partition
232 atari_free_identify_partition_cookie
, // free_identify_partition_cookie
234 // atari_free_partition_cookie, // free_partition_cookie
235 // atari_free_partition_content_cookie, // free_partition_content_cookie
239 partition_module_info
*modules
[] = {
240 &sAtariPartitionModule
,