Statistics
| Branch: | Revision:

root / part / partition.c @ abdb293f

History | View | Annotate | Download (2.2 kB)

1

    
2
#ifdef HAVE_CONFIG_H
3
#include "config.h"
4
#endif
5

    
6
#include <errno.h>
7
#include <endian.h>
8
#include <byteswap.h>
9

    
10
#include "partition.h"
11

    
12
#if BYTE_ORDER == LITTLE_ENDIAN
13
  #define le16_to_cpu(x) (x)
14
  #define le32_to_cpu(x) (x)
15
  #define cpu_to_le16(x) (x)
16
  #define cpu_to_le32(x) (x)
17
#else
18
  #define le16_to_cpu(x) bswap_16(x)
19
  #define le32_to_cpu(x) bswap_32(x)
20
  #define cpu_to_le16(x) bswap_16(x)
21
  #define cpu_to_le32(x) bswap_32(x)
22
#endif
23

    
24
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a)[0])
25

    
26
void
27
primary_partition_in(struct primary_partition *p)
28
{
29
        p->lba    = le32_to_cpu(p->lba);
30
        p->blocks = le32_to_cpu(p->blocks);        
31
}
32

    
33
void
34
primary_partition_out(struct primary_partition *p)
35
{
36
        p->lba    = cpu_to_le32(p->lba);
37
        p->blocks = cpu_to_le32(p->blocks);        
38
}
39

    
40
void
41
partition_table_in(struct partition_table *pt)
42
{
43
        int i;
44

    
45
        pt->disk_signature = le32_to_cpu(pt->disk_signature);
46
        pt->mbr_signature  = le16_to_cpu(pt->mbr_signature);
47

    
48
        for (i = 0; i < ARRAY_SIZE(pt->partitions); i++)
49
                primary_partition_in(pt->partitions + i);
50
}
51

    
52
void
53
partition_table_out(struct partition_table *pt)
54
{
55
        int i;
56

    
57
        pt->disk_signature = cpu_to_le32(pt->disk_signature);
58
        pt->mbr_signature  = cpu_to_le16(pt->mbr_signature);
59

    
60
        for (i = 0; i < ARRAY_SIZE(pt->partitions); i++)
61
                primary_partition_out(pt->partitions + i);
62
}
63

    
64
int
65
primary_partition_validate(struct primary_partition *p)
66
{
67
        if (p->status != PARTITION_BOOTABLE &&
68
            p->status != PARTITION_NON_BOOTABLE)
69
                return EINVAL;
70

    
71
        return 0;
72
}
73

    
74
int
75
partition_table_validate(struct partition_table *pt)
76
{
77
        int i;
78

    
79
        if (pt->mbr_signature != MBR_SIGNATURE)
80
                return EINVAL;
81

    
82
        for (i = 0; i < ARRAY_SIZE(pt->partitions); i++) {
83
                int err = primary_partition_validate(pt->partitions + i);
84
                if (err)
85
                        return err;
86
        }
87

    
88
        return 0;
89
}
90

    
91
struct partition_chs
92
lba_to_chs(struct partition_geometry *geo, uint64_t lba)
93
{
94
        struct partition_chs c;
95

    
96
        if (lba >= 0x3ff * geo->sectors * geo->heads) {
97
                c.chs[0]  = geo->heads - 1;
98
                c.chs[1]  = geo->sectors;
99
                lba       = 0x3ff;
100
        } else {
101
                c.chs[1]  = lba % geo->sectors + 1;
102
                lba      /= geo->sectors;
103

    
104
                c.chs[0]  = lba % geo->heads;
105
                lba      /= geo->heads;
106
        }
107

    
108
        c.chs[2]  = lba & 0xff;
109
        c.chs[1] |= (lba >> 2) & 0xc0;
110

    
111
        return c;
112
}