Merge tag 'defconfig-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
[linux-2.6-microblaze.git] / block / partitions / atari.c
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 (queue_logical_block_size(state->disk->queue) != 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 = get_capacity(state->disk);
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 }