ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / fs / partitions / sun.c
1 /*
2  *  fs/partitions/sun.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 "check.h"
11 #include "sun.h"
12
13 int sun_partition(struct parsed_partitions *state, struct block_device *bdev)
14 {
15         int i, csum;
16         int slot = 1;
17         unsigned short *ush;
18         Sector sect;
19         struct sun_disklabel {
20                 unsigned char info[128];   /* Informative text string */
21                 unsigned char spare0[14];
22                 struct sun_info {
23                         unsigned char spare1;
24                         unsigned char id;
25                         unsigned char spare2;
26                         unsigned char flags;
27                 } infos[8];
28                 unsigned char spare[246];  /* Boot information etc. */
29                 unsigned short rspeed;     /* Disk rotational speed */
30                 unsigned short pcylcount;  /* Physical cylinder count */
31                 unsigned short sparecyl;   /* extra sects per cylinder */
32                 unsigned char spare2[4];   /* More magic... */
33                 unsigned short ilfact;     /* Interleave factor */
34                 unsigned short ncyl;       /* Data cylinder count */
35                 unsigned short nacyl;      /* Alt. cylinder count */
36                 unsigned short ntrks;      /* Tracks per cylinder */
37                 unsigned short nsect;      /* Sectors per track */
38                 unsigned char spare3[4];   /* Even more magic... */
39                 struct sun_partition {
40                         __u32 start_cylinder;
41                         __u32 num_sectors;
42                 } partitions[8];
43                 unsigned short magic;      /* Magic number */
44                 unsigned short csum;       /* Label xor'd checksum */
45         } * label;              
46         struct sun_partition *p;
47         unsigned long spc;
48         char b[BDEVNAME_SIZE];
49
50         label = (struct sun_disklabel *)read_dev_sector(bdev, 0, &sect);
51         if (!label)
52                 return -1;
53
54         p = label->partitions;
55         if (be16_to_cpu(label->magic) != SUN_LABEL_MAGIC) {
56 /*              printk(KERN_INFO "Dev %s Sun disklabel: bad magic %04x\n",
57                        bdevname(bdev, b), be16_to_cpu(label->magic)); */
58                 put_dev_sector(sect);
59                 return 0;
60         }
61         /* Look at the checksum */
62         ush = ((unsigned short *) (label+1)) - 1;
63         for (csum = 0; ush >= ((unsigned short *) label);)
64                 csum ^= *ush--;
65         if (csum) {
66                 printk("Dev %s Sun disklabel: Csum bad, label corrupted\n",
67                        bdevname(bdev, b));
68                 put_dev_sector(sect);
69                 return 0;
70         }
71
72         /* All Sun disks have 8 partition entries */
73         spc = be16_to_cpu(label->ntrks) * be16_to_cpu(label->nsect);
74         for (i = 0; i < 8; i++, p++) {
75                 unsigned long st_sector;
76                 int num_sectors;
77
78                 st_sector = be32_to_cpu(p->start_cylinder) * spc;
79                 num_sectors = be32_to_cpu(p->num_sectors);
80                 if (num_sectors) {
81                         put_partition(state, slot, st_sector, num_sectors);
82                         if (label->infos[i].id == LINUX_RAID_PARTITION)
83                                 state->parts[slot].flags = 1;
84                 }
85                 slot++;
86         }
87         printk("\n");
88         put_dev_sector(sect);
89         return 1;
90 }