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, §); 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, §2); 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