1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
29be96f3fSAl Viro /*
39be96f3fSAl Viro * fs/partitions/atari.c
49be96f3fSAl Viro *
59be96f3fSAl Viro * Code extracted from drivers/block/genhd.c
69be96f3fSAl Viro *
79be96f3fSAl Viro * Copyright (C) 1991-1998 Linus Torvalds
89be96f3fSAl Viro * Re-organised Feb 1998 Russell King
99be96f3fSAl Viro */
109be96f3fSAl Viro
119be96f3fSAl Viro #include <linux/ctype.h>
129be96f3fSAl Viro #include "check.h"
139be96f3fSAl Viro #include "atari.h"
149be96f3fSAl Viro
159be96f3fSAl Viro /* ++guenther: this should be settable by the user ("make config")?.
169be96f3fSAl Viro */
179be96f3fSAl Viro #define ICD_PARTS
189be96f3fSAl Viro
199be96f3fSAl Viro /* check if a partition entry looks valid -- Atari format is assumed if at
209be96f3fSAl Viro least one of the primary entries is ok this way */
219be96f3fSAl Viro #define VALID_PARTITION(pi,hdsiz) \
229be96f3fSAl Viro (((pi)->flg & 1) && \
239be96f3fSAl Viro isalnum((pi)->id[0]) && isalnum((pi)->id[1]) && isalnum((pi)->id[2]) && \
249be96f3fSAl Viro be32_to_cpu((pi)->st) <= (hdsiz) && \
259be96f3fSAl Viro be32_to_cpu((pi)->st) + be32_to_cpu((pi)->siz) <= (hdsiz))
269be96f3fSAl Viro
OK_id(char * s)279be96f3fSAl Viro static inline int OK_id(char *s)
289be96f3fSAl Viro {
299be96f3fSAl Viro return memcmp (s, "GEM", 3) == 0 || memcmp (s, "BGM", 3) == 0 ||
309be96f3fSAl Viro memcmp (s, "LNX", 3) == 0 || memcmp (s, "SWP", 3) == 0 ||
319be96f3fSAl Viro memcmp (s, "RAW", 3) == 0 ;
329be96f3fSAl Viro }
339be96f3fSAl Viro
atari_partition(struct parsed_partitions * state)349be96f3fSAl Viro int atari_partition(struct parsed_partitions *state)
359be96f3fSAl Viro {
369be96f3fSAl Viro Sector sect;
379be96f3fSAl Viro struct rootsector *rs;
389be96f3fSAl Viro struct partition_info *pi;
399be96f3fSAl Viro u32 extensect;
409be96f3fSAl Viro u32 hd_size;
419be96f3fSAl Viro int slot;
429be96f3fSAl Viro #ifdef ICD_PARTS
439be96f3fSAl Viro int part_fmt = 0; /* 0:unknown, 1:AHDI, 2:ICD/Supra */
449be96f3fSAl Viro #endif
459be96f3fSAl Viro
469c874716SGabriel Krisman Bertazi /*
479c874716SGabriel Krisman Bertazi * ATARI partition scheme supports 512 lba only. If this is not
489c874716SGabriel Krisman Bertazi * the case, bail early to avoid miscalculating hd_size.
499c874716SGabriel Krisman Bertazi */
50*a08aa9bcSChristoph Hellwig if (queue_logical_block_size(state->disk->queue) != 512)
519c874716SGabriel Krisman Bertazi return 0;
529c874716SGabriel Krisman Bertazi
539be96f3fSAl Viro rs = read_part_sector(state, 0, §);
549be96f3fSAl Viro if (!rs)
559be96f3fSAl Viro return -1;
569be96f3fSAl Viro
579be96f3fSAl Viro /* Verify this is an Atari rootsector: */
58*a08aa9bcSChristoph Hellwig hd_size = get_capacity(state->disk);
599be96f3fSAl Viro if (!VALID_PARTITION(&rs->part[0], hd_size) &&
609be96f3fSAl Viro !VALID_PARTITION(&rs->part[1], hd_size) &&
619be96f3fSAl Viro !VALID_PARTITION(&rs->part[2], hd_size) &&
629be96f3fSAl Viro !VALID_PARTITION(&rs->part[3], hd_size)) {
639be96f3fSAl Viro /*
649be96f3fSAl Viro * if there's no valid primary partition, assume that no Atari
659be96f3fSAl Viro * format partition table (there's no reliable magic or the like
669be96f3fSAl Viro * :-()
679be96f3fSAl Viro */
689be96f3fSAl Viro put_dev_sector(sect);
699be96f3fSAl Viro return 0;
709be96f3fSAl Viro }
719be96f3fSAl Viro
729be96f3fSAl Viro pi = &rs->part[0];
739be96f3fSAl Viro strlcat(state->pp_buf, " AHDI", PAGE_SIZE);
749be96f3fSAl Viro for (slot = 1; pi < &rs->part[4] && slot < state->limit; slot++, pi++) {
759be96f3fSAl Viro struct rootsector *xrs;
769be96f3fSAl Viro Sector sect2;
779be96f3fSAl Viro ulong partsect;
789be96f3fSAl Viro
799be96f3fSAl Viro if ( !(pi->flg & 1) )
809be96f3fSAl Viro continue;
819be96f3fSAl Viro /* active partition */
829be96f3fSAl Viro if (memcmp (pi->id, "XGM", 3) != 0) {
839be96f3fSAl Viro /* we don't care about other id's */
849be96f3fSAl Viro put_partition (state, slot, be32_to_cpu(pi->st),
859be96f3fSAl Viro be32_to_cpu(pi->siz));
869be96f3fSAl Viro continue;
879be96f3fSAl Viro }
889be96f3fSAl Viro /* extension partition */
899be96f3fSAl Viro #ifdef ICD_PARTS
909be96f3fSAl Viro part_fmt = 1;
919be96f3fSAl Viro #endif
929be96f3fSAl Viro strlcat(state->pp_buf, " XGM<", PAGE_SIZE);
939be96f3fSAl Viro partsect = extensect = be32_to_cpu(pi->st);
949be96f3fSAl Viro while (1) {
959be96f3fSAl Viro xrs = read_part_sector(state, partsect, §2);
969be96f3fSAl Viro if (!xrs) {
979be96f3fSAl Viro printk (" block %ld read failed\n", partsect);
989be96f3fSAl Viro put_dev_sector(sect);
999be96f3fSAl Viro return -1;
1009be96f3fSAl Viro }
1019be96f3fSAl Viro
1029be96f3fSAl Viro /* ++roman: sanity check: bit 0 of flg field must be set */
1039be96f3fSAl Viro if (!(xrs->part[0].flg & 1)) {
1049be96f3fSAl Viro printk( "\nFirst sub-partition in extended partition is not valid!\n" );
1059be96f3fSAl Viro put_dev_sector(sect2);
1069be96f3fSAl Viro break;
1079be96f3fSAl Viro }
1089be96f3fSAl Viro
1099be96f3fSAl Viro put_partition(state, slot,
1109be96f3fSAl Viro partsect + be32_to_cpu(xrs->part[0].st),
1119be96f3fSAl Viro be32_to_cpu(xrs->part[0].siz));
1129be96f3fSAl Viro
1139be96f3fSAl Viro if (!(xrs->part[1].flg & 1)) {
1149be96f3fSAl Viro /* end of linked partition list */
1159be96f3fSAl Viro put_dev_sector(sect2);
1169be96f3fSAl Viro break;
1179be96f3fSAl Viro }
1189be96f3fSAl Viro if (memcmp( xrs->part[1].id, "XGM", 3 ) != 0) {
1199be96f3fSAl Viro printk("\nID of extended partition is not XGM!\n");
1209be96f3fSAl Viro put_dev_sector(sect2);
1219be96f3fSAl Viro break;
1229be96f3fSAl Viro }
1239be96f3fSAl Viro
1249be96f3fSAl Viro partsect = be32_to_cpu(xrs->part[1].st) + extensect;
1259be96f3fSAl Viro put_dev_sector(sect2);
1269be96f3fSAl Viro if (++slot == state->limit) {
1279be96f3fSAl Viro printk( "\nMaximum number of partitions reached!\n" );
1289be96f3fSAl Viro break;
1299be96f3fSAl Viro }
1309be96f3fSAl Viro }
1319be96f3fSAl Viro strlcat(state->pp_buf, " >", PAGE_SIZE);
1329be96f3fSAl Viro }
1339be96f3fSAl Viro #ifdef ICD_PARTS
1349be96f3fSAl Viro if ( part_fmt!=1 ) { /* no extended partitions -> test ICD-format */
1359be96f3fSAl Viro pi = &rs->icdpart[0];
1369be96f3fSAl Viro /* sanity check: no ICD format if first partition invalid */
1379be96f3fSAl Viro if (OK_id(pi->id)) {
1389be96f3fSAl Viro strlcat(state->pp_buf, " ICD<", PAGE_SIZE);
1399be96f3fSAl Viro for (; pi < &rs->icdpart[8] && slot < state->limit; slot++, pi++) {
1409be96f3fSAl Viro /* accept only GEM,BGM,RAW,LNX,SWP partitions */
1419be96f3fSAl Viro if (!((pi->flg & 1) && OK_id(pi->id)))
1429be96f3fSAl Viro continue;
1439be96f3fSAl Viro put_partition (state, slot,
1449be96f3fSAl Viro be32_to_cpu(pi->st),
1459be96f3fSAl Viro be32_to_cpu(pi->siz));
1469be96f3fSAl Viro }
1479be96f3fSAl Viro strlcat(state->pp_buf, " >", PAGE_SIZE);
1489be96f3fSAl Viro }
1499be96f3fSAl Viro }
1509be96f3fSAl Viro #endif
1519be96f3fSAl Viro put_dev_sector(sect);
1529be96f3fSAl Viro
1539be96f3fSAl Viro strlcat(state->pp_buf, "\n", PAGE_SIZE);
1549be96f3fSAl Viro
1559be96f3fSAl Viro return 1;
1569be96f3fSAl Viro }
157