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 rs = read_part_sector(state, 0, §); 46 if (!rs) 47 return -1; 48 49 /* Verify this is an Atari rootsector: */ 50 hd_size = state->bdev->bd_inode->i_size >> 9; 51 if (!VALID_PARTITION(&rs->part[0], hd_size) && 52 !VALID_PARTITION(&rs->part[1], hd_size) && 53 !VALID_PARTITION(&rs->part[2], hd_size) && 54 !VALID_PARTITION(&rs->part[3], hd_size)) { 55 /* 56 * if there's no valid primary partition, assume that no Atari 57 * format partition table (there's no reliable magic or the like 58 * :-() 59 */ 60 put_dev_sector(sect); 61 return 0; 62 } 63 64 pi = &rs->part[0]; 65 strlcat(state->pp_buf, " AHDI", PAGE_SIZE); 66 for (slot = 1; pi < &rs->part[4] && slot < state->limit; slot++, pi++) { 67 struct rootsector *xrs; 68 Sector sect2; 69 ulong partsect; 70 71 if ( !(pi->flg & 1) ) 72 continue; 73 /* active partition */ 74 if (memcmp (pi->id, "XGM", 3) != 0) { 75 /* we don't care about other id's */ 76 put_partition (state, slot, be32_to_cpu(pi->st), 77 be32_to_cpu(pi->siz)); 78 continue; 79 } 80 /* extension partition */ 81 #ifdef ICD_PARTS 82 part_fmt = 1; 83 #endif 84 strlcat(state->pp_buf, " XGM<", PAGE_SIZE); 85 partsect = extensect = be32_to_cpu(pi->st); 86 while (1) { 87 xrs = read_part_sector(state, partsect, §2); 88 if (!xrs) { 89 printk (" block %ld read failed\n", partsect); 90 put_dev_sector(sect); 91 return -1; 92 } 93 94 /* ++roman: sanity check: bit 0 of flg field must be set */ 95 if (!(xrs->part[0].flg & 1)) { 96 printk( "\nFirst sub-partition in extended partition is not valid!\n" ); 97 put_dev_sector(sect2); 98 break; 99 } 100 101 put_partition(state, slot, 102 partsect + be32_to_cpu(xrs->part[0].st), 103 be32_to_cpu(xrs->part[0].siz)); 104 105 if (!(xrs->part[1].flg & 1)) { 106 /* end of linked partition list */ 107 put_dev_sector(sect2); 108 break; 109 } 110 if (memcmp( xrs->part[1].id, "XGM", 3 ) != 0) { 111 printk("\nID of extended partition is not XGM!\n"); 112 put_dev_sector(sect2); 113 break; 114 } 115 116 partsect = be32_to_cpu(xrs->part[1].st) + extensect; 117 put_dev_sector(sect2); 118 if (++slot == state->limit) { 119 printk( "\nMaximum number of partitions reached!\n" ); 120 break; 121 } 122 } 123 strlcat(state->pp_buf, " >", PAGE_SIZE); 124 } 125 #ifdef ICD_PARTS 126 if ( part_fmt!=1 ) { /* no extended partitions -> test ICD-format */ 127 pi = &rs->icdpart[0]; 128 /* sanity check: no ICD format if first partition invalid */ 129 if (OK_id(pi->id)) { 130 strlcat(state->pp_buf, " ICD<", PAGE_SIZE); 131 for (; pi < &rs->icdpart[8] && slot < state->limit; slot++, pi++) { 132 /* accept only GEM,BGM,RAW,LNX,SWP partitions */ 133 if (!((pi->flg & 1) && OK_id(pi->id))) 134 continue; 135 part_fmt = 2; 136 put_partition (state, slot, 137 be32_to_cpu(pi->st), 138 be32_to_cpu(pi->siz)); 139 } 140 strlcat(state->pp_buf, " >", PAGE_SIZE); 141 } 142 } 143 #endif 144 put_dev_sector(sect); 145 146 strlcat(state->pp_buf, "\n", PAGE_SIZE); 147 148 return 1; 149 } 150