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