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