2 ** Copyright 2003-2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3 ** Distributed under the terms of the Haiku License.
9 #include <ddm_modules.h>
10 #include <disk_device_types.h>
11 #include <KernelExport.h>
13 # include <boot/partitions.h>
15 # include <DiskDeviceTypes.h>
17 #include <util/kernel_cpp.h>
25 # define TRACE(x) dprintf x
30 #define APPLE_PARTITION_MODULE_NAME "partitioning_systems/apple/v1"
32 static const char *kApplePartitionTypes
[] = {
33 "partition_map", // the partition map itself
34 "Driver", // contains a device driver
35 "Driver43", // the SCSI 4.3 manager
36 "MFS", // Macintosh File System
37 "HFS", // Hierarchical File System (HFS/HFS+)
40 "Free", // unused partition
41 "Scratch", // empty partition
42 "Driver_ATA", // the device driver for an ATA device
43 "Driver_ATAPI", // the device driver for an ATAPI device
44 "Driver43_CD", // an SCSI CD-ROM driver suitable for booting
45 "FWDriver", // a FireWire driver for the device
46 "Void", // dummy partition map entry (used to align entries for CD-ROM)
51 static const char *kOtherPartitionTypes
[] = {
52 "Be_BFS", // Be's BFS (not specified endian)
57 get_next_partition(int fd
, apple_driver_descriptor
&descriptor
, uint32
&cookie
,
58 apple_partition_map
&partition
)
60 uint32 block
= cookie
;
62 // find first partition map if this is the first call,
63 // or else, just load the next block
65 ssize_t bytesRead
= read_pos(fd
, (off_t
)block
* descriptor
.BlockSize(),
66 (void *)&partition
, sizeof(apple_partition_map
));
67 if (bytesRead
< (ssize_t
)sizeof(apple_partition_map
))
71 } while (cookie
== 0 && block
< 64 && !partition
.HasValidSignature());
73 if (!partition
.HasValidSignature()) {
75 return B_ENTRY_NOT_FOUND
;
77 // we searched for the first partition map entry and failed
81 // the first partition map entry must be of type Apple_partition_map
82 if (!cookie
&& (strncmp(partition
.type
, "Apple_", 6)
83 || strcmp(partition
.type
+ 6, kApplePartitionTypes
[0])))
86 // ToDo: warn about unknown types?
94 // Apple public module interface
98 apple_std_ops(int32 op
, ...)
102 case B_MODULE_UNINIT
:
111 apple_identify_partition(int fd
, partition_data
*partition
, void **_cookie
)
113 struct apple_driver_descriptor
*descriptor
;
116 if (read_pos(fd
, 0, buffer
, sizeof(buffer
)) < (ssize_t
)sizeof(buffer
))
119 descriptor
= (apple_driver_descriptor
*)buffer
;
121 TRACE(("apple: read first chunk (signature = %x)\n", descriptor
->signature
));
123 if (!descriptor
->HasValidSignature())
126 TRACE(("apple: valid partition descriptor!\n"));
128 // ToDo: Should probably call get_next_partition() once to know if there
129 // are any partitions on this disk
131 // copy the relevant part of the first block
132 descriptor
= new apple_driver_descriptor();
133 memcpy(descriptor
, buffer
, sizeof(apple_driver_descriptor
));
135 *_cookie
= (void *)descriptor
;
137 // ToDo: reevaluate the priority with ISO-9660 and others in mind
138 // (for CD-ROM only, as far as I can tell)
144 apple_scan_partition(int fd
, partition_data
*partition
, void *_cookie
)
146 TRACE(("apple_scan_partition(cookie = %p)\n", _cookie
));
148 apple_driver_descriptor
&descriptor
= *(apple_driver_descriptor
*)_cookie
;
150 partition
->status
= B_PARTITION_VALID
;
151 partition
->flags
|= B_PARTITION_PARTITIONING_SYSTEM
152 | B_PARTITION_READ_ONLY
;
153 partition
->content_size
= descriptor
.BlockSize() * descriptor
.BlockCount();
157 apple_partition_map partitionMap
;
158 uint32 index
= 0, cookie
= 0;
161 while ((status
= get_next_partition(fd
, descriptor
, cookie
, partitionMap
)) == B_OK
) {
162 TRACE(("apple: found partition: name = \"%s\", type = \"%s\"\n",
163 partitionMap
.name
, partitionMap
.type
));
165 if (partitionMap
.Start(descriptor
) + partitionMap
.Size(descriptor
) > (uint64
)partition
->size
) {
166 TRACE(("apple: child partition exceeds existing space (%Ld bytes)\n",
167 partitionMap
.Size(descriptor
)));
171 partition_data
*child
= create_child_partition(partition
->id
, index
++,
172 partition
->offset
+ partitionMap
.Start(descriptor
),
173 partitionMap
.Size(descriptor
), -1);
175 TRACE(("apple: Creating child at index %ld failed\n", index
- 1));
179 child
->block_size
= partition
->block_size
;
182 if (status
== B_ENTRY_NOT_FOUND
)
190 apple_free_identify_partition_cookie(partition_data
*partition
, void *_cookie
)
192 delete (apple_driver_descriptor
*)_cookie
;
197 static partition_module_info sApplePartitionModule
= {
199 partition_module_info gApplePartitionModule
= {
202 APPLE_PARTITION_MODULE_NAME
,
206 "apple", // short_name
207 APPLE_PARTITION_NAME
, // pretty_name
211 apple_identify_partition
, // identify_partition
212 apple_scan_partition
, // scan_partition
213 apple_free_identify_partition_cookie
, // free_identify_partition_cookie
218 partition_module_info
*modules
[] = {
219 &sApplePartitionModule
,