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