1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 1996-2000 Russell King. 4 * 5 * Scan ADFS partitions on hard disk drives. Unfortunately, there 6 * isn't a standard for partitioning drives on Acorn machines, so 7 * every single manufacturer of SCSI and IDE cards created their own 8 * method. 9 */ 10 #include <linux/buffer_head.h> 11 #include <linux/adfs_fs.h> 12 13 #include "check.h" 14 15 /* 16 * Partition types. (Oh for reusability) 17 */ 18 #define PARTITION_RISCIX_MFM 1 19 #define PARTITION_RISCIX_SCSI 2 20 #define PARTITION_LINUX 9 21 22 #if defined(CONFIG_ACORN_PARTITION_CUMANA) || \ 23 defined(CONFIG_ACORN_PARTITION_ADFS) 24 static struct adfs_discrecord * 25 adfs_partition(struct parsed_partitions *state, char *name, char *data, 26 unsigned long first_sector, int slot) 27 { 28 struct adfs_discrecord *dr; 29 unsigned int nr_sects; 30 31 if (adfs_checkbblk(data)) 32 return NULL; 33 34 dr = (struct adfs_discrecord *)(data + 0x1c0); 35 36 if (dr->disc_size == 0 && dr->disc_size_high == 0) 37 return NULL; 38 39 nr_sects = (le32_to_cpu(dr->disc_size_high) << 23) | 40 (le32_to_cpu(dr->disc_size) >> 9); 41 42 if (name) { 43 seq_buf_printf(&state->pp_buf, " [%s]", name); 44 } 45 put_partition(state, slot, first_sector, nr_sects); 46 return dr; 47 } 48 #endif 49 50 #ifdef CONFIG_ACORN_PARTITION_RISCIX 51 52 struct riscix_part { 53 __le32 start; 54 __le32 length; 55 __le32 one; 56 char name[16]; 57 }; 58 59 struct riscix_record { 60 __le32 magic; 61 #define RISCIX_MAGIC cpu_to_le32(0x4a657320) 62 __le32 date; 63 struct riscix_part part[8]; 64 }; 65 66 #if defined(CONFIG_ACORN_PARTITION_CUMANA) || \ 67 defined(CONFIG_ACORN_PARTITION_ADFS) 68 static int riscix_partition(struct parsed_partitions *state, 69 unsigned long first_sect, int slot, 70 unsigned long nr_sects) 71 { 72 Sector sect; 73 struct riscix_record *rr; 74 75 rr = read_part_sector(state, first_sect, §); 76 if (!rr) 77 return -1; 78 79 seq_buf_puts(&state->pp_buf, " [RISCiX]"); 80 81 82 if (rr->magic == RISCIX_MAGIC) { 83 unsigned long size = nr_sects > 2 ? 2 : nr_sects; 84 int part; 85 86 seq_buf_puts(&state->pp_buf, " <"); 87 88 put_partition(state, slot++, first_sect, size); 89 for (part = 0; part < 8; part++) { 90 if (rr->part[part].one && 91 memcmp(rr->part[part].name, "All\0", 4)) { 92 put_partition(state, slot++, 93 le32_to_cpu(rr->part[part].start), 94 le32_to_cpu(rr->part[part].length)); 95 seq_buf_printf(&state->pp_buf, "(%s)", rr->part[part].name); 96 } 97 } 98 99 seq_buf_puts(&state->pp_buf, " >\n"); 100 } else { 101 put_partition(state, slot++, first_sect, nr_sects); 102 } 103 104 put_dev_sector(sect); 105 return slot; 106 } 107 #endif 108 #endif 109 110 #define LINUX_NATIVE_MAGIC 0xdeafa1de 111 #define LINUX_SWAP_MAGIC 0xdeafab1e 112 113 struct linux_part { 114 __le32 magic; 115 __le32 start_sect; 116 __le32 nr_sects; 117 }; 118 119 #if defined(CONFIG_ACORN_PARTITION_CUMANA) || \ 120 defined(CONFIG_ACORN_PARTITION_ADFS) 121 static int linux_partition(struct parsed_partitions *state, 122 unsigned long first_sect, int slot, 123 unsigned long nr_sects) 124 { 125 Sector sect; 126 struct linux_part *linuxp; 127 unsigned long size = nr_sects > 2 ? 2 : nr_sects; 128 129 seq_buf_puts(&state->pp_buf, " [Linux]"); 130 131 put_partition(state, slot++, first_sect, size); 132 133 linuxp = read_part_sector(state, first_sect, §); 134 if (!linuxp) 135 return -1; 136 137 seq_buf_puts(&state->pp_buf, " <"); 138 while (linuxp->magic == cpu_to_le32(LINUX_NATIVE_MAGIC) || 139 linuxp->magic == cpu_to_le32(LINUX_SWAP_MAGIC)) { 140 if (slot == state->limit) 141 break; 142 put_partition(state, slot++, first_sect + 143 le32_to_cpu(linuxp->start_sect), 144 le32_to_cpu(linuxp->nr_sects)); 145 linuxp ++; 146 } 147 seq_buf_puts(&state->pp_buf, " >"); 148 149 put_dev_sector(sect); 150 return slot; 151 } 152 #endif 153 154 #ifdef CONFIG_ACORN_PARTITION_CUMANA 155 int adfspart_check_CUMANA(struct parsed_partitions *state) 156 { 157 unsigned long first_sector = 0; 158 unsigned int start_blk = 0; 159 Sector sect; 160 unsigned char *data; 161 char *name = "CUMANA/ADFS"; 162 int first = 1; 163 int slot = 1; 164 165 /* 166 * Try Cumana style partitions - sector 6 contains ADFS boot block 167 * with pointer to next 'drive'. 168 * 169 * There are unknowns in this code - is the 'cylinder number' of the 170 * next partition relative to the start of this one - I'm assuming 171 * it is. 172 * 173 * Also, which ID did Cumana use? 174 * 175 * This is totally unfinished, and will require more work to get it 176 * going. Hence it is totally untested. 177 */ 178 do { 179 struct adfs_discrecord *dr; 180 unsigned int nr_sects; 181 182 data = read_part_sector(state, start_blk * 2 + 6, §); 183 if (!data) 184 return -1; 185 186 if (slot == state->limit) 187 break; 188 189 dr = adfs_partition(state, name, data, first_sector, slot++); 190 if (!dr) 191 break; 192 193 name = NULL; 194 195 nr_sects = (data[0x1fd] + (data[0x1fe] << 8)) * 196 (dr->heads + (dr->lowsector & 0x40 ? 1 : 0)) * 197 dr->secspertrack; 198 199 if (!nr_sects) 200 break; 201 202 first = 0; 203 first_sector += nr_sects; 204 start_blk += nr_sects >> (BLOCK_SIZE_BITS - 9); 205 nr_sects = 0; /* hmm - should be partition size */ 206 207 switch (data[0x1fc] & 15) { 208 case 0: /* No partition / ADFS? */ 209 break; 210 211 #ifdef CONFIG_ACORN_PARTITION_RISCIX 212 case PARTITION_RISCIX_SCSI: 213 /* RISCiX - we don't know how to find the next one. */ 214 slot = riscix_partition(state, first_sector, slot, 215 nr_sects); 216 break; 217 #endif 218 219 case PARTITION_LINUX: 220 slot = linux_partition(state, first_sector, slot, 221 nr_sects); 222 break; 223 } 224 put_dev_sector(sect); 225 if (slot == -1) 226 return -1; 227 } while (1); 228 put_dev_sector(sect); 229 return first ? 0 : 1; 230 } 231 #endif 232 233 #ifdef CONFIG_ACORN_PARTITION_ADFS 234 /* 235 * Purpose: allocate ADFS partitions. 236 * 237 * Params : hd - pointer to gendisk structure to store partition info. 238 * dev - device number to access. 239 * 240 * Returns: -1 on error, 0 for no ADFS boot sector, 1 for ok. 241 * 242 * Alloc : hda = whole drive 243 * hda1 = ADFS partition on first drive. 244 * hda2 = non-ADFS partition. 245 */ 246 int adfspart_check_ADFS(struct parsed_partitions *state) 247 { 248 unsigned long start_sect, nr_sects, sectscyl, heads; 249 Sector sect; 250 unsigned char *data; 251 struct adfs_discrecord *dr; 252 unsigned char id; 253 int slot = 1; 254 255 data = read_part_sector(state, 6, §); 256 if (!data) 257 return -1; 258 259 dr = adfs_partition(state, "ADFS", data, 0, slot++); 260 if (!dr) { 261 put_dev_sector(sect); 262 return 0; 263 } 264 265 heads = dr->heads + ((dr->lowsector >> 6) & 1); 266 sectscyl = dr->secspertrack * heads; 267 start_sect = ((data[0x1fe] << 8) + data[0x1fd]) * sectscyl; 268 id = data[0x1fc] & 15; 269 put_dev_sector(sect); 270 271 /* 272 * Work out start of non-adfs partition. 273 */ 274 nr_sects = get_capacity(state->disk) - start_sect; 275 276 if (start_sect) { 277 switch (id) { 278 #ifdef CONFIG_ACORN_PARTITION_RISCIX 279 case PARTITION_RISCIX_SCSI: 280 case PARTITION_RISCIX_MFM: 281 riscix_partition(state, start_sect, slot, 282 nr_sects); 283 break; 284 #endif 285 286 case PARTITION_LINUX: 287 linux_partition(state, start_sect, slot, 288 nr_sects); 289 break; 290 } 291 } 292 seq_buf_puts(&state->pp_buf, "\n"); 293 return 1; 294 } 295 #endif 296 297 #ifdef CONFIG_ACORN_PARTITION_ICS 298 299 struct ics_part { 300 __le32 start; 301 __le32 size; 302 }; 303 304 static int adfspart_check_ICSLinux(struct parsed_partitions *state, 305 unsigned long block) 306 { 307 Sector sect; 308 unsigned char *data = read_part_sector(state, block, §); 309 int result = 0; 310 311 if (data) { 312 if (memcmp(data, "LinuxPart", 9) == 0) 313 result = 1; 314 put_dev_sector(sect); 315 } 316 317 return result; 318 } 319 320 /* 321 * Check for a valid ICS partition using the checksum. 322 */ 323 static inline int valid_ics_sector(const unsigned char *data) 324 { 325 unsigned long sum; 326 int i; 327 328 for (i = 0, sum = 0x50617274; i < 508; i++) 329 sum += data[i]; 330 331 sum -= le32_to_cpu(*(__le32 *)(&data[508])); 332 333 return sum == 0; 334 } 335 336 /* 337 * Purpose: allocate ICS partitions. 338 * Params : hd - pointer to gendisk structure to store partition info. 339 * dev - device number to access. 340 * Returns: -1 on error, 0 for no ICS table, 1 for partitions ok. 341 * Alloc : hda = whole drive 342 * hda1 = ADFS partition 0 on first drive. 343 * hda2 = ADFS partition 1 on first drive. 344 * ..etc.. 345 */ 346 int adfspart_check_ICS(struct parsed_partitions *state) 347 { 348 const unsigned char *data; 349 const struct ics_part *p; 350 int slot; 351 Sector sect; 352 353 /* 354 * Try ICS style partitions - sector 0 contains partition info. 355 */ 356 data = read_part_sector(state, 0, §); 357 if (!data) 358 return -1; 359 360 if (!valid_ics_sector(data)) { 361 put_dev_sector(sect); 362 return 0; 363 } 364 365 seq_buf_puts(&state->pp_buf, " [ICS]"); 366 367 for (slot = 1, p = (const struct ics_part *)data; p->size; p++) { 368 u32 start = le32_to_cpu(p->start); 369 s32 size = le32_to_cpu(p->size); /* yes, it's signed. */ 370 371 if (slot == state->limit) 372 break; 373 374 /* 375 * Negative sizes tell the RISC OS ICS driver to ignore 376 * this partition - in effect it says that this does not 377 * contain an ADFS filesystem. 378 */ 379 if (size < 0) { 380 size = -size; 381 382 /* 383 * Our own extension - We use the first sector 384 * of the partition to identify what type this 385 * partition is. We must not make this visible 386 * to the filesystem. 387 */ 388 if (size > 1 && adfspart_check_ICSLinux(state, start)) { 389 start += 1; 390 size -= 1; 391 } 392 } 393 394 if (size) 395 put_partition(state, slot++, start, size); 396 } 397 398 put_dev_sector(sect); 399 seq_buf_puts(&state->pp_buf, "\n"); 400 return 1; 401 } 402 #endif 403 404 #ifdef CONFIG_ACORN_PARTITION_POWERTEC 405 struct ptec_part { 406 __le32 unused1; 407 __le32 unused2; 408 __le32 start; 409 __le32 size; 410 __le32 unused5; 411 char type[8]; 412 }; 413 414 static inline int valid_ptec_sector(const unsigned char *data) 415 { 416 unsigned char checksum = 0x2a; 417 int i; 418 419 /* 420 * If it looks like a PC/BIOS partition, then it 421 * probably isn't PowerTec. 422 */ 423 if (data[510] == 0x55 && data[511] == 0xaa) 424 return 0; 425 426 for (i = 0; i < 511; i++) 427 checksum += data[i]; 428 429 return checksum == data[511]; 430 } 431 432 /* 433 * Purpose: allocate ICS partitions. 434 * Params : hd - pointer to gendisk structure to store partition info. 435 * dev - device number to access. 436 * Returns: -1 on error, 0 for no ICS table, 1 for partitions ok. 437 * Alloc : hda = whole drive 438 * hda1 = ADFS partition 0 on first drive. 439 * hda2 = ADFS partition 1 on first drive. 440 * ..etc.. 441 */ 442 int adfspart_check_POWERTEC(struct parsed_partitions *state) 443 { 444 Sector sect; 445 const unsigned char *data; 446 const struct ptec_part *p; 447 int slot = 1; 448 int i; 449 450 data = read_part_sector(state, 0, §); 451 if (!data) 452 return -1; 453 454 if (!valid_ptec_sector(data)) { 455 put_dev_sector(sect); 456 return 0; 457 } 458 459 seq_buf_puts(&state->pp_buf, " [POWERTEC]"); 460 461 for (i = 0, p = (const struct ptec_part *)data; i < 12; i++, p++) { 462 u32 start = le32_to_cpu(p->start); 463 u32 size = le32_to_cpu(p->size); 464 465 if (size) 466 put_partition(state, slot++, start, size); 467 } 468 469 put_dev_sector(sect); 470 seq_buf_puts(&state->pp_buf, "\n"); 471 return 1; 472 } 473 #endif 474 475 #ifdef CONFIG_ACORN_PARTITION_EESOX 476 struct eesox_part { 477 char magic[6]; 478 char name[10]; 479 __le32 start; 480 __le32 unused6; 481 __le32 unused7; 482 __le32 unused8; 483 }; 484 485 /* 486 * Guess who created this format? 487 */ 488 static const char eesox_name[] = { 489 'N', 'e', 'i', 'l', ' ', 490 'C', 'r', 'i', 't', 'c', 'h', 'e', 'l', 'l', ' ', ' ' 491 }; 492 493 /* 494 * EESOX SCSI partition format. 495 * 496 * This is a goddamned awful partition format. We don't seem to store 497 * the size of the partition in this table, only the start addresses. 498 * 499 * There are two possibilities where the size comes from: 500 * 1. The individual ADFS boot block entries that are placed on the disk. 501 * 2. The start address of the next entry. 502 */ 503 int adfspart_check_EESOX(struct parsed_partitions *state) 504 { 505 Sector sect; 506 const unsigned char *data; 507 unsigned char buffer[256]; 508 struct eesox_part *p; 509 sector_t start = 0; 510 int i, slot = 1; 511 512 data = read_part_sector(state, 7, §); 513 if (!data) 514 return -1; 515 516 /* 517 * "Decrypt" the partition table. God knows why... 518 */ 519 for (i = 0; i < 256; i++) 520 buffer[i] = data[i] ^ eesox_name[i & 15]; 521 522 put_dev_sector(sect); 523 524 for (i = 0, p = (struct eesox_part *)buffer; i < 8; i++, p++) { 525 sector_t next; 526 527 if (memcmp(p->magic, "Eesox", 6)) 528 break; 529 530 next = le32_to_cpu(p->start); 531 if (i) 532 put_partition(state, slot++, start, next - start); 533 start = next; 534 } 535 536 if (i != 0) { 537 sector_t size; 538 539 size = get_capacity(state->disk); 540 put_partition(state, slot++, start, size - start); 541 seq_buf_puts(&state->pp_buf, "\n"); 542 } 543 544 return i ? 1 : 0; 545 } 546 #endif 547