xref: /linux/block/partitions/atari.c (revision fd639726bf15fca8ee1a00dce8e0096d0ad9bd18)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  *  fs/partitions/atari.c
4  *
5  *  Code extracted from drivers/block/genhd.c
6  *
7  *  Copyright (C) 1991-1998  Linus Torvalds
8  *  Re-organised Feb 1998 Russell King
9  */
10 
11 #include <linux/ctype.h>
12 #include "check.h"
13 #include "atari.h"
14 
15 /* ++guenther: this should be settable by the user ("make config")?.
16  */
17 #define ICD_PARTS
18 
19 /* check if a partition entry looks valid -- Atari format is assumed if at
20    least one of the primary entries is ok this way */
21 #define	VALID_PARTITION(pi,hdsiz)					     \
22     (((pi)->flg & 1) &&							     \
23      isalnum((pi)->id[0]) && isalnum((pi)->id[1]) && isalnum((pi)->id[2]) && \
24      be32_to_cpu((pi)->st) <= (hdsiz) &&				     \
25      be32_to_cpu((pi)->st) + be32_to_cpu((pi)->siz) <= (hdsiz))
26 
27 static inline int OK_id(char *s)
28 {
29 	return  memcmp (s, "GEM", 3) == 0 || memcmp (s, "BGM", 3) == 0 ||
30 		memcmp (s, "LNX", 3) == 0 || memcmp (s, "SWP", 3) == 0 ||
31 		memcmp (s, "RAW", 3) == 0 ;
32 }
33 
34 int atari_partition(struct parsed_partitions *state)
35 {
36 	Sector sect;
37 	struct rootsector *rs;
38 	struct partition_info *pi;
39 	u32 extensect;
40 	u32 hd_size;
41 	int slot;
42 #ifdef ICD_PARTS
43 	int part_fmt = 0; /* 0:unknown, 1:AHDI, 2:ICD/Supra */
44 #endif
45 
46 	/*
47 	 * ATARI partition scheme supports 512 lba only.  If this is not
48 	 * the case, bail early to avoid miscalculating hd_size.
49 	 */
50 	if (bdev_logical_block_size(state->bdev) != 512)
51 		return 0;
52 
53 	rs = read_part_sector(state, 0, &sect);
54 	if (!rs)
55 		return -1;
56 
57 	/* Verify this is an Atari rootsector: */
58 	hd_size = state->bdev->bd_inode->i_size >> 9;
59 	if (!VALID_PARTITION(&rs->part[0], hd_size) &&
60 	    !VALID_PARTITION(&rs->part[1], hd_size) &&
61 	    !VALID_PARTITION(&rs->part[2], hd_size) &&
62 	    !VALID_PARTITION(&rs->part[3], hd_size)) {
63 		/*
64 		 * if there's no valid primary partition, assume that no Atari
65 		 * format partition table (there's no reliable magic or the like
66 	         * :-()
67 		 */
68 		put_dev_sector(sect);
69 		return 0;
70 	}
71 
72 	pi = &rs->part[0];
73 	strlcat(state->pp_buf, " AHDI", PAGE_SIZE);
74 	for (slot = 1; pi < &rs->part[4] && slot < state->limit; slot++, pi++) {
75 		struct rootsector *xrs;
76 		Sector sect2;
77 		ulong partsect;
78 
79 		if ( !(pi->flg & 1) )
80 			continue;
81 		/* active partition */
82 		if (memcmp (pi->id, "XGM", 3) != 0) {
83 			/* we don't care about other id's */
84 			put_partition (state, slot, be32_to_cpu(pi->st),
85 					be32_to_cpu(pi->siz));
86 			continue;
87 		}
88 		/* extension partition */
89 #ifdef ICD_PARTS
90 		part_fmt = 1;
91 #endif
92 		strlcat(state->pp_buf, " XGM<", PAGE_SIZE);
93 		partsect = extensect = be32_to_cpu(pi->st);
94 		while (1) {
95 			xrs = read_part_sector(state, partsect, &sect2);
96 			if (!xrs) {
97 				printk (" block %ld read failed\n", partsect);
98 				put_dev_sector(sect);
99 				return -1;
100 			}
101 
102 			/* ++roman: sanity check: bit 0 of flg field must be set */
103 			if (!(xrs->part[0].flg & 1)) {
104 				printk( "\nFirst sub-partition in extended partition is not valid!\n" );
105 				put_dev_sector(sect2);
106 				break;
107 			}
108 
109 			put_partition(state, slot,
110 				   partsect + be32_to_cpu(xrs->part[0].st),
111 				   be32_to_cpu(xrs->part[0].siz));
112 
113 			if (!(xrs->part[1].flg & 1)) {
114 				/* end of linked partition list */
115 				put_dev_sector(sect2);
116 				break;
117 			}
118 			if (memcmp( xrs->part[1].id, "XGM", 3 ) != 0) {
119 				printk("\nID of extended partition is not XGM!\n");
120 				put_dev_sector(sect2);
121 				break;
122 			}
123 
124 			partsect = be32_to_cpu(xrs->part[1].st) + extensect;
125 			put_dev_sector(sect2);
126 			if (++slot == state->limit) {
127 				printk( "\nMaximum number of partitions reached!\n" );
128 				break;
129 			}
130 		}
131 		strlcat(state->pp_buf, " >", PAGE_SIZE);
132 	}
133 #ifdef ICD_PARTS
134 	if ( part_fmt!=1 ) { /* no extended partitions -> test ICD-format */
135 		pi = &rs->icdpart[0];
136 		/* sanity check: no ICD format if first partition invalid */
137 		if (OK_id(pi->id)) {
138 			strlcat(state->pp_buf, " ICD<", PAGE_SIZE);
139 			for (; pi < &rs->icdpart[8] && slot < state->limit; slot++, pi++) {
140 				/* accept only GEM,BGM,RAW,LNX,SWP partitions */
141 				if (!((pi->flg & 1) && OK_id(pi->id)))
142 					continue;
143 				part_fmt = 2;
144 				put_partition (state, slot,
145 						be32_to_cpu(pi->st),
146 						be32_to_cpu(pi->siz));
147 			}
148 			strlcat(state->pp_buf, " >", PAGE_SIZE);
149 		}
150 	}
151 #endif
152 	put_dev_sector(sect);
153 
154 	strlcat(state->pp_buf, "\n", PAGE_SIZE);
155 
156 	return 1;
157 }
158