xref: /openbmc/linux/block/partitions/atari.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
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, &sect);
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, &sect2);
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