make oldconfig will rebuild these...
[linux-2.4.21-pre4.git] / fs / partitions / sgi.c
1 /*
2  *  fs/partitions/sgi.c
3  *
4  *  Code extracted from drivers/block/genhd.c
5  */
6
7 #include <linux/fs.h>
8 #include <linux/genhd.h>
9 #include <linux/kernel.h>
10 #include <linux/major.h>
11 #include <linux/string.h>
12 #include <linux/blk.h>
13
14 #include <asm/byteorder.h>
15 #include <asm/system.h>
16
17 #include "check.h"
18 #include "sgi.h"
19
20 int sgi_partition(struct gendisk *hd, struct block_device *bdev, unsigned long first_sector, int current_minor)
21 {
22         int i, csum, magic;
23         unsigned int *ui, start, blocks, cs;
24         Sector sect;
25         kdev_t dev = to_kdev_t(bdev->bd_dev);
26         struct sgi_disklabel {
27                 int magic_mushroom;         /* Big fat spliff... */
28                 short root_part_num;        /* Root partition number */
29                 short swap_part_num;        /* Swap partition number */
30                 char boot_file[16];         /* Name of boot file for ARCS */
31                 unsigned char _unused0[48]; /* Device parameter useless crapola.. */
32                 struct sgi_volume {
33                         char name[8];       /* Name of volume */
34                         int  block_num;     /* Logical block number */
35                         int  num_bytes;     /* How big, in bytes */
36                 } volume[15];
37                 struct sgi_partition {
38                         int num_blocks;     /* Size in logical blocks */
39                         int first_block;    /* First logical block */
40                         int type;           /* Type of this partition */
41                 } partitions[16];
42                 int csum;                   /* Disk label checksum */
43                 int _unused1;               /* Padding */
44         } *label;
45         struct sgi_partition *p;
46
47         label = (struct sgi_disklabel *) read_dev_sector(bdev, 0, &sect);
48         if (!label)
49                 return -1;
50         p = &label->partitions[0];
51         magic = label->magic_mushroom;
52         if(be32_to_cpu(magic) != SGI_LABEL_MAGIC) {
53                 /*printk("Dev %s SGI disklabel: bad magic %08x\n",
54                        bdevname(dev), magic);*/
55                 put_dev_sector(sect);
56                 return 0;
57         }
58         ui = ((unsigned int *) (label + 1)) - 1;
59         for(csum = 0; ui >= ((unsigned int *) label);) {
60                 cs = *ui--;
61                 csum += be32_to_cpu(cs);
62         }
63         if(csum) {
64                 printk(KERN_WARNING "Dev %s SGI disklabel: csum bad, label corrupted\n",
65                        bdevname(dev));
66                 put_dev_sector(sect);
67                 return 0;
68         }
69         /* All SGI disk labels have 16 partitions, disks under Linux only
70          * have 15 minor's.  Luckily there are always a few zero length
71          * partitions which we don't care about so we never overflow the
72          * current_minor.
73          */
74         for(i = 0; i < 16; i++, p++) {
75                 blocks = be32_to_cpu(p->num_blocks);
76                 start  = be32_to_cpu(p->first_block);
77                 if(!blocks)
78                         continue;
79                 add_gd_partition(hd, current_minor, start, blocks);
80                 current_minor++;
81         }
82         printk("\n");
83         put_dev_sector(sect);
84         return 1;
85 }