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
sgi_partition(struct gendisk * hd,struct block_device * bdev,unsigned long first_sector,int current_minor)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, §);
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 }
86