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