1/* 2 * Copyright 2003-2004, Axel D��rfler, axeld@pinc-software.de. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7#include "atari.h" 8 9#include <ByteOrder.h> 10#include <KernelExport.h> 11#include <ddm_modules.h> 12#ifdef _BOOT_MODE 13# include <boot/partitions.h> 14#else 15# include <DiskDeviceTypes.h> 16#endif 17#include <util/kernel_cpp.h> 18 19#include <unistd.h> 20#include <string.h> 21#include <ctype.h> 22 23#define SECTSZ 512 24 25//#define TRACE_ATARI_PARTITION 26#ifdef TRACE_ATARI_PARTITION 27# define TRACE(x) dprintf x 28#else 29# define TRACE(x) ; 30#endif 31 32 33#define ATARI_PARTITION_MODULE_NAME "partitioning_systems/atari/v1" 34#define ATARI_PARTITION_NAME "Atari Partition Map" 35 36 37#if 0 38template<typename Type> bool 39validate_check_sum(Type *type) 40{ 41 if (type->SummedLongs() != sizeof(*type) / sizeof(uint32)) 42 return false; 43 44 // check checksum 45 uint32 *longs = (uint32 *)type; 46 uint32 sum = 0; 47 for (uint32 i = 0; i < type->SummedLongs(); i++) 48 sum += B_BENDIAN_TO_HOST_INT32(longs[i]); 49 50#ifdef TRACE_ATARI_PARTITION 51 if (sum != 0) 52 TRACE(("search_rdb: check sum is incorrect!\n")); 53#endif 54 55 return sum == 0; 56} 57#endif 58 59 60// #pragma mark - 61// Atari Root Block public module interface 62 63 64static status_t 65atari_std_ops(int32 op, ...) 66{ 67 switch (op) { 68 case B_MODULE_INIT: 69 case B_MODULE_UNINIT: 70 return B_OK; 71 } 72 73 return B_ERROR; 74} 75 76 77static float 78atari_identify_partition(int fd, partition_data *partition, void **_cookie) 79{ 80 uint8 buffer[512]; 81 atari_root_block *arb = (atari_root_block *)buffer; 82 float weight = 0.5; 83 int i; 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)); 87 return B_ERROR; 88 } 89 if (partition->offset) 90 return B_ERROR; 91 92 if (arb->Checksum() == 0x55aa) 93 weight -= 0.1; /* possible but likely a PC sector */ 94 if (arb->_reserved_1[0] != 0x00) 95 weight -= 10; 96 /* hope so */ 97 if (arb->MaxPartitionSize() < 10) 98 weight -= 20; 99 100 if ((arb->BadSectorsStart()+arb->BadSectorsCount())*(off_t)SECTSZ > partition->size) 101 return B_ERROR; 102 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)) 109 weight -= 10.0; 110 /* id should be readable */ 111 if (!isalnum(p->id[0])) 112 weight -= 1.0; 113 if (!isalnum(p->id[1])) 114 weight -= 1.0; 115 if (!isalnum(p->id[2])) 116 weight -= 1.0; 117 /* make sure partition doesn't overlap bad sector list */ 118 if ((arb->BadSectorsStart() < p->Start()) && 119 ((arb->BadSectorsStart() + arb->BadSectorsCount()) > p->Start())) 120 weight -= 10; 121 if ((p->Start()+p->Size())*(off_t)SECTSZ > partition->size) 122 return B_ERROR; 123 /* should check partitions don't overlap each other... */ 124 } else { 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()) 128 weight -= 10.0; 129 else 130 weight += 0.1; 131 } 132 } 133 /* not exactly sure */ 134 if (arb->Checksum() != ATARI_BOOTABLE_MAGIC) 135 weight -= 0.1; 136 137 if (weight > 1.0) 138 weight = 1.0; 139 140 if (weight > 0.0) { 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)); 144 145 *_cookie = (void *)arb; 146 return weight; 147 } 148 149 return B_ERROR; 150} 151 152 153static status_t 154atari_scan_partition(int fd, partition_data *partition, void *_cookie) 155{ 156 TRACE(("atari_scan_partition(cookie = %p)\n", _cookie)); 157 158 atari_root_block &arb = *(atari_root_block *)_cookie; 159 160 partition->status = B_PARTITION_VALID; 161 partition->flags |= B_PARTITION_PARTITIONING_SYSTEM 162 | B_PARTITION_READ_ONLY; 163 partition->content_size = partition->size; 164 165 // scan all children 166 167 uint32 index = 0; 168 status_t status = B_ENTRY_NOT_FOUND; 169 170 for (index = 0; index < 4; index++) { 171 struct atari_partition_entry *p = &arb.partitions[index]; 172 if (!(p->Flags() & ATARI_PART_EXISTS)) 173 continue; 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 (%lld bytes)\n", p->Size()*SECTSZ)); 177 continue; 178 } 179 if (!isalnum(p->id[0])) 180 continue; 181 if (!isalnum(p->id[1])) 182 continue; 183 if (!isalnum(p->id[2])) 184 continue; 185 186 partition_data *child = create_child_partition(partition->id, index, 187 partition->offset + p->Start() * (uint64)SECTSZ, 188 p->Size() * (uint64)SECTSZ, -1); 189 if (child == NULL) { 190 TRACE(("atari: Creating child at index %ld failed\n", index - 1)); 191 return B_ERROR; 192 } 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; 198 status = B_OK; 199 } 200 201 if (status == B_ENTRY_NOT_FOUND) 202 return B_OK; 203 204 return status; 205} 206 207 208static void 209atari_free_identify_partition_cookie(partition_data *partition, void *_cookie) 210{ 211 delete (atari_root_block *)_cookie; 212} 213 214 215#ifndef _BOOT_MODE 216static partition_module_info sAtariPartitionModule = { 217#else 218partition_module_info gAtariPartitionModule = { 219#endif 220 { 221 ATARI_PARTITION_MODULE_NAME, 222 0, 223 atari_std_ops 224 }, 225 "atari", // short_name 226 ATARI_PARTITION_NAME, // pretty_name 227 0, // flags 228 229 // scanning 230 atari_identify_partition, // identify_partition 231 atari_scan_partition, // scan_partition 232 atari_free_identify_partition_cookie, // free_identify_partition_cookie 233 NULL, 234// atari_free_partition_cookie, // free_partition_cookie 235// atari_free_partition_content_cookie, // free_partition_content_cookie 236}; 237 238#ifndef _BOOT_MODE 239partition_module_info *modules[] = { 240 &sAtariPartitionModule, 241 NULL 242}; 243#endif 244