Import changeset
[linux-flexiantxendom0-3.2.10.git] / fs / partitions / atari.c
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/fs.h>
11 #include <linux/genhd.h>
12 #include <linux/kernel.h>
13 #include <linux/major.h>
14 #include <linux/string.h>
15 #include <linux/blk.h>
16 #include <linux/ctype.h>
17
18 #include <asm/byteorder.h>
19 #include <asm/system.h>
20
21 #include "check.h"
22 #include "atari.h"
23
24 /* ++guenther: this should be settable by the user ("make config")?.
25  */
26 #define ICD_PARTS
27
28 /* check if a partition entry looks valid -- Atari format is assumed if at
29    least one of the primary entries is ok this way */
30 #define VALID_PARTITION(pi,hdsiz)                                            \
31     (((pi)->flg & 1) &&                                                      \
32      isalnum((pi)->id[0]) && isalnum((pi)->id[1]) && isalnum((pi)->id[2]) && \
33      be32_to_cpu((pi)->st) <= (hdsiz) &&                                     \
34      be32_to_cpu((pi)->st) + be32_to_cpu((pi)->siz) <= (hdsiz))
35
36 int atari_partition (struct gendisk *hd, kdev_t dev,
37                      unsigned long first_sector, int minor)
38 {
39   int m_lim = minor + hd->max_p;
40   struct buffer_head *bh;
41   struct rootsector *rs;
42   struct partition_info *pi;
43   u32 extensect;
44   u32 hd_size;
45 #ifdef ICD_PARTS
46   int part_fmt = 0; /* 0:unknown, 1:AHDI, 2:ICD/Supra */
47 #endif
48
49   bh = bread (dev, 0, get_ptable_blocksize(dev));
50   if (!bh) {
51       if (warn_no_part) printk (" unable to read block 0 (partition table)\n");
52       return -1;
53   }
54
55   /* Verify this is an Atari rootsector: */
56   rs = (struct rootsector *) bh->b_data;
57   hd_size = hd->part[minor - 1].nr_sects;
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       /* if there's no valid primary partition, assume that no Atari
63          format partition table (there's no reliable magic or the like
64          :-() */
65       brelse(bh);
66       return 0;
67   }
68
69   pi = &rs->part[0];
70   printk (" AHDI");
71   for (; pi < &rs->part[4] && minor < m_lim; minor++, pi++)
72     {
73       if (pi->flg & 1)
74         /* active partition */
75         {
76           if (memcmp (pi->id, "XGM", 3) == 0)
77             /* extension partition */
78             {
79               struct rootsector *xrs;
80               struct buffer_head *xbh;
81               ulong partsect;
82
83 #ifdef ICD_PARTS
84               part_fmt = 1;
85 #endif
86               printk(" XGM<");
87               partsect = extensect = be32_to_cpu(pi->st);
88               while (1)
89                 {
90                   xbh = bread (dev, partsect / 2, get_ptable_blocksize(dev));
91                   if (!xbh)
92                     {
93                       printk (" block %ld read failed\n", partsect);
94                       brelse(bh);
95                       return 0;
96                     }
97                   if (partsect & 1)
98                     xrs = (struct rootsector *) &xbh->b_data[512];
99                   else
100                     xrs = (struct rootsector *) &xbh->b_data[0];
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                     break;
106                   }
107
108                   add_gd_partition(hd, minor,
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                     brelse( xbh );
115                     break;
116                   }
117                   if (memcmp( xrs->part[1].id, "XGM", 3 ) != 0) {
118                     printk( "\nID of extended partition is not XGM!\n" );
119                     brelse( xbh );
120                     break;
121                   }
122
123                   partsect = be32_to_cpu(xrs->part[1].st) + extensect;
124                   brelse (xbh);
125                   minor++;
126                   if (minor >= m_lim) {
127                     printk( "\nMaximum number of partitions reached!\n" );
128                     break;
129                   }
130                 }
131               printk(" >");
132             }
133           else
134             {
135               /* we don't care about other id's */
136               add_gd_partition (hd, minor, be32_to_cpu(pi->st),
137                                 be32_to_cpu(pi->siz));
138             }
139         }
140     }
141 #ifdef ICD_PARTS
142   if ( part_fmt!=1 ) /* no extended partitions -> test ICD-format */
143   {
144     pi = &rs->icdpart[0];
145     /* sanity check: no ICD format if first partition invalid */
146     if (memcmp (pi->id, "GEM", 3) == 0 ||
147         memcmp (pi->id, "BGM", 3) == 0 ||
148         memcmp (pi->id, "LNX", 3) == 0 ||
149         memcmp (pi->id, "SWP", 3) == 0 ||
150         memcmp (pi->id, "RAW", 3) == 0 )
151     {
152       printk(" ICD<");
153       for (; pi < &rs->icdpart[8] && minor < m_lim; minor++, pi++)
154       {
155         /* accept only GEM,BGM,RAW,LNX,SWP partitions */
156         if (pi->flg & 1 && 
157             (memcmp (pi->id, "GEM", 3) == 0 ||
158              memcmp (pi->id, "BGM", 3) == 0 ||
159              memcmp (pi->id, "LNX", 3) == 0 ||
160              memcmp (pi->id, "SWP", 3) == 0 ||
161              memcmp (pi->id, "RAW", 3) == 0) )
162         {
163           part_fmt = 2;
164           add_gd_partition (hd, minor, be32_to_cpu(pi->st),
165                             be32_to_cpu(pi->siz));
166         }
167       }
168       printk(" >");
169     }
170   }
171 #endif
172   brelse (bh);
173
174   printk ("\n");
175
176   return 1;
177 }
178